c-decl.c revision 96263
118334Speter/* Process declarations and variables for C compiler.
290075Sobrien   Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
390075Sobrien   2001, 2002 Free Software Foundation, Inc.
418334Speter
590075SobrienThis file is part of GCC.
618334Speter
790075SobrienGCC is free software; you can redistribute it and/or modify it under
890075Sobrienthe terms of the GNU General Public License as published by the Free
990075SobrienSoftware Foundation; either version 2, or (at your option) any later
1090075Sobrienversion.
1118334Speter
1290075SobrienGCC is distributed in the hope that it will be useful, but WITHOUT ANY
1390075SobrienWARRANTY; without even the implied warranty of MERCHANTABILITY or
1490075SobrienFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1590075Sobrienfor more details.
1618334Speter
1718334SpeterYou should have received a copy of the GNU General Public License
1890075Sobrienalong with GCC; see the file COPYING.  If not, write to the Free
1990075SobrienSoftware Foundation, 59 Temple Place - Suite 330, Boston, MA
2090075Sobrien02111-1307, USA.  */
2118334Speter
2218334Speter/* Process declarations and symbol lookup for C front end.
2318334Speter   Also constructs types; the standard scalar types at initialization,
2418334Speter   and structure, union, array and enum types when they are declared.  */
2518334Speter
2618334Speter/* ??? not all decl nodes are given the most useful possible
2718334Speter   line numbers.  For example, the CONST_DECLs for enum values.  */
2818334Speter
2918334Speter#include "config.h"
3050397Sobrien#include "system.h"
3190075Sobrien#include "intl.h"
3218334Speter#include "tree.h"
3390075Sobrien#include "tree-inline.h"
3490075Sobrien#include "rtl.h"
3518334Speter#include "flags.h"
3690075Sobrien#include "function.h"
3718334Speter#include "output.h"
3890075Sobrien#include "expr.h"
3918334Speter#include "c-tree.h"
4018334Speter#include "c-lex.h"
4150397Sobrien#include "toplev.h"
4290075Sobrien#include "ggc.h"
4390075Sobrien#include "tm_p.h"
4450397Sobrien#include "cpplib.h"
4590075Sobrien#include "target.h"
4690075Sobrien#include "debug.h"
4790075Sobrien#include "timevar.h"
4890075Sobrien#include "c-common.h"
4996263Sobrien#include "c-pragma.h"
5050397Sobrien
5118334Speter/* In grokdeclarator, distinguish syntactic contexts of declarators.  */
5218334Speterenum decl_context
5318334Speter{ NORMAL,			/* Ordinary declaration */
5418334Speter  FUNCDEF,			/* Function definition */
5518334Speter  PARM,				/* Declaration of parm before function body */
5618334Speter  FIELD,			/* Declaration inside struct or union */
5796263Sobrien  BITFIELD,			/* Likewise but with specified width */
5818334Speter  TYPENAME};			/* Typename (inside cast or sizeof)  */
5918334Speter
6018334Speter
6118334Speter/* Nonzero if we have seen an invalid cross reference
6218334Speter   to a struct, union, or enum, but not yet printed the message.  */
6318334Speter
6418334Spetertree pending_invalid_xref;
6518334Speter/* File and line to appear in the eventual error message.  */
6690075Sobrienconst char *pending_invalid_xref_file;
6718334Speterint pending_invalid_xref_line;
6818334Speter
6918334Speter/* While defining an enum type, this is 1 plus the last enumerator
7018334Speter   constant value.  Note that will do not have to save this or `enum_overflow'
7118334Speter   around nested function definition since such a definition could only
7218334Speter   occur in an enum value expression and we don't use these variables in
7318334Speter   that case.  */
7418334Speter
7518334Speterstatic tree enum_next_value;
7618334Speter
7718334Speter/* Nonzero means that there was overflow computing enum_next_value.  */
7818334Speter
7918334Speterstatic int enum_overflow;
8018334Speter
8118334Speter/* Parsing a function declarator leaves a list of parameter names
8218334Speter   or a chain or parameter decls here.  */
8318334Speter
8418334Speterstatic tree last_function_parms;
8518334Speter
8618334Speter/* Parsing a function declarator leaves here a chain of structure
8718334Speter   and enum types declared in the parmlist.  */
8818334Speter
8918334Speterstatic tree last_function_parm_tags;
9018334Speter
9118334Speter/* After parsing the declarator that starts a function definition,
9218334Speter   `start_function' puts here the list of parameter names or chain of decls.
9318334Speter   `store_parm_decls' finds it here.  */
9418334Speter
9518334Speterstatic tree current_function_parms;
9618334Speter
9718334Speter/* Similar, for last_function_parm_tags.  */
9818334Speterstatic tree current_function_parm_tags;
9918334Speter
10018334Speter/* Similar, for the file and line that the prototype came from if this is
10118334Speter   an old-style definition.  */
10290075Sobrienstatic const char *current_function_prototype_file;
10318334Speterstatic int current_function_prototype_line;
10418334Speter
10590075Sobrien/* The current statement tree.  */
10690075Sobrien
10790075Sobrienstatic struct stmt_tree_s c_stmt_tree;
10890075Sobrien
10990075Sobrien/* The current scope statement stack.  */
11090075Sobrien
11190075Sobrienstatic tree c_scope_stmt_stack;
11290075Sobrien
11318334Speter/* A list (chain of TREE_LIST nodes) of all LABEL_DECLs in the function
11418334Speter   that have names.  Here so we can clear out their names' definitions
11518334Speter   at the end of the function.  */
11618334Speter
11718334Speterstatic tree named_labels;
11818334Speter
11918334Speter/* A list of LABEL_DECLs from outer contexts that are currently shadowed.  */
12018334Speter
12118334Speterstatic tree shadowed_labels;
12218334Speter
12318334Speter/* Nonzero when store_parm_decls is called indicates a varargs function.
12418334Speter   Value not meaningful after store_parm_decls.  */
12518334Speter
12618334Speterstatic int c_function_varargs;
12718334Speter
12818334Speter/* Set to 0 at beginning of a function definition, set to 1 if
12918334Speter   a return statement that specifies a return value is seen.  */
13018334Speter
13118334Speterint current_function_returns_value;
13218334Speter
13318334Speter/* Set to 0 at beginning of a function definition, set to 1 if
13418334Speter   a return statement with no argument is seen.  */
13518334Speter
13618334Speterint current_function_returns_null;
13718334Speter
13896263Sobrien/* Set to 0 at beginning of a function definition, set to 1 if
13996263Sobrien   a call to a noreturn function is seen.  */
14096263Sobrien
14196263Sobrienint current_function_returns_abnormally;
14296263Sobrien
14318334Speter/* Set to nonzero by `grokdeclarator' for a function
14418334Speter   whose return type is defaulted, if warnings for this are desired.  */
14518334Speter
14618334Speterstatic int warn_about_return_type;
14718334Speter
14818334Speter/* Nonzero when starting a function declared `extern inline'.  */
14918334Speter
15018334Speterstatic int current_extern_inline;
15118334Speter
15218334Speter/* For each binding contour we allocate a binding_level structure
15318334Speter * which records the names defined in that contour.
15418334Speter * Contours include:
15518334Speter *  0) the global one
15618334Speter *  1) one for each function definition,
15718334Speter *     where internal declarations of the parameters appear.
15818334Speter *  2) one for each compound statement,
15918334Speter *     to record its declarations.
16018334Speter *
16118334Speter * The current meaning of a name can be found by searching the levels from
16218334Speter * the current one out to the global one.
16318334Speter */
16418334Speter
16518334Speter/* Note that the information in the `names' component of the global contour
16618334Speter   is duplicated in the IDENTIFIER_GLOBAL_VALUEs of all identifiers.  */
16718334Speter
16818334Speterstruct binding_level
16918334Speter  {
17018334Speter    /* A chain of _DECL nodes for all variables, constants, functions,
17118334Speter       and typedef types.  These are in the reverse of the order supplied.
17218334Speter     */
17318334Speter    tree names;
17418334Speter
17518334Speter    /* A list of structure, union and enum definitions,
17618334Speter     * for looking up tag names.
17718334Speter     * It is a chain of TREE_LIST nodes, each of whose TREE_PURPOSE is a name,
17818334Speter     * or NULL_TREE; and whose TREE_VALUE is a RECORD_TYPE, UNION_TYPE,
17918334Speter     * or ENUMERAL_TYPE node.
18018334Speter     */
18118334Speter    tree tags;
18218334Speter
18318334Speter    /* For each level, a list of shadowed outer-level local definitions
18418334Speter       to be restored when this level is popped.
18518334Speter       Each link is a TREE_LIST whose TREE_PURPOSE is an identifier and
18618334Speter       whose TREE_VALUE is its old definition (a kind of ..._DECL node).  */
18718334Speter    tree shadowed;
18818334Speter
18918334Speter    /* For each level (except not the global one),
19018334Speter       a chain of BLOCK nodes for all the levels
19118334Speter       that were entered and exited one level down.  */
19218334Speter    tree blocks;
19318334Speter
19418334Speter    /* The BLOCK node for this level, if one has been preallocated.
19518334Speter       If 0, the BLOCK is allocated (if needed) when the level is popped.  */
19618334Speter    tree this_block;
19718334Speter
19818334Speter    /* The binding level which this one is contained in (inherits from).  */
19918334Speter    struct binding_level *level_chain;
20018334Speter
20118334Speter    /* Nonzero for the level that holds the parameters of a function.  */
20218334Speter    char parm_flag;
20318334Speter
20418334Speter    /* Nonzero if this level "doesn't exist" for tags.  */
20518334Speter    char tag_transparent;
20618334Speter
20718334Speter    /* Nonzero if sublevels of this level "don't exist" for tags.
20818334Speter       This is set in the parm level of a function definition
20918334Speter       while reading the function body, so that the outermost block
21018334Speter       of the function body will be tag-transparent.  */
21118334Speter    char subblocks_tag_transparent;
21218334Speter
21318334Speter    /* Nonzero means make a BLOCK for this level regardless of all else.  */
21418334Speter    char keep;
21518334Speter
21618334Speter    /* Nonzero means make a BLOCK if this level has any subblocks.  */
21718334Speter    char keep_if_subblocks;
21818334Speter
21990075Sobrien    /* Number of decls in `names' that have incomplete
22018334Speter       structure or union types.  */
22118334Speter    int n_incomplete;
22218334Speter
22318334Speter    /* A list of decls giving the (reversed) specified order of parms,
22418334Speter       not including any forward-decls in the parmlist.
22518334Speter       This is so we can put the parms in proper order for assign_parms.  */
22618334Speter    tree parm_order;
22718334Speter  };
22818334Speter
22918334Speter#define NULL_BINDING_LEVEL (struct binding_level *) NULL
23090075Sobrien
23118334Speter/* The binding level currently in effect.  */
23218334Speter
23318334Speterstatic struct binding_level *current_binding_level;
23418334Speter
23518334Speter/* A chain of binding_level structures awaiting reuse.  */
23618334Speter
23718334Speterstatic struct binding_level *free_binding_level;
23818334Speter
23918334Speter/* The outermost binding level, for names of file scope.
24018334Speter   This is created when the compiler is started and exists
24118334Speter   through the entire run.  */
24218334Speter
24318334Speterstatic struct binding_level *global_binding_level;
24418334Speter
24518334Speter/* Binding level structures are initialized by copying this one.  */
24618334Speter
24718334Speterstatic struct binding_level clear_binding_level
24818334Speter  = {NULL, NULL, NULL, NULL, NULL, NULL_BINDING_LEVEL, 0, 0, 0, 0, 0, 0,
24918334Speter     NULL};
25018334Speter
25118334Speter/* Nonzero means unconditionally make a BLOCK for the next level pushed.  */
25218334Speter
25318334Speterstatic int keep_next_level_flag;
25418334Speter
25518334Speter/* Nonzero means make a BLOCK for the next level pushed
25618334Speter   if it has subblocks.  */
25718334Speter
25818334Speterstatic int keep_next_if_subblocks;
25990075Sobrien
26018334Speter/* The chain of outer levels of label scopes.
26118334Speter   This uses the same data structure used for binding levels,
26218334Speter   but it works differently: each link in the chain records
26318334Speter   saved values of named_labels and shadowed_labels for
26418334Speter   a label binding level outside the current one.  */
26518334Speter
26618334Speterstatic struct binding_level *label_level_chain;
26718334Speter
26818334Speter/* Functions called automatically at the beginning and end of execution.  */
26918334Speter
27018334Spetertree static_ctors, static_dtors;
27118334Speter
27218334Speter/* Forward declarations.  */
27318334Speter
27490075Sobrienstatic struct binding_level * make_binding_level	PARAMS ((void));
27590075Sobrienstatic void mark_binding_level		PARAMS ((void *));
27690075Sobrienstatic void clear_limbo_values		PARAMS ((tree));
27790075Sobrienstatic int duplicate_decls		PARAMS ((tree, tree, int));
27890075Sobrienstatic int redeclaration_error_message	PARAMS ((tree, tree));
27990075Sobrienstatic void storedecls			PARAMS ((tree));
28090075Sobrienstatic void storetags			PARAMS ((tree));
28190075Sobrienstatic tree lookup_tag			PARAMS ((enum tree_code, tree,
28290075Sobrien						 struct binding_level *, int));
28390075Sobrienstatic tree lookup_tag_reverse		PARAMS ((tree));
28490075Sobrienstatic tree grokdeclarator		PARAMS ((tree, tree, enum decl_context,
28596263Sobrien						 int));
28690075Sobrienstatic tree grokparms			PARAMS ((tree, int));
28790075Sobrienstatic void layout_array_type		PARAMS ((tree));
28890075Sobrienstatic tree c_make_fname_decl           PARAMS ((tree, int));
28990075Sobrienstatic void c_expand_body               PARAMS ((tree, int, int));
29090075Sobrienstatic void warn_if_shadowing		PARAMS ((tree, tree));
29118334Speter
29218334Speter/* C-specific option variables.  */
29318334Speter
29418334Speter/* Nonzero means allow type mismatches in conditional expressions;
29590075Sobrien   just make their values `void'.  */
29618334Speter
29718334Speterint flag_cond_mismatch;
29818334Speter
29918334Speter/* Nonzero means don't recognize the keyword `asm'.  */
30018334Speter
30118334Speterint flag_no_asm;
30218334Speter
30390075Sobrien/* Nonzero means do some things the same way PCC does.  */
30418334Speter
30590075Sobrienint flag_traditional;
30618334Speter
30790075Sobrien/* Nonzero means enable C89 Amendment 1 features.  */
30818334Speter
30990075Sobrienint flag_isoc94 = 0;
31018334Speter
31190075Sobrien/* Nonzero means use the ISO C99 dialect of C.  */
31218334Speter
31390075Sobrienint flag_isoc99 = 0;
31418334Speter
31550397Sobrien/* Nonzero means that we have builtin functions, and main is an int */
31650397Sobrien
31750397Sobrienint flag_hosted = 1;
31850397Sobrien
31990075Sobrien/* Nonzero means add default format_arg attributes for functions not
32090075Sobrien   in ISO C.  */
32190075Sobrien
32290075Sobrienint flag_noniso_default_format_attributes = 1;
32390075Sobrien
32418334Speter/* Nonzero means to allow single precision math even if we're generally
32550397Sobrien   being traditional.  */
32618334Speterint flag_allow_single_precision = 0;
32718334Speter
32896263Sobrien/* Nonzero means to treat bitfields as signed unless they say `unsigned'.  */
32918334Speter
33018334Speterint flag_signed_bitfields = 1;
33118334Speterint explicit_flag_signed_bitfields = 0;
33218334Speter
33390075Sobrien/* Nonzero means warn about use of implicit int.  */
33418334Speter
33550397Sobrienint warn_implicit_int;
33618334Speter
33750397Sobrien/* Nonzero means warn about usage of long long when `-pedantic'.  */
33850397Sobrien
33950397Sobrienint warn_long_long = 1;
34050397Sobrien
34150397Sobrien/* Nonzero means message about use of implicit function declarations;
34290075Sobrien 1 means warning; 2 means error.  */
34350397Sobrien
34490075Sobrienint mesg_implicit_function_declaration = -1;
34550397Sobrien
34618334Speter/* Nonzero means give string constants the type `const char *'
34718334Speter   to get extra warnings from them.  These warnings will be too numerous
34818334Speter   to be useful, except in thoroughly ANSIfied programs.  */
34918334Speter
35052284Sobrienint flag_const_strings;
35118334Speter
35218334Speter/* Nonzero means warn about pointer casts that can drop a type qualifier
35318334Speter   from the pointer target type.  */
35418334Speter
35518334Speterint warn_cast_qual;
35618334Speter
35718334Speter/* Nonzero means warn when casting a function call to a type that does
35818334Speter   not match the return type (e.g. (float)sqrt() or (anything*)malloc()
35918334Speter   when there is no previous declaration of sqrt or malloc.  */
36018334Speter
36118334Speterint warn_bad_function_cast;
36218334Speter
36390075Sobrien/* Warn about functions which might be candidates for format attributes.  */
36452284Sobrien
36590075Sobrienint warn_missing_format_attribute;
36652284Sobrien
36718334Speter/* Warn about traditional constructs whose meanings changed in ANSI C.  */
36818334Speter
36918334Speterint warn_traditional;
37018334Speter
37118334Speter/* Nonzero means warn about sizeof(function) or addition/subtraction
37218334Speter   of function pointers.  */
37318334Speter
37418334Speterint warn_pointer_arith;
37518334Speter
37618334Speter/* Nonzero means warn for non-prototype function decls
37718334Speter   or non-prototyped defs without previous prototype.  */
37818334Speter
37918334Speterint warn_strict_prototypes;
38018334Speter
38118334Speter/* Nonzero means warn for any global function def
38218334Speter   without separate previous prototype decl.  */
38318334Speter
38418334Speterint warn_missing_prototypes;
38518334Speter
38618334Speter/* Nonzero means warn for any global function def
38718334Speter   without separate previous decl.  */
38818334Speter
38918334Speterint warn_missing_declarations;
39018334Speter
39118334Speter/* Nonzero means warn about multiple (redundant) decls for the same single
39218334Speter   variable or function.  */
39318334Speter
39418334Speterint warn_redundant_decls = 0;
39518334Speter
39618334Speter/* Nonzero means warn about extern declarations of objects not at
39718334Speter   file-scope level and about *all* declarations of functions (whether
39818334Speter   extern or static) not at file-scope level.  Note that we exclude
39918334Speter   implicit function declarations.  To get warnings about those, use
40018334Speter   -Wimplicit.  */
40118334Speter
40218334Speterint warn_nested_externs = 0;
40318334Speter
40418334Speter/* Warn about a subscript that has type char.  */
40518334Speter
40618334Speterint warn_char_subscripts = 0;
40718334Speter
40818334Speter/* Warn if a type conversion is done that might have confusing results.  */
40918334Speter
41018334Speterint warn_conversion;
41118334Speter
41218334Speter/* Warn if adding () is suggested.  */
41318334Speter
41418334Speterint warn_parentheses;
41518334Speter
41618334Speter/* Warn if initializer is not completely bracketed.  */
41718334Speter
41818334Speterint warn_missing_braces;
41918334Speter
42050397Sobrien/* Warn if main is suspicious.  */
42118334Speter
42250397Sobrienint warn_main;
42350397Sobrien
42450397Sobrien/* Warn about #pragma directives that are not recognised.  */
42550397Sobrien
42690075Sobrienint warn_unknown_pragmas = 0; /* Tri state variable.  */
42750397Sobrien
42850397Sobrien/* Warn about comparison of signed and unsigned values.
42950397Sobrien   If -1, neither -Wsign-compare nor -Wno-sign-compare has been specified.  */
43050397Sobrien
43150397Sobrienint warn_sign_compare = -1;
43250397Sobrien
43390075Sobrien/* Warn about testing equality of floating point numbers.  */
43490075Sobrien
43590075Sobrienint warn_float_equal = 0;
43690075Sobrien
43750397Sobrien/* Nonzero means warn about use of multicharacter literals.  */
43850397Sobrien
43950397Sobrienint warn_multichar = 1;
44050397Sobrien
44150397Sobrien/* Nonzero means `$' can be in an identifier.  */
44250397Sobrien
44318334Speter#ifndef DOLLARS_IN_IDENTIFIERS
44418334Speter#define DOLLARS_IN_IDENTIFIERS 1
44518334Speter#endif
44650397Sobrienint dollars_in_ident = DOLLARS_IN_IDENTIFIERS;
44718334Speter
44890075Sobrien/* States indicating how grokdeclarator() should handle declspecs marked
44990075Sobrien   with __attribute__((deprecated)).  An object declared as
45090075Sobrien   __attribute__((deprecated)) suppresses warnings of uses of other
45190075Sobrien   deprecated items.  */
45290075Sobrien
45390075Sobrienenum deprecated_states {
45490075Sobrien  DEPRECATED_NORMAL,
45590075Sobrien  DEPRECATED_SUPPRESS
45690075Sobrien};
45790075Sobrien
45890075Sobrienstatic enum deprecated_states deprecated_state = DEPRECATED_NORMAL;
45990075Sobrien
46018334Speter/* Decode the string P as a language-specific option for C.
46190075Sobrien   Return the number of strings consumed.  Should not complain
46290075Sobrien   if it does not recognise the option.  */
46390075Sobrien
46418334Speterint
46550397Sobrienc_decode_option (argc, argv)
46652284Sobrien     int argc ATTRIBUTE_UNUSED;
46750397Sobrien     char **argv;
46818334Speter{
46950397Sobrien  int strings_processed;
47050397Sobrien  char *p = argv[0];
47150397Sobrien
47290075Sobrien  strings_processed = cpp_handle_option (parse_in, argc, argv, 0);
47390075Sobrien
47418334Speter  if (!strcmp (p, "-ftraditional") || !strcmp (p, "-traditional"))
47518334Speter    {
47690075Sobrien      warning ("-traditional is deprecated and may be removed");
47718334Speter      flag_traditional = 1;
47818334Speter      flag_writable_strings = 1;
47918334Speter    }
48018334Speter  else if (!strcmp (p, "-fallow-single-precision"))
48118334Speter    flag_allow_single_precision = 1;
48250397Sobrien  else if (!strcmp (p, "-fhosted") || !strcmp (p, "-fno-freestanding"))
48350397Sobrien    {
48450397Sobrien      flag_hosted = 1;
48550397Sobrien      flag_no_builtin = 0;
48650397Sobrien    }
48750397Sobrien  else if (!strcmp (p, "-ffreestanding") || !strcmp (p, "-fno-hosted"))
48850397Sobrien    {
48950397Sobrien      flag_hosted = 0;
49050397Sobrien      flag_no_builtin = 1;
49150397Sobrien      /* warn_main will be 2 if set by -Wall, 1 if set by -Wmain */
49250397Sobrien      if (warn_main == 2)
49350397Sobrien	warn_main = 0;
49450397Sobrien    }
49518334Speter  else if (!strcmp (p, "-fnotraditional") || !strcmp (p, "-fno-traditional"))
49618334Speter    {
49718334Speter      flag_traditional = 0;
49818334Speter      flag_writable_strings = 0;
49918334Speter    }
50052284Sobrien  else if (!strncmp (p, "-std=", 5))
50152284Sobrien    {
50252284Sobrien      /* Select the appropriate language standard.  We currently
50352284Sobrien	 recognize:
50452284Sobrien	 -std=iso9899:1990	same as -ansi
50552284Sobrien	 -std=iso9899:199409	ISO C as modified in amend. 1
50690075Sobrien	 -std=iso9899:1999	ISO C 99
50752284Sobrien	 -std=c89		same as -std=iso9899:1990
50890075Sobrien	 -std=c99		same as -std=iso9899:1999
50952284Sobrien	 -std=gnu89		default, iso9899:1990 + gnu extensions
51090075Sobrien	 -std=gnu99		iso9899:1999 + gnu extensions
51152284Sobrien      */
51290075Sobrien      const char *const argstart = &p[5];
51352284Sobrien
51452284Sobrien      if (!strcmp (argstart, "iso9899:1990")
51552284Sobrien	  || !strcmp (argstart, "c89"))
51652284Sobrien	{
51752284Sobrien	iso_1990:
51890075Sobrien	  flag_isoc94 = 0;
51990075Sobrien	iso_1994:
52052284Sobrien	  flag_traditional = 0;
52152284Sobrien	  flag_writable_strings = 0;
52252284Sobrien	  flag_no_asm = 1;
52352284Sobrien	  flag_no_nonansi_builtin = 1;
52490075Sobrien	  flag_noniso_default_format_attributes = 0;
52590075Sobrien	  flag_isoc99 = 0;
52652284Sobrien	}
52752284Sobrien      else if (!strcmp (argstart, "iso9899:199409"))
52852284Sobrien	{
52990075Sobrien	  flag_isoc94 = 1;
53090075Sobrien	  goto iso_1994;
53152284Sobrien	}
53252284Sobrien      else if (!strcmp (argstart, "iso9899:199x")
53390075Sobrien	       || !strcmp (argstart, "iso9899:1999")
53490075Sobrien	       || !strcmp (argstart, "c9x")
53590075Sobrien	       || !strcmp (argstart, "c99"))
53652284Sobrien	{
53752284Sobrien	  flag_traditional = 0;
53852284Sobrien	  flag_writable_strings = 0;
53952284Sobrien	  flag_no_asm = 1;
54052284Sobrien	  flag_no_nonansi_builtin = 1;
54190075Sobrien	  flag_noniso_default_format_attributes = 0;
54290075Sobrien	  flag_isoc99 = 1;
54390075Sobrien	  flag_isoc94 = 1;
54452284Sobrien	}
54552284Sobrien      else if (!strcmp (argstart, "gnu89"))
54652284Sobrien	{
54752284Sobrien	  flag_traditional = 0;
54852284Sobrien	  flag_writable_strings = 0;
54952284Sobrien	  flag_no_asm = 0;
55052284Sobrien	  flag_no_nonansi_builtin = 0;
55190075Sobrien	  flag_noniso_default_format_attributes = 1;
55290075Sobrien	  flag_isoc99 = 0;
55390075Sobrien	  flag_isoc94 = 0;
55452284Sobrien	}
55590075Sobrien      else if (!strcmp (argstart, "gnu9x") || !strcmp (argstart, "gnu99"))
55652284Sobrien	{
55752284Sobrien	  flag_traditional = 0;
55852284Sobrien	  flag_writable_strings = 0;
55952284Sobrien	  flag_no_asm = 0;
56052284Sobrien	  flag_no_nonansi_builtin = 0;
56190075Sobrien	  flag_noniso_default_format_attributes = 1;
56290075Sobrien	  flag_isoc99 = 1;
56390075Sobrien	  flag_isoc94 = 1;
56452284Sobrien	}
56552284Sobrien      else
56652284Sobrien	error ("unknown C standard `%s'", argstart);
56752284Sobrien    }
56818334Speter  else if (!strcmp (p, "-fdollars-in-identifiers"))
56950397Sobrien    dollars_in_ident = 1;
57018334Speter  else if (!strcmp (p, "-fno-dollars-in-identifiers"))
57118334Speter    dollars_in_ident = 0;
57218334Speter  else if (!strcmp (p, "-fsigned-char"))
57318334Speter    flag_signed_char = 1;
57418334Speter  else if (!strcmp (p, "-funsigned-char"))
57518334Speter    flag_signed_char = 0;
57618334Speter  else if (!strcmp (p, "-fno-signed-char"))
57718334Speter    flag_signed_char = 0;
57818334Speter  else if (!strcmp (p, "-fno-unsigned-char"))
57918334Speter    flag_signed_char = 1;
58018334Speter  else if (!strcmp (p, "-fsigned-bitfields")
58118334Speter	   || !strcmp (p, "-fno-unsigned-bitfields"))
58218334Speter    {
58318334Speter      flag_signed_bitfields = 1;
58418334Speter      explicit_flag_signed_bitfields = 1;
58518334Speter    }
58618334Speter  else if (!strcmp (p, "-funsigned-bitfields")
58718334Speter	   || !strcmp (p, "-fno-signed-bitfields"))
58818334Speter    {
58918334Speter      flag_signed_bitfields = 0;
59018334Speter      explicit_flag_signed_bitfields = 1;
59118334Speter    }
59218334Speter  else if (!strcmp (p, "-fshort-enums"))
59318334Speter    flag_short_enums = 1;
59418334Speter  else if (!strcmp (p, "-fno-short-enums"))
59518334Speter    flag_short_enums = 0;
59690075Sobrien  else if (!strcmp (p, "-fshort-wchar"))
59790075Sobrien    flag_short_wchar = 1;
59890075Sobrien  else if (!strcmp (p, "-fno-short-wchar"))
59990075Sobrien    flag_short_wchar = 0;
60018334Speter  else if (!strcmp (p, "-fcond-mismatch"))
60118334Speter    flag_cond_mismatch = 1;
60218334Speter  else if (!strcmp (p, "-fno-cond-mismatch"))
60318334Speter    flag_cond_mismatch = 0;
60418334Speter  else if (!strcmp (p, "-fshort-double"))
60518334Speter    flag_short_double = 1;
60618334Speter  else if (!strcmp (p, "-fno-short-double"))
60718334Speter    flag_short_double = 0;
60818334Speter  else if (!strcmp (p, "-fasm"))
60918334Speter    flag_no_asm = 0;
61018334Speter  else if (!strcmp (p, "-fno-asm"))
61118334Speter    flag_no_asm = 1;
61218334Speter  else if (!strcmp (p, "-fbuiltin"))
61318334Speter    flag_no_builtin = 0;
61418334Speter  else if (!strcmp (p, "-fno-builtin"))
61518334Speter    flag_no_builtin = 1;
61690075Sobrien  else if (!strncmp (p, "-fno-builtin-", strlen ("-fno-builtin-")))
61790075Sobrien    disable_builtin_function (p + strlen ("-fno-builtin-"));
61890075Sobrien  else if (p[0] == '-' && p[1] == 'f' && dump_switch_p (p + 2))
61990075Sobrien    ;
62018334Speter  else if (!strcmp (p, "-ansi"))
62152284Sobrien    goto iso_1990;
62250397Sobrien  else if (!strcmp (p, "-Werror-implicit-function-declaration"))
62350397Sobrien    mesg_implicit_function_declaration = 2;
62450397Sobrien  else if (!strcmp (p, "-Wimplicit-function-declaration"))
62550397Sobrien    mesg_implicit_function_declaration = 1;
62650397Sobrien  else if (!strcmp (p, "-Wno-implicit-function-declaration"))
62750397Sobrien    mesg_implicit_function_declaration = 0;
62850397Sobrien  else if (!strcmp (p, "-Wimplicit-int"))
62950397Sobrien    warn_implicit_int = 1;
63050397Sobrien  else if (!strcmp (p, "-Wno-implicit-int"))
63150397Sobrien    warn_implicit_int = 0;
63218334Speter  else if (!strcmp (p, "-Wimplicit"))
63350397Sobrien    {
63450397Sobrien      warn_implicit_int = 1;
63550397Sobrien      if (mesg_implicit_function_declaration != 2)
63690075Sobrien	mesg_implicit_function_declaration = 1;
63750397Sobrien    }
63818334Speter  else if (!strcmp (p, "-Wno-implicit"))
63950397Sobrien    warn_implicit_int = 0, mesg_implicit_function_declaration = 0;
64050397Sobrien  else if (!strcmp (p, "-Wlong-long"))
64150397Sobrien    warn_long_long = 1;
64250397Sobrien  else if (!strcmp (p, "-Wno-long-long"))
64350397Sobrien    warn_long_long = 0;
64418334Speter  else if (!strcmp (p, "-Wwrite-strings"))
64552284Sobrien    flag_const_strings = 1;
64618334Speter  else if (!strcmp (p, "-Wno-write-strings"))
64752284Sobrien    flag_const_strings = 0;
64818334Speter  else if (!strcmp (p, "-Wcast-qual"))
64918334Speter    warn_cast_qual = 1;
65018334Speter  else if (!strcmp (p, "-Wno-cast-qual"))
65118334Speter    warn_cast_qual = 0;
65218334Speter  else if (!strcmp (p, "-Wbad-function-cast"))
65318334Speter    warn_bad_function_cast = 1;
65418334Speter  else if (!strcmp (p, "-Wno-bad-function-cast"))
65518334Speter    warn_bad_function_cast = 0;
65652284Sobrien  else if (!strcmp (p, "-Wno-missing-noreturn"))
65752284Sobrien    warn_missing_noreturn = 0;
65890075Sobrien  else if (!strcmp (p, "-Wmissing-format-attribute"))
65990075Sobrien    warn_missing_format_attribute = 1;
66090075Sobrien  else if (!strcmp (p, "-Wno-missing-format-attribute"))
66190075Sobrien    warn_missing_format_attribute = 0;
66218334Speter  else if (!strcmp (p, "-Wpointer-arith"))
66318334Speter    warn_pointer_arith = 1;
66418334Speter  else if (!strcmp (p, "-Wno-pointer-arith"))
66518334Speter    warn_pointer_arith = 0;
66618334Speter  else if (!strcmp (p, "-Wstrict-prototypes"))
66718334Speter    warn_strict_prototypes = 1;
66818334Speter  else if (!strcmp (p, "-Wno-strict-prototypes"))
66918334Speter    warn_strict_prototypes = 0;
67018334Speter  else if (!strcmp (p, "-Wmissing-prototypes"))
67118334Speter    warn_missing_prototypes = 1;
67218334Speter  else if (!strcmp (p, "-Wno-missing-prototypes"))
67318334Speter    warn_missing_prototypes = 0;
67418334Speter  else if (!strcmp (p, "-Wmissing-declarations"))
67518334Speter    warn_missing_declarations = 1;
67618334Speter  else if (!strcmp (p, "-Wno-missing-declarations"))
67718334Speter    warn_missing_declarations = 0;
67818334Speter  else if (!strcmp (p, "-Wredundant-decls"))
67918334Speter    warn_redundant_decls = 1;
68018334Speter  else if (!strcmp (p, "-Wno-redundant-decls"))
68118334Speter    warn_redundant_decls = 0;
68218334Speter  else if (!strcmp (p, "-Wnested-externs"))
68318334Speter    warn_nested_externs = 1;
68418334Speter  else if (!strcmp (p, "-Wno-nested-externs"))
68518334Speter    warn_nested_externs = 0;
68618334Speter  else if (!strcmp (p, "-Wtraditional"))
68718334Speter    warn_traditional = 1;
68818334Speter  else if (!strcmp (p, "-Wno-traditional"))
68918334Speter    warn_traditional = 0;
69090075Sobrien  else if (!strncmp (p, "-Wformat=", 9))
69190075Sobrien    set_Wformat (atoi (p + 9));
69218334Speter  else if (!strcmp (p, "-Wformat"))
69390075Sobrien    set_Wformat (1);
69418334Speter  else if (!strcmp (p, "-Wno-format"))
69590075Sobrien    set_Wformat (0);
69690075Sobrien  else if (!strcmp (p, "-Wformat-y2k"))
69790075Sobrien    warn_format_y2k = 1;
69890075Sobrien  else if (!strcmp (p, "-Wno-format-y2k"))
69990075Sobrien    warn_format_y2k = 0;
70090075Sobrien  else if (!strcmp (p, "-Wformat-extra-args"))
70190075Sobrien    warn_format_extra_args = 1;
70290075Sobrien  else if (!strcmp (p, "-Wno-format-extra-args"))
70390075Sobrien    warn_format_extra_args = 0;
70490075Sobrien  else if (!strcmp (p, "-Wformat-nonliteral"))
70590075Sobrien    warn_format_nonliteral = 1;
70690075Sobrien  else if (!strcmp (p, "-Wno-format-nonliteral"))
70790075Sobrien    warn_format_nonliteral = 0;
70890075Sobrien  else if (!strcmp (p, "-Wformat-security"))
70990075Sobrien    warn_format_security = 1;
71090075Sobrien  else if (!strcmp (p, "-Wno-format-security"))
71190075Sobrien    warn_format_security = 0;
71218334Speter  else if (!strcmp (p, "-Wchar-subscripts"))
71318334Speter    warn_char_subscripts = 1;
71418334Speter  else if (!strcmp (p, "-Wno-char-subscripts"))
71518334Speter    warn_char_subscripts = 0;
71618334Speter  else if (!strcmp (p, "-Wconversion"))
71718334Speter    warn_conversion = 1;
71818334Speter  else if (!strcmp (p, "-Wno-conversion"))
71918334Speter    warn_conversion = 0;
72018334Speter  else if (!strcmp (p, "-Wparentheses"))
72118334Speter    warn_parentheses = 1;
72218334Speter  else if (!strcmp (p, "-Wno-parentheses"))
72318334Speter    warn_parentheses = 0;
72418334Speter  else if (!strcmp (p, "-Wreturn-type"))
72518334Speter    warn_return_type = 1;
72618334Speter  else if (!strcmp (p, "-Wno-return-type"))
72718334Speter    warn_return_type = 0;
72890075Sobrien  else if (!strcmp (p, "-Wsequence-point"))
72990075Sobrien    warn_sequence_point = 1;
73090075Sobrien  else if (!strcmp (p, "-Wno-sequence-point"))
73190075Sobrien    warn_sequence_point = 0;
73218334Speter  else if (!strcmp (p, "-Wcomment"))
73318334Speter    ; /* cpp handles this one.  */
73418334Speter  else if (!strcmp (p, "-Wno-comment"))
73518334Speter    ; /* cpp handles this one.  */
73618334Speter  else if (!strcmp (p, "-Wcomments"))
73718334Speter    ; /* cpp handles this one.  */
73818334Speter  else if (!strcmp (p, "-Wno-comments"))
73918334Speter    ; /* cpp handles this one.  */
74018334Speter  else if (!strcmp (p, "-Wtrigraphs"))
74118334Speter    ; /* cpp handles this one.  */
74218334Speter  else if (!strcmp (p, "-Wno-trigraphs"))
74318334Speter    ; /* cpp handles this one.  */
74450397Sobrien  else if (!strcmp (p, "-Wundef"))
74550397Sobrien    ; /* cpp handles this one.  */
74650397Sobrien  else if (!strcmp (p, "-Wno-undef"))
74750397Sobrien    ; /* cpp handles this one.  */
74818334Speter  else if (!strcmp (p, "-Wimport"))
74918334Speter    ; /* cpp handles this one.  */
75018334Speter  else if (!strcmp (p, "-Wno-import"))
75118334Speter    ; /* cpp handles this one.  */
75218334Speter  else if (!strcmp (p, "-Wmissing-braces"))
75318334Speter    warn_missing_braces = 1;
75418334Speter  else if (!strcmp (p, "-Wno-missing-braces"))
75518334Speter    warn_missing_braces = 0;
75650397Sobrien  else if (!strcmp (p, "-Wmain"))
75750397Sobrien    warn_main = 1;
75850397Sobrien  else if (!strcmp (p, "-Wno-main"))
75952284Sobrien    warn_main = -1;
76050397Sobrien  else if (!strcmp (p, "-Wsign-compare"))
76150397Sobrien    warn_sign_compare = 1;
76250397Sobrien  else if (!strcmp (p, "-Wno-sign-compare"))
76350397Sobrien    warn_sign_compare = 0;
76490075Sobrien  else if (!strcmp (p, "-Wfloat-equal"))
76590075Sobrien    warn_float_equal = 1;
76690075Sobrien  else if (!strcmp (p, "-Wno-float-equal"))
76790075Sobrien    warn_float_equal = 0;
76850397Sobrien  else if (!strcmp (p, "-Wmultichar"))
76950397Sobrien    warn_multichar = 1;
77050397Sobrien  else if (!strcmp (p, "-Wno-multichar"))
77150397Sobrien    warn_multichar = 0;
77290075Sobrien  else if (!strcmp (p, "-Wdiv-by-zero"))
77390075Sobrien    warn_div_by_zero = 1;
77490075Sobrien  else if (!strcmp (p, "-Wno-div-by-zero"))
77590075Sobrien    warn_div_by_zero = 0;
77650397Sobrien  else if (!strcmp (p, "-Wunknown-pragmas"))
77750397Sobrien    /* Set to greater than 1, so that even unknown pragmas in system
77850397Sobrien       headers will be warned about.  */
77950397Sobrien    warn_unknown_pragmas = 2;
78050397Sobrien  else if (!strcmp (p, "-Wno-unknown-pragmas"))
78150397Sobrien    warn_unknown_pragmas = 0;
78218334Speter  else if (!strcmp (p, "-Wall"))
78318334Speter    {
78418334Speter      /* We save the value of warn_uninitialized, since if they put
78518334Speter	 -Wuninitialized on the command line, we need to generate a
78618334Speter	 warning about not using it without also specifying -O.  */
78718334Speter      if (warn_uninitialized != 1)
78818334Speter	warn_uninitialized = 2;
78950397Sobrien      warn_implicit_int = 1;
79050397Sobrien      mesg_implicit_function_declaration = 1;
79118334Speter      warn_return_type = 1;
79290075Sobrien      set_Wunused (1);
79318334Speter      warn_switch = 1;
79490075Sobrien      set_Wformat (1);
79518334Speter      warn_char_subscripts = 1;
79618334Speter      warn_parentheses = 1;
79790075Sobrien      warn_sequence_point = 1;
79818334Speter      warn_missing_braces = 1;
79950397Sobrien      /* We set this to 2 here, but 1 in -Wmain, so -ffreestanding can turn
80050397Sobrien	 it off only if it's not explicit.  */
80150397Sobrien      warn_main = 2;
80250397Sobrien      /* Only warn about unknown pragmas that are not in system headers.  */
80350397Sobrien      warn_unknown_pragmas = 1;
80418334Speter    }
80518334Speter  else
80650397Sobrien    return strings_processed;
80718334Speter
80818334Speter  return 1;
80918334Speter}
81018334Speter
81118334Spetervoid
81290075Sobrienc_print_identifier (file, node, indent)
81318334Speter     FILE *file;
81418334Speter     tree node;
81518334Speter     int indent;
81618334Speter{
81718334Speter  print_node (file, "global", IDENTIFIER_GLOBAL_VALUE (node), indent + 4);
81818334Speter  print_node (file, "local", IDENTIFIER_LOCAL_VALUE (node), indent + 4);
81918334Speter  print_node (file, "label", IDENTIFIER_LABEL_VALUE (node), indent + 4);
82018334Speter  print_node (file, "implicit", IDENTIFIER_IMPLICIT_DECL (node), indent + 4);
82118334Speter  print_node (file, "error locus", IDENTIFIER_ERROR_LOCUS (node), indent + 4);
82218334Speter  print_node (file, "limbo value", IDENTIFIER_LIMBO_VALUE (node), indent + 4);
82390075Sobrien  if (C_IS_RESERVED_WORD (node))
82490075Sobrien    {
82590075Sobrien      tree rid = ridpointers[C_RID_CODE (node)];
82690075Sobrien      indent_to (file, indent + 4);
82790075Sobrien      fprintf (file, "rid ");
82890075Sobrien      fprintf (file, HOST_PTR_PRINTF, (void *)rid);
82990075Sobrien      fprintf (file, " \"%s\"", IDENTIFIER_POINTER (rid));
83090075Sobrien    }
83118334Speter}
83218334Speter
83318334Speter/* Hook called at end of compilation to assume 1 elt
83490075Sobrien   for a top-level tentative array defn that wasn't complete before.  */
83590075Sobrien
83618334Spetervoid
83718334Speterfinish_incomplete_decl (decl)
83818334Speter     tree decl;
83918334Speter{
84050397Sobrien  if (TREE_CODE (decl) == VAR_DECL)
84118334Speter    {
84218334Speter      tree type = TREE_TYPE (decl);
84350397Sobrien      if (type != error_mark_node
84450397Sobrien	  && TREE_CODE (type) == ARRAY_TYPE
84590075Sobrien	  && ! DECL_EXTERNAL (decl)
84650397Sobrien	  && TYPE_DOMAIN (type) == 0)
84718334Speter	{
84890075Sobrien	  warning_with_decl (decl, "array `%s' assumed to have one element");
84950397Sobrien
85018334Speter	  complete_array_type (type, NULL_TREE, 1);
85118334Speter
85218334Speter	  layout_decl (decl, 0);
85318334Speter	}
85418334Speter    }
85518334Speter}
85618334Speter
85718334Speter/* Create a new `struct binding_level'.  */
85818334Speter
85990075Sobrienstatic struct binding_level *
86018334Spetermake_binding_level ()
86118334Speter{
86218334Speter  /* NOSTRICT */
86318334Speter  return (struct binding_level *) xmalloc (sizeof (struct binding_level));
86418334Speter}
86518334Speter
86618334Speter/* Nonzero if we are currently in the global binding level.  */
86718334Speter
86818334Speterint
86918334Speterglobal_bindings_p ()
87018334Speter{
87118334Speter  return current_binding_level == global_binding_level;
87218334Speter}
87318334Speter
87418334Spetervoid
87518334Speterkeep_next_level ()
87618334Speter{
87718334Speter  keep_next_level_flag = 1;
87818334Speter}
87918334Speter
88018334Speter/* Nonzero if the current level needs to have a BLOCK made.  */
88118334Speter
88218334Speterint
88318334Speterkept_level_p ()
88418334Speter{
88518334Speter  return ((current_binding_level->keep_if_subblocks
88618334Speter	   && current_binding_level->blocks != 0)
88718334Speter	  || current_binding_level->keep
88818334Speter	  || current_binding_level->names != 0
88918334Speter	  || (current_binding_level->tags != 0
89018334Speter	      && !current_binding_level->tag_transparent));
89118334Speter}
89218334Speter
89318334Speter/* Identify this binding level as a level of parameters.
89418334Speter   DEFINITION_FLAG is 1 for a definition, 0 for a declaration.
89518334Speter   But it turns out there is no way to pass the right value for
89618334Speter   DEFINITION_FLAG, so we ignore it.  */
89718334Speter
89818334Spetervoid
89918334Speterdeclare_parm_level (definition_flag)
90052284Sobrien     int definition_flag ATTRIBUTE_UNUSED;
90118334Speter{
90218334Speter  current_binding_level->parm_flag = 1;
90318334Speter}
90418334Speter
90518334Speter/* Nonzero if currently making parm declarations.  */
90618334Speter
90718334Speterint
90818334Speterin_parm_level_p ()
90918334Speter{
91018334Speter  return current_binding_level->parm_flag;
91118334Speter}
91218334Speter
91318334Speter/* Enter a new binding level.
91418334Speter   If TAG_TRANSPARENT is nonzero, do so only for the name space of variables,
91518334Speter   not for that of tags.  */
91618334Speter
91718334Spetervoid
91818334Speterpushlevel (tag_transparent)
91918334Speter     int tag_transparent;
92018334Speter{
92190075Sobrien  struct binding_level *newlevel = NULL_BINDING_LEVEL;
92218334Speter
92318334Speter  /* If this is the top level of a function,
92418334Speter     just make sure that NAMED_LABELS is 0.  */
92518334Speter
92618334Speter  if (current_binding_level == global_binding_level)
92718334Speter    {
92818334Speter      named_labels = 0;
92918334Speter    }
93018334Speter
93118334Speter  /* Reuse or create a struct for this binding level.  */
93218334Speter
93318334Speter  if (free_binding_level)
93418334Speter    {
93518334Speter      newlevel = free_binding_level;
93618334Speter      free_binding_level = free_binding_level->level_chain;
93718334Speter    }
93818334Speter  else
93918334Speter    {
94018334Speter      newlevel = make_binding_level ();
94118334Speter    }
94218334Speter
94318334Speter  /* Add this level to the front of the chain (stack) of levels that
94418334Speter     are active.  */
94518334Speter
94618334Speter  *newlevel = clear_binding_level;
94718334Speter  newlevel->tag_transparent
94818334Speter    = (tag_transparent
94918334Speter       || (current_binding_level
95018334Speter	   ? current_binding_level->subblocks_tag_transparent
95118334Speter	   : 0));
95218334Speter  newlevel->level_chain = current_binding_level;
95318334Speter  current_binding_level = newlevel;
95418334Speter  newlevel->keep = keep_next_level_flag;
95518334Speter  keep_next_level_flag = 0;
95618334Speter  newlevel->keep_if_subblocks = keep_next_if_subblocks;
95718334Speter  keep_next_if_subblocks = 0;
95818334Speter}
95918334Speter
96090075Sobrien/* Clear the limbo values of all identifiers defined in BLOCK or a subblock.  */
96150397Sobrien
96250397Sobrienstatic void
96350397Sobrienclear_limbo_values (block)
96450397Sobrien     tree block;
96550397Sobrien{
96650397Sobrien  tree tem;
96750397Sobrien
96850397Sobrien  for (tem = BLOCK_VARS (block); tem; tem = TREE_CHAIN (tem))
96950397Sobrien    if (DECL_NAME (tem) != 0)
97050397Sobrien      IDENTIFIER_LIMBO_VALUE (DECL_NAME (tem)) = 0;
97150397Sobrien
97250397Sobrien  for (tem = BLOCK_SUBBLOCKS (block); tem; tem = TREE_CHAIN (tem))
97350397Sobrien    clear_limbo_values (tem);
97450397Sobrien}
97590075Sobrien
97618334Speter/* Exit a binding level.
97718334Speter   Pop the level off, and restore the state of the identifier-decl mappings
97818334Speter   that were in effect when this level was entered.
97918334Speter
98018334Speter   If KEEP is nonzero, this level had explicit declarations, so
98118334Speter   and create a "block" (a BLOCK node) for the level
98218334Speter   to record its declarations and subblocks for symbol table output.
98318334Speter
98418334Speter   If FUNCTIONBODY is nonzero, this level is the body of a function,
98518334Speter   so create a block as if KEEP were set and also clear out all
98618334Speter   label names.
98718334Speter
98818334Speter   If REVERSE is nonzero, reverse the order of decls before putting
98918334Speter   them into the BLOCK.  */
99018334Speter
99118334Spetertree
99218334Speterpoplevel (keep, reverse, functionbody)
99318334Speter     int keep;
99418334Speter     int reverse;
99518334Speter     int functionbody;
99618334Speter{
99790075Sobrien  tree link;
99818334Speter  /* The chain of decls was accumulated in reverse order.
99918334Speter     Put it into forward order, just for cleanliness.  */
100018334Speter  tree decls;
100118334Speter  tree tags = current_binding_level->tags;
100218334Speter  tree subblocks = current_binding_level->blocks;
100318334Speter  tree block = 0;
100418334Speter  tree decl;
100518334Speter  int block_previously_created;
100618334Speter
100718334Speter  keep |= current_binding_level->keep;
100818334Speter
100918334Speter  /* This warning is turned off because it causes warnings for
101018334Speter     declarations like `extern struct foo *x'.  */
101118334Speter#if 0
101218334Speter  /* Warn about incomplete structure types in this level.  */
101318334Speter  for (link = tags; link; link = TREE_CHAIN (link))
101490075Sobrien    if (!COMPLETE_TYPE_P (TREE_VALUE (link)))
101518334Speter      {
101618334Speter	tree type = TREE_VALUE (link);
101752284Sobrien	tree type_name = TYPE_NAME (type);
101852284Sobrien	char *id = IDENTIFIER_POINTER (TREE_CODE (type_name) == IDENTIFIER_NODE
101952284Sobrien				       ? type_name
102052284Sobrien				       : DECL_NAME (type_name));
102118334Speter	switch (TREE_CODE (type))
102218334Speter	  {
102318334Speter	  case RECORD_TYPE:
102452284Sobrien	    error ("`struct %s' incomplete in scope ending here", id);
102518334Speter	    break;
102618334Speter	  case UNION_TYPE:
102752284Sobrien	    error ("`union %s' incomplete in scope ending here", id);
102818334Speter	    break;
102918334Speter	  case ENUMERAL_TYPE:
103052284Sobrien	    error ("`enum %s' incomplete in scope ending here", id);
103118334Speter	    break;
103218334Speter	  }
103318334Speter      }
103418334Speter#endif /* 0 */
103518334Speter
103618334Speter  /* Get the decls in the order they were written.
103718334Speter     Usually current_binding_level->names is in reverse order.
103818334Speter     But parameter decls were previously put in forward order.  */
103918334Speter
104018334Speter  if (reverse)
104118334Speter    current_binding_level->names
104218334Speter      = decls = nreverse (current_binding_level->names);
104318334Speter  else
104418334Speter    decls = current_binding_level->names;
104518334Speter
104618334Speter  /* Output any nested inline functions within this block
104718334Speter     if they weren't already output.  */
104818334Speter
104918334Speter  for (decl = decls; decl; decl = TREE_CHAIN (decl))
105018334Speter    if (TREE_CODE (decl) == FUNCTION_DECL
105118334Speter	&& ! TREE_ASM_WRITTEN (decl)
105218334Speter	&& DECL_INITIAL (decl) != 0
105318334Speter	&& TREE_ADDRESSABLE (decl))
105418334Speter      {
105518334Speter	/* If this decl was copied from a file-scope decl
105618334Speter	   on account of a block-scope extern decl,
105718334Speter	   propagate TREE_ADDRESSABLE to the file-scope decl.
105818334Speter
105918334Speter	   DECL_ABSTRACT_ORIGIN can be set to itself if warn_return_type is
106018334Speter	   true, since then the decl goes through save_for_inline_copying.  */
106118334Speter	if (DECL_ABSTRACT_ORIGIN (decl) != 0
106218334Speter	    && DECL_ABSTRACT_ORIGIN (decl) != decl)
106318334Speter	  TREE_ADDRESSABLE (DECL_ABSTRACT_ORIGIN (decl)) = 1;
106418334Speter      }
106518334Speter
106690075Sobrien  /* We used to warn about unused variables in expand_end_bindings,
106790075Sobrien     i.e. while generating RTL.  But in function-at-a-time mode we may
106890075Sobrien     choose to never expand a function at all (e.g. auto inlining), so
106990075Sobrien     we do this explicitly now.  */
107090075Sobrien  warn_about_unused_variables (getdecls ());
107190075Sobrien
107218334Speter  /* If there were any declarations or structure tags in that level,
107318334Speter     or if this level is a function body,
107418334Speter     create a BLOCK to record them for the life of this function.  */
107518334Speter
107618334Speter  block = 0;
107718334Speter  block_previously_created = (current_binding_level->this_block != 0);
107818334Speter  if (block_previously_created)
107918334Speter    block = current_binding_level->this_block;
108018334Speter  else if (keep || functionbody
108118334Speter	   || (current_binding_level->keep_if_subblocks && subblocks != 0))
108218334Speter    block = make_node (BLOCK);
108318334Speter  if (block != 0)
108418334Speter    {
108518334Speter      BLOCK_VARS (block) = decls;
108618334Speter      BLOCK_SUBBLOCKS (block) = subblocks;
108718334Speter    }
108818334Speter
108918334Speter  /* In each subblock, record that this is its superior.  */
109018334Speter
109118334Speter  for (link = subblocks; link; link = TREE_CHAIN (link))
109218334Speter    BLOCK_SUPERCONTEXT (link) = block;
109318334Speter
109418334Speter  /* Clear out the meanings of the local variables of this level.  */
109518334Speter
109618334Speter  for (link = decls; link; link = TREE_CHAIN (link))
109718334Speter    {
109818334Speter      if (DECL_NAME (link) != 0)
109918334Speter	{
110018334Speter	  /* If the ident. was used or addressed via a local extern decl,
110118334Speter	     don't forget that fact.  */
110218334Speter	  if (DECL_EXTERNAL (link))
110318334Speter	    {
110418334Speter	      if (TREE_USED (link))
110518334Speter		TREE_USED (DECL_NAME (link)) = 1;
110618334Speter	      if (TREE_ADDRESSABLE (link))
110718334Speter		TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (link)) = 1;
110818334Speter	    }
110918334Speter	  IDENTIFIER_LOCAL_VALUE (DECL_NAME (link)) = 0;
111018334Speter	}
111118334Speter    }
111218334Speter
111318334Speter  /* Restore all name-meanings of the outer levels
111418334Speter     that were shadowed by this level.  */
111518334Speter
111618334Speter  for (link = current_binding_level->shadowed; link; link = TREE_CHAIN (link))
111718334Speter    IDENTIFIER_LOCAL_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link);
111818334Speter
111918334Speter  /* If the level being exited is the top level of a function,
112018334Speter     check over all the labels, and clear out the current
112118334Speter     (function local) meanings of their names.  */
112218334Speter
112318334Speter  if (functionbody)
112418334Speter    {
112550397Sobrien      clear_limbo_values (block);
112650397Sobrien
112718334Speter      /* If this is the top level block of a function,
112818334Speter	 the vars are the function's parameters.
112918334Speter	 Don't leave them in the BLOCK because they are
113018334Speter	 found in the FUNCTION_DECL instead.  */
113118334Speter
113218334Speter      BLOCK_VARS (block) = 0;
113318334Speter
113418334Speter      /* Clear out the definitions of all label names,
113518334Speter	 since their scopes end here,
113618334Speter	 and add them to BLOCK_VARS.  */
113718334Speter
113818334Speter      for (link = named_labels; link; link = TREE_CHAIN (link))
113918334Speter	{
114090075Sobrien	  tree label = TREE_VALUE (link);
114118334Speter
114218334Speter	  if (DECL_INITIAL (label) == 0)
114318334Speter	    {
114418334Speter	      error_with_decl (label, "label `%s' used but not defined");
114518334Speter	      /* Avoid crashing later.  */
114618334Speter	      define_label (input_filename, lineno,
114718334Speter			    DECL_NAME (label));
114818334Speter	    }
114990075Sobrien	  else if (warn_unused_label && !TREE_USED (label))
115018334Speter	    warning_with_decl (label, "label `%s' defined but not used");
115118334Speter	  IDENTIFIER_LABEL_VALUE (DECL_NAME (label)) = 0;
115218334Speter
115318334Speter	  /* Put the labels into the "variables" of the
115418334Speter	     top-level block, so debugger can see them.  */
115518334Speter	  TREE_CHAIN (label) = BLOCK_VARS (block);
115618334Speter	  BLOCK_VARS (block) = label;
115718334Speter	}
115818334Speter    }
115918334Speter
116018334Speter  /* Pop the current level, and free the structure for reuse.  */
116118334Speter
116218334Speter  {
116390075Sobrien    struct binding_level *level = current_binding_level;
116418334Speter    current_binding_level = current_binding_level->level_chain;
116518334Speter
116618334Speter    level->level_chain = free_binding_level;
116718334Speter    free_binding_level = level;
116818334Speter  }
116918334Speter
117018334Speter  /* Dispose of the block that we just made inside some higher level.  */
117118334Speter  if (functionbody)
117218334Speter    DECL_INITIAL (current_function_decl) = block;
117318334Speter  else if (block)
117418334Speter    {
117518334Speter      if (!block_previously_created)
117690075Sobrien	current_binding_level->blocks
117790075Sobrien	  = chainon (current_binding_level->blocks, block);
117818334Speter    }
117918334Speter  /* If we did not make a block for the level just exited,
118018334Speter     any blocks made for inner levels
118118334Speter     (since they cannot be recorded as subblocks in that level)
118218334Speter     must be carried forward so they will later become subblocks
118318334Speter     of something else.  */
118418334Speter  else if (subblocks)
118518334Speter    current_binding_level->blocks
118618334Speter      = chainon (current_binding_level->blocks, subblocks);
118718334Speter
118818334Speter  /* Set the TYPE_CONTEXTs for all of the tagged types belonging to this
118918334Speter     binding contour so that they point to the appropriate construct, i.e.
119018334Speter     either to the current FUNCTION_DECL node, or else to the BLOCK node
119118334Speter     we just constructed.
119218334Speter
119318334Speter     Note that for tagged types whose scope is just the formal parameter
119418334Speter     list for some function type specification, we can't properly set
119518334Speter     their TYPE_CONTEXTs here, because we don't have a pointer to the
119618334Speter     appropriate FUNCTION_TYPE node readily available to us.  For those
119718334Speter     cases, the TYPE_CONTEXTs of the relevant tagged type nodes get set
119818334Speter     in `grokdeclarator' as soon as we have created the FUNCTION_TYPE
119918334Speter     node which will represent the "scope" for these "parameter list local"
120090075Sobrien     tagged types.  */
120118334Speter
120218334Speter  if (functionbody)
120318334Speter    for (link = tags; link; link = TREE_CHAIN (link))
120418334Speter      TYPE_CONTEXT (TREE_VALUE (link)) = current_function_decl;
120518334Speter  else if (block)
120618334Speter    for (link = tags; link; link = TREE_CHAIN (link))
120718334Speter      TYPE_CONTEXT (TREE_VALUE (link)) = block;
120818334Speter
120918334Speter  if (block)
121018334Speter    TREE_USED (block) = 1;
121190075Sobrien
121218334Speter  return block;
121318334Speter}
121418334Speter
121518334Speter/* Insert BLOCK at the end of the list of subblocks of the
121618334Speter   current binding level.  This is used when a BIND_EXPR is expanded,
121718334Speter   to handle the BLOCK node inside the BIND_EXPR.  */
121818334Speter
121918334Spetervoid
122018334Speterinsert_block (block)
122118334Speter     tree block;
122218334Speter{
122318334Speter  TREE_USED (block) = 1;
122418334Speter  current_binding_level->blocks
122518334Speter    = chainon (current_binding_level->blocks, block);
122618334Speter}
122718334Speter
122818334Speter/* Set the BLOCK node for the innermost scope
122918334Speter   (the one we are currently in).  */
123018334Speter
123118334Spetervoid
123218334Speterset_block (block)
123390075Sobrien     tree block;
123418334Speter{
123518334Speter  current_binding_level->this_block = block;
123690075Sobrien  current_binding_level->names = chainon (current_binding_level->names,
123790075Sobrien					  BLOCK_VARS (block));
123890075Sobrien  current_binding_level->blocks = chainon (current_binding_level->blocks,
123990075Sobrien					   BLOCK_SUBBLOCKS (block));
124018334Speter}
124118334Speter
124218334Spetervoid
124318334Speterpush_label_level ()
124418334Speter{
124590075Sobrien  struct binding_level *newlevel;
124618334Speter
124718334Speter  /* Reuse or create a struct for this binding level.  */
124818334Speter
124918334Speter  if (free_binding_level)
125018334Speter    {
125118334Speter      newlevel = free_binding_level;
125218334Speter      free_binding_level = free_binding_level->level_chain;
125318334Speter    }
125418334Speter  else
125518334Speter    {
125618334Speter      newlevel = make_binding_level ();
125718334Speter    }
125818334Speter
125918334Speter  /* Add this level to the front of the chain (stack) of label levels.  */
126018334Speter
126118334Speter  newlevel->level_chain = label_level_chain;
126218334Speter  label_level_chain = newlevel;
126318334Speter
126418334Speter  newlevel->names = named_labels;
126518334Speter  newlevel->shadowed = shadowed_labels;
126618334Speter  named_labels = 0;
126718334Speter  shadowed_labels = 0;
126818334Speter}
126918334Speter
127018334Spetervoid
127118334Speterpop_label_level ()
127218334Speter{
127390075Sobrien  struct binding_level *level = label_level_chain;
127418334Speter  tree link, prev;
127518334Speter
127618334Speter  /* Clear out the definitions of the declared labels in this level.
127718334Speter     Leave in the list any ordinary, non-declared labels.  */
127818334Speter  for (link = named_labels, prev = 0; link;)
127918334Speter    {
128018334Speter      if (C_DECLARED_LABEL_FLAG (TREE_VALUE (link)))
128118334Speter	{
128218334Speter	  if (DECL_SOURCE_LINE (TREE_VALUE (link)) == 0)
128318334Speter	    {
128418334Speter	      error_with_decl (TREE_VALUE (link),
128518334Speter			       "label `%s' used but not defined");
128618334Speter	      /* Avoid crashing later.  */
128718334Speter	      define_label (input_filename, lineno,
128818334Speter			    DECL_NAME (TREE_VALUE (link)));
128918334Speter	    }
129090075Sobrien	  else if (warn_unused_label && !TREE_USED (TREE_VALUE (link)))
129190075Sobrien	    warning_with_decl (TREE_VALUE (link),
129218334Speter			       "label `%s' defined but not used");
129318334Speter	  IDENTIFIER_LABEL_VALUE (DECL_NAME (TREE_VALUE (link))) = 0;
129418334Speter
129518334Speter	  /* Delete this element from the list.  */
129618334Speter	  link = TREE_CHAIN (link);
129718334Speter	  if (prev)
129818334Speter	    TREE_CHAIN (prev) = link;
129918334Speter	  else
130018334Speter	    named_labels = link;
130118334Speter	}
130218334Speter      else
130318334Speter	{
130418334Speter	  prev = link;
130518334Speter	  link = TREE_CHAIN (link);
130618334Speter	}
130718334Speter    }
130818334Speter
130918334Speter  /* Bring back all the labels that were shadowed.  */
131018334Speter  for (link = shadowed_labels; link; link = TREE_CHAIN (link))
131118334Speter    if (DECL_NAME (TREE_VALUE (link)) != 0)
131218334Speter      IDENTIFIER_LABEL_VALUE (DECL_NAME (TREE_VALUE (link)))
131318334Speter	= TREE_VALUE (link);
131418334Speter
131518334Speter  named_labels = chainon (named_labels, level->names);
131618334Speter  shadowed_labels = level->shadowed;
131718334Speter
131818334Speter  /* Pop the current level, and free the structure for reuse.  */
131918334Speter  label_level_chain = label_level_chain->level_chain;
132018334Speter  level->level_chain = free_binding_level;
132118334Speter  free_binding_level = level;
132218334Speter}
132318334Speter
132418334Speter/* Push a definition or a declaration of struct, union or enum tag "name".
132518334Speter   "type" should be the type node.
132618334Speter   We assume that the tag "name" is not already defined.
132718334Speter
132818334Speter   Note that the definition may really be just a forward reference.
132918334Speter   In that case, the TYPE_SIZE will be zero.  */
133018334Speter
133118334Spetervoid
133218334Speterpushtag (name, type)
133318334Speter     tree name, type;
133418334Speter{
133590075Sobrien  struct binding_level *b;
133618334Speter
133718334Speter  /* Find the proper binding level for this type tag.  */
133818334Speter
133918334Speter  for (b = current_binding_level; b->tag_transparent; b = b->level_chain)
134018334Speter    continue;
134118334Speter
134218334Speter  if (name)
134318334Speter    {
134418334Speter      /* Record the identifier as the type's name if it has none.  */
134518334Speter
134618334Speter      if (TYPE_NAME (type) == 0)
134718334Speter	TYPE_NAME (type) = name;
134818334Speter    }
134918334Speter
135090075Sobrien  b->tags = tree_cons (name, type, b->tags);
135118334Speter
135218334Speter  /* Create a fake NULL-named TYPE_DECL node whose TREE_TYPE will be the
135318334Speter     tagged type we just added to the current binding level.  This fake
135418334Speter     NULL-named TYPE_DECL node helps dwarfout.c to know when it needs
135518334Speter     to output a representation of a tagged type, and it also gives
135618334Speter     us a convenient place to record the "scope start" address for the
135718334Speter     tagged type.  */
135818334Speter
135918334Speter  TYPE_STUB_DECL (type) = pushdecl (build_decl (TYPE_DECL, NULL_TREE, type));
136050397Sobrien
136150397Sobrien  /* An approximation for now, so we can tell this is a function-scope tag.
136250397Sobrien     This will be updated in poplevel.  */
136350397Sobrien  TYPE_CONTEXT (type) = DECL_CONTEXT (TYPE_STUB_DECL (type));
136418334Speter}
136518334Speter
136618334Speter/* Handle when a new declaration NEWDECL
136718334Speter   has the same name as an old one OLDDECL
136818334Speter   in the same binding contour.
136918334Speter   Prints an error message if appropriate.
137018334Speter
137118334Speter   If safely possible, alter OLDDECL to look like NEWDECL, and return 1.
137250397Sobrien   Otherwise, return 0.
137318334Speter
137450397Sobrien   When DIFFERENT_BINDING_LEVEL is true, NEWDECL is an external declaration,
137550397Sobrien   and OLDDECL is in an outer binding level and should thus not be changed.  */
137650397Sobrien
137718334Speterstatic int
137850397Sobrienduplicate_decls (newdecl, olddecl, different_binding_level)
137990075Sobrien     tree newdecl, olddecl;
138050397Sobrien     int different_binding_level;
138118334Speter{
138218334Speter  int types_match = comptypes (TREE_TYPE (newdecl), TREE_TYPE (olddecl));
138318334Speter  int new_is_definition = (TREE_CODE (newdecl) == FUNCTION_DECL
138418334Speter			   && DECL_INITIAL (newdecl) != 0);
138518334Speter  tree oldtype = TREE_TYPE (olddecl);
138618334Speter  tree newtype = TREE_TYPE (newdecl);
138752284Sobrien  int errmsg = 0;
138818334Speter
138990075Sobrien  if (DECL_P (olddecl))
139090075Sobrien    {
139190075Sobrien      if (TREE_CODE (newdecl) == FUNCTION_DECL
139290075Sobrien	  && TREE_CODE (olddecl) == FUNCTION_DECL
139390075Sobrien	  && (DECL_UNINLINABLE (newdecl) || DECL_UNINLINABLE (olddecl)))
139490075Sobrien	{
139590075Sobrien	  if (DECL_DECLARED_INLINE_P (newdecl)
139690075Sobrien	      && DECL_UNINLINABLE (newdecl)
139790075Sobrien	      && lookup_attribute ("noinline", DECL_ATTRIBUTES (newdecl)))
139890075Sobrien	    /* Already warned elsewhere.  */;
139990075Sobrien	  else if (DECL_DECLARED_INLINE_P (olddecl)
140090075Sobrien		   && DECL_UNINLINABLE (olddecl)
140190075Sobrien		   && lookup_attribute ("noinline", DECL_ATTRIBUTES (olddecl)))
140290075Sobrien	    /* Already warned.  */;
140390075Sobrien	  else if (DECL_DECLARED_INLINE_P (newdecl)
140490075Sobrien		   && ! DECL_DECLARED_INLINE_P (olddecl)
140590075Sobrien		   && DECL_UNINLINABLE (olddecl)
140690075Sobrien		   && lookup_attribute ("noinline", DECL_ATTRIBUTES (olddecl)))
140790075Sobrien	    {
140890075Sobrien	      warning_with_decl (newdecl,
140990075Sobrien				 "function `%s' redeclared as inline");
141090075Sobrien	      warning_with_decl (olddecl,
141190075Sobrien				 "previous declaration of function `%s' with attribute noinline");
141290075Sobrien	    }
141390075Sobrien	  else if (DECL_DECLARED_INLINE_P (olddecl)
141490075Sobrien		   && DECL_UNINLINABLE (newdecl)
141590075Sobrien		   && lookup_attribute ("noinline", DECL_ATTRIBUTES (newdecl)))
141690075Sobrien	    {
141790075Sobrien	      warning_with_decl (newdecl,
141890075Sobrien				 "function `%s' redeclared with attribute noinline");
141990075Sobrien	      warning_with_decl (olddecl,
142090075Sobrien				 "previous declaration of function `%s' was inline");
142190075Sobrien	    }
142290075Sobrien	}
142318334Speter
142490075Sobrien      DECL_ATTRIBUTES (newdecl)
142590075Sobrien	= (*targetm.merge_decl_attributes) (olddecl, newdecl);
142690075Sobrien    }
142790075Sobrien
142818334Speter  if (TREE_CODE (newtype) == ERROR_MARK
142918334Speter      || TREE_CODE (oldtype) == ERROR_MARK)
143018334Speter    types_match = 0;
143118334Speter
143218334Speter  /* New decl is completely inconsistent with the old one =>
143318334Speter     tell caller to replace the old one.
143418334Speter     This is always an error except in the case of shadowing a builtin.  */
143518334Speter  if (TREE_CODE (olddecl) != TREE_CODE (newdecl))
143618334Speter    {
143718334Speter      if (TREE_CODE (olddecl) == FUNCTION_DECL
143818334Speter	  && (DECL_BUILT_IN (olddecl)
143918334Speter	      || DECL_BUILT_IN_NONANSI (olddecl)))
144018334Speter	{
144118334Speter	  /* If you declare a built-in or predefined function name as static,
144218334Speter	     the old definition is overridden,
144318334Speter	     but optionally warn this was a bad choice of name.  */
144418334Speter	  if (!TREE_PUBLIC (newdecl))
144518334Speter	    {
144618334Speter	      if (!warn_shadow)
144718334Speter		;
144818334Speter	      else if (DECL_BUILT_IN (olddecl))
144918334Speter		warning_with_decl (newdecl, "shadowing built-in function `%s'");
145018334Speter	      else
145118334Speter		warning_with_decl (newdecl, "shadowing library function `%s'");
145218334Speter	    }
145318334Speter	  /* Likewise, if the built-in is not ansi, then programs can
145418334Speter	     override it even globally without an error.  */
145518334Speter	  else if (! DECL_BUILT_IN (olddecl))
145618334Speter	    warning_with_decl (newdecl,
145718334Speter			       "library function `%s' declared as non-function");
145818334Speter
145918334Speter	  else if (DECL_BUILT_IN_NONANSI (olddecl))
146018334Speter	    warning_with_decl (newdecl,
146118334Speter			       "built-in function `%s' declared as non-function");
146218334Speter	  else
146318334Speter	    warning_with_decl (newdecl,
146490075Sobrien			       "built-in function `%s' declared as non-function");
146518334Speter	}
146618334Speter      else
146718334Speter	{
146818334Speter	  error_with_decl (newdecl, "`%s' redeclared as different kind of symbol");
146918334Speter	  error_with_decl (olddecl, "previous declaration of `%s'");
147018334Speter	}
147118334Speter
147218334Speter      return 0;
147318334Speter    }
147418334Speter
147518334Speter  /* For real parm decl following a forward decl,
147618334Speter     return 1 so old decl will be reused.  */
147718334Speter  if (types_match && TREE_CODE (newdecl) == PARM_DECL
147818334Speter      && TREE_ASM_WRITTEN (olddecl) && ! TREE_ASM_WRITTEN (newdecl))
147918334Speter    return 1;
148018334Speter
148118334Speter  /* The new declaration is the same kind of object as the old one.
148218334Speter     The declarations may partially match.  Print warnings if they don't
148318334Speter     match enough.  Ultimately, copy most of the information from the new
148418334Speter     decl to the old one, and keep using the old one.  */
148518334Speter
148618334Speter  if (flag_traditional && TREE_CODE (newdecl) == FUNCTION_DECL
148718334Speter      && IDENTIFIER_IMPLICIT_DECL (DECL_NAME (newdecl)) == olddecl
148818334Speter      && DECL_INITIAL (olddecl) == 0)
148918334Speter    /* If -traditional, avoid error for redeclaring fcn
149018334Speter       after implicit decl.  */
149118334Speter    ;
149218334Speter  else if (TREE_CODE (olddecl) == FUNCTION_DECL
149318334Speter	   && DECL_BUILT_IN (olddecl))
149418334Speter    {
149518334Speter      /* A function declaration for a built-in function.  */
149618334Speter      if (!TREE_PUBLIC (newdecl))
149718334Speter	{
149818334Speter	  /* If you declare a built-in function name as static, the
149918334Speter	     built-in definition is overridden,
150018334Speter	     but optionally warn this was a bad choice of name.  */
150118334Speter	  if (warn_shadow)
150218334Speter	    warning_with_decl (newdecl, "shadowing built-in function `%s'");
150318334Speter	  /* Discard the old built-in function.  */
150418334Speter	  return 0;
150518334Speter	}
150618334Speter      else if (!types_match)
150718334Speter	{
150890075Sobrien	  /* Accept the return type of the new declaration if same modes.  */
150950397Sobrien	  tree oldreturntype = TREE_TYPE (oldtype);
151050397Sobrien	  tree newreturntype = TREE_TYPE (newtype);
151118334Speter
151290075Sobrien	  if (TYPE_MODE (oldreturntype) == TYPE_MODE (newreturntype))
151318334Speter	    {
151418334Speter	      /* Function types may be shared, so we can't just modify
151518334Speter		 the return type of olddecl's function type.  */
151650397Sobrien	      tree trytype
151718334Speter		= build_function_type (newreturntype,
151850397Sobrien				       TYPE_ARG_TYPES (oldtype));
151990075Sobrien	      trytype = build_type_attribute_variant (trytype,
152090075Sobrien						      TYPE_ATTRIBUTES (oldtype));
152190075Sobrien
152250397Sobrien              types_match = comptypes (newtype, trytype);
152318334Speter	      if (types_match)
152450397Sobrien		oldtype = trytype;
152518334Speter	    }
152618334Speter	  /* Accept harmless mismatch in first argument type also.
152790075Sobrien	     This is for the ffs and fprintf builtins.  */
152818334Speter	  if (TYPE_ARG_TYPES (TREE_TYPE (newdecl)) != 0
152950397Sobrien	      && TYPE_ARG_TYPES (oldtype) != 0
153050397Sobrien	      && TREE_VALUE (TYPE_ARG_TYPES (newtype)) != 0
153150397Sobrien	      && TREE_VALUE (TYPE_ARG_TYPES (oldtype)) != 0
153250397Sobrien	      && (TYPE_MODE (TREE_VALUE (TYPE_ARG_TYPES (newtype)))
153350397Sobrien		  == TYPE_MODE (TREE_VALUE (TYPE_ARG_TYPES (oldtype)))))
153418334Speter	    {
153518334Speter	      /* Function types may be shared, so we can't just modify
153618334Speter		 the return type of olddecl's function type.  */
153750397Sobrien	      tree trytype
153850397Sobrien		= build_function_type (TREE_TYPE (oldtype),
153990075Sobrien				       tree_cons (NULL_TREE,
154050397Sobrien						  TREE_VALUE (TYPE_ARG_TYPES (newtype)),
154150397Sobrien						  TREE_CHAIN (TYPE_ARG_TYPES (oldtype))));
154290075Sobrien	      trytype = build_type_attribute_variant (trytype,
154390075Sobrien						      TYPE_ATTRIBUTES (oldtype));
154490075Sobrien
154590075Sobrien	      types_match = comptypes (newtype, trytype);
154618334Speter	      if (types_match)
154750397Sobrien		oldtype = trytype;
154818334Speter	    }
154950397Sobrien	  if (! different_binding_level)
155050397Sobrien	    TREE_TYPE (olddecl) = oldtype;
155118334Speter	}
155296263Sobrien      else if (TYPE_ARG_TYPES (oldtype) == NULL
155396263Sobrien	       && TYPE_ARG_TYPES (newtype) != NULL)
155496263Sobrien	{
155596263Sobrien	  /* For bcmp, bzero, fputs the builtin type has arguments not
155696263Sobrien	     specified.  Use the ones from the prototype so that type checking
155796263Sobrien	     is done for them.  */
155896263Sobrien	  tree trytype
155996263Sobrien	    = build_function_type (TREE_TYPE (oldtype),
156096263Sobrien				   TYPE_ARG_TYPES (newtype));
156196263Sobrien	  trytype = build_type_attribute_variant (trytype,
156296263Sobrien						  TYPE_ATTRIBUTES (oldtype));
156396263Sobrien
156496263Sobrien	  oldtype = trytype;
156596263Sobrien	  if (! different_binding_level)
156696263Sobrien	    TREE_TYPE (olddecl) = oldtype;
156796263Sobrien	}
156818334Speter      if (!types_match)
156918334Speter	{
157018334Speter	  /* If types don't match for a built-in, throw away the built-in.  */
157118334Speter	  warning_with_decl (newdecl, "conflicting types for built-in function `%s'");
157218334Speter	  return 0;
157318334Speter	}
157418334Speter    }
157518334Speter  else if (TREE_CODE (olddecl) == FUNCTION_DECL
157618334Speter	   && DECL_SOURCE_LINE (olddecl) == 0)
157718334Speter    {
157818334Speter      /* A function declaration for a predeclared function
157918334Speter	 that isn't actually built in.  */
158018334Speter      if (!TREE_PUBLIC (newdecl))
158118334Speter	{
158218334Speter	  /* If you declare it as static, the
158318334Speter	     default definition is overridden.  */
158418334Speter	  return 0;
158518334Speter	}
158618334Speter      else if (!types_match)
158718334Speter	{
158818334Speter	  /* If the types don't match, preserve volatility indication.
158918334Speter	     Later on, we will discard everything else about the
159018334Speter	     default declaration.  */
159118334Speter	  TREE_THIS_VOLATILE (newdecl) |= TREE_THIS_VOLATILE (olddecl);
159218334Speter	}
159318334Speter    }
159418334Speter  /* Permit char *foo () to match void *foo (...) if not pedantic,
159518334Speter     if one of them came from a system header file.  */
159618334Speter  else if (!types_match
159718334Speter	   && TREE_CODE (olddecl) == FUNCTION_DECL
159818334Speter	   && TREE_CODE (newdecl) == FUNCTION_DECL
159918334Speter	   && TREE_CODE (TREE_TYPE (oldtype)) == POINTER_TYPE
160018334Speter	   && TREE_CODE (TREE_TYPE (newtype)) == POINTER_TYPE
160118334Speter	   && (DECL_IN_SYSTEM_HEADER (olddecl)
160218334Speter	       || DECL_IN_SYSTEM_HEADER (newdecl))
160318334Speter	   && ((TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (newtype))) == void_type_node
160418334Speter		&& TYPE_ARG_TYPES (oldtype) == 0
160518334Speter		&& self_promoting_args_p (TYPE_ARG_TYPES (newtype))
160618334Speter		&& TREE_TYPE (TREE_TYPE (oldtype)) == char_type_node)
160718334Speter	       ||
160818334Speter	       (TREE_TYPE (TREE_TYPE (newtype)) == char_type_node
160918334Speter		&& TYPE_ARG_TYPES (newtype) == 0
161018334Speter		&& self_promoting_args_p (TYPE_ARG_TYPES (oldtype))
161118334Speter		&& TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (oldtype))) == void_type_node)))
161218334Speter    {
161318334Speter      if (pedantic)
161418334Speter	pedwarn_with_decl (newdecl, "conflicting types for `%s'");
161518334Speter      /* Make sure we keep void * as ret type, not char *.  */
161618334Speter      if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (oldtype))) == void_type_node)
161718334Speter	TREE_TYPE (newdecl) = newtype = oldtype;
161818334Speter
161918334Speter      /* Set DECL_IN_SYSTEM_HEADER, so that if we see another declaration
162018334Speter	 we will come back here again.  */
162118334Speter      DECL_IN_SYSTEM_HEADER (newdecl) = 1;
162218334Speter    }
162318334Speter  else if (!types_match
162418334Speter	   /* Permit char *foo (int, ...); followed by char *foo ();
162518334Speter	      if not pedantic.  */
162618334Speter	   && ! (TREE_CODE (olddecl) == FUNCTION_DECL
162718334Speter		 && ! pedantic
162818334Speter		 /* Return types must still match.  */
162918334Speter		 && comptypes (TREE_TYPE (oldtype),
163018334Speter			       TREE_TYPE (newtype))
163118334Speter		 && TYPE_ARG_TYPES (newtype) == 0))
163218334Speter    {
163318334Speter      error_with_decl (newdecl, "conflicting types for `%s'");
163418334Speter      /* Check for function type mismatch
163518334Speter	 involving an empty arglist vs a nonempty one.  */
163618334Speter      if (TREE_CODE (olddecl) == FUNCTION_DECL
163718334Speter	  && comptypes (TREE_TYPE (oldtype),
163818334Speter			TREE_TYPE (newtype))
163918334Speter	  && ((TYPE_ARG_TYPES (oldtype) == 0
164018334Speter	       && DECL_INITIAL (olddecl) == 0)
164118334Speter	      ||
164218334Speter	      (TYPE_ARG_TYPES (newtype) == 0
164318334Speter	       && DECL_INITIAL (newdecl) == 0)))
164418334Speter	{
164518334Speter	  /* Classify the problem further.  */
164690075Sobrien	  tree t = TYPE_ARG_TYPES (oldtype);
164718334Speter	  if (t == 0)
164818334Speter	    t = TYPE_ARG_TYPES (newtype);
164918334Speter	  for (; t; t = TREE_CHAIN (t))
165018334Speter	    {
165190075Sobrien	      tree type = TREE_VALUE (t);
165218334Speter
165318334Speter	      if (TREE_CHAIN (t) == 0
165418334Speter		  && TYPE_MAIN_VARIANT (type) != void_type_node)
165518334Speter		{
165690075Sobrien		  error ("a parameter list with an ellipsis can't match an empty parameter name list declaration");
165718334Speter		  break;
165818334Speter		}
165918334Speter
166090075Sobrien	      if (simple_type_promotes_to (type) != NULL_TREE)
166118334Speter		{
166290075Sobrien		  error ("an argument type that has a default promotion can't match an empty parameter name list declaration");
166318334Speter		  break;
166418334Speter		}
166518334Speter	    }
166618334Speter	}
166718334Speter      error_with_decl (olddecl, "previous declaration of `%s'");
166818334Speter    }
166918334Speter  else
167018334Speter    {
167118334Speter      errmsg = redeclaration_error_message (newdecl, olddecl);
167218334Speter      if (errmsg)
167318334Speter	{
167452284Sobrien	  switch (errmsg)
167552284Sobrien	    {
167652284Sobrien	    case 1:
167752284Sobrien	      error_with_decl (newdecl, "redefinition of `%s'");
167852284Sobrien	      break;
167952284Sobrien	    case 2:
168052284Sobrien	      error_with_decl (newdecl, "redeclaration of `%s'");
168152284Sobrien	      break;
168252284Sobrien	    case 3:
168352284Sobrien	      error_with_decl (newdecl, "conflicting declarations of `%s'");
168452284Sobrien	      break;
168552284Sobrien	    default:
168652284Sobrien	      abort ();
168752284Sobrien	    }
168852284Sobrien
168918334Speter	  error_with_decl (olddecl,
169018334Speter			   ((DECL_INITIAL (olddecl)
169118334Speter			     && current_binding_level == global_binding_level)
169218334Speter			    ? "`%s' previously defined here"
169318334Speter			    : "`%s' previously declared here"));
169496263Sobrien	  return 0;
169518334Speter	}
169618334Speter      else if (TREE_CODE (newdecl) == TYPE_DECL
169790075Sobrien               && (DECL_IN_SYSTEM_HEADER (olddecl)
169818334Speter                   || DECL_IN_SYSTEM_HEADER (newdecl)))
169918334Speter	{
170018334Speter	  warning_with_decl (newdecl, "redefinition of `%s'");
170190075Sobrien	  warning_with_decl
170218334Speter	    (olddecl,
170318334Speter	     ((DECL_INITIAL (olddecl)
170418334Speter	       && current_binding_level == global_binding_level)
170518334Speter	      ? "`%s' previously defined here"
170618334Speter	      : "`%s' previously declared here"));
170718334Speter	}
170818334Speter      else if (TREE_CODE (olddecl) == FUNCTION_DECL
170918334Speter	       && DECL_INITIAL (olddecl) != 0
171018334Speter	       && TYPE_ARG_TYPES (oldtype) == 0
171118334Speter	       && TYPE_ARG_TYPES (newtype) != 0
171218334Speter	       && TYPE_ACTUAL_ARG_TYPES (oldtype) != 0)
171318334Speter	{
171490075Sobrien	  tree type, parm;
171590075Sobrien	  int nargs;
171618334Speter	  /* Prototype decl follows defn w/o prototype.  */
171718334Speter
171818334Speter	  for (parm = TYPE_ACTUAL_ARG_TYPES (oldtype),
171918334Speter	       type = TYPE_ARG_TYPES (newtype),
172018334Speter	       nargs = 1;
172152284Sobrien	       ;
172218334Speter	       parm = TREE_CHAIN (parm), type = TREE_CHAIN (type), nargs++)
172318334Speter	    {
172418334Speter	      if (TYPE_MAIN_VARIANT (TREE_VALUE (parm)) == void_type_node
172552284Sobrien		  && TYPE_MAIN_VARIANT (TREE_VALUE (type)) == void_type_node)
172652284Sobrien		{
172752284Sobrien		  warning_with_decl (newdecl, "prototype for `%s' follows");
172852284Sobrien		  warning_with_decl (olddecl, "non-prototype definition here");
172952284Sobrien		  break;
173052284Sobrien		}
173152284Sobrien	      if (TYPE_MAIN_VARIANT (TREE_VALUE (parm)) == void_type_node
173218334Speter		  || TYPE_MAIN_VARIANT (TREE_VALUE (type)) == void_type_node)
173318334Speter		{
173490075Sobrien		  error_with_decl (newdecl,
173590075Sobrien				   "prototype for `%s' follows and number of arguments doesn't match");
173652284Sobrien		  error_with_decl (olddecl, "non-prototype definition here");
173752284Sobrien		  errmsg = 1;
173818334Speter		  break;
173918334Speter		}
174018334Speter	      /* Type for passing arg must be consistent
174118334Speter		 with that declared for the arg.  */
174218334Speter	      if (! comptypes (TREE_VALUE (parm), TREE_VALUE (type))
174318334Speter		  /* If -traditional, allow `unsigned int' instead of `int'
174418334Speter		     in the prototype.  */
174518334Speter		  && (! (flag_traditional
174618334Speter			 && TYPE_MAIN_VARIANT (TREE_VALUE (parm)) == integer_type_node
174718334Speter			 && TYPE_MAIN_VARIANT (TREE_VALUE (type)) == unsigned_type_node)))
174818334Speter		{
174952284Sobrien		  error_with_decl (newdecl,
175052284Sobrien				   "prototype for `%s' follows and argument %d doesn't match",
175152284Sobrien				   nargs);
175252284Sobrien		  error_with_decl (olddecl, "non-prototype definition here");
175352284Sobrien		  errmsg = 1;
175418334Speter		  break;
175518334Speter		}
175618334Speter	    }
175718334Speter	}
175818334Speter      /* Warn about mismatches in various flags.  */
175918334Speter      else
176018334Speter	{
176118334Speter	  /* Warn if function is now inline
176218334Speter	     but was previously declared not inline and has been called.  */
176318334Speter	  if (TREE_CODE (olddecl) == FUNCTION_DECL
176490075Sobrien	      && ! DECL_DECLARED_INLINE_P (olddecl)
176590075Sobrien	      && DECL_DECLARED_INLINE_P (newdecl)
176618334Speter	      && TREE_USED (olddecl))
176718334Speter	    warning_with_decl (newdecl,
176818334Speter			       "`%s' declared inline after being called");
176918334Speter	  if (TREE_CODE (olddecl) == FUNCTION_DECL
177090075Sobrien	      && ! DECL_DECLARED_INLINE_P (olddecl)
177190075Sobrien	      && DECL_DECLARED_INLINE_P (newdecl)
177218334Speter	      && DECL_INITIAL (olddecl) != 0)
177318334Speter	    warning_with_decl (newdecl,
177418334Speter			       "`%s' declared inline after its definition");
177518334Speter
177618334Speter	  /* If pedantic, warn when static declaration follows a non-static
177718334Speter	     declaration.  Otherwise, do so only for functions.  */
177818334Speter	  if ((pedantic || TREE_CODE (olddecl) == FUNCTION_DECL)
177918334Speter	      && TREE_PUBLIC (olddecl)
178018334Speter	      && !TREE_PUBLIC (newdecl))
178118334Speter	    warning_with_decl (newdecl, "static declaration for `%s' follows non-static");
178218334Speter
178352284Sobrien	  /* If warn_traditional, warn when a non-static function
178490075Sobrien	     declaration follows a static one.  */
178590075Sobrien	  if (warn_traditional && !in_system_header
178652284Sobrien	      && TREE_CODE (olddecl) == FUNCTION_DECL
178752284Sobrien	      && !TREE_PUBLIC (olddecl)
178852284Sobrien	      && TREE_PUBLIC (newdecl))
178952284Sobrien	    warning_with_decl (newdecl, "non-static declaration for `%s' follows static");
179052284Sobrien
179118334Speter	  /* Warn when const declaration follows a non-const
179218334Speter	     declaration, but not for functions.  */
179318334Speter	  if (TREE_CODE (olddecl) != FUNCTION_DECL
179418334Speter	      && !TREE_READONLY (olddecl)
179518334Speter	      && TREE_READONLY (newdecl))
179618334Speter	    warning_with_decl (newdecl, "const declaration for `%s' follows non-const");
179718334Speter	  /* These bits are logically part of the type, for variables.
179818334Speter	     But not for functions
179918334Speter	     (where qualifiers are not valid ANSI anyway).  */
180018334Speter	  else if (pedantic && TREE_CODE (olddecl) != FUNCTION_DECL
180118334Speter	      && (TREE_READONLY (newdecl) != TREE_READONLY (olddecl)
180218334Speter		  || TREE_THIS_VOLATILE (newdecl) != TREE_THIS_VOLATILE (olddecl)))
180318334Speter	    pedwarn_with_decl (newdecl, "type qualifiers for `%s' conflict with previous decl");
180418334Speter	}
180518334Speter    }
180618334Speter
180718334Speter  /* Optionally warn about more than one declaration for the same name.  */
180818334Speter  if (errmsg == 0 && warn_redundant_decls && DECL_SOURCE_LINE (olddecl) != 0
180950397Sobrien      /* Don't warn about a function declaration
181018334Speter	 followed by a definition.  */
181118334Speter      && !(TREE_CODE (newdecl) == FUNCTION_DECL && DECL_INITIAL (newdecl) != 0
181218334Speter	   && DECL_INITIAL (olddecl) == 0)
181318334Speter      /* Don't warn about extern decl followed by (tentative) definition.  */
181418334Speter      && !(DECL_EXTERNAL (olddecl) && ! DECL_EXTERNAL (newdecl)))
181518334Speter    {
181618334Speter      warning_with_decl (newdecl, "redundant redeclaration of `%s' in same scope");
181718334Speter      warning_with_decl (olddecl, "previous declaration of `%s'");
181818334Speter    }
181918334Speter
182018334Speter  /* Copy all the DECL_... slots specified in the new decl
182118334Speter     except for any that we copy here from the old type.
182218334Speter
182318334Speter     Past this point, we don't change OLDTYPE and NEWTYPE
182418334Speter     even if we change the types of NEWDECL and OLDDECL.  */
182518334Speter
182618334Speter  if (types_match)
182718334Speter    {
182850397Sobrien      /* When copying info to olddecl, we store into write_olddecl
182950397Sobrien	 instead.  This allows us to avoid modifying olddecl when
183050397Sobrien	 different_binding_level is true.  */
183150397Sobrien      tree write_olddecl = different_binding_level ? newdecl : olddecl;
183250397Sobrien
183318334Speter      /* Merge the data types specified in the two decls.  */
183418334Speter      if (TREE_CODE (newdecl) != FUNCTION_DECL || !DECL_BUILT_IN (olddecl))
183550397Sobrien	{
183650397Sobrien	  if (different_binding_level)
183790075Sobrien	    {
183890075Sobrien	      if (TYPE_ARG_TYPES (oldtype) != 0
183990075Sobrien		  && TYPE_ARG_TYPES (newtype) == 0)
184090075Sobrien		TREE_TYPE (newdecl) = common_type (newtype, oldtype);
184190075Sobrien	      else
184290075Sobrien		TREE_TYPE (newdecl)
184390075Sobrien		  = build_type_attribute_variant
184490075Sobrien		    (newtype,
184590075Sobrien		     merge_attributes (TYPE_ATTRIBUTES (newtype),
184690075Sobrien				       TYPE_ATTRIBUTES (oldtype)));
184790075Sobrien	    }
184850397Sobrien	  else
184950397Sobrien	    TREE_TYPE (newdecl)
185050397Sobrien	      = TREE_TYPE (olddecl)
185150397Sobrien		= common_type (newtype, oldtype);
185250397Sobrien	}
185318334Speter
185418334Speter      /* Lay the type out, unless already done.  */
185518334Speter      if (oldtype != TREE_TYPE (newdecl))
185618334Speter	{
185718334Speter	  if (TREE_TYPE (newdecl) != error_mark_node)
185818334Speter	    layout_type (TREE_TYPE (newdecl));
185918334Speter	  if (TREE_CODE (newdecl) != FUNCTION_DECL
186018334Speter	      && TREE_CODE (newdecl) != TYPE_DECL
186118334Speter	      && TREE_CODE (newdecl) != CONST_DECL)
186218334Speter	    layout_decl (newdecl, 0);
186318334Speter	}
186418334Speter      else
186518334Speter	{
186618334Speter	  /* Since the type is OLDDECL's, make OLDDECL's size go with.  */
186718334Speter	  DECL_SIZE (newdecl) = DECL_SIZE (olddecl);
186890075Sobrien	  DECL_SIZE_UNIT (newdecl) = DECL_SIZE_UNIT (olddecl);
186957844Sobrien	  DECL_MODE (newdecl) = DECL_MODE (olddecl);
187018334Speter	  if (TREE_CODE (olddecl) != FUNCTION_DECL)
187118334Speter	    if (DECL_ALIGN (olddecl) > DECL_ALIGN (newdecl))
187290075Sobrien	      {
187390075Sobrien		DECL_ALIGN (newdecl) = DECL_ALIGN (olddecl);
187490075Sobrien		DECL_USER_ALIGN (newdecl) |= DECL_ALIGN (olddecl);
187590075Sobrien	      }
187618334Speter	}
187718334Speter
187818334Speter      /* Keep the old rtl since we can safely use it.  */
187990075Sobrien      COPY_DECL_RTL (olddecl, newdecl);
188018334Speter
188118334Speter      /* Merge the type qualifiers.  */
188290075Sobrien      if (TREE_CODE (olddecl) == FUNCTION_DECL
188390075Sobrien	  && DECL_BUILT_IN_NONANSI (olddecl) && TREE_THIS_VOLATILE (olddecl)
188490075Sobrien	  && ! TREE_THIS_VOLATILE (newdecl))
188550397Sobrien	TREE_THIS_VOLATILE (write_olddecl) = 0;
188690075Sobrien
188718334Speter      if (TREE_READONLY (newdecl))
188850397Sobrien	TREE_READONLY (write_olddecl) = 1;
188990075Sobrien
189018334Speter      if (TREE_THIS_VOLATILE (newdecl))
189118334Speter	{
189250397Sobrien	  TREE_THIS_VOLATILE (write_olddecl) = 1;
189390075Sobrien	  if (TREE_CODE (newdecl) == VAR_DECL
189490075Sobrien	      /* If an automatic variable is re-declared in the same
189590075Sobrien		 function scope, but the old declaration was not
189690075Sobrien		 volatile, make_var_volatile() would crash because the
189790075Sobrien		 variable would have been assigned to a pseudo, not a
189890075Sobrien		 MEM.  Since this duplicate declaration is invalid
189990075Sobrien		 anyway, we just skip the call.  */
190090075Sobrien	      && errmsg == 0)
190118334Speter	    make_var_volatile (newdecl);
190218334Speter	}
190318334Speter
190450397Sobrien      /* Keep source location of definition rather than declaration.  */
190550397Sobrien      /* When called with different_binding_level set, keep the old
190650397Sobrien	 information so that meaningful diagnostics can be given.  */
190750397Sobrien      if (DECL_INITIAL (newdecl) == 0 && DECL_INITIAL (olddecl) != 0
190850397Sobrien	  && ! different_binding_level)
190918334Speter	{
191018334Speter	  DECL_SOURCE_LINE (newdecl) = DECL_SOURCE_LINE (olddecl);
191118334Speter	  DECL_SOURCE_FILE (newdecl) = DECL_SOURCE_FILE (olddecl);
191218334Speter	}
191318334Speter
191418334Speter      /* Merge the unused-warning information.  */
191518334Speter      if (DECL_IN_SYSTEM_HEADER (olddecl))
191618334Speter	DECL_IN_SYSTEM_HEADER (newdecl) = 1;
191718334Speter      else if (DECL_IN_SYSTEM_HEADER (newdecl))
191850397Sobrien	DECL_IN_SYSTEM_HEADER (write_olddecl) = 1;
191918334Speter
192018334Speter      /* Merge the initialization information.  */
192150397Sobrien      /* When called with different_binding_level set, don't copy over
192250397Sobrien	 DECL_INITIAL, so that we don't accidentally change function
192350397Sobrien	 declarations into function definitions.  */
192450397Sobrien      if (DECL_INITIAL (newdecl) == 0 && ! different_binding_level)
192518334Speter	DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
192618334Speter
192718334Speter      /* Merge the section attribute.
192818334Speter         We want to issue an error if the sections conflict but that must be
192918334Speter	 done later in decl_attributes since we are called before attributes
193018334Speter	 are assigned.  */
193118334Speter      if (DECL_SECTION_NAME (newdecl) == NULL_TREE)
193218334Speter	DECL_SECTION_NAME (newdecl) = DECL_SECTION_NAME (olddecl);
193318334Speter
193490075Sobrien      /* Copy the assembler name.
193590075Sobrien	 Currently, it can only be defined in the prototype.  */
193690075Sobrien      COPY_DECL_ASSEMBLER_NAME (olddecl, newdecl);
193790075Sobrien
193818334Speter      if (TREE_CODE (newdecl) == FUNCTION_DECL)
193918334Speter	{
194018334Speter	  DECL_STATIC_CONSTRUCTOR(newdecl) |= DECL_STATIC_CONSTRUCTOR(olddecl);
194118334Speter	  DECL_STATIC_DESTRUCTOR (newdecl) |= DECL_STATIC_DESTRUCTOR (olddecl);
194290075Sobrien	  DECL_NO_LIMIT_STACK (newdecl) |= DECL_NO_LIMIT_STACK (olddecl);
194352284Sobrien	  DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (newdecl)
194452284Sobrien	    |= DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (olddecl);
194518334Speter	}
194618334Speter    }
194718334Speter  /* If cannot merge, then use the new type and qualifiers,
194818334Speter     and don't preserve the old rtl.  */
194950397Sobrien  else if (! different_binding_level)
195018334Speter    {
195118334Speter      TREE_TYPE (olddecl) = TREE_TYPE (newdecl);
195218334Speter      TREE_READONLY (olddecl) = TREE_READONLY (newdecl);
195318334Speter      TREE_THIS_VOLATILE (olddecl) = TREE_THIS_VOLATILE (newdecl);
195418334Speter      TREE_SIDE_EFFECTS (olddecl) = TREE_SIDE_EFFECTS (newdecl);
195518334Speter    }
195618334Speter
195718334Speter  /* Merge the storage class information.  */
195896263Sobrien  merge_weak (newdecl, olddecl);
195996263Sobrien
196018334Speter  /* For functions, static overrides non-static.  */
196118334Speter  if (TREE_CODE (newdecl) == FUNCTION_DECL)
196218334Speter    {
196318334Speter      TREE_PUBLIC (newdecl) &= TREE_PUBLIC (olddecl);
196418334Speter      /* This is since we don't automatically
196518334Speter	 copy the attributes of NEWDECL into OLDDECL.  */
196650397Sobrien      /* No need to worry about different_binding_level here because
196750397Sobrien	 then TREE_PUBLIC (newdecl) was true.  */
196818334Speter      TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl);
196918334Speter      /* If this clears `static', clear it in the identifier too.  */
197018334Speter      if (! TREE_PUBLIC (olddecl))
197118334Speter	TREE_PUBLIC (DECL_NAME (olddecl)) = 0;
197218334Speter    }
197318334Speter  if (DECL_EXTERNAL (newdecl))
197418334Speter    {
197590075Sobrien      if (! different_binding_level)
197690075Sobrien	{
197790075Sobrien	  /* Don't mess with these flags on local externs; they remain
197890075Sobrien	     external even if there's a declaration at file scope which
197990075Sobrien	     isn't.  */
198090075Sobrien	  TREE_STATIC (newdecl) = TREE_STATIC (olddecl);
198190075Sobrien	  DECL_EXTERNAL (newdecl) = DECL_EXTERNAL (olddecl);
198290075Sobrien	}
198318334Speter      /* An extern decl does not override previous storage class.  */
198418334Speter      TREE_PUBLIC (newdecl) = TREE_PUBLIC (olddecl);
198550397Sobrien      if (! DECL_EXTERNAL (newdecl))
198650397Sobrien	DECL_CONTEXT (newdecl) = DECL_CONTEXT (olddecl);
198718334Speter    }
198818334Speter  else
198918334Speter    {
199018334Speter      TREE_STATIC (olddecl) = TREE_STATIC (newdecl);
199118334Speter      TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl);
199218334Speter    }
199318334Speter
199450397Sobrien  if (TREE_CODE (newdecl) == FUNCTION_DECL)
199518334Speter    {
199690075Sobrien      /* If we're redefining a function previously defined as extern
199790075Sobrien	 inline, make sure we emit debug info for the inline before we
199890075Sobrien	 throw it away, in case it was inlined into a function that hasn't
199990075Sobrien	 been written out yet.  */
200090075Sobrien      if (new_is_definition && DECL_INITIAL (olddecl) && TREE_USED (olddecl))
200190075Sobrien	{
200290075Sobrien	  (*debug_hooks->outlining_inline_function) (olddecl);
200390075Sobrien
200490075Sobrien	  /* The new defn must not be inline.  */
200590075Sobrien	  DECL_INLINE (newdecl) = 0;
200690075Sobrien	  DECL_UNINLINABLE (newdecl) = 1;
200790075Sobrien	}
200890075Sobrien      else
200990075Sobrien	{
201090075Sobrien	  /* If either decl says `inline', this fn is inline,
201190075Sobrien	     unless its definition was passed already.  */
201290075Sobrien	  if (DECL_DECLARED_INLINE_P (newdecl)
201390075Sobrien	      || DECL_DECLARED_INLINE_P (olddecl))
201490075Sobrien	    DECL_DECLARED_INLINE_P (newdecl) = 1;
201590075Sobrien
201690075Sobrien	  DECL_UNINLINABLE (newdecl) = DECL_UNINLINABLE (olddecl)
201790075Sobrien	    = (DECL_UNINLINABLE (newdecl) || DECL_UNINLINABLE (olddecl));
201890075Sobrien	}
201990075Sobrien
202018334Speter      if (DECL_BUILT_IN (olddecl))
202118334Speter	{
202250397Sobrien	  /* Get rid of any built-in function if new arg types don't match it
202350397Sobrien	     or if we have a function definition.  */
202450397Sobrien	  if (! types_match || new_is_definition)
202550397Sobrien	    {
202650397Sobrien	      if (! different_binding_level)
202750397Sobrien		{
202850397Sobrien		  TREE_TYPE (olddecl) = TREE_TYPE (newdecl);
202990075Sobrien		  DECL_BUILT_IN_CLASS (olddecl) = NOT_BUILT_IN;
203050397Sobrien		}
203150397Sobrien	    }
203250397Sobrien	  else
203350397Sobrien	    {
203450397Sobrien	      /* If redeclaring a builtin function, and not a definition,
203550397Sobrien		 it stays built in.  */
203690075Sobrien	      DECL_BUILT_IN_CLASS (newdecl) = DECL_BUILT_IN_CLASS (olddecl);
203750397Sobrien	      DECL_FUNCTION_CODE (newdecl) = DECL_FUNCTION_CODE (olddecl);
203850397Sobrien	    }
203918334Speter	}
204090075Sobrien
204150397Sobrien      /* Also preserve various other info from the definition.  */
204250397Sobrien      if (! new_is_definition)
204350397Sobrien	{
204450397Sobrien	  DECL_RESULT (newdecl) = DECL_RESULT (olddecl);
204550397Sobrien	  /* When called with different_binding_level set, don't copy over
204650397Sobrien	     DECL_INITIAL, so that we don't accidentally change function
204750397Sobrien	     declarations into function definitions.  */
204850397Sobrien	  if (! different_binding_level)
204950397Sobrien	    DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
205050397Sobrien	  DECL_SAVED_INSNS (newdecl) = DECL_SAVED_INSNS (olddecl);
205190075Sobrien	  DECL_SAVED_TREE (newdecl) = DECL_SAVED_TREE (olddecl);
205290075Sobrien	  DECL_NUM_STMTS (newdecl) = DECL_NUM_STMTS (olddecl);
205350397Sobrien	  DECL_ARGUMENTS (newdecl) = DECL_ARGUMENTS (olddecl);
205490075Sobrien
205590075Sobrien	  /* Set DECL_INLINE on the declaration if we've got a body
205690075Sobrien	     from which to instantiate.  */
205790075Sobrien	  if (DECL_INLINE (olddecl) && ! DECL_UNINLINABLE (newdecl))
205890075Sobrien	    {
205990075Sobrien	      DECL_INLINE (newdecl) = 1;
206090075Sobrien	      DECL_ABSTRACT_ORIGIN (newdecl)
206190075Sobrien		= (different_binding_level
206290075Sobrien		   ? DECL_ORIGIN (olddecl)
206390075Sobrien		   : DECL_ABSTRACT_ORIGIN (olddecl));
206490075Sobrien	    }
206550397Sobrien	}
206690075Sobrien      else
206790075Sobrien	{
206890075Sobrien	  /* If a previous declaration said inline, mark the
206990075Sobrien	     definition as inlinable.  */
207090075Sobrien	  if (DECL_DECLARED_INLINE_P (newdecl)
207190075Sobrien	      && ! DECL_UNINLINABLE (newdecl))
207290075Sobrien	    DECL_INLINE (newdecl) = 1;
207390075Sobrien	}
207450397Sobrien    }
207550397Sobrien  if (different_binding_level)
207690075Sobrien    return 0;
207718334Speter
207818334Speter  /* Copy most of the decl-specific fields of NEWDECL into OLDDECL.
207950397Sobrien     But preserve OLDDECL's DECL_UID.  */
208018334Speter  {
208190075Sobrien    unsigned olddecl_uid = DECL_UID (olddecl);
208218334Speter
208390075Sobrien    memcpy ((char *) olddecl + sizeof (struct tree_common),
208490075Sobrien	    (char *) newdecl + sizeof (struct tree_common),
208590075Sobrien	    sizeof (struct tree_decl) - sizeof (struct tree_common));
208618334Speter    DECL_UID (olddecl) = olddecl_uid;
208718334Speter  }
208818334Speter
208950397Sobrien  /* NEWDECL contains the merged attribute lists.
209050397Sobrien     Update OLDDECL to be the same.  */
209190075Sobrien  DECL_ATTRIBUTES (olddecl) = DECL_ATTRIBUTES (newdecl);
209250397Sobrien
209318334Speter  return 1;
209418334Speter}
209518334Speter
209690075Sobrien/* Check whether decl-node X shadows an existing declaration.
209790075Sobrien   OLDLOCAL is the old IDENTIFIER_LOCAL_VALUE of the DECL_NAME of X,
209890075Sobrien   which might be a NULL_TREE.  */
209990075Sobrienstatic void
210090075Sobrienwarn_if_shadowing (x, oldlocal)
210190075Sobrien     tree x, oldlocal;
210290075Sobrien{
210390075Sobrien  tree name;
210490075Sobrien
210590075Sobrien  if (DECL_EXTERNAL (x))
210690075Sobrien    return;
210790075Sobrien
210890075Sobrien  name = DECL_NAME (x);
210990075Sobrien
211090075Sobrien  /* Warn if shadowing an argument at the top level of the body.  */
211190075Sobrien  if (oldlocal != 0
211290075Sobrien      /* This warning doesn't apply to the parms of a nested fcn.  */
211390075Sobrien      && ! current_binding_level->parm_flag
211490075Sobrien      /* Check that this is one level down from the parms.  */
211590075Sobrien      && current_binding_level->level_chain->parm_flag
211690075Sobrien      /* Check that the decl being shadowed
211790075Sobrien	 comes from the parm level, one level up.  */
211890075Sobrien      && chain_member (oldlocal, current_binding_level->level_chain->names))
211990075Sobrien    {
212090075Sobrien      if (TREE_CODE (oldlocal) == PARM_DECL)
212190075Sobrien	pedwarn ("declaration of `%s' shadows a parameter",
212290075Sobrien		 IDENTIFIER_POINTER (name));
212390075Sobrien      else
212490075Sobrien	pedwarn ("declaration of `%s' shadows a symbol from the parameter list",
212590075Sobrien		 IDENTIFIER_POINTER (name));
212690075Sobrien    }
212790075Sobrien  /* Maybe warn if shadowing something else.  */
212890075Sobrien  else if (warn_shadow
212990075Sobrien	   /* No shadow warnings for internally generated vars.  */
213090075Sobrien	   && DECL_SOURCE_LINE (x) != 0
213190075Sobrien	   /* No shadow warnings for vars made for inlining.  */
213290075Sobrien	   && ! DECL_FROM_INLINE (x))
213390075Sobrien    {
213490075Sobrien      if (TREE_CODE (x) == PARM_DECL
213590075Sobrien	  && current_binding_level->level_chain->parm_flag)
213690075Sobrien	/* Don't warn about the parm names in function declarator
213790075Sobrien	   within a function declarator.
213890075Sobrien	   It would be nice to avoid warning in any function
213990075Sobrien	   declarator in a declaration, as opposed to a definition,
214090075Sobrien	   but there is no way to tell it's not a definition.  */
214190075Sobrien	;
214290075Sobrien      else if (oldlocal)
214390075Sobrien	{
214490075Sobrien	  if (TREE_CODE (oldlocal) == PARM_DECL)
214590075Sobrien	    shadow_warning ("a parameter", name, oldlocal);
214690075Sobrien	  else
214790075Sobrien	    shadow_warning ("a previous local", name, oldlocal);
214890075Sobrien	}
214990075Sobrien      else if (IDENTIFIER_GLOBAL_VALUE (name) != 0
215090075Sobrien	       && IDENTIFIER_GLOBAL_VALUE (name) != error_mark_node)
215190075Sobrien	shadow_warning ("a global declaration", name,
215290075Sobrien			IDENTIFIER_GLOBAL_VALUE (name));
215390075Sobrien    }
215490075Sobrien}
215590075Sobrien
215618334Speter/* Record a decl-node X as belonging to the current lexical scope.
215718334Speter   Check for errors (such as an incompatible declaration for the same
215818334Speter   name already seen in the same scope).
215918334Speter
216018334Speter   Returns either X or an old decl for the same name.
216118334Speter   If an old decl is returned, it may have been smashed
216218334Speter   to agree with what X says.  */
216318334Speter
216418334Spetertree
216518334Speterpushdecl (x)
216618334Speter     tree x;
216718334Speter{
216890075Sobrien  tree t;
216990075Sobrien  tree name = DECL_NAME (x);
217090075Sobrien  struct binding_level *b = current_binding_level;
217118334Speter
217290075Sobrien  /* Functions need the lang_decl data.  */
217390075Sobrien  if (TREE_CODE (x) == FUNCTION_DECL && ! DECL_LANG_SPECIFIC (x))
217490075Sobrien    DECL_LANG_SPECIFIC (x) = (struct lang_decl *)
217590075Sobrien      ggc_alloc_cleared (sizeof (struct lang_decl));
217690075Sobrien
217718334Speter  DECL_CONTEXT (x) = current_function_decl;
217818334Speter  /* A local extern declaration for a function doesn't constitute nesting.
217918334Speter     A local auto declaration does, since it's a forward decl
218018334Speter     for a nested function coming later.  */
218190075Sobrien  if ((TREE_CODE (x) == FUNCTION_DECL || TREE_CODE (x) == VAR_DECL)
218290075Sobrien      && DECL_INITIAL (x) == 0 && DECL_EXTERNAL (x))
218318334Speter    DECL_CONTEXT (x) = 0;
218418334Speter
218518334Speter  if (name)
218618334Speter    {
218750397Sobrien      int different_binding_level = 0;
218818334Speter
218990075Sobrien      if (warn_nested_externs
219090075Sobrien	  && DECL_EXTERNAL (x)
219190075Sobrien	  && b != global_binding_level
219290075Sobrien	  && x != IDENTIFIER_IMPLICIT_DECL (name)
219390075Sobrien	  /* No error messages for __FUNCTION__ and __PRETTY_FUNCTION__.  */
219490075Sobrien	  && !DECL_IN_SYSTEM_HEADER (x))
219590075Sobrien	warning ("nested extern declaration of `%s'",
219690075Sobrien		 IDENTIFIER_POINTER (name));
219790075Sobrien
219850397Sobrien      t = lookup_name_current_level (name);
219918334Speter      /* Don't type check externs here when -traditional.  This is so that
220018334Speter	 code with conflicting declarations inside blocks will get warnings
220118334Speter	 not errors.  X11 for instance depends on this.  */
220250397Sobrien      if (! t && DECL_EXTERNAL (x) && TREE_PUBLIC (x) && ! flag_traditional)
220350397Sobrien	{
220496263Sobrien	  t = IDENTIFIER_GLOBAL_VALUE (name);
220550397Sobrien	  /* Type decls at global scope don't conflict with externs declared
220650397Sobrien	     inside lexical blocks.  */
220796263Sobrien	  if (! t || TREE_CODE (t) == TYPE_DECL)
220896263Sobrien	    /* If there's no visible global declaration, try for an
220996263Sobrien               invisible one.  */
221096263Sobrien	    t = IDENTIFIER_LIMBO_VALUE (name);
221150397Sobrien	  different_binding_level = 1;
221250397Sobrien	}
221318334Speter      if (t != 0 && t == error_mark_node)
221418334Speter	/* error_mark_node is 0 for a while during initialization!  */
221518334Speter	{
221618334Speter	  t = 0;
221718334Speter	  error_with_decl (x, "`%s' used prior to declaration");
221818334Speter	}
221918334Speter
222050397Sobrien      /* If this decl is `static' and an implicit decl was seen previously,
222150397Sobrien	 warn.  But don't complain if -traditional,
222250397Sobrien	 since traditional compilers don't complain.  */
222350397Sobrien      if (! flag_traditional && TREE_PUBLIC (name)
222450397Sobrien	  /* Don't test for DECL_EXTERNAL, because grokdeclarator
222550397Sobrien	     sets this for all functions.  */
222650397Sobrien	  && ! TREE_PUBLIC (x)
222750397Sobrien	  && (TREE_CODE (x) == FUNCTION_DECL || b == global_binding_level)
222850397Sobrien	  /* We used to warn also for explicit extern followed by static,
222950397Sobrien	     but sometimes you need to do it that way.  */
223050397Sobrien	  && IDENTIFIER_IMPLICIT_DECL (name) != 0)
223118334Speter	{
223250397Sobrien	  pedwarn ("`%s' was declared implicitly `extern' and later `static'",
223350397Sobrien		   IDENTIFIER_POINTER (name));
223450397Sobrien	  pedwarn_with_file_and_line
223550397Sobrien	    (DECL_SOURCE_FILE (IDENTIFIER_IMPLICIT_DECL (name)),
223650397Sobrien	     DECL_SOURCE_LINE (IDENTIFIER_IMPLICIT_DECL (name)),
223750397Sobrien	     "previous declaration of `%s'",
223850397Sobrien	     IDENTIFIER_POINTER (name));
223950397Sobrien	  TREE_THIS_VOLATILE (name) = 1;
224050397Sobrien	}
224150397Sobrien
224250397Sobrien      if (t != 0 && duplicate_decls (x, t, different_binding_level))
224350397Sobrien	{
224418334Speter	  if (TREE_CODE (t) == PARM_DECL)
224518334Speter	    {
224618334Speter	      /* Don't allow more than one "real" duplicate
224718334Speter		 of a forward parm decl.  */
224818334Speter	      TREE_ASM_WRITTEN (t) = TREE_ASM_WRITTEN (x);
224918334Speter	      return t;
225018334Speter	    }
225150397Sobrien	  return t;
225218334Speter	}
225318334Speter
225418334Speter      /* If we are processing a typedef statement, generate a whole new
225518334Speter	 ..._TYPE node (which will be just an variant of the existing
225618334Speter	 ..._TYPE node with identical properties) and then install the
225718334Speter	 TYPE_DECL node generated to represent the typedef name as the
225818334Speter	 TYPE_NAME of this brand new (duplicate) ..._TYPE node.
225918334Speter
226018334Speter	 The whole point here is to end up with a situation where each
226118334Speter	 and every ..._TYPE node the compiler creates will be uniquely
226218334Speter	 associated with AT MOST one node representing a typedef name.
226318334Speter	 This way, even though the compiler substitutes corresponding
226418334Speter	 ..._TYPE nodes for TYPE_DECL (i.e. "typedef name") nodes very
226518334Speter	 early on, later parts of the compiler can always do the reverse
226618334Speter	 translation and get back the corresponding typedef name.  For
226718334Speter	 example, given:
226818334Speter
226918334Speter		typedef struct S MY_TYPE;
227018334Speter		MY_TYPE object;
227118334Speter
227218334Speter	 Later parts of the compiler might only know that `object' was of
227350397Sobrien	 type `struct S' if it were not for code just below.  With this
227418334Speter	 code however, later parts of the compiler see something like:
227518334Speter
227618334Speter		struct S' == struct S
227718334Speter		typedef struct S' MY_TYPE;
227818334Speter		struct S' object;
227918334Speter
228018334Speter	 And they can then deduce (from the node for type struct S') that
228118334Speter	 the original object declaration was:
228218334Speter
228318334Speter		MY_TYPE object;
228418334Speter
228518334Speter	 Being able to do this is important for proper support of protoize,
228618334Speter	 and also for generating precise symbolic debugging information
228718334Speter	 which takes full account of the programmer's (typedef) vocabulary.
228818334Speter
228918334Speter         Obviously, we don't want to generate a duplicate ..._TYPE node if
229018334Speter	 the TYPE_DECL node that we are now processing really represents a
229118334Speter	 standard built-in type.
229218334Speter
229318334Speter         Since all standard types are effectively declared at line zero
229418334Speter         in the source file, we can easily check to see if we are working
229518334Speter         on a standard type by checking the current value of lineno.  */
229618334Speter
229718334Speter      if (TREE_CODE (x) == TYPE_DECL)
229890075Sobrien	{
229990075Sobrien	  if (DECL_SOURCE_LINE (x) == 0)
230090075Sobrien	    {
230118334Speter	      if (TYPE_NAME (TREE_TYPE (x)) == 0)
230290075Sobrien		TYPE_NAME (TREE_TYPE (x)) = x;
230390075Sobrien	    }
230490075Sobrien	  else if (TREE_TYPE (x) != error_mark_node
230550397Sobrien		   && DECL_ORIGINAL_TYPE (x) == NULL_TREE)
230690075Sobrien	    {
230790075Sobrien	      tree tt = TREE_TYPE (x);
230850397Sobrien	      DECL_ORIGINAL_TYPE (x) = tt;
230990075Sobrien	      tt = build_type_copy (tt);
231090075Sobrien	      TYPE_NAME (tt) = x;
231190075Sobrien	      TREE_USED (tt) = TREE_USED (x);
231290075Sobrien	      TREE_TYPE (x) = tt;
231390075Sobrien	    }
231490075Sobrien	}
231518334Speter
231618334Speter      /* Multiple external decls of the same identifier ought to match.
231718334Speter	 Check against both global declarations (when traditional) and out of
231818334Speter	 scope (limbo) block level declarations.
231918334Speter
232018334Speter	 We get warnings about inline functions where they are defined.
232118334Speter	 Avoid duplicate warnings where they are used.  */
232290075Sobrien      if (TREE_PUBLIC (x)
232390075Sobrien	  && ! (TREE_CODE (x) == FUNCTION_DECL && DECL_INLINE (x)))
232418334Speter	{
232518334Speter	  tree decl;
232618334Speter
232718334Speter	  if (flag_traditional && IDENTIFIER_GLOBAL_VALUE (name) != 0
232818334Speter	      && (DECL_EXTERNAL (IDENTIFIER_GLOBAL_VALUE (name))
232918334Speter		  || TREE_PUBLIC (IDENTIFIER_GLOBAL_VALUE (name))))
233018334Speter	    decl = IDENTIFIER_GLOBAL_VALUE (name);
233118334Speter	  else if (IDENTIFIER_LIMBO_VALUE (name) != 0)
233218334Speter	    /* Decls in limbo are always extern, so no need to check that.  */
233318334Speter	    decl = IDENTIFIER_LIMBO_VALUE (name);
233418334Speter	  else
233518334Speter	    decl = 0;
233618334Speter
233718334Speter	  if (decl && ! comptypes (TREE_TYPE (x), TREE_TYPE (decl))
233818334Speter	      /* If old decl is built-in, we already warned if we should.  */
233918334Speter	      && !DECL_BUILT_IN (decl))
234018334Speter	    {
234118334Speter	      pedwarn_with_decl (x,
234218334Speter				 "type mismatch with previous external decl");
234318334Speter	      pedwarn_with_decl (decl, "previous external decl of `%s'");
234418334Speter	    }
234518334Speter	}
234618334Speter
234718334Speter      /* If a function has had an implicit declaration, and then is defined,
234818334Speter	 make sure they are compatible.  */
234918334Speter
235018334Speter      if (IDENTIFIER_IMPLICIT_DECL (name) != 0
235118334Speter	  && IDENTIFIER_GLOBAL_VALUE (name) == 0
235218334Speter	  && TREE_CODE (x) == FUNCTION_DECL
235318334Speter	  && ! comptypes (TREE_TYPE (x),
235418334Speter			  TREE_TYPE (IDENTIFIER_IMPLICIT_DECL (name))))
235518334Speter	{
235618334Speter	  warning_with_decl (x, "type mismatch with previous implicit declaration");
235718334Speter	  warning_with_decl (IDENTIFIER_IMPLICIT_DECL (name),
235818334Speter			     "previous implicit declaration of `%s'");
235918334Speter	}
236018334Speter
236118334Speter      /* In PCC-compatibility mode, extern decls of vars with no current decl
236218334Speter	 take effect at top level no matter where they are.  */
236318334Speter      if (flag_traditional && DECL_EXTERNAL (x)
236418334Speter	  && lookup_name (name) == 0)
236518334Speter	{
236618334Speter	  tree type = TREE_TYPE (x);
236718334Speter
236818334Speter	  /* But don't do this if the type contains temporary nodes.  */
236918334Speter	  while (type)
237018334Speter	    {
237118334Speter	      if (type == error_mark_node)
237218334Speter		break;
237390075Sobrien	      if (TYPE_CONTEXT (type))
237418334Speter		{
237518334Speter		  warning_with_decl (x, "type of external `%s' is not global");
237618334Speter		  /* By exiting the loop early, we leave TYPE nonzero,
237718334Speter		     and thus prevent globalization of the decl.  */
237818334Speter		  break;
237918334Speter		}
238018334Speter	      else if (TREE_CODE (type) == FUNCTION_TYPE
238118334Speter		       && TYPE_ARG_TYPES (type) != 0)
238218334Speter		/* The types might not be truly local,
238318334Speter		   but the list of arg types certainly is temporary.
238418334Speter		   Since prototypes are nontraditional,
238518334Speter		   ok not to do the traditional thing.  */
238618334Speter		break;
238718334Speter	      type = TREE_TYPE (type);
238818334Speter	    }
238918334Speter
239018334Speter	  if (type == 0)
239118334Speter	    b = global_binding_level;
239218334Speter	}
239318334Speter
239418334Speter      /* This name is new in its binding level.
239518334Speter	 Install the new declaration and return it.  */
239618334Speter      if (b == global_binding_level)
239718334Speter	{
239818334Speter	  /* Install a global value.  */
239990075Sobrien
240018334Speter	  /* If the first global decl has external linkage,
240118334Speter	     warn if we later see static one.  */
240218334Speter	  if (IDENTIFIER_GLOBAL_VALUE (name) == 0 && TREE_PUBLIC (x))
240318334Speter	    TREE_PUBLIC (name) = 1;
240418334Speter
240518334Speter	  IDENTIFIER_GLOBAL_VALUE (name) = x;
240618334Speter
240718334Speter	  /* We no longer care about any previous block level declarations.  */
240818334Speter	  IDENTIFIER_LIMBO_VALUE (name) = 0;
240918334Speter
241018334Speter	  /* Don't forget if the function was used via an implicit decl.  */
241118334Speter	  if (IDENTIFIER_IMPLICIT_DECL (name)
241218334Speter	      && TREE_USED (IDENTIFIER_IMPLICIT_DECL (name)))
241318334Speter	    TREE_USED (x) = 1, TREE_USED (name) = 1;
241418334Speter
241518334Speter	  /* Don't forget if its address was taken in that way.  */
241618334Speter	  if (IDENTIFIER_IMPLICIT_DECL (name)
241718334Speter	      && TREE_ADDRESSABLE (IDENTIFIER_IMPLICIT_DECL (name)))
241818334Speter	    TREE_ADDRESSABLE (x) = 1;
241918334Speter
242018334Speter	  /* Warn about mismatches against previous implicit decl.  */
242118334Speter	  if (IDENTIFIER_IMPLICIT_DECL (name) != 0
242218334Speter	      /* If this real decl matches the implicit, don't complain.  */
242318334Speter	      && ! (TREE_CODE (x) == FUNCTION_DECL
242418334Speter		    && (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (x)))
242518334Speter			== integer_type_node)))
242618334Speter	    pedwarn ("`%s' was previously implicitly declared to return `int'",
242718334Speter		     IDENTIFIER_POINTER (name));
242818334Speter
242918334Speter	  /* If this decl is `static' and an `extern' was seen previously,
243018334Speter	     that is erroneous.  */
243118334Speter	  if (TREE_PUBLIC (name)
243218334Speter	      && ! TREE_PUBLIC (x) && ! DECL_EXTERNAL (x))
243318334Speter	    {
243418334Speter	      /* Okay to redeclare an ANSI built-in as static.  */
243518334Speter	      if (t != 0 && DECL_BUILT_IN (t))
243618334Speter		;
243718334Speter	      /* Okay to declare a non-ANSI built-in as anything.  */
243818334Speter	      else if (t != 0 && DECL_BUILT_IN_NONANSI (t))
243918334Speter		;
244050397Sobrien	      /* Okay to have global type decl after an earlier extern
244150397Sobrien		 declaration inside a lexical block.  */
244250397Sobrien	      else if (TREE_CODE (x) == TYPE_DECL)
244350397Sobrien		;
244418334Speter	      else if (IDENTIFIER_IMPLICIT_DECL (name))
244550397Sobrien		{
244650397Sobrien		  if (! TREE_THIS_VOLATILE (name))
244750397Sobrien		    pedwarn ("`%s' was declared implicitly `extern' and later `static'",
244850397Sobrien			     IDENTIFIER_POINTER (name));
244950397Sobrien		}
245018334Speter	      else
245118334Speter		pedwarn ("`%s' was declared `extern' and later `static'",
245218334Speter			 IDENTIFIER_POINTER (name));
245318334Speter	    }
245418334Speter	}
245518334Speter      else
245618334Speter	{
245718334Speter	  /* Here to install a non-global value.  */
245818334Speter	  tree oldlocal = IDENTIFIER_LOCAL_VALUE (name);
245918334Speter	  tree oldglobal = IDENTIFIER_GLOBAL_VALUE (name);
246090075Sobrien
246118334Speter	  IDENTIFIER_LOCAL_VALUE (name) = x;
246218334Speter
246318334Speter	  /* If this is an extern function declaration, see if we
246418334Speter	     have a global definition or declaration for the function.  */
246518334Speter	  if (oldlocal == 0
246618334Speter	      && oldglobal != 0
246718334Speter	      && TREE_CODE (x) == FUNCTION_DECL
246890075Sobrien	      && TREE_CODE (oldglobal) == FUNCTION_DECL
246990075Sobrien	      && DECL_EXTERNAL (x)
247090075Sobrien	      && ! DECL_DECLARED_INLINE_P (x))
247118334Speter	    {
247218334Speter	      /* We have one.  Their types must agree.  */
247318334Speter	      if (! comptypes (TREE_TYPE (x),
247418334Speter			       TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (name))))
247518334Speter		pedwarn_with_decl (x, "extern declaration of `%s' doesn't match global one");
247618334Speter	      else
247718334Speter		{
247818334Speter		  /* Inner extern decl is inline if global one is.
247918334Speter		     Copy enough to really inline it.  */
248090075Sobrien		  if (DECL_DECLARED_INLINE_P (oldglobal))
248118334Speter		    {
248290075Sobrien		      DECL_DECLARED_INLINE_P (x)
248390075Sobrien		        = DECL_DECLARED_INLINE_P (oldglobal);
248418334Speter		      DECL_INLINE (x) = DECL_INLINE (oldglobal);
248518334Speter		      DECL_INITIAL (x) = (current_function_decl == oldglobal
248618334Speter					  ? 0 : DECL_INITIAL (oldglobal));
248718334Speter		      DECL_SAVED_INSNS (x) = DECL_SAVED_INSNS (oldglobal);
248890075Sobrien		      DECL_NUM_STMTS (x) = DECL_NUM_STMTS (oldglobal);
248918334Speter		      DECL_ARGUMENTS (x) = DECL_ARGUMENTS (oldglobal);
249018334Speter		      DECL_RESULT (x) = DECL_RESULT (oldglobal);
249118334Speter		      TREE_ASM_WRITTEN (x) = TREE_ASM_WRITTEN (oldglobal);
249290075Sobrien		      DECL_ABSTRACT_ORIGIN (x)
249390075Sobrien			= DECL_ABSTRACT_ORIGIN (oldglobal);
249418334Speter		    }
249518334Speter		  /* Inner extern decl is built-in if global one is.  */
249618334Speter		  if (DECL_BUILT_IN (oldglobal))
249718334Speter		    {
249890075Sobrien		      DECL_BUILT_IN_CLASS (x) = DECL_BUILT_IN_CLASS (oldglobal);
249918334Speter		      DECL_FUNCTION_CODE (x) = DECL_FUNCTION_CODE (oldglobal);
250018334Speter		    }
250118334Speter		  /* Keep the arg types from a file-scope fcn defn.  */
250218334Speter		  if (TYPE_ARG_TYPES (TREE_TYPE (oldglobal)) != 0
250318334Speter		      && DECL_INITIAL (oldglobal)
250418334Speter		      && TYPE_ARG_TYPES (TREE_TYPE (x)) == 0)
250518334Speter		    TREE_TYPE (x) = TREE_TYPE (oldglobal);
250618334Speter		}
250718334Speter	    }
250818334Speter
250990075Sobrien#if 0
251090075Sobrien	  /* This case is probably sometimes the right thing to do.  */
251118334Speter	  /* If we have a local external declaration,
251218334Speter	     then any file-scope declaration should not
251318334Speter	     have been static.  */
251418334Speter	  if (oldlocal == 0 && oldglobal != 0
251518334Speter	      && !TREE_PUBLIC (oldglobal)
251618334Speter	      && DECL_EXTERNAL (x) && TREE_PUBLIC (x))
251718334Speter	    warning ("`%s' locally external but globally static",
251818334Speter		     IDENTIFIER_POINTER (name));
251918334Speter#endif
252018334Speter
252118334Speter	  /* If we have a local external declaration,
252218334Speter	     and no file-scope declaration has yet been seen,
252318334Speter	     then if we later have a file-scope decl it must not be static.  */
252418334Speter	  if (oldlocal == 0
252518334Speter	      && DECL_EXTERNAL (x)
252618334Speter	      && TREE_PUBLIC (x))
252718334Speter	    {
252850397Sobrien	      if (oldglobal == 0)
252990075Sobrien		TREE_PUBLIC (name) = 1;
253018334Speter
253118334Speter	      /* Save this decl, so that we can do type checking against
253218334Speter		 other decls after it falls out of scope.
253318334Speter
253418334Speter		 Only save it once.  This prevents temporary decls created in
253518334Speter		 expand_inline_function from being used here, since this
253618334Speter		 will have been set when the inline function was parsed.
253718334Speter		 It also helps give slightly better warnings.  */
253818334Speter	      if (IDENTIFIER_LIMBO_VALUE (name) == 0)
253918334Speter		IDENTIFIER_LIMBO_VALUE (name) = x;
254018334Speter	    }
254118334Speter
254290075Sobrien	  warn_if_shadowing (x, oldlocal);
254318334Speter
254418334Speter	  /* If storing a local value, there may already be one (inherited).
254518334Speter	     If so, record it for restoration when this binding level ends.  */
254618334Speter	  if (oldlocal != 0)
254718334Speter	    b->shadowed = tree_cons (name, oldlocal, b->shadowed);
254818334Speter	}
254918334Speter
255090075Sobrien      /* Keep count of variables in this level with incomplete type.
255190075Sobrien	 If the input is erroneous, we can have error_mark in the type
255290075Sobrien	 slot (e.g. "f(void a, ...)") - that doesn't count as an
255390075Sobrien	 incomplete type.  */
255490075Sobrien      if (TREE_TYPE (x) != error_mark_node
255590075Sobrien	  && !COMPLETE_TYPE_P (TREE_TYPE (x)))
255690075Sobrien	{
255790075Sobrien	  tree element = TREE_TYPE (x);
255890075Sobrien
255990075Sobrien	  while (TREE_CODE (element) == ARRAY_TYPE)
256090075Sobrien	    element = TREE_TYPE (element);
256190075Sobrien	  if (TREE_CODE (element) == RECORD_TYPE
256290075Sobrien	      || TREE_CODE (element) == UNION_TYPE)
256390075Sobrien	    ++b->n_incomplete;
256490075Sobrien	}
256518334Speter    }
256618334Speter
256718334Speter  /* Put decls on list in reverse order.
256818334Speter     We will reverse them later if necessary.  */
256918334Speter  TREE_CHAIN (x) = b->names;
257018334Speter  b->names = x;
257118334Speter
257218334Speter  return x;
257318334Speter}
257418334Speter
257518334Speter/* Like pushdecl, only it places X in GLOBAL_BINDING_LEVEL, if appropriate.  */
257618334Speter
257718334Spetertree
257818334Speterpushdecl_top_level (x)
257918334Speter     tree x;
258018334Speter{
258190075Sobrien  tree t;
258290075Sobrien  struct binding_level *b = current_binding_level;
258318334Speter
258418334Speter  current_binding_level = global_binding_level;
258518334Speter  t = pushdecl (x);
258618334Speter  current_binding_level = b;
258718334Speter  return t;
258818334Speter}
258918334Speter
259018334Speter/* Generate an implicit declaration for identifier FUNCTIONID
259118334Speter   as a function of type int ().  Print a warning if appropriate.  */
259218334Speter
259318334Spetertree
259418334Speterimplicitly_declare (functionid)
259518334Speter     tree functionid;
259618334Speter{
259790075Sobrien  tree decl;
259818334Speter  int traditional_warning = 0;
259918334Speter  /* Only one "implicit declaration" warning per identifier.  */
260018334Speter  int implicit_warning;
260118334Speter
260218334Speter  /* We used to reuse an old implicit decl here,
260318334Speter     but this loses with inline functions because it can clobber
260418334Speter     the saved decl chains.  */
260590075Sobrien#if 0
260690075Sobrien  if (IDENTIFIER_IMPLICIT_DECL (functionid) != 0)
260718334Speter    decl = IDENTIFIER_IMPLICIT_DECL (functionid);
260890075Sobrien  else
260990075Sobrien#endif
261018334Speter    decl = build_decl (FUNCTION_DECL, functionid, default_function_type);
261118334Speter
261218334Speter  /* Warn of implicit decl following explicit local extern decl.
261318334Speter     This is probably a program designed for traditional C.  */
261418334Speter  if (TREE_PUBLIC (functionid) && IDENTIFIER_GLOBAL_VALUE (functionid) == 0)
261518334Speter    traditional_warning = 1;
261618334Speter
261718334Speter  /* Warn once of an implicit declaration.  */
261818334Speter  implicit_warning = (IDENTIFIER_IMPLICIT_DECL (functionid) == 0);
261918334Speter
262018334Speter  DECL_EXTERNAL (decl) = 1;
262118334Speter  TREE_PUBLIC (decl) = 1;
262218334Speter
262318334Speter  /* Record that we have an implicit decl and this is it.  */
262418334Speter  IDENTIFIER_IMPLICIT_DECL (functionid) = decl;
262518334Speter
262618334Speter  /* ANSI standard says implicit declarations are in the innermost block.
262718334Speter     So we record the decl in the standard fashion.
262818334Speter     If flag_traditional is set, pushdecl does it top-level.  */
262918334Speter  pushdecl (decl);
263018334Speter
263118334Speter  /* This is a no-op in c-lang.c or something real in objc-actions.c.  */
263218334Speter  maybe_objc_check_decl (decl);
263318334Speter
263490075Sobrien  rest_of_decl_compilation (decl, NULL, 0, 0);
263518334Speter
263690075Sobrien  if (implicit_warning)
263790075Sobrien    implicit_decl_warning (functionid);
263818334Speter  else if (warn_traditional && traditional_warning)
263918334Speter    warning ("function `%s' was previously declared within a block",
264018334Speter	     IDENTIFIER_POINTER (functionid));
264118334Speter
264218334Speter  /* Write a record describing this implicit function declaration to the
264318334Speter     prototypes file (if requested).  */
264418334Speter
264518334Speter  gen_aux_info_record (decl, 0, 1, 0);
264618334Speter
264790075Sobrien  /* Possibly apply some default attributes to this implicit declaration.  */
264890075Sobrien  decl_attributes (&decl, NULL_TREE, 0);
264918334Speter
265018334Speter  return decl;
265118334Speter}
265218334Speter
265390075Sobrienvoid
265490075Sobrienimplicit_decl_warning (id)
265590075Sobrien     tree id;
265690075Sobrien{
265790075Sobrien  const char *name = IDENTIFIER_POINTER (id);
265890075Sobrien  if (mesg_implicit_function_declaration == 2)
265990075Sobrien    error ("implicit declaration of function `%s'", name);
266090075Sobrien  else if (mesg_implicit_function_declaration == 1)
266190075Sobrien    warning ("implicit declaration of function `%s'", name);
266290075Sobrien}
266390075Sobrien
266418334Speter/* Return zero if the declaration NEWDECL is valid
266518334Speter   when the declaration OLDDECL (assumed to be for the same name)
266618334Speter   has already been seen.
266752284Sobrien   Otherwise return 1 if NEWDECL is a redefinition, 2 if it is a redeclaration,
266852284Sobrien   and 3 if it is a conflicting declaration.  */
266918334Speter
267052284Sobrienstatic int
267118334Speterredeclaration_error_message (newdecl, olddecl)
267218334Speter     tree newdecl, olddecl;
267318334Speter{
267418334Speter  if (TREE_CODE (newdecl) == TYPE_DECL)
267518334Speter    {
267618334Speter      if (flag_traditional && TREE_TYPE (newdecl) == TREE_TYPE (olddecl))
267718334Speter	return 0;
267818334Speter      /* pushdecl creates distinct types for TYPE_DECLs by calling
267918334Speter	 build_type_copy, so the above comparison generally fails.  We do
268018334Speter	 another test against the TYPE_MAIN_VARIANT of the olddecl, which
268118334Speter	 is equivalent to what this code used to do before the build_type_copy
268218334Speter	 call.  The variant type distinction should not matter for traditional
268318334Speter	 code, because it doesn't have type qualifiers.  */
268490075Sobrien      if (flag_traditional
268518334Speter	  && TYPE_MAIN_VARIANT (TREE_TYPE (olddecl)) == TREE_TYPE (newdecl))
268618334Speter	return 0;
268718334Speter      if (DECL_IN_SYSTEM_HEADER (olddecl) || DECL_IN_SYSTEM_HEADER (newdecl))
268818334Speter	return 0;
268952284Sobrien      return 1;
269018334Speter    }
269118334Speter  else if (TREE_CODE (newdecl) == FUNCTION_DECL)
269218334Speter    {
269318334Speter      /* Declarations of functions can insist on internal linkage
269418334Speter	 but they can't be inconsistent with internal linkage,
269518334Speter	 so there can be no error on that account.
269618334Speter	 However defining the same name twice is no good.  */
269718334Speter      if (DECL_INITIAL (olddecl) != 0 && DECL_INITIAL (newdecl) != 0
269818334Speter	  /* However, defining once as extern inline and a second
269918334Speter	     time in another way is ok.  */
270090075Sobrien	  && ! (DECL_DECLARED_INLINE_P (olddecl) && DECL_EXTERNAL (olddecl)
270190075Sobrien	       && ! (DECL_DECLARED_INLINE_P (newdecl)
270290075Sobrien		     && DECL_EXTERNAL (newdecl))))
270352284Sobrien	return 1;
270418334Speter      return 0;
270518334Speter    }
270690075Sobrien  else if (DECL_CONTEXT (newdecl) == NULL_TREE)
270718334Speter    {
270818334Speter      /* Objects declared at top level:  */
270918334Speter      /* If at least one is a reference, it's ok.  */
271018334Speter      if (DECL_EXTERNAL (newdecl) || DECL_EXTERNAL (olddecl))
271118334Speter	return 0;
271218334Speter      /* Reject two definitions.  */
271318334Speter      if (DECL_INITIAL (olddecl) != 0 && DECL_INITIAL (newdecl) != 0)
271452284Sobrien	return 1;
271518334Speter      /* Now we have two tentative defs, or one tentative and one real def.  */
271618334Speter      /* Insist that the linkage match.  */
271718334Speter      if (TREE_PUBLIC (olddecl) != TREE_PUBLIC (newdecl))
271852284Sobrien	return 3;
271918334Speter      return 0;
272018334Speter    }
272118334Speter  else if (current_binding_level->parm_flag
272218334Speter	   && TREE_ASM_WRITTEN (olddecl) && !TREE_ASM_WRITTEN (newdecl))
272318334Speter    return 0;
272418334Speter  else
272518334Speter    {
272618334Speter      /* Newdecl has block scope.  If olddecl has block scope also, then
272718334Speter	 reject two definitions, and reject a definition together with an
272818334Speter	 external reference.  Otherwise, it is OK, because newdecl must
272918334Speter	 be an extern reference to olddecl.  */
273018334Speter      if (!(DECL_EXTERNAL (newdecl) && DECL_EXTERNAL (olddecl))
273118334Speter	  && DECL_CONTEXT (newdecl) == DECL_CONTEXT (olddecl))
273252284Sobrien	return 2;
273318334Speter      return 0;
273418334Speter    }
273518334Speter}
273618334Speter
273718334Speter/* Get the LABEL_DECL corresponding to identifier ID as a label.
273818334Speter   Create one if none exists so far for the current function.
273918334Speter   This function is called for both label definitions and label references.  */
274018334Speter
274118334Spetertree
274218334Speterlookup_label (id)
274318334Speter     tree id;
274418334Speter{
274590075Sobrien  tree decl = IDENTIFIER_LABEL_VALUE (id);
274618334Speter
274718334Speter  if (current_function_decl == 0)
274818334Speter    {
274918334Speter      error ("label %s referenced outside of any function",
275018334Speter	     IDENTIFIER_POINTER (id));
275118334Speter      return 0;
275218334Speter    }
275318334Speter
275418334Speter  /* Use a label already defined or ref'd with this name.  */
275518334Speter  if (decl != 0)
275618334Speter    {
275718334Speter      /* But not if it is inherited and wasn't declared to be inheritable.  */
275818334Speter      if (DECL_CONTEXT (decl) != current_function_decl
275918334Speter	  && ! C_DECLARED_LABEL_FLAG (decl))
276018334Speter	return shadow_label (id);
276118334Speter      return decl;
276218334Speter    }
276318334Speter
276418334Speter  decl = build_decl (LABEL_DECL, id, void_type_node);
276518334Speter
276618334Speter  /* A label not explicitly declared must be local to where it's ref'd.  */
276718334Speter  DECL_CONTEXT (decl) = current_function_decl;
276818334Speter
276918334Speter  DECL_MODE (decl) = VOIDmode;
277018334Speter
277118334Speter  /* Say where one reference is to the label,
277218334Speter     for the sake of the error if it is not defined.  */
277318334Speter  DECL_SOURCE_LINE (decl) = lineno;
277418334Speter  DECL_SOURCE_FILE (decl) = input_filename;
277518334Speter
277618334Speter  IDENTIFIER_LABEL_VALUE (id) = decl;
277718334Speter
277818334Speter  named_labels = tree_cons (NULL_TREE, decl, named_labels);
277918334Speter
278018334Speter  return decl;
278118334Speter}
278218334Speter
278318334Speter/* Make a label named NAME in the current function,
278418334Speter   shadowing silently any that may be inherited from containing functions
278518334Speter   or containing scopes.
278618334Speter
278718334Speter   Note that valid use, if the label being shadowed
278818334Speter   comes from another scope in the same function,
278918334Speter   requires calling declare_nonlocal_label right away.  */
279018334Speter
279118334Spetertree
279218334Spetershadow_label (name)
279318334Speter     tree name;
279418334Speter{
279590075Sobrien  tree decl = IDENTIFIER_LABEL_VALUE (name);
279618334Speter
279718334Speter  if (decl != 0)
279818334Speter    {
279990075Sobrien      tree dup;
280018334Speter
280118334Speter      /* Check to make sure that the label hasn't already been declared
280218334Speter	 at this label scope */
280318334Speter      for (dup = named_labels; dup; dup = TREE_CHAIN (dup))
280418334Speter	if (TREE_VALUE (dup) == decl)
280518334Speter	  {
280690075Sobrien	    error ("duplicate label declaration `%s'",
280718334Speter		   IDENTIFIER_POINTER (name));
280818334Speter	    error_with_decl (TREE_VALUE (dup),
280918334Speter			     "this is a previous declaration");
281018334Speter	    /* Just use the previous declaration.  */
281118334Speter	    return lookup_label (name);
281218334Speter	  }
281318334Speter
281418334Speter      shadowed_labels = tree_cons (NULL_TREE, decl, shadowed_labels);
281518334Speter      IDENTIFIER_LABEL_VALUE (name) = decl = 0;
281618334Speter    }
281718334Speter
281818334Speter  return lookup_label (name);
281918334Speter}
282018334Speter
282118334Speter/* Define a label, specifying the location in the source file.
282218334Speter   Return the LABEL_DECL node for the label, if the definition is valid.
282318334Speter   Otherwise return 0.  */
282418334Speter
282518334Spetertree
282618334Speterdefine_label (filename, line, name)
282790075Sobrien     const char *filename;
282818334Speter     int line;
282918334Speter     tree name;
283018334Speter{
283118334Speter  tree decl = lookup_label (name);
283218334Speter
283318334Speter  /* If label with this name is known from an outer context, shadow it.  */
283418334Speter  if (decl != 0 && DECL_CONTEXT (decl) != current_function_decl)
283518334Speter    {
283618334Speter      shadowed_labels = tree_cons (NULL_TREE, decl, shadowed_labels);
283718334Speter      IDENTIFIER_LABEL_VALUE (name) = 0;
283818334Speter      decl = lookup_label (name);
283918334Speter    }
284018334Speter
284190075Sobrien  if (warn_traditional && !in_system_header && lookup_name (name))
284290075Sobrien    warning_with_file_and_line (filename, line,
284390075Sobrien				"traditional C lacks a separate namespace for labels, identifier `%s' conflicts",
284490075Sobrien				IDENTIFIER_POINTER (name));
284590075Sobrien
284618334Speter  if (DECL_INITIAL (decl) != 0)
284718334Speter    {
284890075Sobrien      error_with_file_and_line (filename, line, "duplicate label `%s'",
284990075Sobrien				IDENTIFIER_POINTER (name));
285018334Speter      return 0;
285118334Speter    }
285218334Speter  else
285318334Speter    {
285418334Speter      /* Mark label as having been defined.  */
285518334Speter      DECL_INITIAL (decl) = error_mark_node;
285618334Speter      /* Say where in the source.  */
285718334Speter      DECL_SOURCE_FILE (decl) = filename;
285818334Speter      DECL_SOURCE_LINE (decl) = line;
285918334Speter      return decl;
286018334Speter    }
286118334Speter}
286218334Speter
286318334Speter/* Return the list of declarations of the current level.
286418334Speter   Note that this list is in reverse order unless/until
286518334Speter   you nreverse it; and when you do nreverse it, you must
286618334Speter   store the result back using `storedecls' or you will lose.  */
286718334Speter
286818334Spetertree
286918334Spetergetdecls ()
287018334Speter{
287118334Speter  return current_binding_level->names;
287218334Speter}
287318334Speter
287418334Speter/* Return the list of type-tags (for structs, etc) of the current level.  */
287518334Speter
287618334Spetertree
287718334Spetergettags ()
287818334Speter{
287918334Speter  return current_binding_level->tags;
288018334Speter}
288118334Speter
288218334Speter/* Store the list of declarations of the current level.
288318334Speter   This is done for the parameter declarations of a function being defined,
288418334Speter   after they are modified in the light of any missing parameters.  */
288518334Speter
288618334Speterstatic void
288718334Speterstoredecls (decls)
288818334Speter     tree decls;
288918334Speter{
289018334Speter  current_binding_level->names = decls;
289118334Speter}
289218334Speter
289318334Speter/* Similarly, store the list of tags of the current level.  */
289418334Speter
289518334Speterstatic void
289618334Speterstoretags (tags)
289718334Speter     tree tags;
289818334Speter{
289918334Speter  current_binding_level->tags = tags;
290018334Speter}
290118334Speter
290218334Speter/* Given NAME, an IDENTIFIER_NODE,
290318334Speter   return the structure (or union or enum) definition for that name.
290418334Speter   Searches binding levels from BINDING_LEVEL up to the global level.
290518334Speter   If THISLEVEL_ONLY is nonzero, searches only the specified context
290618334Speter   (but skips any tag-transparent contexts to find one that is
290718334Speter   meaningful for tags).
290818334Speter   CODE says which kind of type the caller wants;
290918334Speter   it is RECORD_TYPE or UNION_TYPE or ENUMERAL_TYPE.
291018334Speter   If the wrong kind of type is found, an error is reported.  */
291118334Speter
291218334Speterstatic tree
291318334Speterlookup_tag (code, name, binding_level, thislevel_only)
291418334Speter     enum tree_code code;
291518334Speter     struct binding_level *binding_level;
291618334Speter     tree name;
291718334Speter     int thislevel_only;
291818334Speter{
291990075Sobrien  struct binding_level *level;
292090075Sobrien  int thislevel = 1;
292118334Speter
292218334Speter  for (level = binding_level; level; level = level->level_chain)
292318334Speter    {
292490075Sobrien      tree tail;
292518334Speter      for (tail = level->tags; tail; tail = TREE_CHAIN (tail))
292618334Speter	{
292718334Speter	  if (TREE_PURPOSE (tail) == name)
292818334Speter	    {
292918334Speter	      if (TREE_CODE (TREE_VALUE (tail)) != code)
293018334Speter		{
293118334Speter		  /* Definition isn't the kind we were looking for.  */
293218334Speter		  pending_invalid_xref = name;
293318334Speter		  pending_invalid_xref_file = input_filename;
293418334Speter		  pending_invalid_xref_line = lineno;
293590075Sobrien		  /* If in the same binding level as a declaration as a tag
293690075Sobrien		     of a different type, this must not be allowed to
293790075Sobrien		     shadow that tag, so give the error immediately.
293890075Sobrien		     (For example, "struct foo; union foo;" is invalid.)  */
293990075Sobrien		  if (thislevel)
294090075Sobrien		    pending_xref_error ();
294118334Speter		}
294218334Speter	      return TREE_VALUE (tail);
294318334Speter	    }
294418334Speter	}
294590075Sobrien      if (! level->tag_transparent)
294690075Sobrien	{
294790075Sobrien	  if (thislevel_only)
294890075Sobrien	    return NULL_TREE;
294990075Sobrien	  thislevel = 0;
295090075Sobrien	}
295118334Speter    }
295218334Speter  return NULL_TREE;
295318334Speter}
295418334Speter
295518334Speter/* Print an error message now
295618334Speter   for a recent invalid struct, union or enum cross reference.
295718334Speter   We don't print them immediately because they are not invalid
295818334Speter   when used in the `struct foo;' construct for shadowing.  */
295918334Speter
296018334Spetervoid
296118334Speterpending_xref_error ()
296218334Speter{
296318334Speter  if (pending_invalid_xref != 0)
296418334Speter    error_with_file_and_line (pending_invalid_xref_file,
296518334Speter			      pending_invalid_xref_line,
296618334Speter			      "`%s' defined as wrong kind of tag",
296718334Speter			      IDENTIFIER_POINTER (pending_invalid_xref));
296818334Speter  pending_invalid_xref = 0;
296918334Speter}
297018334Speter
297118334Speter/* Given a type, find the tag that was defined for it and return the tag name.
297218334Speter   Otherwise return 0.  */
297318334Speter
297418334Speterstatic tree
297518334Speterlookup_tag_reverse (type)
297618334Speter     tree type;
297718334Speter{
297890075Sobrien  struct binding_level *level;
297918334Speter
298018334Speter  for (level = current_binding_level; level; level = level->level_chain)
298118334Speter    {
298290075Sobrien      tree tail;
298318334Speter      for (tail = level->tags; tail; tail = TREE_CHAIN (tail))
298418334Speter	{
298518334Speter	  if (TREE_VALUE (tail) == type)
298618334Speter	    return TREE_PURPOSE (tail);
298718334Speter	}
298818334Speter    }
298918334Speter  return NULL_TREE;
299018334Speter}
299118334Speter
299218334Speter/* Look up NAME in the current binding level and its superiors
299318334Speter   in the namespace of variables, functions and typedefs.
299418334Speter   Return a ..._DECL node of some kind representing its definition,
299518334Speter   or return 0 if it is undefined.  */
299618334Speter
299718334Spetertree
299818334Speterlookup_name (name)
299918334Speter     tree name;
300018334Speter{
300190075Sobrien  tree val;
300290075Sobrien
300318334Speter  if (current_binding_level != global_binding_level
300418334Speter      && IDENTIFIER_LOCAL_VALUE (name))
300518334Speter    val = IDENTIFIER_LOCAL_VALUE (name);
300618334Speter  else
300718334Speter    val = IDENTIFIER_GLOBAL_VALUE (name);
300818334Speter  return val;
300918334Speter}
301018334Speter
301118334Speter/* Similar to `lookup_name' but look only at current binding level.  */
301218334Speter
301318334Spetertree
301418334Speterlookup_name_current_level (name)
301518334Speter     tree name;
301618334Speter{
301790075Sobrien  tree t;
301818334Speter
301918334Speter  if (current_binding_level == global_binding_level)
302018334Speter    return IDENTIFIER_GLOBAL_VALUE (name);
302118334Speter
302218334Speter  if (IDENTIFIER_LOCAL_VALUE (name) == 0)
302318334Speter    return 0;
302418334Speter
302518334Speter  for (t = current_binding_level->names; t; t = TREE_CHAIN (t))
302618334Speter    if (DECL_NAME (t) == name)
302718334Speter      break;
302818334Speter
302918334Speter  return t;
303018334Speter}
303118334Speter
303290075Sobrien/* Mark ARG for GC.  */
303390075Sobrien
303490075Sobrienstatic void
303590075Sobrienmark_binding_level (arg)
303690075Sobrien     void *arg;
303790075Sobrien{
303890075Sobrien  struct binding_level *level = *(struct binding_level **) arg;
303990075Sobrien
304090075Sobrien  for (; level != 0; level = level->level_chain)
304190075Sobrien    {
304290075Sobrien      ggc_mark_tree (level->names);
304390075Sobrien      ggc_mark_tree (level->tags);
304490075Sobrien      ggc_mark_tree (level->shadowed);
304590075Sobrien      ggc_mark_tree (level->blocks);
304690075Sobrien      ggc_mark_tree (level->this_block);
304790075Sobrien      ggc_mark_tree (level->parm_order);
304890075Sobrien    }
304990075Sobrien}
305090075Sobrien
305118334Speter/* Create the predefined scalar types of C,
305250397Sobrien   and some nodes representing standard constants (0, 1, (void *) 0).
305318334Speter   Initialize the global binding level.
305418334Speter   Make definitions for built-in primitive functions.  */
305518334Speter
305618334Spetervoid
305790075Sobrienc_init_decl_processing ()
305818334Speter{
305990075Sobrien  tree endlink;
306090075Sobrien  tree ptr_ftype_void, ptr_ftype_ptr;
306118334Speter
306290075Sobrien  /* Adds some ggc roots, and reserved words for c-parse.in.  */
306390075Sobrien  c_parse_init ();
306490075Sobrien
306518334Speter  current_function_decl = NULL;
306618334Speter  named_labels = NULL;
306718334Speter  current_binding_level = NULL_BINDING_LEVEL;
306818334Speter  free_binding_level = NULL_BINDING_LEVEL;
306990075Sobrien
307090075Sobrien  /* Make the binding_level structure for global names.  */
307190075Sobrien  pushlevel (0);
307218334Speter  global_binding_level = current_binding_level;
307318334Speter
307490075Sobrien  build_common_tree_nodes (flag_signed_char);
307518334Speter
307690075Sobrien  c_common_nodes_and_builtins ();
307718334Speter
307818334Speter  boolean_type_node = integer_type_node;
307918334Speter  boolean_true_node = integer_one_node;
308018334Speter  boolean_false_node = integer_zero_node;
308118334Speter
308296263Sobrien  c_bool_type_node = make_unsigned_type (BOOL_TYPE_SIZE);
308390075Sobrien  TREE_SET_CODE (c_bool_type_node, BOOLEAN_TYPE);
308490075Sobrien  TYPE_MAX_VALUE (c_bool_type_node) = build_int_2 (1, 0);
308590075Sobrien  TREE_TYPE (TYPE_MAX_VALUE (c_bool_type_node)) = c_bool_type_node;
308690075Sobrien  TYPE_PRECISION (c_bool_type_node) = 1;
308790075Sobrien  pushdecl (build_decl (TYPE_DECL, get_identifier ("_Bool"),
308890075Sobrien			c_bool_type_node));
308990075Sobrien  c_bool_false_node = build_int_2 (0, 0);
309090075Sobrien  TREE_TYPE (c_bool_false_node) = c_bool_type_node;
309190075Sobrien  c_bool_true_node = build_int_2 (1, 0);
309290075Sobrien  TREE_TYPE (c_bool_true_node) = c_bool_type_node;
309318334Speter
309490075Sobrien  endlink = void_list_node;
309550397Sobrien  ptr_ftype_void = build_function_type (ptr_type_node, endlink);
309650397Sobrien  ptr_ftype_ptr
309750397Sobrien    = build_function_type (ptr_type_node,
309850397Sobrien			   tree_cons (NULL_TREE, ptr_type_node, endlink));
309950397Sobrien
310090075Sobrien  /* Types which are common to the fortran compiler and libf2c.  When
310190075Sobrien     changing these, you also need to be concerned with f/com.h.  */
310218334Speter
310390075Sobrien  if (TYPE_PRECISION (float_type_node)
310490075Sobrien      == TYPE_PRECISION (long_integer_type_node))
310590075Sobrien    {
310690075Sobrien      g77_integer_type_node = long_integer_type_node;
310790075Sobrien      g77_uinteger_type_node = long_unsigned_type_node;
310890075Sobrien    }
310990075Sobrien  else if (TYPE_PRECISION (float_type_node)
311090075Sobrien	   == TYPE_PRECISION (integer_type_node))
311190075Sobrien    {
311290075Sobrien      g77_integer_type_node = integer_type_node;
311390075Sobrien      g77_uinteger_type_node = unsigned_type_node;
311490075Sobrien    }
311590075Sobrien  else
311690075Sobrien    g77_integer_type_node = g77_uinteger_type_node = NULL_TREE;
311718334Speter
311890075Sobrien  if (g77_integer_type_node != NULL_TREE)
311990075Sobrien    {
312090075Sobrien      pushdecl (build_decl (TYPE_DECL, get_identifier ("__g77_integer"),
312190075Sobrien			    g77_integer_type_node));
312290075Sobrien      pushdecl (build_decl (TYPE_DECL, get_identifier ("__g77_uinteger"),
312390075Sobrien			    g77_uinteger_type_node));
312490075Sobrien    }
312518334Speter
312690075Sobrien  if (TYPE_PRECISION (float_type_node) * 2
312790075Sobrien      == TYPE_PRECISION (long_integer_type_node))
312890075Sobrien    {
312990075Sobrien      g77_longint_type_node = long_integer_type_node;
313090075Sobrien      g77_ulongint_type_node = long_unsigned_type_node;
313190075Sobrien    }
313290075Sobrien  else if (TYPE_PRECISION (float_type_node) * 2
313390075Sobrien	   == TYPE_PRECISION (long_long_integer_type_node))
313490075Sobrien    {
313590075Sobrien      g77_longint_type_node = long_long_integer_type_node;
313690075Sobrien      g77_ulongint_type_node = long_long_unsigned_type_node;
313790075Sobrien    }
313890075Sobrien  else
313990075Sobrien    g77_longint_type_node = g77_ulongint_type_node = NULL_TREE;
314050397Sobrien
314190075Sobrien  if (g77_longint_type_node != NULL_TREE)
314218334Speter    {
314390075Sobrien      pushdecl (build_decl (TYPE_DECL, get_identifier ("__g77_longint"),
314490075Sobrien			    g77_longint_type_node));
314590075Sobrien      pushdecl (build_decl (TYPE_DECL, get_identifier ("__g77_ulongint"),
314690075Sobrien			    g77_ulongint_type_node));
314718334Speter    }
314818334Speter
314990075Sobrien  pedantic_lvalues = pedantic;
315018334Speter
315190075Sobrien  make_fname_decl = c_make_fname_decl;
315290075Sobrien  start_fname_decls ();
315318334Speter
315490075Sobrien  incomplete_decl_finalize_hook = finish_incomplete_decl;
315518334Speter
315690075Sobrien  /* Record our roots.  */
315718334Speter
315890075Sobrien  ggc_add_tree_root (c_global_trees, CTI_MAX);
315990075Sobrien  ggc_add_root (&c_stmt_tree, 1, sizeof c_stmt_tree, mark_stmt_tree);
316090075Sobrien  ggc_add_tree_root (&c_scope_stmt_stack, 1);
316190075Sobrien  ggc_add_tree_root (&named_labels, 1);
316290075Sobrien  ggc_add_tree_root (&shadowed_labels, 1);
316390075Sobrien  ggc_add_root (&current_binding_level, 1, sizeof current_binding_level,
316490075Sobrien		mark_binding_level);
316590075Sobrien  ggc_add_root (&label_level_chain, 1, sizeof label_level_chain,
316690075Sobrien		mark_binding_level);
316790075Sobrien  ggc_add_tree_root (&static_ctors, 1);
316890075Sobrien  ggc_add_tree_root (&static_dtors, 1);
316990075Sobrien}
317018334Speter
317190075Sobrien/* Create the VAR_DECL for __FUNCTION__ etc. ID is the name to give the
317290075Sobrien   decl, NAME is the initialization string and TYPE_DEP indicates whether
317390075Sobrien   NAME depended on the type of the function.  As we don't yet implement
317490075Sobrien   delayed emission of static data, we mark the decl as emitted
317590075Sobrien   so it is not placed in the output.  Anything using it must therefore pull
317690075Sobrien   out the STRING_CST initializer directly.  This does mean that these names
317790075Sobrien   are string merging candidates, which is wrong for C99's __func__.  FIXME.  */
317818334Speter
317990075Sobrienstatic tree
318090075Sobrienc_make_fname_decl (id, type_dep)
318190075Sobrien     tree id;
318290075Sobrien     int type_dep;
318390075Sobrien{
318490075Sobrien  const char *name = fname_as_string (type_dep);
318590075Sobrien  tree decl, type, init;
318690075Sobrien  size_t length = strlen (name);
318718334Speter
318890075Sobrien  type =  build_array_type
318990075Sobrien          (build_qualified_type (char_type_node, TYPE_QUAL_CONST),
319090075Sobrien	   build_index_type (size_int (length)));
319118334Speter
319290075Sobrien  decl = build_decl (VAR_DECL, id, type);
319390075Sobrien  /* We don't push the decl, so have to set its context here.  */
319490075Sobrien  DECL_CONTEXT (decl) = current_function_decl;
319590075Sobrien
319690075Sobrien  TREE_STATIC (decl) = 1;
319790075Sobrien  TREE_READONLY (decl) = 1;
319890075Sobrien  DECL_ARTIFICIAL (decl) = 1;
319990075Sobrien
320090075Sobrien  init = build_string (length + 1, name);
320190075Sobrien  TREE_TYPE (init) = type;
320290075Sobrien  DECL_INITIAL (decl) = init;
320318334Speter
320490075Sobrien  TREE_USED (decl) = 1;
320590075Sobrien
320690075Sobrien  finish_decl (decl, init, NULL_TREE);
320718334Speter
320890075Sobrien  return decl;
320918334Speter}
321018334Speter
321118334Speter/* Return a definition for a builtin function named NAME and whose data type
321218334Speter   is TYPE.  TYPE should be a function type with argument types.
321318334Speter   FUNCTION_CODE tells later passes how to compile calls to this function.
321418334Speter   See tree.h for its possible values.
321518334Speter
321618334Speter   If LIBRARY_NAME is nonzero, use that for DECL_ASSEMBLER_NAME,
321718334Speter   the name to be called if we can't opencode the function.  */
321818334Speter
321918334Spetertree
322090075Sobrienbuiltin_function (name, type, function_code, class, library_name)
322152284Sobrien     const char *name;
322218334Speter     tree type;
322390075Sobrien     int function_code;
322490075Sobrien     enum built_in_class class;
322552284Sobrien     const char *library_name;
322618334Speter{
322718334Speter  tree decl = build_decl (FUNCTION_DECL, get_identifier (name), type);
322818334Speter  DECL_EXTERNAL (decl) = 1;
322918334Speter  TREE_PUBLIC (decl) = 1;
323018334Speter  /* If -traditional, permit redefining a builtin function any way you like.
323118334Speter     (Though really, if the program redefines these functions,
323218334Speter     it probably won't work right unless compiled with -fno-builtin.)  */
323318334Speter  if (flag_traditional && name[0] != '_')
323418334Speter    DECL_BUILT_IN_NONANSI (decl) = 1;
323518334Speter  if (library_name)
323690075Sobrien    SET_DECL_ASSEMBLER_NAME (decl, get_identifier (library_name));
323790075Sobrien  make_decl_rtl (decl, NULL);
323818334Speter  pushdecl (decl);
323990075Sobrien  DECL_BUILT_IN_CLASS (decl) = class;
324090075Sobrien  DECL_FUNCTION_CODE (decl) = function_code;
324190075Sobrien
324296263Sobrien  /* The return builtins leave the current function.  */
324396263Sobrien  if (function_code == BUILT_IN_RETURN || function_code == BUILT_IN_EH_RETURN)
324496263Sobrien    TREE_THIS_VOLATILE (decl) = 1;
324596263Sobrien
324618334Speter  /* Warn if a function in the namespace for users
324718334Speter     is used without an occasion to consider it declared.  */
324818334Speter  if (name[0] != '_' || name[1] != '_')
324918334Speter    C_DECL_ANTICIPATED (decl) = 1;
325018334Speter
325190075Sobrien  /* Possibly apply some default attributes to this built-in function.  */
325290075Sobrien  decl_attributes (&decl, NULL_TREE, 0);
325390075Sobrien
325418334Speter  return decl;
325518334Speter}
325690075Sobrien
325790075Sobrien/* Apply default attributes to a function, if a system function with default
325890075Sobrien   attributes.  */
325990075Sobrien
326090075Sobrienvoid
326190075Sobrieninsert_default_attributes (decl)
326290075Sobrien     tree decl;
326390075Sobrien{
326490075Sobrien  if (!TREE_PUBLIC (decl))
326590075Sobrien    return;
326690075Sobrien  c_common_insert_default_attributes (decl);
326790075Sobrien}
326818334Speter
326918334Speter/* Called when a declaration is seen that contains no names to declare.
327018334Speter   If its type is a reference to a structure, union or enum inherited
327118334Speter   from a containing scope, shadow that tag name for the current scope
327218334Speter   with a forward reference.
327318334Speter   If its type defines a new named structure or union
327418334Speter   or defines an enum, it is valid but we need not do anything here.
327518334Speter   Otherwise, it is an error.  */
327618334Speter
327718334Spetervoid
327818334Spetershadow_tag (declspecs)
327918334Speter     tree declspecs;
328018334Speter{
328118334Speter  shadow_tag_warned (declspecs, 0);
328218334Speter}
328318334Speter
328418334Spetervoid
328518334Spetershadow_tag_warned (declspecs, warned)
328618334Speter     tree declspecs;
328718334Speter     int warned;
328818334Speter     /* 1 => we have done a pedwarn.  2 => we have done a warning, but
328918334Speter	no pedwarn.  */
329018334Speter{
329118334Speter  int found_tag = 0;
329290075Sobrien  tree link;
329350397Sobrien  tree specs, attrs;
329418334Speter
329518334Speter  pending_invalid_xref = 0;
329618334Speter
329750397Sobrien  /* Remove the attributes from declspecs, since they will confuse the
329850397Sobrien     following code.  */
329950397Sobrien  split_specs_attrs (declspecs, &specs, &attrs);
330050397Sobrien
330150397Sobrien  for (link = specs; link; link = TREE_CHAIN (link))
330218334Speter    {
330390075Sobrien      tree value = TREE_VALUE (link);
330490075Sobrien      enum tree_code code = TREE_CODE (value);
330518334Speter
330618334Speter      if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
330718334Speter	/* Used to test also that TYPE_SIZE (value) != 0.
330818334Speter	   That caused warning for `struct foo;' at top level in the file.  */
330918334Speter	{
331090075Sobrien	  tree name = lookup_tag_reverse (value);
331190075Sobrien	  tree t;
331218334Speter
331318334Speter	  found_tag++;
331418334Speter
331518334Speter	  if (name == 0)
331618334Speter	    {
331718334Speter	      if (warned != 1 && code != ENUMERAL_TYPE)
331818334Speter		/* Empty unnamed enum OK */
331918334Speter		{
332018334Speter		  pedwarn ("unnamed struct/union that defines no instances");
332118334Speter		  warned = 1;
332218334Speter		}
332318334Speter	    }
332418334Speter	  else
332518334Speter	    {
332618334Speter	      t = lookup_tag (code, name, current_binding_level, 1);
332718334Speter
332818334Speter	      if (t == 0)
332918334Speter		{
333018334Speter		  t = make_node (code);
333118334Speter		  pushtag (name, t);
333218334Speter		}
333318334Speter	    }
333418334Speter	}
333518334Speter      else
333618334Speter	{
333718334Speter	  if (!warned && ! in_system_header)
333818334Speter	    {
333918334Speter	      warning ("useless keyword or type name in empty declaration");
334018334Speter	      warned = 2;
334118334Speter	    }
334218334Speter	}
334318334Speter    }
334418334Speter
334518334Speter  if (found_tag > 1)
334618334Speter    error ("two types specified in one empty declaration");
334718334Speter
334818334Speter  if (warned != 1)
334918334Speter    {
335018334Speter      if (found_tag == 0)
335118334Speter	pedwarn ("empty declaration");
335218334Speter    }
335318334Speter}
335418334Speter
335590075Sobrien/* Construct an array declarator.  EXPR is the expression inside [], or
335690075Sobrien   NULL_TREE.  QUALS are the type qualifiers inside the [] (to be applied
335790075Sobrien   to the pointer to which a parameter array is converted).  STATIC_P is
335890075Sobrien   non-zero if "static" is inside the [], zero otherwise.  VLA_UNSPEC_P
335990075Sobrien   is non-zero is the array is [*], a VLA of unspecified length which is
336090075Sobrien   nevertheless a complete type (not currently implemented by GCC),
336190075Sobrien   zero otherwise.  The declarator is constructed as an ARRAY_REF
336290075Sobrien   (to be decoded by grokdeclarator), whose operand 0 is what's on the
336390075Sobrien   left of the [] (filled by in set_array_declarator_type) and operand 1
336490075Sobrien   is the expression inside; whose TREE_TYPE is the type qualifiers and
336590075Sobrien   which has TREE_STATIC set if "static" is used.  */
336690075Sobrien
336790075Sobrientree
336890075Sobrienbuild_array_declarator (expr, quals, static_p, vla_unspec_p)
336990075Sobrien     tree expr;
337090075Sobrien     tree quals;
337190075Sobrien     int static_p;
337290075Sobrien     int vla_unspec_p;
337390075Sobrien{
337490075Sobrien  tree decl;
337590075Sobrien  decl = build_nt (ARRAY_REF, NULL_TREE, expr);
337690075Sobrien  TREE_TYPE (decl) = quals;
337790075Sobrien  TREE_STATIC (decl) = (static_p ? 1 : 0);
337890075Sobrien  if (pedantic && !flag_isoc99)
337990075Sobrien    {
338090075Sobrien      if (static_p || quals != NULL_TREE)
338190075Sobrien	pedwarn ("ISO C89 does not support `static' or type qualifiers in parameter array declarators");
338290075Sobrien      if (vla_unspec_p)
338390075Sobrien	pedwarn ("ISO C89 does not support `[*]' array declarators");
338490075Sobrien    }
338590075Sobrien  if (vla_unspec_p)
338690075Sobrien    warning ("GCC does not yet properly implement `[*]' array declarators");
338790075Sobrien  return decl;
338890075Sobrien}
338990075Sobrien
339090075Sobrien/* Set the type of an array declarator.  DECL is the declarator, as
339190075Sobrien   constructed by build_array_declarator; TYPE is what appears on the left
339290075Sobrien   of the [] and goes in operand 0.  ABSTRACT_P is non-zero if it is an
339390075Sobrien   abstract declarator, zero otherwise; this is used to reject static and
339490075Sobrien   type qualifiers in abstract declarators, where they are not in the
339590075Sobrien   C99 grammar.  */
339690075Sobrien
339790075Sobrientree
339890075Sobrienset_array_declarator_type (decl, type, abstract_p)
339990075Sobrien     tree decl;
340090075Sobrien     tree type;
340190075Sobrien     int abstract_p;
340290075Sobrien{
340390075Sobrien  TREE_OPERAND (decl, 0) = type;
340490075Sobrien  if (abstract_p && (TREE_TYPE (decl) != NULL_TREE || TREE_STATIC (decl)))
340590075Sobrien    error ("static or type qualifiers in abstract declarator");
340690075Sobrien  return decl;
340790075Sobrien}
340890075Sobrien
340918334Speter/* Decode a "typename", such as "int **", returning a ..._TYPE node.  */
341018334Speter
341118334Spetertree
341218334Spetergroktypename (typename)
341318334Speter     tree typename;
341418334Speter{
341590075Sobrien  tree specs, attrs;
341690075Sobrien
341718334Speter  if (TREE_CODE (typename) != TREE_LIST)
341818334Speter    return typename;
341990075Sobrien
342090075Sobrien  split_specs_attrs (TREE_PURPOSE (typename), &specs, &attrs);
342190075Sobrien
342296263Sobrien  typename = grokdeclarator (TREE_VALUE (typename), specs, TYPENAME, 0);
342390075Sobrien
342490075Sobrien  /* Apply attributes.  */
342590075Sobrien  decl_attributes (&typename, attrs, 0);
342690075Sobrien
342790075Sobrien  return typename;
342818334Speter}
342918334Speter
343018334Speter/* Return a PARM_DECL node for a given pair of specs and declarator.  */
343118334Speter
343218334Spetertree
343318334Spetergroktypename_in_parm_context (typename)
343418334Speter     tree typename;
343518334Speter{
343618334Speter  if (TREE_CODE (typename) != TREE_LIST)
343718334Speter    return typename;
343818334Speter  return grokdeclarator (TREE_VALUE (typename),
343918334Speter			 TREE_PURPOSE (typename),
344096263Sobrien			 PARM, 0);
344118334Speter}
344218334Speter
344318334Speter/* Decode a declarator in an ordinary declaration or data definition.
344418334Speter   This is called as soon as the type information and variable name
344518334Speter   have been parsed, before parsing the initializer if any.
344618334Speter   Here we create the ..._DECL node, fill in its type,
344718334Speter   and put it on the list of decls for the current context.
344818334Speter   The ..._DECL node is returned as the value.
344918334Speter
345018334Speter   Exception: for arrays where the length is not specified,
345118334Speter   the type is left null, to be filled in by `finish_decl'.
345218334Speter
345318334Speter   Function definitions do not come here; they go to start_function
345418334Speter   instead.  However, external and forward declarations of functions
345518334Speter   do go through here.  Structure field declarations are done by
345618334Speter   grokfield and not through here.  */
345718334Speter
345818334Spetertree
345990075Sobrienstart_decl (declarator, declspecs, initialized, attributes)
346018334Speter     tree declarator, declspecs;
346118334Speter     int initialized;
346290075Sobrien     tree attributes;
346318334Speter{
346490075Sobrien  tree decl;
346590075Sobrien  tree tem;
346690075Sobrien
346790075Sobrien  /* An object declared as __attribute__((deprecated)) suppresses
346890075Sobrien     warnings of uses of other deprecated items.  */
346990075Sobrien  if (lookup_attribute ("deprecated", attributes))
347090075Sobrien    deprecated_state = DEPRECATED_SUPPRESS;
347118334Speter
347290075Sobrien  decl = grokdeclarator (declarator, declspecs,
347396263Sobrien			 NORMAL, initialized);
347490075Sobrien
347590075Sobrien  deprecated_state = DEPRECATED_NORMAL;
347618334Speter
347790075Sobrien  if (warn_main > 0 && TREE_CODE (decl) != FUNCTION_DECL
347890075Sobrien      && MAIN_NAME_P (DECL_NAME (decl)))
347950397Sobrien    warning_with_decl (decl, "`%s' is usually a function");
348050397Sobrien
348118334Speter  if (initialized)
348218334Speter    /* Is it valid for this decl to have an initializer at all?
348318334Speter       If not, set INITIALIZED to zero, which will indirectly
348418334Speter       tell `finish_decl' to ignore the initializer once it is parsed.  */
348518334Speter    switch (TREE_CODE (decl))
348618334Speter      {
348718334Speter      case TYPE_DECL:
348818334Speter	/* typedef foo = bar  means give foo the same type as bar.
348918334Speter	   We haven't parsed bar yet, so `finish_decl' will fix that up.
349018334Speter	   Any other case of an initialization in a TYPE_DECL is an error.  */
349118334Speter	if (pedantic || list_length (declspecs) > 1)
349218334Speter	  {
349318334Speter	    error ("typedef `%s' is initialized",
349418334Speter		   IDENTIFIER_POINTER (DECL_NAME (decl)));
349518334Speter	    initialized = 0;
349618334Speter	  }
349718334Speter	break;
349818334Speter
349918334Speter      case FUNCTION_DECL:
350018334Speter	error ("function `%s' is initialized like a variable",
350118334Speter	       IDENTIFIER_POINTER (DECL_NAME (decl)));
350218334Speter	initialized = 0;
350318334Speter	break;
350418334Speter
350518334Speter      case PARM_DECL:
350618334Speter	/* DECL_INITIAL in a PARM_DECL is really DECL_ARG_TYPE.  */
350718334Speter	error ("parameter `%s' is initialized",
350818334Speter	       IDENTIFIER_POINTER (DECL_NAME (decl)));
350918334Speter	initialized = 0;
351018334Speter	break;
351118334Speter
351218334Speter      default:
351318334Speter	/* Don't allow initializations for incomplete types
351418334Speter	   except for arrays which might be completed by the initialization.  */
351590075Sobrien
351690075Sobrien	/* This can happen if the array size is an undefined macro.  We already
351790075Sobrien	   gave a warning, so we don't need another one.  */
351890075Sobrien	if (TREE_TYPE (decl) == error_mark_node)
351990075Sobrien	  initialized = 0;
352090075Sobrien	else if (COMPLETE_TYPE_P (TREE_TYPE (decl)))
352118334Speter	  {
352218334Speter	    /* A complete type is ok if size is fixed.  */
352318334Speter
352418334Speter	    if (TREE_CODE (TYPE_SIZE (TREE_TYPE (decl))) != INTEGER_CST
352518334Speter		|| C_DECL_VARIABLE_SIZE (decl))
352618334Speter	      {
352718334Speter		error ("variable-sized object may not be initialized");
352818334Speter		initialized = 0;
352918334Speter	      }
353018334Speter	  }
353118334Speter	else if (TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE)
353218334Speter	  {
353318334Speter	    error ("variable `%s' has initializer but incomplete type",
353418334Speter		   IDENTIFIER_POINTER (DECL_NAME (decl)));
353518334Speter	    initialized = 0;
353618334Speter	  }
353790075Sobrien	else if (!COMPLETE_TYPE_P (TREE_TYPE (TREE_TYPE (decl))))
353818334Speter	  {
353918334Speter	    error ("elements of array `%s' have incomplete type",
354018334Speter		   IDENTIFIER_POINTER (DECL_NAME (decl)));
354118334Speter	    initialized = 0;
354218334Speter	  }
354318334Speter      }
354418334Speter
354518334Speter  if (initialized)
354618334Speter    {
354790075Sobrien#if 0
354890075Sobrien      /* Seems redundant with grokdeclarator.  */
354918334Speter      if (current_binding_level != global_binding_level
355018334Speter	  && DECL_EXTERNAL (decl)
355118334Speter	  && TREE_CODE (decl) != FUNCTION_DECL)
355218334Speter	warning ("declaration of `%s' has `extern' and is initialized",
355318334Speter		 IDENTIFIER_POINTER (DECL_NAME (decl)));
355418334Speter#endif
355518334Speter      DECL_EXTERNAL (decl) = 0;
355618334Speter      if (current_binding_level == global_binding_level)
355718334Speter	TREE_STATIC (decl) = 1;
355818334Speter
355918334Speter      /* Tell `pushdecl' this is an initialized decl
356018334Speter	 even though we don't yet have the initializer expression.
356118334Speter	 Also tell `finish_decl' it may store the real initializer.  */
356218334Speter      DECL_INITIAL (decl) = error_mark_node;
356318334Speter    }
356418334Speter
356518334Speter  /* If this is a function declaration, write a record describing it to the
356618334Speter     prototypes file (if requested).  */
356718334Speter
356818334Speter  if (TREE_CODE (decl) == FUNCTION_DECL)
356918334Speter    gen_aux_info_record (decl, 0, 0, TYPE_ARG_TYPES (TREE_TYPE (decl)) != 0);
357018334Speter
357150397Sobrien  /* ANSI specifies that a tentative definition which is not merged with
357250397Sobrien     a non-tentative definition behaves exactly like a definition with an
357350397Sobrien     initializer equal to zero.  (Section 3.7.2)
357450397Sobrien     -fno-common gives strict ANSI behavior.  Usually you don't want it.
357550397Sobrien     This matters only for variables with external linkage.  */
357650397Sobrien  if (! flag_no_common || ! TREE_PUBLIC (decl))
357750397Sobrien    DECL_COMMON (decl) = 1;
357818334Speter
357918334Speter  /* Set attributes here so if duplicate decl, will have proper attributes.  */
358090075Sobrien  decl_attributes (&decl, attributes, 0);
358118334Speter
358296263Sobrien  /* If #pragma weak was used, mark the decl weak now.  */
358396263Sobrien  if (current_binding_level == global_binding_level)
358496263Sobrien    maybe_apply_pragma_weak (decl);
358596263Sobrien
358690075Sobrien  if (TREE_CODE (decl) == FUNCTION_DECL
358790075Sobrien      && DECL_DECLARED_INLINE_P (decl)
358890075Sobrien      && DECL_UNINLINABLE (decl)
358990075Sobrien      && lookup_attribute ("noinline", DECL_ATTRIBUTES (decl)))
359090075Sobrien    warning_with_decl (decl,
359190075Sobrien		       "inline function `%s' given attribute noinline");
359290075Sobrien
359318334Speter  /* Add this decl to the current binding level.
359418334Speter     TEM may equal DECL or it may be a previous decl of the same name.  */
359518334Speter  tem = pushdecl (decl);
359618334Speter
359718334Speter  /* For a local variable, define the RTL now.  */
359818334Speter  if (current_binding_level != global_binding_level
359918334Speter      /* But not if this is a duplicate decl
360018334Speter	 and we preserved the rtl from the previous one
360118334Speter	 (which may or may not happen).  */
360290075Sobrien      && !DECL_RTL_SET_P (tem)
360390075Sobrien      && !DECL_CONTEXT (tem))
360418334Speter    {
360590075Sobrien      if (TREE_TYPE (tem) != error_mark_node
360690075Sobrien	  && COMPLETE_TYPE_P (TREE_TYPE (tem)))
360718334Speter	expand_decl (tem);
360818334Speter      else if (TREE_CODE (TREE_TYPE (tem)) == ARRAY_TYPE
360918334Speter	       && DECL_INITIAL (tem) != 0)
361018334Speter	expand_decl (tem);
361118334Speter    }
361218334Speter
361318334Speter  return tem;
361418334Speter}
361518334Speter
361618334Speter/* Finish processing of a declaration;
361718334Speter   install its initial value.
361818334Speter   If the length of an array type is not known before,
361918334Speter   it must be determined now, from the initial value, or it is an error.  */
362018334Speter
362118334Spetervoid
362218334Speterfinish_decl (decl, init, asmspec_tree)
362318334Speter     tree decl, init;
362418334Speter     tree asmspec_tree;
362518334Speter{
362690075Sobrien  tree type = TREE_TYPE (decl);
362718334Speter  int was_incomplete = (DECL_SIZE (decl) == 0);
362890075Sobrien  const char *asmspec = 0;
362918334Speter
363090075Sobrien  /* If a name was specified, get the string.  */
363196263Sobrien  if (current_binding_level == global_binding_level)
363296263Sobrien    asmspec_tree = maybe_apply_renaming_pragma (decl, asmspec_tree);
363318334Speter  if (asmspec_tree)
363418334Speter    asmspec = TREE_STRING_POINTER (asmspec_tree);
363518334Speter
363618334Speter  /* If `start_decl' didn't like having an initialization, ignore it now.  */
363718334Speter  if (init != 0 && DECL_INITIAL (decl) == 0)
363818334Speter    init = 0;
363990075Sobrien
364018334Speter  /* Don't crash if parm is initialized.  */
364118334Speter  if (TREE_CODE (decl) == PARM_DECL)
364218334Speter    init = 0;
364318334Speter
364418334Speter  if (init)
364518334Speter    {
364618334Speter      if (TREE_CODE (decl) != TYPE_DECL)
364718334Speter	store_init_value (decl, init);
364818334Speter      else
364918334Speter	{
365018334Speter	  /* typedef foo = bar; store the type of bar as the type of foo.  */
365118334Speter	  TREE_TYPE (decl) = TREE_TYPE (init);
365218334Speter	  DECL_INITIAL (decl) = init = 0;
365318334Speter	}
365418334Speter    }
365518334Speter
365618334Speter  /* Deduce size of array from initialization, if not already known */
365718334Speter  if (TREE_CODE (type) == ARRAY_TYPE
365818334Speter      && TYPE_DOMAIN (type) == 0
365918334Speter      && TREE_CODE (decl) != TYPE_DECL)
366018334Speter    {
366118334Speter      int do_default
366218334Speter	= (TREE_STATIC (decl)
366318334Speter	   /* Even if pedantic, an external linkage array
366418334Speter	      may have incomplete type at first.  */
366518334Speter	   ? pedantic && !TREE_PUBLIC (decl)
366618334Speter	   : !DECL_EXTERNAL (decl));
366718334Speter      int failure
366818334Speter	= complete_array_type (type, DECL_INITIAL (decl), do_default);
366918334Speter
367018334Speter      /* Get the completed type made by complete_array_type.  */
367118334Speter      type = TREE_TYPE (decl);
367218334Speter
367318334Speter      if (failure == 1)
367418334Speter	error_with_decl (decl, "initializer fails to determine size of `%s'");
367518334Speter
367690075Sobrien      else if (failure == 2)
367718334Speter	{
367818334Speter	  if (do_default)
367918334Speter	    error_with_decl (decl, "array size missing in `%s'");
368018334Speter	  /* If a `static' var's size isn't known,
368118334Speter	     make it extern as well as static, so it does not get
368218334Speter	     allocated.
368318334Speter	     If it is not `static', then do not mark extern;
368418334Speter	     finish_incomplete_decl will give it a default size
368518334Speter	     and it will get allocated.  */
368618334Speter	  else if (!pedantic && TREE_STATIC (decl) && ! TREE_PUBLIC (decl))
368718334Speter	    DECL_EXTERNAL (decl) = 1;
368818334Speter	}
368918334Speter
369018334Speter      /* TYPE_MAX_VALUE is always one less than the number of elements
369118334Speter	 in the array, because we start counting at zero.  Therefore,
369218334Speter	 warn only if the value is less than zero.  */
369390075Sobrien      else if (pedantic && TYPE_DOMAIN (type) != 0
369490075Sobrien	      && tree_int_cst_sgn (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) < 0)
369518334Speter	error_with_decl (decl, "zero or negative size array `%s'");
369618334Speter
369718334Speter      layout_decl (decl, 0);
369818334Speter    }
369918334Speter
370018334Speter  if (TREE_CODE (decl) == VAR_DECL)
370118334Speter    {
370290075Sobrien      if (DECL_SIZE (decl) == 0 && TREE_TYPE (decl) != error_mark_node
370390075Sobrien	  && COMPLETE_TYPE_P (TREE_TYPE (decl)))
370418334Speter	layout_decl (decl, 0);
370518334Speter
370618334Speter      if (DECL_SIZE (decl) == 0
370790075Sobrien	  /* Don't give an error if we already gave one earlier.  */
370890075Sobrien	  && TREE_TYPE (decl) != error_mark_node
370918334Speter	  && (TREE_STATIC (decl)
371018334Speter	      ?
371118334Speter		/* A static variable with an incomplete type
371218334Speter		   is an error if it is initialized.
371318334Speter		   Also if it is not file scope.
371418334Speter		   Otherwise, let it through, but if it is not `extern'
371518334Speter		   then it may cause an error message later.  */
371650397Sobrien		(DECL_INITIAL (decl) != 0
371790075Sobrien		 || DECL_CONTEXT (decl) != 0)
371818334Speter	      :
371918334Speter		/* An automatic variable with an incomplete type
372018334Speter		   is an error.  */
372118334Speter		!DECL_EXTERNAL (decl)))
372218334Speter	{
372318334Speter	  error_with_decl (decl, "storage size of `%s' isn't known");
372418334Speter	  TREE_TYPE (decl) = error_mark_node;
372518334Speter	}
372618334Speter
372718334Speter      if ((DECL_EXTERNAL (decl) || TREE_STATIC (decl))
372818334Speter	  && DECL_SIZE (decl) != 0)
372918334Speter	{
373018334Speter	  if (TREE_CODE (DECL_SIZE (decl)) == INTEGER_CST)
373118334Speter	    constant_expression_warning (DECL_SIZE (decl));
373218334Speter	  else
373318334Speter	    error_with_decl (decl, "storage size of `%s' isn't constant");
373418334Speter	}
373550397Sobrien
373690075Sobrien      if (TREE_USED (type))
373750397Sobrien	TREE_USED (decl) = 1;
373818334Speter    }
373918334Speter
374018334Speter  /* If this is a function and an assembler name is specified, it isn't
374118334Speter     builtin any more.  Also reset DECL_RTL so we can give it its new
374218334Speter     name.  */
374318334Speter  if (TREE_CODE (decl) == FUNCTION_DECL && asmspec)
374490075Sobrien    {
374590075Sobrien      DECL_BUILT_IN_CLASS (decl) = NOT_BUILT_IN;
374690075Sobrien      SET_DECL_RTL (decl, NULL_RTX);
374790075Sobrien      SET_DECL_ASSEMBLER_NAME (decl, get_identifier (asmspec));
374890075Sobrien    }
374918334Speter
375018334Speter  /* Output the assembler code and/or RTL code for variables and functions,
375118334Speter     unless the type is an undefined structure or union.
375218334Speter     If not, it will get done when the type is completed.  */
375318334Speter
375418334Speter  if (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == FUNCTION_DECL)
375518334Speter    {
375690075Sobrien      /* This is a no-op in c-lang.c or something real in objc-actions.c.  */
375790075Sobrien      maybe_objc_check_decl (decl);
375890075Sobrien
375990075Sobrien      if (!DECL_CONTEXT (decl))
376018334Speter	{
376190075Sobrien	  if (DECL_INITIAL (decl) == NULL_TREE
376290075Sobrien	      || DECL_INITIAL (decl) == error_mark_node)
376390075Sobrien	    /* Don't output anything
376490075Sobrien	       when a tentative file-scope definition is seen.
376590075Sobrien	       But at end of compilation, do output code for them.  */
376690075Sobrien	    DECL_DEFER_OUTPUT (decl) = 1;
376750397Sobrien	  rest_of_decl_compilation (decl, asmspec,
376850397Sobrien				    (DECL_CONTEXT (decl) == 0
376990075Sobrien				     || TREE_ASM_WRITTEN (decl)), 0);
377018334Speter	}
377118334Speter      else
377218334Speter	{
377390075Sobrien	  /* This is a local variable.  If there is an ASMSPEC, the
377490075Sobrien	     user has requested that we handle it specially.  */
377590075Sobrien	  if (asmspec)
377690075Sobrien	    {
377790075Sobrien	      /* In conjunction with an ASMSPEC, the `register'
377890075Sobrien		 keyword indicates that we should place the variable
377990075Sobrien		 in a particular register.  */
378090075Sobrien	      if (DECL_REGISTER (decl))
378190075Sobrien		DECL_C_HARD_REGISTER (decl) = 1;
378290075Sobrien
378390075Sobrien	      /* If this is not a static variable, issue a warning.
378490075Sobrien		 It doesn't make any sense to give an ASMSPEC for an
378590075Sobrien		 ordinary, non-register local variable.  Historically,
378690075Sobrien		 GCC has accepted -- but ignored -- the ASMSPEC in
378790075Sobrien		 this case.  */
378890075Sobrien	      if (TREE_CODE (decl) == VAR_DECL
378990075Sobrien		  && !DECL_REGISTER (decl)
379090075Sobrien		  && !TREE_STATIC (decl))
379190075Sobrien		warning_with_decl (decl,
379290075Sobrien				   "ignoring asm-specifier for non-static local variable `%s'");
379390075Sobrien	      else
379490075Sobrien		SET_DECL_ASSEMBLER_NAME (decl, get_identifier (asmspec));
379590075Sobrien	    }
379690075Sobrien
379790075Sobrien	  if (TREE_CODE (decl) != FUNCTION_DECL)
379890075Sobrien	    add_decl_stmt (decl);
379918334Speter	}
380090075Sobrien
380118334Speter      if (DECL_CONTEXT (decl) != 0)
380218334Speter	{
380318334Speter	  /* Recompute the RTL of a local array now
380418334Speter	     if it used to be an incomplete type.  */
380518334Speter	  if (was_incomplete
380618334Speter	      && ! TREE_STATIC (decl) && ! DECL_EXTERNAL (decl))
380718334Speter	    {
380818334Speter	      /* If we used it already as memory, it must stay in memory.  */
380918334Speter	      TREE_ADDRESSABLE (decl) = TREE_USED (decl);
381018334Speter	      /* If it's still incomplete now, no init will save it.  */
381118334Speter	      if (DECL_SIZE (decl) == 0)
381218334Speter		DECL_INITIAL (decl) = 0;
381318334Speter	    }
381418334Speter	}
381518334Speter    }
381618334Speter
381718334Speter  if (TREE_CODE (decl) == TYPE_DECL)
381818334Speter    {
381918334Speter      /* This is a no-op in c-lang.c or something real in objc-actions.c.  */
382018334Speter      maybe_objc_check_decl (decl);
382190075Sobrien      rest_of_decl_compilation (decl, NULL, DECL_CONTEXT (decl) == 0, 0);
382218334Speter    }
382318334Speter
382418334Speter  /* At the end of a declaration, throw away any variable type sizes
382518334Speter     of types defined inside that declaration.  There is no use
382618334Speter     computing them in the following function definition.  */
382718334Speter  if (current_binding_level == global_binding_level)
382818334Speter    get_pending_sizes ();
382918334Speter}
383018334Speter
383118334Speter/* If DECL has a cleanup, build and return that cleanup here.
383218334Speter   This is a callback called by expand_expr.  */
383318334Speter
383418334Spetertree
383518334Spetermaybe_build_cleanup (decl)
383650397Sobrien     tree decl ATTRIBUTE_UNUSED;
383718334Speter{
383818334Speter  /* There are no cleanups in C.  */
383918334Speter  return NULL_TREE;
384018334Speter}
384118334Speter
384218334Speter/* Given a parsed parameter declaration,
384318334Speter   decode it into a PARM_DECL and push that on the current binding level.
384418334Speter   Also, for the sake of forward parm decls,
384518334Speter   record the given order of parms in `parm_order'.  */
384618334Speter
384718334Spetervoid
384818334Speterpush_parm_decl (parm)
384918334Speter     tree parm;
385018334Speter{
385118334Speter  tree decl;
385218334Speter  int old_immediate_size_expand = immediate_size_expand;
385318334Speter  /* Don't try computing parm sizes now -- wait till fn is called.  */
385418334Speter  immediate_size_expand = 0;
385518334Speter
385618334Speter  decl = grokdeclarator (TREE_VALUE (TREE_PURPOSE (parm)),
385796263Sobrien			 TREE_PURPOSE (TREE_PURPOSE (parm)), PARM, 0);
385890075Sobrien  decl_attributes (&decl, TREE_VALUE (parm), 0);
385918334Speter
386018334Speter#if 0
386118334Speter  if (DECL_NAME (decl))
386218334Speter    {
386318334Speter      tree olddecl;
386418334Speter      olddecl = lookup_name (DECL_NAME (decl));
386518334Speter      if (pedantic && olddecl != 0 && TREE_CODE (olddecl) == TYPE_DECL)
386690075Sobrien	pedwarn_with_decl (decl,
386790075Sobrien			   "ISO C forbids parameter `%s' shadowing typedef");
386818334Speter    }
386918334Speter#endif
387018334Speter
387118334Speter  decl = pushdecl (decl);
387218334Speter
387318334Speter  immediate_size_expand = old_immediate_size_expand;
387418334Speter
387518334Speter  current_binding_level->parm_order
387618334Speter    = tree_cons (NULL_TREE, decl, current_binding_level->parm_order);
387718334Speter
387818334Speter  /* Add this decl to the current binding level.  */
387918334Speter  finish_decl (decl, NULL_TREE, NULL_TREE);
388018334Speter}
388118334Speter
388218334Speter/* Clear the given order of parms in `parm_order'.
388318334Speter   Used at start of parm list,
388418334Speter   and also at semicolon terminating forward decls.  */
388518334Speter
388618334Spetervoid
388718334Speterclear_parm_order ()
388818334Speter{
388918334Speter  current_binding_level->parm_order = NULL_TREE;
389018334Speter}
389118334Speter
389290075Sobrien/* Build a COMPOUND_LITERAL_EXPR.  TYPE is the type given in the compound
389390075Sobrien   literal, which may be an incomplete array type completed by the
389490075Sobrien   initializer; INIT is a CONSTRUCTOR that initializes the compound
389590075Sobrien   literal.  */
389690075Sobrien
389790075Sobrientree
389890075Sobrienbuild_compound_literal (type, init)
389990075Sobrien     tree type;
390090075Sobrien     tree init;
390190075Sobrien{
390290075Sobrien  /* We do not use start_decl here because we have a type, not a declarator;
390390075Sobrien     and do not use finish_decl because the decl should be stored inside
390490075Sobrien     the COMPOUND_LITERAL_EXPR rather than added elsewhere as a DECL_STMT.  */
390590075Sobrien  tree decl = build_decl (VAR_DECL, NULL_TREE, type);
390690075Sobrien  tree complit;
390790075Sobrien  tree stmt;
390890075Sobrien  DECL_EXTERNAL (decl) = 0;
390990075Sobrien  TREE_PUBLIC (decl) = 0;
391090075Sobrien  TREE_STATIC (decl) = (current_binding_level == global_binding_level);
391190075Sobrien  DECL_CONTEXT (decl) = current_function_decl;
391290075Sobrien  TREE_USED (decl) = 1;
391390075Sobrien  TREE_TYPE (decl) = type;
391490075Sobrien  store_init_value (decl, init);
391590075Sobrien
391690075Sobrien  if (TREE_CODE (type) == ARRAY_TYPE && !COMPLETE_TYPE_P (type))
391790075Sobrien    {
391890075Sobrien      int failure = complete_array_type (type, DECL_INITIAL (decl), 1);
391990075Sobrien      if (failure)
392090075Sobrien	abort ();
392190075Sobrien    }
392290075Sobrien
392390075Sobrien  type = TREE_TYPE (decl);
392490075Sobrien  if (type == error_mark_node || !COMPLETE_TYPE_P (type))
392590075Sobrien    return error_mark_node;
392690075Sobrien
392790075Sobrien  stmt = build_stmt (DECL_STMT, decl);
392890075Sobrien  complit = build1 (COMPOUND_LITERAL_EXPR, TREE_TYPE (decl), stmt);
392990075Sobrien  TREE_SIDE_EFFECTS (complit) = 1;
393090075Sobrien
393190075Sobrien  layout_decl (decl, 0);
393290075Sobrien
393390075Sobrien  if (TREE_STATIC (decl))
393490075Sobrien    {
393590075Sobrien      /* This decl needs a name for the assembler output.  We also need
393690075Sobrien	 a unique suffix to be added to the name, for which DECL_CONTEXT
393790075Sobrien	 must be set.  */
393890075Sobrien      DECL_NAME (decl) = get_identifier ("__compound_literal");
393990075Sobrien      DECL_CONTEXT (decl) = complit;
394090075Sobrien      rest_of_decl_compilation (decl, NULL, 1, 0);
394190075Sobrien      DECL_CONTEXT (decl) = NULL_TREE;
394290075Sobrien    }
394390075Sobrien
394490075Sobrien  return complit;
394590075Sobrien}
394690075Sobrien
394718334Speter/* Make TYPE a complete type based on INITIAL_VALUE.
394818334Speter   Return 0 if successful, 1 if INITIAL_VALUE can't be deciphered,
394918334Speter   2 if there was no information (in which case assume 1 if DO_DEFAULT).  */
395018334Speter
395118334Speterint
395218334Spetercomplete_array_type (type, initial_value, do_default)
395318334Speter     tree type;
395418334Speter     tree initial_value;
395518334Speter     int do_default;
395618334Speter{
395790075Sobrien  tree maxindex = NULL_TREE;
395818334Speter  int value = 0;
395918334Speter
396018334Speter  if (initial_value)
396118334Speter    {
396218334Speter      /* Note MAXINDEX  is really the maximum index,
396318334Speter	 one less than the size.  */
396418334Speter      if (TREE_CODE (initial_value) == STRING_CST)
396518334Speter	{
396618334Speter	  int eltsize
396718334Speter	    = int_size_in_bytes (TREE_TYPE (TREE_TYPE (initial_value)));
396818334Speter	  maxindex = build_int_2 ((TREE_STRING_LENGTH (initial_value)
396918334Speter				   / eltsize) - 1, 0);
397018334Speter	}
397118334Speter      else if (TREE_CODE (initial_value) == CONSTRUCTOR)
397218334Speter	{
397318334Speter	  tree elts = CONSTRUCTOR_ELTS (initial_value);
397490075Sobrien	  maxindex = build_int_2 (-1, -1);
397518334Speter	  for (; elts; elts = TREE_CHAIN (elts))
397618334Speter	    {
397718334Speter	      if (TREE_PURPOSE (elts))
397818334Speter		maxindex = TREE_PURPOSE (elts);
397918334Speter	      else
398090075Sobrien		maxindex = fold (build (PLUS_EXPR, integer_type_node,
398190075Sobrien					maxindex, integer_one_node));
398218334Speter	    }
398318334Speter	  maxindex = copy_node (maxindex);
398418334Speter	}
398518334Speter      else
398618334Speter	{
398718334Speter	  /* Make an error message unless that happened already.  */
398818334Speter	  if (initial_value != error_mark_node)
398918334Speter	    value = 1;
399018334Speter
399118334Speter	  /* Prevent further error messages.  */
399218334Speter	  maxindex = build_int_2 (0, 0);
399318334Speter	}
399418334Speter    }
399518334Speter
399618334Speter  if (!maxindex)
399718334Speter    {
399818334Speter      if (do_default)
399918334Speter	maxindex = build_int_2 (0, 0);
400018334Speter      value = 2;
400118334Speter    }
400218334Speter
400318334Speter  if (maxindex)
400418334Speter    {
400518334Speter      TYPE_DOMAIN (type) = build_index_type (maxindex);
400618334Speter      if (!TREE_TYPE (maxindex))
400718334Speter	TREE_TYPE (maxindex) = TYPE_DOMAIN (type);
400818334Speter    }
400918334Speter
401018334Speter  /* Lay out the type now that we can get the real answer.  */
401118334Speter
401218334Speter  layout_type (type);
401318334Speter
401418334Speter  return value;
401518334Speter}
401618334Speter
401718334Speter/* Given declspecs and a declarator,
401818334Speter   determine the name and type of the object declared
401918334Speter   and construct a ..._DECL node for it.
402018334Speter   (In one case we can return a ..._TYPE node instead.
402118334Speter    For invalid input we sometimes return 0.)
402218334Speter
402318334Speter   DECLSPECS is a chain of tree_list nodes whose value fields
402418334Speter    are the storage classes and type specifiers.
402518334Speter
402618334Speter   DECL_CONTEXT says which syntactic context this declaration is in:
402718334Speter     NORMAL for most contexts.  Make a VAR_DECL or FUNCTION_DECL or TYPE_DECL.
402818334Speter     FUNCDEF for a function definition.  Like NORMAL but a few different
402918334Speter      error messages in each case.  Return value may be zero meaning
403018334Speter      this definition is too screwy to try to parse.
403118334Speter     PARM for a parameter declaration (either within a function prototype
403218334Speter      or before a function body).  Make a PARM_DECL, or return void_type_node.
403318334Speter     TYPENAME if for a typename (in a cast or sizeof).
403418334Speter      Don't make a DECL node; just return the ..._TYPE node.
403518334Speter     FIELD for a struct or union field; make a FIELD_DECL.
403696263Sobrien     BITFIELD for a field with specified width.
403718334Speter   INITIALIZED is 1 if the decl has an initializer.
403818334Speter
403918334Speter   In the TYPENAME case, DECLARATOR is really an absolute declarator.
404018334Speter   It may also be so in the PARM case, for a prototype where the
404118334Speter   argument type is specified but not the name.
404218334Speter
404318334Speter   This function is where the complicated C meanings of `static'
404418334Speter   and `extern' are interpreted.  */
404518334Speter
404618334Speterstatic tree
404796263Sobriengrokdeclarator (declarator, declspecs, decl_context, initialized)
404818334Speter     tree declspecs;
404918334Speter     tree declarator;
405018334Speter     enum decl_context decl_context;
405118334Speter     int initialized;
405218334Speter{
405318334Speter  int specbits = 0;
405418334Speter  tree spec;
405518334Speter  tree type = NULL_TREE;
405618334Speter  int longlong = 0;
405718334Speter  int constp;
405852284Sobrien  int restrictp;
405918334Speter  int volatilep;
406052284Sobrien  int type_quals = TYPE_UNQUALIFIED;
406118334Speter  int inlinep;
406218334Speter  int explicit_int = 0;
406318334Speter  int explicit_char = 0;
406418334Speter  int defaulted_int = 0;
406518334Speter  tree typedef_decl = 0;
406696263Sobrien  const char *name;
406718334Speter  tree typedef_type = 0;
406818334Speter  int funcdef_flag = 0;
406918334Speter  enum tree_code innermost_code = ERROR_MARK;
407096263Sobrien  int bitfield = 0;
407118334Speter  int size_varies = 0;
407290075Sobrien  tree decl_attr = NULL_TREE;
407390075Sobrien  tree array_ptr_quals = NULL_TREE;
407490075Sobrien  int array_parm_static = 0;
407590075Sobrien  tree returned_attrs = NULL_TREE;
407618334Speter
407796263Sobrien  if (decl_context == BITFIELD)
407896263Sobrien    bitfield = 1, decl_context = FIELD;
407996263Sobrien
408018334Speter  if (decl_context == FUNCDEF)
408118334Speter    funcdef_flag = 1, decl_context = NORMAL;
408218334Speter
408318334Speter  /* Look inside a declarator for the name being declared
408418334Speter     and get it as a string, for an error message.  */
408518334Speter  {
408690075Sobrien    tree decl = declarator;
408718334Speter    name = 0;
408818334Speter
408918334Speter    while (decl)
409018334Speter      switch (TREE_CODE (decl))
409118334Speter	{
409218334Speter	case ARRAY_REF:
409318334Speter	case INDIRECT_REF:
409418334Speter	case CALL_EXPR:
409518334Speter	  innermost_code = TREE_CODE (decl);
409618334Speter	  decl = TREE_OPERAND (decl, 0);
409718334Speter	  break;
409818334Speter
409990075Sobrien	case TREE_LIST:
410090075Sobrien	  decl = TREE_VALUE (decl);
410190075Sobrien	  break;
410290075Sobrien
410318334Speter	case IDENTIFIER_NODE:
410418334Speter	  name = IDENTIFIER_POINTER (decl);
410518334Speter	  decl = 0;
410618334Speter	  break;
410718334Speter
410818334Speter	default:
410918334Speter	  abort ();
411018334Speter	}
411118334Speter    if (name == 0)
411218334Speter      name = "type name";
411318334Speter  }
411418334Speter
411518334Speter  /* A function definition's declarator must have the form of
411618334Speter     a function declarator.  */
411718334Speter
411818334Speter  if (funcdef_flag && innermost_code != CALL_EXPR)
411918334Speter    return 0;
412018334Speter
412118334Speter  /* Anything declared one level down from the top level
412218334Speter     must be one of the parameters of a function
412318334Speter     (because the body is at least two levels down).  */
412418334Speter
412518334Speter  /* If this looks like a function definition, make it one,
412618334Speter     even if it occurs where parms are expected.
412718334Speter     Then store_parm_decls will reject it and not use it as a parm.  */
412818334Speter  if (decl_context == NORMAL && !funcdef_flag
412918334Speter      && current_binding_level->parm_flag)
413018334Speter    decl_context = PARM;
413118334Speter
413218334Speter  /* Look through the decl specs and record which ones appear.
413318334Speter     Some typespecs are defined as built-in typenames.
413418334Speter     Others, the ones that are modifiers of other types,
413518334Speter     are represented by bits in SPECBITS: set the bits for
413618334Speter     the modifiers that appear.  Storage class keywords are also in SPECBITS.
413718334Speter
413818334Speter     If there is a typedef name or a type, store the type in TYPE.
413918334Speter     This includes builtin typedefs such as `int'.
414018334Speter
414118334Speter     Set EXPLICIT_INT or EXPLICIT_CHAR if the type is `int' or `char'
414218334Speter     and did not come from a user typedef.
414318334Speter
414418334Speter     Set LONGLONG if `long' is mentioned twice.  */
414518334Speter
414618334Speter  for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
414718334Speter    {
414890075Sobrien      tree id = TREE_VALUE (spec);
414918334Speter
415090075Sobrien      /* If the entire declaration is itself tagged as deprecated then
415190075Sobrien         suppress reports of deprecated items.  */
415290075Sobrien      if (id && TREE_DEPRECATED (id))
415390075Sobrien        {
415490075Sobrien	  if (deprecated_state != DEPRECATED_SUPPRESS)
415590075Sobrien	    warn_deprecated_use (id);
415690075Sobrien        }
415790075Sobrien
415818334Speter      if (id == ridpointers[(int) RID_INT])
415918334Speter	explicit_int = 1;
416018334Speter      if (id == ridpointers[(int) RID_CHAR])
416118334Speter	explicit_char = 1;
416218334Speter
416390075Sobrien      if (TREE_CODE (id) == IDENTIFIER_NODE && C_IS_RESERVED_WORD (id))
416490075Sobrien	{
416590075Sobrien	  enum rid i = C_RID_CODE (id);
416690075Sobrien	  if ((int) i <= (int) RID_LAST_MODIFIER)
416790075Sobrien	    {
416890075Sobrien	      if (i == RID_LONG && (specbits & (1 << (int) i)))
416990075Sobrien		{
417090075Sobrien		  if (longlong)
417190075Sobrien		    error ("`long long long' is too long for GCC");
417290075Sobrien		  else
417390075Sobrien		    {
417490075Sobrien		      if (pedantic && !flag_isoc99 && ! in_system_header
417590075Sobrien			  && warn_long_long)
417690075Sobrien			pedwarn ("ISO C89 does not support `long long'");
417790075Sobrien		      longlong = 1;
417890075Sobrien		    }
417990075Sobrien		}
418090075Sobrien	      else if (specbits & (1 << (int) i))
418190075Sobrien		pedwarn ("duplicate `%s'", IDENTIFIER_POINTER (id));
418290075Sobrien	      specbits |= 1 << (int) i;
418390075Sobrien	      goto found;
418490075Sobrien	    }
418590075Sobrien	}
418618334Speter      if (type)
418718334Speter	error ("two or more data types in declaration of `%s'", name);
418818334Speter      /* Actual typedefs come to us as TYPE_DECL nodes.  */
418918334Speter      else if (TREE_CODE (id) == TYPE_DECL)
419018334Speter	{
419190075Sobrien	  if (TREE_TYPE (id) == error_mark_node)
419290075Sobrien	    ; /* Allow the type to default to int to avoid cascading errors.  */
419390075Sobrien	  else
419490075Sobrien	    {
419590075Sobrien	      type = TREE_TYPE (id);
419690075Sobrien	      decl_attr = DECL_ATTRIBUTES (id);
419790075Sobrien	      typedef_decl = id;
419890075Sobrien	    }
419918334Speter	}
420018334Speter      /* Built-in types come as identifiers.  */
420118334Speter      else if (TREE_CODE (id) == IDENTIFIER_NODE)
420218334Speter	{
420390075Sobrien	  tree t = lookup_name (id);
420418334Speter	  if (TREE_TYPE (t) == error_mark_node)
420518334Speter	    ;
420618334Speter	  else if (!t || TREE_CODE (t) != TYPE_DECL)
420718334Speter	    error ("`%s' fails to be a typedef or built in type",
420818334Speter		   IDENTIFIER_POINTER (id));
420918334Speter	  else
421018334Speter	    {
421118334Speter	      type = TREE_TYPE (t);
421218334Speter	      typedef_decl = t;
421318334Speter	    }
421418334Speter	}
421518334Speter      else if (TREE_CODE (id) != ERROR_MARK)
421618334Speter	type = id;
421718334Speter
421890075Sobrien    found:
421990075Sobrien      ;
422018334Speter    }
422118334Speter
422218334Speter  typedef_type = type;
422318334Speter  if (type)
422418334Speter    size_varies = C_TYPE_VARIABLE_SIZE (type);
422518334Speter
422618334Speter  /* No type at all: default to `int', and set DEFAULTED_INT
422718334Speter     because it was not a user-defined typedef.  */
422818334Speter
422918334Speter  if (type == 0)
423018334Speter    {
423150397Sobrien      if ((! (specbits & ((1 << (int) RID_LONG) | (1 << (int) RID_SHORT)
423250397Sobrien			  | (1 << (int) RID_SIGNED)
423390075Sobrien			  | (1 << (int) RID_UNSIGNED)
423490075Sobrien			  | (1 << (int) RID_COMPLEX))))
423550397Sobrien	  /* Don't warn about typedef foo = bar.  */
423650397Sobrien	  && ! (specbits & (1 << (int) RID_TYPEDEF) && initialized)
423790075Sobrien	  && ! in_system_header)
423850397Sobrien	{
423990075Sobrien	  /* Issue a warning if this is an ISO C 99 program or if -Wreturn-type
424052284Sobrien	     and this is a function, or if -Wimplicit; prefer the former
424152284Sobrien	     warning since it is more explicit.  */
424290075Sobrien	  if ((warn_implicit_int || warn_return_type || flag_isoc99)
424390075Sobrien	      && funcdef_flag)
424450397Sobrien	    warn_about_return_type = 1;
424590075Sobrien	  else if (warn_implicit_int || flag_isoc99)
424690075Sobrien	    pedwarn_c99 ("type defaults to `int' in declaration of `%s'",
424790075Sobrien			 name);
424850397Sobrien	}
424950397Sobrien
425018334Speter      defaulted_int = 1;
425118334Speter      type = integer_type_node;
425218334Speter    }
425318334Speter
425418334Speter  /* Now process the modifiers that were specified
425518334Speter     and check for invalid combinations.  */
425618334Speter
425718334Speter  /* Long double is a special combination.  */
425818334Speter
425950397Sobrien  if ((specbits & 1 << (int) RID_LONG) && ! longlong
426018334Speter      && TYPE_MAIN_VARIANT (type) == double_type_node)
426118334Speter    {
426290075Sobrien      specbits &= ~(1 << (int) RID_LONG);
426318334Speter      type = long_double_type_node;
426418334Speter    }
426518334Speter
426618334Speter  /* Check all other uses of type modifiers.  */
426718334Speter
426818334Speter  if (specbits & ((1 << (int) RID_LONG) | (1 << (int) RID_SHORT)
426918334Speter		  | (1 << (int) RID_UNSIGNED) | (1 << (int) RID_SIGNED)))
427018334Speter    {
427118334Speter      int ok = 0;
427218334Speter
427350397Sobrien      if ((specbits & 1 << (int) RID_LONG)
427450397Sobrien	  && (specbits & 1 << (int) RID_SHORT))
427550397Sobrien	error ("both long and short specified for `%s'", name);
427618334Speter      else if (((specbits & 1 << (int) RID_LONG)
427718334Speter		|| (specbits & 1 << (int) RID_SHORT))
427818334Speter	       && explicit_char)
427918334Speter	error ("long or short specified with char for `%s'", name);
428018334Speter      else if (((specbits & 1 << (int) RID_LONG)
428118334Speter		|| (specbits & 1 << (int) RID_SHORT))
428218334Speter	       && TREE_CODE (type) == REAL_TYPE)
428350397Sobrien	{
428450397Sobrien	  static int already = 0;
428550397Sobrien
428650397Sobrien	  error ("long or short specified with floating type for `%s'", name);
428750397Sobrien	  if (! already && ! pedantic)
428850397Sobrien	    {
428950397Sobrien	      error ("the only valid combination is `long double'");
429050397Sobrien	      already = 1;
429150397Sobrien	    }
429250397Sobrien	}
429318334Speter      else if ((specbits & 1 << (int) RID_SIGNED)
429418334Speter	       && (specbits & 1 << (int) RID_UNSIGNED))
429550397Sobrien	error ("both signed and unsigned specified for `%s'", name);
429650397Sobrien      else if (TREE_CODE (type) != INTEGER_TYPE)
429750397Sobrien	error ("long, short, signed or unsigned invalid for `%s'", name);
429818334Speter      else
429918334Speter	{
430018334Speter	  ok = 1;
430118334Speter	  if (!explicit_int && !defaulted_int && !explicit_char && pedantic)
430218334Speter	    {
430318334Speter	      pedwarn ("long, short, signed or unsigned used invalidly for `%s'",
430418334Speter		       name);
430518334Speter	      if (flag_pedantic_errors)
430618334Speter		ok = 0;
430718334Speter	    }
430818334Speter	}
430918334Speter
431018334Speter      /* Discard the type modifiers if they are invalid.  */
431118334Speter      if (! ok)
431218334Speter	{
431318334Speter	  specbits &= ~((1 << (int) RID_LONG) | (1 << (int) RID_SHORT)
431418334Speter			| (1 << (int) RID_UNSIGNED) | (1 << (int) RID_SIGNED));
431518334Speter	  longlong = 0;
431618334Speter	}
431718334Speter    }
431818334Speter
431918334Speter  if ((specbits & (1 << (int) RID_COMPLEX))
432018334Speter      && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
432118334Speter    {
432218334Speter      error ("complex invalid for `%s'", name);
432390075Sobrien      specbits &= ~(1 << (int) RID_COMPLEX);
432418334Speter    }
432518334Speter
432618334Speter  /* Decide whether an integer type is signed or not.
432796263Sobrien     Optionally treat bitfields as signed by default.  */
432818334Speter  if (specbits & 1 << (int) RID_UNSIGNED
432996263Sobrien      /* Traditionally, all bitfields are unsigned.  */
433018334Speter      || (bitfield && flag_traditional
433118334Speter	  && (! explicit_flag_signed_bitfields || !flag_signed_bitfields))
433218334Speter      || (bitfield && ! flag_signed_bitfields
433318334Speter	  && (explicit_int || defaulted_int || explicit_char
433418334Speter	      /* A typedef for plain `int' without `signed'
433518334Speter		 can be controlled just like plain `int'.  */
433618334Speter	      || ! (typedef_decl != 0
433718334Speter		    && C_TYPEDEF_EXPLICITLY_SIGNED (typedef_decl)))
433818334Speter	  && TREE_CODE (type) != ENUMERAL_TYPE
433918334Speter	  && !(specbits & 1 << (int) RID_SIGNED)))
434018334Speter    {
434118334Speter      if (longlong)
434218334Speter	type = long_long_unsigned_type_node;
434318334Speter      else if (specbits & 1 << (int) RID_LONG)
434418334Speter	type = long_unsigned_type_node;
434518334Speter      else if (specbits & 1 << (int) RID_SHORT)
434618334Speter	type = short_unsigned_type_node;
434718334Speter      else if (type == char_type_node)
434818334Speter	type = unsigned_char_type_node;
434918334Speter      else if (typedef_decl)
435018334Speter	type = unsigned_type (type);
435118334Speter      else
435218334Speter	type = unsigned_type_node;
435318334Speter    }
435418334Speter  else if ((specbits & 1 << (int) RID_SIGNED)
435518334Speter	   && type == char_type_node)
435618334Speter    type = signed_char_type_node;
435718334Speter  else if (longlong)
435818334Speter    type = long_long_integer_type_node;
435918334Speter  else if (specbits & 1 << (int) RID_LONG)
436018334Speter    type = long_integer_type_node;
436118334Speter  else if (specbits & 1 << (int) RID_SHORT)
436218334Speter    type = short_integer_type_node;
436318334Speter
436418334Speter  if (specbits & 1 << (int) RID_COMPLEX)
436518334Speter    {
436690075Sobrien      if (pedantic && !flag_isoc99)
436790075Sobrien	pedwarn ("ISO C89 does not support complex types");
436818334Speter      /* If we just have "complex", it is equivalent to
436918334Speter	 "complex double", but if any modifiers at all are specified it is
437018334Speter	 the complex form of TYPE.  E.g, "complex short" is
437118334Speter	 "complex short int".  */
437218334Speter
437318334Speter      if (defaulted_int && ! longlong
437418334Speter	  && ! (specbits & ((1 << (int) RID_LONG) | (1 << (int) RID_SHORT)
437518334Speter			    | (1 << (int) RID_SIGNED)
437618334Speter			    | (1 << (int) RID_UNSIGNED))))
437790075Sobrien	{
437890075Sobrien	  if (pedantic)
437990075Sobrien	    pedwarn ("ISO C does not support plain `complex' meaning `double complex'");
438090075Sobrien	  type = complex_double_type_node;
438190075Sobrien	}
438218334Speter      else if (type == integer_type_node)
438390075Sobrien	{
438490075Sobrien	  if (pedantic)
438590075Sobrien	    pedwarn ("ISO C does not support complex integer types");
438690075Sobrien	  type = complex_integer_type_node;
438790075Sobrien	}
438818334Speter      else if (type == float_type_node)
438918334Speter	type = complex_float_type_node;
439018334Speter      else if (type == double_type_node)
439118334Speter	type = complex_double_type_node;
439218334Speter      else if (type == long_double_type_node)
439318334Speter	type = complex_long_double_type_node;
439418334Speter      else
439590075Sobrien	{
439690075Sobrien	  if (pedantic)
439790075Sobrien	    pedwarn ("ISO C does not support complex integer types");
439890075Sobrien	  type = build_complex_type (type);
439990075Sobrien	}
440018334Speter    }
440118334Speter
440252284Sobrien  /* Figure out the type qualifiers for the declaration.  There are
440352284Sobrien     two ways a declaration can become qualified.  One is something
440452284Sobrien     like `const int i' where the `const' is explicit.  Another is
440552284Sobrien     something like `typedef const int CI; CI i' where the type of the
440652284Sobrien     declaration contains the `const'.  */
440718334Speter  constp = !! (specbits & 1 << (int) RID_CONST) + TYPE_READONLY (type);
440852284Sobrien  restrictp = !! (specbits & 1 << (int) RID_RESTRICT) + TYPE_RESTRICT (type);
440918334Speter  volatilep = !! (specbits & 1 << (int) RID_VOLATILE) + TYPE_VOLATILE (type);
441018334Speter  inlinep = !! (specbits & (1 << (int) RID_INLINE));
441190075Sobrien  if (constp > 1 && ! flag_isoc99)
441218334Speter    pedwarn ("duplicate `const'");
441390075Sobrien  if (restrictp > 1 && ! flag_isoc99)
441452284Sobrien    pedwarn ("duplicate `restrict'");
441590075Sobrien  if (volatilep > 1 && ! flag_isoc99)
441618334Speter    pedwarn ("duplicate `volatile'");
441752284Sobrien  if (! flag_gen_aux_info && (TYPE_QUALS (type)))
441818334Speter    type = TYPE_MAIN_VARIANT (type);
441952284Sobrien  type_quals = ((constp ? TYPE_QUAL_CONST : 0)
442052284Sobrien		| (restrictp ? TYPE_QUAL_RESTRICT : 0)
442152284Sobrien		| (volatilep ? TYPE_QUAL_VOLATILE : 0));
442218334Speter
442318334Speter  /* Warn if two storage classes are given. Default to `auto'.  */
442418334Speter
442518334Speter  {
442618334Speter    int nclasses = 0;
442718334Speter
442818334Speter    if (specbits & 1 << (int) RID_AUTO) nclasses++;
442918334Speter    if (specbits & 1 << (int) RID_STATIC) nclasses++;
443018334Speter    if (specbits & 1 << (int) RID_EXTERN) nclasses++;
443118334Speter    if (specbits & 1 << (int) RID_REGISTER) nclasses++;
443218334Speter    if (specbits & 1 << (int) RID_TYPEDEF) nclasses++;
443318334Speter
443418334Speter    /* Warn about storage classes that are invalid for certain
443518334Speter       kinds of declarations (parameters, typenames, etc.).  */
443618334Speter
443718334Speter    if (nclasses > 1)
443818334Speter      error ("multiple storage classes in declaration of `%s'", name);
443918334Speter    else if (funcdef_flag
444018334Speter	     && (specbits
444118334Speter		 & ((1 << (int) RID_REGISTER)
444218334Speter		    | (1 << (int) RID_AUTO)
444318334Speter		    | (1 << (int) RID_TYPEDEF))))
444418334Speter      {
444518334Speter	if (specbits & 1 << (int) RID_AUTO
444618334Speter	    && (pedantic || current_binding_level == global_binding_level))
444718334Speter	  pedwarn ("function definition declared `auto'");
444818334Speter	if (specbits & 1 << (int) RID_REGISTER)
444918334Speter	  error ("function definition declared `register'");
445018334Speter	if (specbits & 1 << (int) RID_TYPEDEF)
445118334Speter	  error ("function definition declared `typedef'");
445290075Sobrien	specbits &= ~((1 << (int) RID_TYPEDEF) | (1 << (int) RID_REGISTER)
445390075Sobrien		      | (1 << (int) RID_AUTO));
445418334Speter      }
445518334Speter    else if (decl_context != NORMAL && nclasses > 0)
445618334Speter      {
445718334Speter	if (decl_context == PARM && specbits & 1 << (int) RID_REGISTER)
445818334Speter	  ;
445918334Speter	else
446018334Speter	  {
446190075Sobrien	    switch (decl_context)
446290075Sobrien	      {
446390075Sobrien	      case FIELD:
446490075Sobrien		error ("storage class specified for structure field `%s'",
446590075Sobrien		       name);
446690075Sobrien		break;
446790075Sobrien	      case PARM:
446890075Sobrien		error ("storage class specified for parameter `%s'", name);
446990075Sobrien		break;
447090075Sobrien	      default:
447190075Sobrien		error ("storage class specified for typename");
447290075Sobrien		break;
447390075Sobrien	      }
447490075Sobrien	    specbits &= ~((1 << (int) RID_TYPEDEF) | (1 << (int) RID_REGISTER)
447590075Sobrien			  | (1 << (int) RID_AUTO) | (1 << (int) RID_STATIC)
447690075Sobrien			  | (1 << (int) RID_EXTERN));
447718334Speter	  }
447818334Speter      }
447918334Speter    else if (specbits & 1 << (int) RID_EXTERN && initialized && ! funcdef_flag)
448018334Speter      {
448118334Speter	/* `extern' with initialization is invalid if not at top level.  */
448218334Speter	if (current_binding_level == global_binding_level)
448318334Speter	  warning ("`%s' initialized and declared `extern'", name);
448418334Speter	else
448518334Speter	  error ("`%s' has both `extern' and initializer", name);
448618334Speter      }
448718334Speter    else if (specbits & 1 << (int) RID_EXTERN && funcdef_flag
448818334Speter	     && current_binding_level != global_binding_level)
448918334Speter      error ("nested function `%s' declared `extern'", name);
449018334Speter    else if (current_binding_level == global_binding_level
449118334Speter	     && specbits & (1 << (int) RID_AUTO))
449218334Speter      error ("top-level declaration of `%s' specifies `auto'", name);
449318334Speter  }
449418334Speter
449518334Speter  /* Now figure out the structure of the declarator proper.
449618334Speter     Descend through it, creating more complex types, until we reach
449718334Speter     the declared identifier (or NULL_TREE, in an absolute declarator).  */
449818334Speter
449918334Speter  while (declarator && TREE_CODE (declarator) != IDENTIFIER_NODE)
450018334Speter    {
450118334Speter      if (type == error_mark_node)
450218334Speter	{
450318334Speter	  declarator = TREE_OPERAND (declarator, 0);
450418334Speter	  continue;
450518334Speter	}
450618334Speter
450718334Speter      /* Each level of DECLARATOR is either an ARRAY_REF (for ...[..]),
450818334Speter	 an INDIRECT_REF (for *...),
450918334Speter	 a CALL_EXPR (for ...(...)),
451090075Sobrien	 a TREE_LIST (for nested attributes),
451118334Speter	 an identifier (for the name being declared)
451218334Speter	 or a null pointer (for the place in an absolute declarator
451318334Speter	 where the name was omitted).
451418334Speter	 For the last two cases, we have just exited the loop.
451518334Speter
451618334Speter	 At this point, TYPE is the type of elements of an array,
451718334Speter	 or for a function to return, or for a pointer to point to.
451818334Speter	 After this sequence of ifs, TYPE is the type of the
451918334Speter	 array or function or pointer, and DECLARATOR has had its
452018334Speter	 outermost layer removed.  */
452118334Speter
452290075Sobrien      if (array_ptr_quals != NULL_TREE || array_parm_static)
452318334Speter	{
452490075Sobrien	  /* Only the innermost declarator (making a parameter be of
452590075Sobrien	     array type which is converted to pointer type)
452690075Sobrien	     may have static or type qualifiers.  */
452790075Sobrien	  error ("static or type qualifiers in non-parameter array declarator");
452890075Sobrien	  array_ptr_quals = NULL_TREE;
452990075Sobrien	  array_parm_static = 0;
453090075Sobrien	}
453190075Sobrien
453290075Sobrien      if (TREE_CODE (declarator) == TREE_LIST)
453390075Sobrien	{
453490075Sobrien	  /* We encode a declarator with embedded attributes using
453590075Sobrien	     a TREE_LIST.  */
453690075Sobrien	  tree attrs = TREE_PURPOSE (declarator);
453790075Sobrien	  tree inner_decl;
453890075Sobrien	  int attr_flags = 0;
453990075Sobrien	  declarator = TREE_VALUE (declarator);
454090075Sobrien	  inner_decl = declarator;
454190075Sobrien	  while (inner_decl != NULL_TREE
454290075Sobrien		 && TREE_CODE (inner_decl) == TREE_LIST)
454390075Sobrien	    inner_decl = TREE_VALUE (inner_decl);
454490075Sobrien	  if (inner_decl == NULL_TREE
454590075Sobrien	      || TREE_CODE (inner_decl) == IDENTIFIER_NODE)
454690075Sobrien	    attr_flags |= (int) ATTR_FLAG_DECL_NEXT;
454796263Sobrien	  else if (TREE_CODE (inner_decl) == CALL_EXPR)
454890075Sobrien	    attr_flags |= (int) ATTR_FLAG_FUNCTION_NEXT;
454996263Sobrien	  else if (TREE_CODE (inner_decl) == ARRAY_REF)
455090075Sobrien	    attr_flags |= (int) ATTR_FLAG_ARRAY_NEXT;
455190075Sobrien	  returned_attrs = decl_attributes (&type,
455290075Sobrien					    chainon (returned_attrs, attrs),
455390075Sobrien					    attr_flags);
455490075Sobrien	}
455590075Sobrien      else if (TREE_CODE (declarator) == ARRAY_REF)
455690075Sobrien	{
455790075Sobrien	  tree itype = NULL_TREE;
455890075Sobrien	  tree size = TREE_OPERAND (declarator, 1);
455918334Speter	  /* The index is a signed object `sizetype' bits wide.  */
456018334Speter	  tree index_type = signed_type (sizetype);
456118334Speter
456290075Sobrien	  array_ptr_quals = TREE_TYPE (declarator);
456390075Sobrien	  array_parm_static = TREE_STATIC (declarator);
456490075Sobrien
456518334Speter	  declarator = TREE_OPERAND (declarator, 0);
456618334Speter
456718334Speter	  /* Check for some types that there cannot be arrays of.  */
456818334Speter
456990075Sobrien	  if (VOID_TYPE_P (type))
457018334Speter	    {
457118334Speter	      error ("declaration of `%s' as array of voids", name);
457218334Speter	      type = error_mark_node;
457318334Speter	    }
457418334Speter
457518334Speter	  if (TREE_CODE (type) == FUNCTION_TYPE)
457618334Speter	    {
457718334Speter	      error ("declaration of `%s' as array of functions", name);
457818334Speter	      type = error_mark_node;
457918334Speter	    }
458018334Speter
458118334Speter	  if (size == error_mark_node)
458218334Speter	    type = error_mark_node;
458318334Speter
458418334Speter	  if (type == error_mark_node)
458518334Speter	    continue;
458618334Speter
458718334Speter	  /* If size was specified, set ITYPE to a range-type for that size.
458818334Speter	     Otherwise, ITYPE remains null.  finish_decl may figure it out
458918334Speter	     from an initial value.  */
459018334Speter
459118334Speter	  if (size)
459218334Speter	    {
459318334Speter	      /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue.  */
459418334Speter	      STRIP_TYPE_NOPS (size);
459518334Speter
459690075Sobrien	      if (! INTEGRAL_TYPE_P (TREE_TYPE (size)))
459718334Speter		{
459818334Speter		  error ("size of array `%s' has non-integer type", name);
459918334Speter		  size = integer_one_node;
460018334Speter		}
460118334Speter
460218334Speter	      if (pedantic && integer_zerop (size))
460390075Sobrien		pedwarn ("ISO C forbids zero-size array `%s'", name);
460418334Speter
460518334Speter	      if (TREE_CODE (size) == INTEGER_CST)
460618334Speter		{
460718334Speter		  constant_expression_warning (size);
460818334Speter		  if (tree_int_cst_sgn (size) < 0)
460918334Speter		    {
461018334Speter		      error ("size of array `%s' is negative", name);
461118334Speter		      size = integer_one_node;
461218334Speter		    }
461318334Speter		}
461418334Speter	      else
461518334Speter		{
461618334Speter		  /* Make sure the array size remains visibly nonconstant
461718334Speter		     even if it is (eg) a const variable with known value.  */
461818334Speter		  size_varies = 1;
461918334Speter
462018334Speter		  if (pedantic)
462118334Speter		    {
462218334Speter		      if (TREE_CONSTANT (size))
462390075Sobrien			pedwarn ("ISO C89 forbids array `%s' whose size can't be evaluated",
462490075Sobrien				 name);
462518334Speter		      else
462690075Sobrien			pedwarn ("ISO C89 forbids variable-size array `%s'",
462790075Sobrien				 name);
462818334Speter		    }
462918334Speter		}
463018334Speter
463190075Sobrien	      if (integer_zerop (size))
463250397Sobrien		{
463390075Sobrien		  /* A zero-length array cannot be represented with an
463490075Sobrien		     unsigned index type, which is what we'll get with
463590075Sobrien		     build_index_type.  Create an open-ended range instead.  */
463690075Sobrien		  itype = build_range_type (sizetype, size, NULL_TREE);
463750397Sobrien		}
463890075Sobrien	      else
463990075Sobrien		{
464090075Sobrien		  /* Compute the maximum valid index, that is, size - 1.
464190075Sobrien		     Do the calculation in index_type, so that if it is
464290075Sobrien		     a variable the computations will be done in the
464390075Sobrien		     proper mode.  */
464490075Sobrien	          itype = fold (build (MINUS_EXPR, index_type,
464590075Sobrien				       convert (index_type, size),
464690075Sobrien				       convert (index_type, size_one_node)));
464750397Sobrien
464890075Sobrien	          /* If that overflowed, the array is too big.
464990075Sobrien		     ??? While a size of INT_MAX+1 technically shouldn't
465090075Sobrien		     cause an overflow (because we subtract 1), the overflow
465190075Sobrien		     is recorded during the conversion to index_type, before
465290075Sobrien		     the subtraction.  Handling this case seems like an
465390075Sobrien		     unnecessary complication.  */
465490075Sobrien		  if (TREE_OVERFLOW (itype))
465590075Sobrien		    {
465690075Sobrien		      error ("size of array `%s' is too large", name);
465790075Sobrien		      type = error_mark_node;
465890075Sobrien		      continue;
465990075Sobrien		    }
466090075Sobrien
466190075Sobrien		  if (size_varies)
466290075Sobrien		    itype = variable_size (itype);
466390075Sobrien		  itype = build_index_type (itype);
466490075Sobrien		}
466518334Speter	    }
466690075Sobrien	  else if (decl_context == FIELD)
466790075Sobrien	    {
466890075Sobrien	      if (pedantic && !flag_isoc99 && !in_system_header)
466990075Sobrien		pedwarn ("ISO C89 does not support flexible array members");
467018334Speter
467190075Sobrien	      /* ISO C99 Flexible array members are effectively identical
467290075Sobrien		 to GCC's zero-length array extension.  */
467390075Sobrien	      itype = build_range_type (sizetype, size_zero_node, NULL_TREE);
467490075Sobrien	    }
467518334Speter
467690075Sobrien	  /* If pedantic, complain about arrays of incomplete types.  */
467790075Sobrien
467890075Sobrien	  if (pedantic && !COMPLETE_TYPE_P (type))
467990075Sobrien	    pedwarn ("array type has incomplete element type");
468090075Sobrien
468190075Sobrien#if 0
468290075Sobrien	  /* We shouldn't have a function type here at all!
468390075Sobrien	     Functions aren't allowed as array elements.  */
468418334Speter	  if (pedantic && TREE_CODE (type) == FUNCTION_TYPE
468518334Speter	      && (constp || volatilep))
468690075Sobrien	    pedwarn ("ISO C forbids const or volatile function types");
468718334Speter#endif
468818334Speter
468918334Speter	  /* Build the array type itself, then merge any constancy or
469018334Speter	     volatility into the target type.  We must do it in this order
469118334Speter	     to ensure that the TYPE_MAIN_VARIANT field of the array type
469218334Speter	     is set correctly.  */
469318334Speter
469418334Speter	  type = build_array_type (type, itype);
469552284Sobrien	  if (type_quals)
469652284Sobrien	    type = c_build_qualified_type (type, type_quals);
469718334Speter
469818334Speter	  if (size_varies)
469918334Speter	    C_TYPE_VARIABLE_SIZE (type) = 1;
470090075Sobrien
470190075Sobrien	  /* The GCC extension for zero-length arrays differs from
470290075Sobrien	     ISO flexible array members in that sizeof yields zero.  */
470390075Sobrien	  if (size && integer_zerop (size))
470490075Sobrien	    {
470590075Sobrien	      layout_type (type);
470690075Sobrien	      TYPE_SIZE (type) = bitsize_zero_node;
470790075Sobrien	      TYPE_SIZE_UNIT (type) = size_zero_node;
470890075Sobrien	    }
470990075Sobrien	  if (decl_context != PARM
471090075Sobrien	      && (array_ptr_quals != NULL_TREE || array_parm_static))
471190075Sobrien	    {
471290075Sobrien	      error ("static or type qualifiers in non-parameter array declarator");
471390075Sobrien	      array_ptr_quals = NULL_TREE;
471490075Sobrien	      array_parm_static = 0;
471590075Sobrien	    }
471618334Speter	}
471718334Speter      else if (TREE_CODE (declarator) == CALL_EXPR)
471818334Speter	{
471918334Speter	  tree arg_types;
472018334Speter
472118334Speter	  /* Declaring a function type.
472218334Speter	     Make sure we have a valid type for the function to return.  */
472318334Speter	  if (type == error_mark_node)
472418334Speter	    continue;
472518334Speter
472618334Speter	  size_varies = 0;
472718334Speter
472818334Speter	  /* Warn about some types functions can't return.  */
472918334Speter
473018334Speter	  if (TREE_CODE (type) == FUNCTION_TYPE)
473118334Speter	    {
473218334Speter	      error ("`%s' declared as function returning a function", name);
473318334Speter	      type = integer_type_node;
473418334Speter	    }
473518334Speter	  if (TREE_CODE (type) == ARRAY_TYPE)
473618334Speter	    {
473718334Speter	      error ("`%s' declared as function returning an array", name);
473818334Speter	      type = integer_type_node;
473918334Speter	    }
474018334Speter
474118334Speter#ifndef TRADITIONAL_RETURN_FLOAT
474218334Speter	  /* Traditionally, declaring return type float means double.  */
474318334Speter
474418334Speter	  if (flag_traditional && TYPE_MAIN_VARIANT (type) == float_type_node)
474518334Speter	    type = double_type_node;
474618334Speter#endif /* TRADITIONAL_RETURN_FLOAT */
474718334Speter
474818334Speter	  /* Construct the function type and go to the next
474918334Speter	     inner layer of declarator.  */
475018334Speter
475118334Speter	  arg_types = grokparms (TREE_OPERAND (declarator, 1),
475218334Speter				 funcdef_flag
475318334Speter				 /* Say it's a definition
475418334Speter				    only for the CALL_EXPR
475518334Speter				    closest to the identifier.  */
475618334Speter				 && TREE_CODE (TREE_OPERAND (declarator, 0)) == IDENTIFIER_NODE);
475752284Sobrien	  /* Type qualifiers before the return type of the function
475852284Sobrien	     qualify the return type, not the function type.  */
475952284Sobrien	  if (type_quals)
476090075Sobrien	    {
476190075Sobrien	      /* Type qualifiers on a function return type are normally
476290075Sobrien		 permitted by the standard but have no effect, so give a
476390075Sobrien		 warning at -W.  Qualifiers on a void return type have
476490075Sobrien		 meaning as a GNU extension, and are banned on function
476590075Sobrien		 definitions in ISO C.  FIXME: strictly we shouldn't
476690075Sobrien		 pedwarn for qualified void return types except on function
476790075Sobrien		 definitions, but not doing so could lead to the undesirable
476890075Sobrien		 state of a "volatile void" function return type not being
476990075Sobrien		 warned about, and a use of the function being compiled
477090075Sobrien		 with GNU semantics, with no diagnostics under -pedantic.  */
477190075Sobrien	      if (VOID_TYPE_P (type) && pedantic && !in_system_header)
477290075Sobrien		pedwarn ("ISO C forbids qualified void function return type");
477390075Sobrien	      else if (extra_warnings
477490075Sobrien		       && !(VOID_TYPE_P (type)
477590075Sobrien			    && type_quals == TYPE_QUAL_VOLATILE))
477690075Sobrien		warning ("type qualifiers ignored on function return type");
477790075Sobrien
477890075Sobrien	      type = c_build_qualified_type (type, type_quals);
477990075Sobrien	    }
478052284Sobrien	  type_quals = TYPE_UNQUALIFIED;
478118334Speter
478218334Speter	  type = build_function_type (type, arg_types);
478318334Speter	  declarator = TREE_OPERAND (declarator, 0);
478418334Speter
478518334Speter	  /* Set the TYPE_CONTEXTs for each tagged type which is local to
478618334Speter	     the formal parameter list of this FUNCTION_TYPE to point to
478718334Speter	     the FUNCTION_TYPE node itself.  */
478818334Speter
478918334Speter	  {
479090075Sobrien	    tree link;
479118334Speter
479250397Sobrien	    for (link = last_function_parm_tags;
479318334Speter		 link;
479418334Speter		 link = TREE_CHAIN (link))
479518334Speter	      TYPE_CONTEXT (TREE_VALUE (link)) = type;
479618334Speter	  }
479718334Speter	}
479818334Speter      else if (TREE_CODE (declarator) == INDIRECT_REF)
479918334Speter	{
480018334Speter	  /* Merge any constancy or volatility into the target type
480118334Speter	     for the pointer.  */
480218334Speter
480318334Speter	  if (pedantic && TREE_CODE (type) == FUNCTION_TYPE
480452284Sobrien	      && type_quals)
480590075Sobrien	    pedwarn ("ISO C forbids qualified function types");
480652284Sobrien	  if (type_quals)
480752284Sobrien	    type = c_build_qualified_type (type, type_quals);
480852284Sobrien	  type_quals = TYPE_UNQUALIFIED;
480918334Speter	  size_varies = 0;
481018334Speter
481118334Speter	  type = build_pointer_type (type);
481218334Speter
481318334Speter	  /* Process a list of type modifier keywords
481418334Speter	     (such as const or volatile) that were given inside the `*'.  */
481518334Speter
481618334Speter	  if (TREE_TYPE (declarator))
481718334Speter	    {
481890075Sobrien	      tree typemodlist;
481918334Speter	      int erred = 0;
482052284Sobrien
482152284Sobrien	      constp = 0;
482252284Sobrien	      volatilep = 0;
482352284Sobrien	      restrictp = 0;
482418334Speter	      for (typemodlist = TREE_TYPE (declarator); typemodlist;
482518334Speter		   typemodlist = TREE_CHAIN (typemodlist))
482618334Speter		{
482752284Sobrien		  tree qualifier = TREE_VALUE (typemodlist);
482852284Sobrien
482990075Sobrien		  if (C_IS_RESERVED_WORD (qualifier))
483018334Speter		    {
483190075Sobrien		      if (C_RID_CODE (qualifier) == RID_CONST)
483290075Sobrien			constp++;
483390075Sobrien		      else if (C_RID_CODE (qualifier) == RID_VOLATILE)
483490075Sobrien			volatilep++;
483590075Sobrien		      else if (C_RID_CODE (qualifier) == RID_RESTRICT)
483690075Sobrien			restrictp++;
483790075Sobrien		      else
483890075Sobrien			erred++;
483918334Speter		    }
484090075Sobrien		  else
484190075Sobrien		    erred++;
484218334Speter		}
484390075Sobrien
484490075Sobrien	      if (erred)
484590075Sobrien		error ("invalid type modifier within pointer declarator");
484690075Sobrien	      if (constp > 1 && ! flag_isoc99)
484718334Speter		pedwarn ("duplicate `const'");
484890075Sobrien	      if (volatilep > 1 && ! flag_isoc99)
484918334Speter		pedwarn ("duplicate `volatile'");
485090075Sobrien	      if (restrictp > 1 && ! flag_isoc99)
485152284Sobrien		pedwarn ("duplicate `restrict'");
485252284Sobrien
485352284Sobrien	      type_quals = ((constp ? TYPE_QUAL_CONST : 0)
485452284Sobrien			    | (restrictp ? TYPE_QUAL_RESTRICT : 0)
485552284Sobrien			    | (volatilep ? TYPE_QUAL_VOLATILE : 0));
485618334Speter	    }
485718334Speter
485818334Speter	  declarator = TREE_OPERAND (declarator, 0);
485918334Speter	}
486018334Speter      else
486118334Speter	abort ();
486218334Speter
486318334Speter    }
486418334Speter
486518334Speter  /* Now TYPE has the actual type.  */
486618334Speter
486750397Sobrien  /* Did array size calculations overflow?  */
486850397Sobrien
486950397Sobrien  if (TREE_CODE (type) == ARRAY_TYPE
487090075Sobrien      && COMPLETE_TYPE_P (type)
487150397Sobrien      && TREE_OVERFLOW (TYPE_SIZE (type)))
487290075Sobrien    {
487390075Sobrien      error ("size of array `%s' is too large", name);
487490075Sobrien      /* If we proceed with the array type as it is, we'll eventually
487590075Sobrien	 crash in tree_low_cst().  */
487690075Sobrien      type = error_mark_node;
487790075Sobrien    }
487850397Sobrien
487918334Speter  /* If this is declaring a typedef name, return a TYPE_DECL.  */
488018334Speter
488118334Speter  if (specbits & (1 << (int) RID_TYPEDEF))
488218334Speter    {
488318334Speter      tree decl;
488418334Speter      /* Note that the grammar rejects storage classes
488518334Speter	 in typenames, fields or parameters */
488618334Speter      if (pedantic && TREE_CODE (type) == FUNCTION_TYPE
488752284Sobrien	  && type_quals)
488890075Sobrien	pedwarn ("ISO C forbids qualified function types");
488952284Sobrien      if (type_quals)
489052284Sobrien	type = c_build_qualified_type (type, type_quals);
489118334Speter      decl = build_decl (TYPE_DECL, declarator, type);
489218334Speter      if ((specbits & (1 << (int) RID_SIGNED))
489318334Speter	  || (typedef_decl && C_TYPEDEF_EXPLICITLY_SIGNED (typedef_decl)))
489418334Speter	C_TYPEDEF_EXPLICITLY_SIGNED (decl) = 1;
489590075Sobrien      decl_attributes (&decl, returned_attrs, 0);
489618334Speter      return decl;
489718334Speter    }
489818334Speter
489918334Speter  /* Detect the case of an array type of unspecified size
490018334Speter     which came, as such, direct from a typedef name.
490118334Speter     We must copy the type, so that each identifier gets
490218334Speter     a distinct type, so that each identifier's size can be
490318334Speter     controlled separately by its own initializer.  */
490418334Speter
490518334Speter  if (type != 0 && typedef_type != 0
490690075Sobrien      && TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type) == 0
490790075Sobrien      && TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (typedef_type))
490818334Speter    {
490918334Speter      type = build_array_type (TREE_TYPE (type), 0);
491018334Speter      if (size_varies)
491118334Speter	C_TYPE_VARIABLE_SIZE (type) = 1;
491218334Speter    }
491318334Speter
491418334Speter  /* If this is a type name (such as, in a cast or sizeof),
491518334Speter     compute the type and return it now.  */
491618334Speter
491718334Speter  if (decl_context == TYPENAME)
491818334Speter    {
491918334Speter      /* Note that the grammar rejects storage classes
492018334Speter	 in typenames, fields or parameters */
492118334Speter      if (pedantic && TREE_CODE (type) == FUNCTION_TYPE
492252284Sobrien	  && type_quals)
492390075Sobrien	pedwarn ("ISO C forbids const or volatile function types");
492452284Sobrien      if (type_quals)
492552284Sobrien	type = c_build_qualified_type (type, type_quals);
492690075Sobrien      decl_attributes (&type, returned_attrs, 0);
492718334Speter      return type;
492818334Speter    }
492918334Speter
493018334Speter  /* Aside from typedefs and type names (handle above),
493118334Speter     `void' at top level (not within pointer)
493218334Speter     is allowed only in public variables.
493318334Speter     We don't complain about parms either, but that is because
493418334Speter     a better error message can be made later.  */
493518334Speter
493690075Sobrien  if (VOID_TYPE_P (type) && decl_context != PARM
493718334Speter      && ! ((decl_context != FIELD && TREE_CODE (type) != FUNCTION_TYPE)
493818334Speter	    && ((specbits & (1 << (int) RID_EXTERN))
493918334Speter		|| (current_binding_level == global_binding_level
494018334Speter		    && !(specbits
494118334Speter			 & ((1 << (int) RID_STATIC) | (1 << (int) RID_REGISTER)))))))
494218334Speter    {
494318334Speter      error ("variable or field `%s' declared void", name);
494418334Speter      type = integer_type_node;
494518334Speter    }
494618334Speter
494718334Speter  /* Now create the decl, which may be a VAR_DECL, a PARM_DECL
494818334Speter     or a FUNCTION_DECL, depending on DECL_CONTEXT and TYPE.  */
494918334Speter
495018334Speter  {
495190075Sobrien    tree decl;
495218334Speter
495318334Speter    if (decl_context == PARM)
495418334Speter      {
495590075Sobrien	tree type_as_written;
495690075Sobrien	tree promoted_type;
495718334Speter
495818334Speter	/* A parameter declared as an array of T is really a pointer to T.
495918334Speter	   One declared as a function is really a pointer to a function.  */
496018334Speter
496118334Speter	if (TREE_CODE (type) == ARRAY_TYPE)
496218334Speter	  {
496318334Speter	    /* Transfer const-ness of array into that of type pointed to.  */
496418334Speter	    type = TREE_TYPE (type);
496552284Sobrien	    if (type_quals)
496652284Sobrien	      type = c_build_qualified_type (type, type_quals);
496718334Speter	    type = build_pointer_type (type);
496852284Sobrien	    type_quals = TYPE_UNQUALIFIED;
496990075Sobrien	    if (array_ptr_quals)
497090075Sobrien	      {
497190075Sobrien		tree new_ptr_quals, new_ptr_attrs;
497290075Sobrien		int erred = 0;
497390075Sobrien		split_specs_attrs (array_ptr_quals, &new_ptr_quals, &new_ptr_attrs);
497490075Sobrien		/* We don't yet implement attributes in this context.  */
497590075Sobrien		if (new_ptr_attrs != NULL_TREE)
497690075Sobrien		  warning ("attributes in parameter array declarator ignored");
497790075Sobrien
497890075Sobrien		constp = 0;
497990075Sobrien		volatilep = 0;
498090075Sobrien		restrictp = 0;
498190075Sobrien		for (; new_ptr_quals; new_ptr_quals = TREE_CHAIN (new_ptr_quals))
498290075Sobrien		  {
498390075Sobrien		    tree qualifier = TREE_VALUE (new_ptr_quals);
498490075Sobrien
498590075Sobrien		    if (C_IS_RESERVED_WORD (qualifier))
498690075Sobrien		      {
498790075Sobrien			if (C_RID_CODE (qualifier) == RID_CONST)
498890075Sobrien			  constp++;
498990075Sobrien			else if (C_RID_CODE (qualifier) == RID_VOLATILE)
499090075Sobrien			  volatilep++;
499190075Sobrien			else if (C_RID_CODE (qualifier) == RID_RESTRICT)
499290075Sobrien			  restrictp++;
499390075Sobrien			else
499490075Sobrien			  erred++;
499590075Sobrien		      }
499690075Sobrien		    else
499790075Sobrien		      erred++;
499890075Sobrien		  }
499990075Sobrien
500090075Sobrien		if (erred)
500190075Sobrien		  error ("invalid type modifier within array declarator");
500290075Sobrien
500390075Sobrien		type_quals = ((constp ? TYPE_QUAL_CONST : 0)
500490075Sobrien			      | (restrictp ? TYPE_QUAL_RESTRICT : 0)
500590075Sobrien			      | (volatilep ? TYPE_QUAL_VOLATILE : 0));
500690075Sobrien	      }
500718334Speter	    size_varies = 0;
500818334Speter	  }
500918334Speter	else if (TREE_CODE (type) == FUNCTION_TYPE)
501018334Speter	  {
501152284Sobrien	    if (pedantic && type_quals)
501290075Sobrien	      pedwarn ("ISO C forbids qualified function types");
501352284Sobrien	    if (type_quals)
501452284Sobrien	      type = c_build_qualified_type (type, type_quals);
501518334Speter	    type = build_pointer_type (type);
501652284Sobrien	    type_quals = TYPE_UNQUALIFIED;
501718334Speter	  }
501890075Sobrien	else if (type_quals)
501990075Sobrien	  type = c_build_qualified_type (type, type_quals);
502090075Sobrien
502190075Sobrien	type_as_written = type;
502218334Speter
502318334Speter	decl = build_decl (PARM_DECL, declarator, type);
502418334Speter	if (size_varies)
502518334Speter	  C_DECL_VARIABLE_SIZE (decl) = 1;
502618334Speter
502718334Speter	/* Compute the type actually passed in the parmlist,
502818334Speter	   for the case where there is no prototype.
502918334Speter	   (For example, shorts and chars are passed as ints.)
503018334Speter	   When there is a prototype, this is overridden later.  */
503118334Speter
503290075Sobrien	if (type == error_mark_node)
503390075Sobrien	  promoted_type = type;
503490075Sobrien	else
503518334Speter	  {
503690075Sobrien	    promoted_type = simple_type_promotes_to (type);
503790075Sobrien	    if (! promoted_type)
503890075Sobrien	      promoted_type = type;
503918334Speter	  }
504018334Speter
504190075Sobrien	DECL_ARG_TYPE (decl) = promoted_type;
504218334Speter	DECL_ARG_TYPE_AS_WRITTEN (decl) = type_as_written;
504318334Speter      }
504418334Speter    else if (decl_context == FIELD)
504518334Speter      {
504618334Speter	/* Structure field.  It may not be a function.  */
504796263Sobrien
504818334Speter	if (TREE_CODE (type) == FUNCTION_TYPE)
504918334Speter	  {
505018334Speter	    error ("field `%s' declared as a function", name);
505118334Speter	    type = build_pointer_type (type);
505218334Speter	  }
505390075Sobrien	else if (TREE_CODE (type) != ERROR_MARK
505490075Sobrien	         && !COMPLETE_OR_UNBOUND_ARRAY_TYPE_P (type))
505518334Speter	  {
505618334Speter	    error ("field `%s' has incomplete type", name);
505718334Speter	    type = error_mark_node;
505818334Speter	  }
505918334Speter	/* Move type qualifiers down to element of an array.  */
506052284Sobrien	if (TREE_CODE (type) == ARRAY_TYPE && type_quals)
506118334Speter	  {
506252284Sobrien	    type = build_array_type (c_build_qualified_type (TREE_TYPE (type),
506352284Sobrien							     type_quals),
506418334Speter				     TYPE_DOMAIN (type));
506590075Sobrien#if 0
506690075Sobrien	    /* Leave the field const or volatile as well.  */
506752284Sobrien	    type_quals = TYPE_UNQUALIFIED;
506818334Speter#endif
506918334Speter	  }
507018334Speter	decl = build_decl (FIELD_DECL, declarator, type);
507190075Sobrien	DECL_NONADDRESSABLE_P (decl) = bitfield;
507290075Sobrien
507318334Speter	if (size_varies)
507418334Speter	  C_DECL_VARIABLE_SIZE (decl) = 1;
507518334Speter      }
507618334Speter    else if (TREE_CODE (type) == FUNCTION_TYPE)
507718334Speter      {
507818334Speter	/* Every function declaration is "external"
507918334Speter	   except for those which are inside a function body
508018334Speter	   in which `auto' is used.
508118334Speter	   That is a case not specified by ANSI C,
508218334Speter	   and we use it for forward declarations for nested functions.  */
508318334Speter	int extern_ref = (!(specbits & (1 << (int) RID_AUTO))
508418334Speter			  || current_binding_level == global_binding_level);
508518334Speter
508618334Speter	if (specbits & (1 << (int) RID_AUTO)
508718334Speter	    && (pedantic || current_binding_level == global_binding_level))
508818334Speter	  pedwarn ("invalid storage class for function `%s'", name);
508918334Speter	if (specbits & (1 << (int) RID_REGISTER))
509018334Speter	  error ("invalid storage class for function `%s'", name);
509118334Speter	/* Function declaration not at top level.
509218334Speter	   Storage classes other than `extern' are not allowed
509318334Speter	   and `extern' makes no difference.  */
509418334Speter	if (current_binding_level != global_binding_level
509518334Speter	    && (specbits & ((1 << (int) RID_STATIC) | (1 << (int) RID_INLINE)))
509618334Speter	    && pedantic)
509718334Speter	  pedwarn ("invalid storage class for function `%s'", name);
509818334Speter
509918334Speter	decl = build_decl (FUNCTION_DECL, declarator, type);
510090075Sobrien	decl = build_decl_attribute_variant (decl, decl_attr);
510118334Speter
510290075Sobrien	DECL_LANG_SPECIFIC (decl) = (struct lang_decl *)
510390075Sobrien	  ggc_alloc_cleared (sizeof (struct lang_decl));
510490075Sobrien
510552284Sobrien	if (pedantic && type_quals && ! DECL_IN_SYSTEM_HEADER (decl))
510690075Sobrien	  pedwarn ("ISO C forbids qualified function types");
510718334Speter
510852284Sobrien	/* GNU C interprets a `volatile void' return type to indicate
510952284Sobrien	   that the function does not return.  */
511052284Sobrien	if ((type_quals & TYPE_QUAL_VOLATILE)
511190075Sobrien	    && !VOID_TYPE_P (TREE_TYPE (TREE_TYPE (decl))))
511218334Speter	  warning ("`noreturn' function returns non-void value");
511318334Speter
511418334Speter	if (extern_ref)
511518334Speter	  DECL_EXTERNAL (decl) = 1;
511618334Speter	/* Record absence of global scope for `static' or `auto'.  */
511718334Speter	TREE_PUBLIC (decl)
511818334Speter	  = !(specbits & ((1 << (int) RID_STATIC) | (1 << (int) RID_AUTO)));
511918334Speter
512096263Sobrien	if (defaulted_int)
512196263Sobrien	  C_FUNCTION_IMPLICIT_INT (decl) = 1;
512296263Sobrien
512318334Speter	/* Record presence of `inline', if it is reasonable.  */
512490075Sobrien	if (MAIN_NAME_P (declarator))
512518334Speter	  {
512690075Sobrien	    if (inlinep)
512718334Speter	      warning ("cannot inline function `main'");
512890075Sobrien	  }
512990075Sobrien	else if (inlinep)
513090075Sobrien	  {
513190075Sobrien	    /* Assume that otherwise the function can be inlined.  */
513290075Sobrien	    DECL_DECLARED_INLINE_P (decl) = 1;
513318334Speter
513490075Sobrien	    /* Do not mark bare declarations as DECL_INLINE.  Doing so
513590075Sobrien	       in the presence of multiple declarations can result in
513690075Sobrien	       the abstract origin pointing between the declarations,
513790075Sobrien	       which will confuse dwarf2out.  */
513890075Sobrien	    if (initialized)
513990075Sobrien	      {
514090075Sobrien		DECL_INLINE (decl) = 1;
514190075Sobrien		if (specbits & (1 << (int) RID_EXTERN))
514290075Sobrien		  current_extern_inline = 1;
514390075Sobrien	      }
514418334Speter	  }
514590075Sobrien	/* If -finline-functions, assume it can be inlined.  This does
514690075Sobrien	   two things: let the function be deferred until it is actually
514790075Sobrien	   needed, and let dwarf2 know that the function is inlinable.  */
514890075Sobrien	else if (flag_inline_trees == 2 && initialized)
514990075Sobrien	  {
515090075Sobrien	    DECL_INLINE (decl) = 1;
515190075Sobrien	    DECL_DECLARED_INLINE_P (decl) = 0;
515290075Sobrien	  }
515318334Speter      }
515418334Speter    else
515518334Speter      {
515618334Speter	/* It's a variable.  */
515718334Speter	/* An uninitialized decl with `extern' is a reference.  */
515818334Speter	int extern_ref = !initialized && (specbits & (1 << (int) RID_EXTERN));
515918334Speter
516018334Speter	/* Move type qualifiers down to element of an array.  */
516152284Sobrien	if (TREE_CODE (type) == ARRAY_TYPE && type_quals)
516218334Speter	  {
516390075Sobrien	    int saved_align = TYPE_ALIGN(type);
516452284Sobrien	    type = build_array_type (c_build_qualified_type (TREE_TYPE (type),
516552284Sobrien							     type_quals),
516618334Speter				     TYPE_DOMAIN (type));
516790075Sobrien	    TYPE_ALIGN (type) = saved_align;
516818334Speter#if 0 /* Leave the variable const or volatile as well.  */
516952284Sobrien	    type_quals = TYPE_UNQUALIFIED;
517018334Speter#endif
517118334Speter	  }
517290075Sobrien	else if (type_quals)
517390075Sobrien	  type = c_build_qualified_type (type, type_quals);
517490075Sobrien
517518334Speter	decl = build_decl (VAR_DECL, declarator, type);
517618334Speter	if (size_varies)
517718334Speter	  C_DECL_VARIABLE_SIZE (decl) = 1;
517818334Speter
517918334Speter	if (inlinep)
518018334Speter	  pedwarn_with_decl (decl, "variable `%s' declared `inline'");
518118334Speter
518218334Speter	DECL_EXTERNAL (decl) = extern_ref;
518318334Speter	/* At top level, the presence of a `static' or `register' storage
518418334Speter	   class specifier, or the absence of all storage class specifiers
518518334Speter	   makes this declaration a definition (perhaps tentative).  Also,
518618334Speter	   the absence of both `static' and `register' makes it public.  */
518718334Speter	if (current_binding_level == global_binding_level)
518818334Speter	  {
518918334Speter	    TREE_PUBLIC (decl)
519018334Speter	      = !(specbits
519118334Speter		  & ((1 << (int) RID_STATIC) | (1 << (int) RID_REGISTER)));
519218334Speter	    TREE_STATIC (decl) = ! DECL_EXTERNAL (decl);
519318334Speter	  }
519418334Speter	/* Not at top level, only `static' makes a static definition.  */
519518334Speter	else
519618334Speter	  {
519718334Speter	    TREE_STATIC (decl) = (specbits & (1 << (int) RID_STATIC)) != 0;
519818334Speter	    TREE_PUBLIC (decl) = DECL_EXTERNAL (decl);
519918334Speter	  }
520018334Speter      }
520118334Speter
520218334Speter    /* Record `register' declaration for warnings on &
520318334Speter       and in case doing stupid register allocation.  */
520418334Speter
520518334Speter    if (specbits & (1 << (int) RID_REGISTER))
520618334Speter      DECL_REGISTER (decl) = 1;
520718334Speter
520818334Speter    /* Record constancy and volatility.  */
520952284Sobrien    c_apply_type_quals_to_decl (type_quals, decl);
521018334Speter
521118334Speter    /* If a type has volatile components, it should be stored in memory.
521218334Speter       Otherwise, the fact that those components are volatile
521318334Speter       will be ignored, and would even crash the compiler.  */
521418334Speter    if (C_TYPE_FIELDS_VOLATILE (TREE_TYPE (decl)))
521518334Speter      mark_addressable (decl);
521618334Speter
521790075Sobrien    decl_attributes (&decl, returned_attrs, 0);
521818334Speter
521918334Speter    return decl;
522018334Speter  }
522118334Speter}
522218334Speter
522318334Speter/* Decode the parameter-list info for a function type or function definition.
522418334Speter   The argument is the value returned by `get_parm_info' (or made in parse.y
522518334Speter   if there is an identifier list instead of a parameter decl list).
522618334Speter   These two functions are separate because when a function returns
522718334Speter   or receives functions then each is called multiple times but the order
522818334Speter   of calls is different.  The last call to `grokparms' is always the one
522918334Speter   that contains the formal parameter names of a function definition.
523018334Speter
523118334Speter   Store in `last_function_parms' a chain of the decls of parms.
523218334Speter   Also store in `last_function_parm_tags' a chain of the struct, union,
523318334Speter   and enum tags declared among the parms.
523418334Speter
523518334Speter   Return a list of arg types to use in the FUNCTION_TYPE for this function.
523618334Speter
523718334Speter   FUNCDEF_FLAG is nonzero for a function definition, 0 for
523818334Speter   a mere declaration.  A nonempty identifier-list gets an error message
523918334Speter   when FUNCDEF_FLAG is zero.  */
524018334Speter
524118334Speterstatic tree
524218334Spetergrokparms (parms_info, funcdef_flag)
524318334Speter     tree parms_info;
524418334Speter     int funcdef_flag;
524518334Speter{
524618334Speter  tree first_parm = TREE_CHAIN (parms_info);
524718334Speter
524818334Speter  last_function_parms = TREE_PURPOSE (parms_info);
524918334Speter  last_function_parm_tags = TREE_VALUE (parms_info);
525018334Speter
525118334Speter  if (warn_strict_prototypes && first_parm == 0 && !funcdef_flag
525218334Speter      && !in_system_header)
525318334Speter    warning ("function declaration isn't a prototype");
525418334Speter
525518334Speter  if (first_parm != 0
525618334Speter      && TREE_CODE (TREE_VALUE (first_parm)) == IDENTIFIER_NODE)
525718334Speter    {
525818334Speter      if (! funcdef_flag)
525918334Speter	pedwarn ("parameter names (without types) in function declaration");
526018334Speter
526118334Speter      last_function_parms = first_parm;
526218334Speter      return 0;
526318334Speter    }
526418334Speter  else
526518334Speter    {
526618334Speter      tree parm;
526718334Speter      tree typelt;
526818334Speter      /* We no longer test FUNCDEF_FLAG.
526918334Speter	 If the arg types are incomplete in a declaration,
527018334Speter	 they must include undefined tags.
527118334Speter	 These tags can never be defined in the scope of the declaration,
527218334Speter	 so the types can never be completed,
527318334Speter	 and no call can be compiled successfully.  */
527418334Speter#if 0
527518334Speter      /* In a fcn definition, arg types must be complete.  */
527618334Speter      if (funcdef_flag)
527718334Speter#endif
527818334Speter	for (parm = last_function_parms, typelt = first_parm;
527918334Speter	     parm;
528018334Speter	     parm = TREE_CHAIN (parm))
528118334Speter	  /* Skip over any enumeration constants declared here.  */
528218334Speter	  if (TREE_CODE (parm) == PARM_DECL)
528318334Speter	    {
528418334Speter	      /* Barf if the parameter itself has an incomplete type.  */
528518334Speter	      tree type = TREE_VALUE (typelt);
528690075Sobrien	      if (type == error_mark_node)
528790075Sobrien		continue;
528890075Sobrien	      if (!COMPLETE_TYPE_P (type))
528918334Speter		{
529018334Speter		  if (funcdef_flag && DECL_NAME (parm) != 0)
529118334Speter		    error ("parameter `%s' has incomplete type",
529218334Speter			   IDENTIFIER_POINTER (DECL_NAME (parm)));
529318334Speter		  else
529418334Speter		    warning ("parameter has incomplete type");
529518334Speter		  if (funcdef_flag)
529618334Speter		    {
529718334Speter		      TREE_VALUE (typelt) = error_mark_node;
529818334Speter		      TREE_TYPE (parm) = error_mark_node;
529918334Speter		    }
530018334Speter		}
530190075Sobrien#if 0
530290075Sobrien	      /* This has been replaced by parm_tags_warning, which
530390075Sobrien		 uses a more accurate criterion for what to warn
530490075Sobrien		 about.  */
530518334Speter	      else
530618334Speter		{
530718334Speter		  /* Now warn if is a pointer to an incomplete type.  */
530818334Speter		  while (TREE_CODE (type) == POINTER_TYPE
530918334Speter			 || TREE_CODE (type) == REFERENCE_TYPE)
531018334Speter		    type = TREE_TYPE (type);
531118334Speter		  type = TYPE_MAIN_VARIANT (type);
531290075Sobrien		  if (!COMPLETE_TYPE_P (type))
531318334Speter		    {
531418334Speter		      if (DECL_NAME (parm) != 0)
531518334Speter			warning ("parameter `%s' points to incomplete type",
531618334Speter				 IDENTIFIER_POINTER (DECL_NAME (parm)));
531718334Speter		      else
531818334Speter			warning ("parameter points to incomplete type");
531918334Speter		    }
532018334Speter		}
532118334Speter#endif
532218334Speter	      typelt = TREE_CHAIN (typelt);
532318334Speter	    }
532418334Speter
532590075Sobrien      return first_parm;
532618334Speter    }
532718334Speter}
532818334Speter
532918334Speter/* Return a tree_list node with info on a parameter list just parsed.
533018334Speter   The TREE_PURPOSE is a chain of decls of those parms.
533118334Speter   The TREE_VALUE is a list of structure, union and enum tags defined.
533218334Speter   The TREE_CHAIN is a list of argument types to go in the FUNCTION_TYPE.
533318334Speter   This tree_list node is later fed to `grokparms'.
533418334Speter
533518334Speter   VOID_AT_END nonzero means append `void' to the end of the type-list.
533618334Speter   Zero means the parmlist ended with an ellipsis so don't append `void'.  */
533718334Speter
533818334Spetertree
533918334Speterget_parm_info (void_at_end)
534018334Speter     int void_at_end;
534118334Speter{
534290075Sobrien  tree decl, t;
534390075Sobrien  tree types = 0;
534418334Speter  int erred = 0;
534518334Speter  tree tags = gettags ();
534618334Speter  tree parms = getdecls ();
534718334Speter  tree new_parms = 0;
534818334Speter  tree order = current_binding_level->parm_order;
534918334Speter
535090075Sobrien  /* Just `void' (and no ellipsis) is special.  There are really no parms.
535190075Sobrien     But if the `void' is qualified (by `const' or `volatile') or has a
535290075Sobrien     storage class specifier (`register'), then the behavior is undefined;
535390075Sobrien     by not counting it as the special case of `void' we will cause an
535490075Sobrien     error later.  Typedefs for `void' are OK (see DR#157).  */
535518334Speter  if (void_at_end && parms != 0
535618334Speter      && TREE_CHAIN (parms) == 0
535790075Sobrien      && VOID_TYPE_P (TREE_TYPE (parms))
535890075Sobrien      && ! TREE_THIS_VOLATILE (parms)
535990075Sobrien      && ! TREE_READONLY (parms)
536090075Sobrien      && ! DECL_REGISTER (parms)
536118334Speter      && DECL_NAME (parms) == 0)
536218334Speter    {
536318334Speter      parms = NULL_TREE;
536418334Speter      storedecls (NULL_TREE);
536590075Sobrien      return tree_cons (NULL_TREE, NULL_TREE,
536690075Sobrien			tree_cons (NULL_TREE, void_type_node, NULL_TREE));
536718334Speter    }
536818334Speter
536918334Speter  /* Extract enumerator values and other non-parms declared with the parms.
537018334Speter     Likewise any forward parm decls that didn't have real parm decls.  */
537190075Sobrien  for (decl = parms; decl;)
537218334Speter    {
537318334Speter      tree next = TREE_CHAIN (decl);
537418334Speter
537518334Speter      if (TREE_CODE (decl) != PARM_DECL)
537618334Speter	{
537718334Speter	  TREE_CHAIN (decl) = new_parms;
537818334Speter	  new_parms = decl;
537918334Speter	}
538018334Speter      else if (TREE_ASM_WRITTEN (decl))
538118334Speter	{
538290075Sobrien	  error_with_decl (decl,
538390075Sobrien			   "parameter `%s' has just a forward declaration");
538418334Speter	  TREE_CHAIN (decl) = new_parms;
538518334Speter	  new_parms = decl;
538618334Speter	}
538718334Speter      decl = next;
538818334Speter    }
538918334Speter
539018334Speter  /* Put the parm decls back in the order they were in in the parm list.  */
539118334Speter  for (t = order; t; t = TREE_CHAIN (t))
539218334Speter    {
539318334Speter      if (TREE_CHAIN (t))
539418334Speter	TREE_CHAIN (TREE_VALUE (t)) = TREE_VALUE (TREE_CHAIN (t));
539518334Speter      else
539618334Speter	TREE_CHAIN (TREE_VALUE (t)) = 0;
539718334Speter    }
539818334Speter
539918334Speter  new_parms = chainon (order ? nreverse (TREE_VALUE (order)) : 0,
540018334Speter		       new_parms);
540118334Speter
540218334Speter  /* Store the parmlist in the binding level since the old one
540318334Speter     is no longer a valid list.  (We have changed the chain pointers.)  */
540418334Speter  storedecls (new_parms);
540518334Speter
540618334Speter  for (decl = new_parms; decl; decl = TREE_CHAIN (decl))
540718334Speter    /* There may also be declarations for enumerators if an enumeration
540818334Speter       type is declared among the parms.  Ignore them here.  */
540918334Speter    if (TREE_CODE (decl) == PARM_DECL)
541018334Speter      {
541118334Speter	/* Since there is a prototype,
541218334Speter	   args are passed in their declared types.  */
541318334Speter	tree type = TREE_TYPE (decl);
541418334Speter	DECL_ARG_TYPE (decl) = type;
541590075Sobrien	if (PROMOTE_PROTOTYPES
541690075Sobrien	    && INTEGRAL_TYPE_P (type)
541718334Speter	    && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))
541818334Speter	  DECL_ARG_TYPE (decl) = integer_type_node;
541918334Speter
542090075Sobrien	types = tree_cons (NULL_TREE, TREE_TYPE (decl), types);
542190075Sobrien	if (VOID_TYPE_P (TREE_VALUE (types)) && ! erred
542218334Speter	    && DECL_NAME (decl) == 0)
542318334Speter	  {
542418334Speter	    error ("`void' in parameter list must be the entire list");
542518334Speter	    erred = 1;
542618334Speter	  }
542718334Speter      }
542818334Speter
542918334Speter  if (void_at_end)
543090075Sobrien    return tree_cons (new_parms, tags,
543190075Sobrien		      nreverse (tree_cons (NULL_TREE, void_type_node, types)));
543218334Speter
543390075Sobrien  return tree_cons (new_parms, tags, nreverse (types));
543418334Speter}
543518334Speter
543618334Speter/* At end of parameter list, warn about any struct, union or enum tags
543718334Speter   defined within.  Do so because these types cannot ever become complete.  */
543818334Speter
543918334Spetervoid
544018334Speterparmlist_tags_warning ()
544118334Speter{
544218334Speter  tree elt;
544318334Speter  static int already;
544418334Speter
544518334Speter  for (elt = current_binding_level->tags; elt; elt = TREE_CHAIN (elt))
544618334Speter    {
544718334Speter      enum tree_code code = TREE_CODE (TREE_VALUE (elt));
544818334Speter      /* An anonymous union parm type is meaningful as a GNU extension.
544918334Speter	 So don't warn for that.  */
545050397Sobrien      if (code == UNION_TYPE && TREE_PURPOSE (elt) == 0 && !pedantic)
545118334Speter	continue;
545218334Speter      if (TREE_PURPOSE (elt) != 0)
545390075Sobrien        {
545490075Sobrien          if (code == RECORD_TYPE)
545590075Sobrien            warning ("`struct %s' declared inside parameter list",
545690075Sobrien                     IDENTIFIER_POINTER (TREE_PURPOSE (elt)));
545790075Sobrien          else if (code == UNION_TYPE)
545890075Sobrien            warning ("`union %s' declared inside parameter list",
545990075Sobrien                     IDENTIFIER_POINTER (TREE_PURPOSE (elt)));
546090075Sobrien          else
546190075Sobrien            warning ("`enum %s' declared inside parameter list",
546290075Sobrien                     IDENTIFIER_POINTER (TREE_PURPOSE (elt)));
546390075Sobrien        }
546418334Speter      else
546590075Sobrien	{
546690075Sobrien	  /* For translation these need to be separate warnings */
546790075Sobrien	  if (code == RECORD_TYPE)
546890075Sobrien	    warning ("anonymous struct declared inside parameter list");
546990075Sobrien	  else if (code == UNION_TYPE)
547090075Sobrien	    warning ("anonymous union declared inside parameter list");
547190075Sobrien	  else
547290075Sobrien	    warning ("anonymous enum declared inside parameter list");
547390075Sobrien	}
547418334Speter      if (! already)
547518334Speter	{
547690075Sobrien	  warning ("its scope is only this definition or declaration, which is probably not what you want");
547718334Speter	  already = 1;
547818334Speter	}
547918334Speter    }
548018334Speter}
548118334Speter
548218334Speter/* Get the struct, enum or union (CODE says which) with tag NAME.
548318334Speter   Define the tag as a forward-reference if it is not defined.  */
548418334Speter
548518334Spetertree
548618334Speterxref_tag (code, name)
548718334Speter     enum tree_code code;
548818334Speter     tree name;
548918334Speter{
549018334Speter  /* If a cross reference is requested, look up the type
549118334Speter     already defined for this tag and return it.  */
549218334Speter
549390075Sobrien  tree ref = lookup_tag (code, name, current_binding_level, 0);
549490075Sobrien  /* If this is the right type of tag, return what we found.
549590075Sobrien     (This reference will be shadowed by shadow_tag later if appropriate.)
549690075Sobrien     If this is the wrong type of tag, do not return it.  If it was the
549790075Sobrien     wrong type in the same binding level, we will have had an error
549890075Sobrien     message already; if in a different binding level and declaring
549990075Sobrien     a name, pending_xref_error will give an error message; but if in a
550090075Sobrien     different binding level and not declaring a name, this tag should
550190075Sobrien     shadow the previous declaration of a different type of tag, and
550290075Sobrien     this would not work properly if we return the reference found.
550390075Sobrien     (For example, with "struct foo" in an outer scope, "union foo;"
550490075Sobrien     must shadow that tag with a new one of union type.)  */
550590075Sobrien  if (ref && TREE_CODE (ref) == code)
550618334Speter    return ref;
550718334Speter
550818334Speter  /* If no such tag is yet defined, create a forward-reference node
550918334Speter     and record it as the "definition".
551018334Speter     When a real declaration of this type is found,
551118334Speter     the forward-reference will be altered into a real type.  */
551218334Speter
551318334Speter  ref = make_node (code);
551418334Speter  if (code == ENUMERAL_TYPE)
551518334Speter    {
551618334Speter      /* Give the type a default layout like unsigned int
551718334Speter	 to avoid crashing if it does not get defined.  */
551818334Speter      TYPE_MODE (ref) = TYPE_MODE (unsigned_type_node);
551918334Speter      TYPE_ALIGN (ref) = TYPE_ALIGN (unsigned_type_node);
552090075Sobrien      TYPE_USER_ALIGN (ref) = 0;
552118334Speter      TREE_UNSIGNED (ref) = 1;
552218334Speter      TYPE_PRECISION (ref) = TYPE_PRECISION (unsigned_type_node);
552318334Speter      TYPE_MIN_VALUE (ref) = TYPE_MIN_VALUE (unsigned_type_node);
552418334Speter      TYPE_MAX_VALUE (ref) = TYPE_MAX_VALUE (unsigned_type_node);
552518334Speter    }
552618334Speter
552718334Speter  pushtag (name, ref);
552818334Speter
552918334Speter  return ref;
553018334Speter}
553118334Speter
553218334Speter/* Make sure that the tag NAME is defined *in the current binding level*
553318334Speter   at least as a forward reference.
553490075Sobrien   CODE says which kind of tag NAME ought to be.  */
553518334Speter
553618334Spetertree
553718334Speterstart_struct (code, name)
553818334Speter     enum tree_code code;
553918334Speter     tree name;
554018334Speter{
554118334Speter  /* If there is already a tag defined at this binding level
554218334Speter     (as a forward reference), just return it.  */
554318334Speter
554490075Sobrien  tree ref = 0;
554518334Speter
554618334Speter  if (name != 0)
554718334Speter    ref = lookup_tag (code, name, current_binding_level, 1);
554818334Speter  if (ref && TREE_CODE (ref) == code)
554918334Speter    {
555018334Speter      C_TYPE_BEING_DEFINED (ref) = 1;
555150397Sobrien      TYPE_PACKED (ref) = flag_pack_struct;
555218334Speter      if (TYPE_FIELDS (ref))
555390075Sobrien        {
555490075Sobrien	  if (code == UNION_TYPE)
555590075Sobrien	    error ("redefinition of `union %s'",
555690075Sobrien		   IDENTIFIER_POINTER (name));
555790075Sobrien          else
555890075Sobrien	    error ("redefinition of `struct %s'",
555990075Sobrien		   IDENTIFIER_POINTER (name));
556090075Sobrien	}
556118334Speter
556218334Speter      return ref;
556318334Speter    }
556418334Speter
556518334Speter  /* Otherwise create a forward-reference just so the tag is in scope.  */
556618334Speter
556718334Speter  ref = make_node (code);
556818334Speter  pushtag (name, ref);
556918334Speter  C_TYPE_BEING_DEFINED (ref) = 1;
557050397Sobrien  TYPE_PACKED (ref) = flag_pack_struct;
557118334Speter  return ref;
557218334Speter}
557318334Speter
557418334Speter/* Process the specs, declarator (NULL if omitted) and width (NULL if omitted)
557518334Speter   of a structure component, returning a FIELD_DECL node.
557696263Sobrien   WIDTH is non-NULL for bit fields only, and is an INTEGER_CST node.
557718334Speter
557818334Speter   This is done during the parsing of the struct declaration.
557918334Speter   The FIELD_DECL nodes are chained together and the lot of them
558018334Speter   are ultimately passed to `build_struct' to make the RECORD_TYPE node.  */
558118334Speter
558218334Spetertree
558318334Spetergrokfield (filename, line, declarator, declspecs, width)
558452284Sobrien     const char *filename ATTRIBUTE_UNUSED;
558552284Sobrien     int line ATTRIBUTE_UNUSED;
558618334Speter     tree declarator, declspecs, width;
558718334Speter{
558818334Speter  tree value;
558918334Speter
559090075Sobrien  if (declarator == NULL_TREE && width == NULL_TREE)
559190075Sobrien    {
559290075Sobrien      /* This is an unnamed decl.  We only support unnamed
559390075Sobrien	 structs/unions, so check for other things and refuse them.  */
559490075Sobrien      if (TREE_CODE (TREE_VALUE (declspecs)) != RECORD_TYPE
559590075Sobrien	  && TREE_CODE (TREE_VALUE (declspecs)) != UNION_TYPE)
559690075Sobrien	{
559790075Sobrien	  error ("unnamed fields of type other than struct or union are not allowed");
559890075Sobrien	  return NULL_TREE;
559990075Sobrien	}
560090075Sobrien    }
560118334Speter
560296263Sobrien  value = grokdeclarator (declarator, declspecs, width ? BITFIELD : FIELD, 0);
560318334Speter
560418334Speter  finish_decl (value, NULL_TREE, NULL_TREE);
560596263Sobrien  DECL_INITIAL (value) = width;
560618334Speter
560718334Speter  maybe_objc_check_decl (value);
560818334Speter  return value;
560918334Speter}
561018334Speter
561118334Speter/* Fill in the fields of a RECORD_TYPE or UNION_TYPE node, T.
561218334Speter   FIELDLIST is a chain of FIELD_DECL nodes for the fields.
561390075Sobrien   ATTRIBUTES are attributes to be applied to the structure.  */
561418334Speter
561518334Spetertree
561618334Speterfinish_struct (t, fieldlist, attributes)
561718334Speter     tree t;
561818334Speter     tree fieldlist;
561918334Speter     tree attributes;
562018334Speter{
562190075Sobrien  tree x;
562218334Speter  int toplevel = global_binding_level == current_binding_level;
562390075Sobrien  int saw_named_field;
562418334Speter
562518334Speter  /* If this type was previously laid out as a forward reference,
562618334Speter     make sure we lay it out again.  */
562718334Speter
562818334Speter  TYPE_SIZE (t) = 0;
562918334Speter
563090075Sobrien  decl_attributes (&t, attributes, (int) ATTR_FLAG_TYPE_IN_PLACE);
563118334Speter
563218334Speter  /* Nameless union parm types are useful as GCC extension.  */
563318334Speter  if (! (TREE_CODE (t) == UNION_TYPE && TYPE_NAME (t) == 0) && !pedantic)
563418334Speter    /* Otherwise, warn about any struct or union def. in parmlist.  */
563518334Speter    if (in_parm_level_p ())
563618334Speter      {
563718334Speter	if (pedantic)
563890075Sobrien	  pedwarn ("%s defined inside parms",
563990075Sobrien		   TREE_CODE (t) == UNION_TYPE ? _("union") : _("structure"));
564018334Speter	else if (! flag_traditional)
564190075Sobrien	  warning ("%s defined inside parms",
564290075Sobrien		   TREE_CODE (t) == UNION_TYPE ? _("union") : _("structure"));
564318334Speter      }
564418334Speter
564550397Sobrien  if (pedantic)
564650397Sobrien    {
564750397Sobrien      for (x = fieldlist; x; x = TREE_CHAIN (x))
564850397Sobrien	if (DECL_NAME (x) != 0)
564950397Sobrien	  break;
565018334Speter
565150397Sobrien      if (x == 0)
565290075Sobrien	pedwarn ("%s has no %s",
565390075Sobrien		 TREE_CODE (t) == UNION_TYPE ? _("union") : _("struct"),
565490075Sobrien		 fieldlist ? _("named members") : _("members"));
565550397Sobrien    }
565650397Sobrien
565796263Sobrien  /* Install struct as DECL_CONTEXT of each field decl.
565896263Sobrien     Also process specified field sizes,m which is found in the DECL_INITIAL.
565996263Sobrien     Store 0 there, except for ": 0" fields (so we can find them
566096263Sobrien     and delete them, below).  */
566118334Speter
566290075Sobrien  saw_named_field = 0;
566318334Speter  for (x = fieldlist; x; x = TREE_CHAIN (x))
566418334Speter    {
566518334Speter      DECL_CONTEXT (x) = t;
566618334Speter      DECL_PACKED (x) |= TYPE_PACKED (t);
566718334Speter
566818334Speter      /* If any field is const, the structure type is pseudo-const.  */
566918334Speter      if (TREE_READONLY (x))
567018334Speter	C_TYPE_FIELDS_READONLY (t) = 1;
567118334Speter      else
567218334Speter	{
567318334Speter	  /* A field that is pseudo-const makes the structure likewise.  */
567418334Speter	  tree t1 = TREE_TYPE (x);
567518334Speter	  while (TREE_CODE (t1) == ARRAY_TYPE)
567618334Speter	    t1 = TREE_TYPE (t1);
567718334Speter	  if ((TREE_CODE (t1) == RECORD_TYPE || TREE_CODE (t1) == UNION_TYPE)
567818334Speter	      && C_TYPE_FIELDS_READONLY (t1))
567918334Speter	    C_TYPE_FIELDS_READONLY (t) = 1;
568018334Speter	}
568118334Speter
568218334Speter      /* Any field that is volatile means variables of this type must be
568318334Speter	 treated in some ways as volatile.  */
568418334Speter      if (TREE_THIS_VOLATILE (x))
568518334Speter	C_TYPE_FIELDS_VOLATILE (t) = 1;
568618334Speter
568718334Speter      /* Any field of nominal variable size implies structure is too.  */
568818334Speter      if (C_DECL_VARIABLE_SIZE (x))
568918334Speter	C_TYPE_VARIABLE_SIZE (t) = 1;
569018334Speter
569118334Speter      /* Detect invalid nested redefinition.  */
569218334Speter      if (TREE_TYPE (x) == t)
569318334Speter	error ("nested redefinition of `%s'",
569418334Speter	       IDENTIFIER_POINTER (TYPE_NAME (t)));
569518334Speter
569696263Sobrien      /* Detect invalid bit-field size.  */
569796263Sobrien      if (DECL_INITIAL (x))
569896263Sobrien	STRIP_NOPS (DECL_INITIAL (x));
569996263Sobrien      if (DECL_INITIAL (x))
570018334Speter	{
570196263Sobrien	  if (TREE_CODE (DECL_INITIAL (x)) == INTEGER_CST)
570296263Sobrien	    constant_expression_warning (DECL_INITIAL (x));
570396263Sobrien	  else
570496263Sobrien	    {
570596263Sobrien	      error_with_decl (x,
570696263Sobrien			       "bit-field `%s' width not an integer constant");
570796263Sobrien	      DECL_INITIAL (x) = NULL;
570896263Sobrien	    }
570996263Sobrien	}
571096263Sobrien
571196263Sobrien      /* Detect invalid bit-field type.  */
571296263Sobrien      if (DECL_INITIAL (x)
571396263Sobrien	  && TREE_CODE (TREE_TYPE (x)) != INTEGER_TYPE
571496263Sobrien	  && TREE_CODE (TREE_TYPE (x)) != BOOLEAN_TYPE
571596263Sobrien	  && TREE_CODE (TREE_TYPE (x)) != ENUMERAL_TYPE)
571696263Sobrien	{
571796263Sobrien	  error_with_decl (x, "bit-field `%s' has invalid type");
571896263Sobrien	  DECL_INITIAL (x) = NULL;
571996263Sobrien	}
572096263Sobrien
572196263Sobrien      if (DECL_INITIAL (x) && pedantic
572296263Sobrien	  && TYPE_MAIN_VARIANT (TREE_TYPE (x)) != integer_type_node
572396263Sobrien	  && TYPE_MAIN_VARIANT (TREE_TYPE (x)) != unsigned_type_node
572496263Sobrien	  && TYPE_MAIN_VARIANT (TREE_TYPE (x)) != c_bool_type_node
572596263Sobrien	  /* Accept an enum that's equivalent to int or unsigned int.  */
572696263Sobrien	  && !(TREE_CODE (TREE_TYPE (x)) == ENUMERAL_TYPE
572796263Sobrien	       && (TYPE_PRECISION (TREE_TYPE (x))
572896263Sobrien		   == TYPE_PRECISION (integer_type_node))))
572996263Sobrien	pedwarn_with_decl (x, "bit-field `%s' type invalid in ISO C");
573096263Sobrien
573196263Sobrien      /* Detect and ignore out of range field width and process valid
573296263Sobrien	 field widths.  */
573396263Sobrien      if (DECL_INITIAL (x))
573496263Sobrien	{
573596263Sobrien	  int max_width
573696263Sobrien	    = (TYPE_MAIN_VARIANT (TREE_TYPE (x)) == c_bool_type_node
573796263Sobrien	       ? CHAR_TYPE_SIZE : TYPE_PRECISION (TREE_TYPE (x)));
573896263Sobrien
573996263Sobrien	  if (tree_int_cst_sgn (DECL_INITIAL (x)) < 0)
574096263Sobrien	    error_with_decl (x, "negative width in bit-field `%s'");
574196263Sobrien	  else if (0 < compare_tree_int (DECL_INITIAL (x), max_width))
574296263Sobrien	    pedwarn_with_decl (x, "width of `%s' exceeds its type");
574396263Sobrien	  else if (integer_zerop (DECL_INITIAL (x)) && DECL_NAME (x) != 0)
574496263Sobrien	    error_with_decl (x, "zero width for bit-field `%s'");
574596263Sobrien	  else
574696263Sobrien	    {
574796263Sobrien	      /* The test above has assured us that TREE_INT_CST_HIGH is 0.  */
574896263Sobrien	      unsigned HOST_WIDE_INT width
574996263Sobrien		= tree_low_cst (DECL_INITIAL (x), 1);
575096263Sobrien
575196263Sobrien	      if (TREE_CODE (TREE_TYPE (x)) == ENUMERAL_TYPE
575296263Sobrien		  && (width < min_precision (TYPE_MIN_VALUE (TREE_TYPE (x)),
575396263Sobrien					     TREE_UNSIGNED (TREE_TYPE (x)))
575496263Sobrien		      || (width
575596263Sobrien			  < min_precision (TYPE_MAX_VALUE (TREE_TYPE (x)),
575696263Sobrien					   TREE_UNSIGNED (TREE_TYPE (x))))))
575796263Sobrien		warning_with_decl (x,
575896263Sobrien				   "`%s' is narrower than values of its type");
575996263Sobrien
576096263Sobrien	      DECL_SIZE (x) = bitsize_int (width);
576196263Sobrien	      DECL_BIT_FIELD (x) = 1;
576296263Sobrien	      SET_DECL_C_BIT_FIELD (x);
576396263Sobrien
576496263Sobrien	      if (width == 0
576596263Sobrien		  && ! (* targetm.ms_bitfield_layout_p) (t))
576696263Sobrien		{
576796263Sobrien		  /* field size 0 => force desired amount of alignment.  */
576896263Sobrien#ifdef EMPTY_FIELD_BOUNDARY
576996263Sobrien		  DECL_ALIGN (x) = MAX (DECL_ALIGN (x), EMPTY_FIELD_BOUNDARY);
577096263Sobrien#endif
577196263Sobrien#ifdef PCC_BITFIELD_TYPE_MATTERS
577296263Sobrien		  if (PCC_BITFIELD_TYPE_MATTERS)
577396263Sobrien		    {
577496263Sobrien		      DECL_ALIGN (x) = MAX (DECL_ALIGN (x),
577596263Sobrien					    TYPE_ALIGN (TREE_TYPE (x)));
577696263Sobrien		      DECL_USER_ALIGN (x) |= TYPE_USER_ALIGN (TREE_TYPE (x));
577796263Sobrien		    }
577896263Sobrien#endif
577996263Sobrien		}
578096263Sobrien	    }
578196263Sobrien	}
578296263Sobrien
578396263Sobrien      else if (TREE_TYPE (x) != error_mark_node)
578496263Sobrien	{
578590075Sobrien	  unsigned int min_align = (DECL_PACKED (x) ? BITS_PER_UNIT
578690075Sobrien				    : TYPE_ALIGN (TREE_TYPE (x)));
578718334Speter
578890075Sobrien	  /* Non-bit-fields are aligned for their type, except packed
578990075Sobrien	     fields which require only BITS_PER_UNIT alignment.  */
579090075Sobrien	  DECL_ALIGN (x) = MAX (DECL_ALIGN (x), min_align);
579190075Sobrien	  if (! DECL_PACKED (x))
579290075Sobrien	    DECL_USER_ALIGN (x) |= TYPE_USER_ALIGN (TREE_TYPE (x));
579318334Speter	}
579418334Speter
579596263Sobrien      DECL_INITIAL (x) = 0;
579696263Sobrien
579790075Sobrien      /* Detect flexible array member in an invalid context.  */
579890075Sobrien      if (TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE
579990075Sobrien	  && TYPE_SIZE (TREE_TYPE (x)) == NULL_TREE
580090075Sobrien	  && TYPE_DOMAIN (TREE_TYPE (x)) != NULL_TREE
580190075Sobrien	  && TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (x))) == NULL_TREE)
580218334Speter	{
580390075Sobrien	  if (TREE_CODE (t) == UNION_TYPE)
580490075Sobrien	    error_with_decl (x, "flexible array member in union");
580590075Sobrien	  else if (TREE_CHAIN (x) != NULL_TREE)
580690075Sobrien	    error_with_decl (x, "flexible array member not at end of struct");
580790075Sobrien	  else if (! saw_named_field)
580890075Sobrien	    error_with_decl (x, "flexible array member in otherwise empty struct");
580918334Speter	}
581090075Sobrien      if (DECL_NAME (x))
581190075Sobrien	saw_named_field = 1;
581218334Speter    }
581318334Speter
581418334Speter  /* Delete all duplicate fields from the fieldlist */
581518334Speter  for (x = fieldlist; x && TREE_CHAIN (x);)
581618334Speter    /* Anonymous fields aren't duplicates.  */
581718334Speter    if (DECL_NAME (TREE_CHAIN (x)) == 0)
581818334Speter      x = TREE_CHAIN (x);
581918334Speter    else
582018334Speter      {
582190075Sobrien	tree y = fieldlist;
582290075Sobrien
582318334Speter	while (1)
582418334Speter	  {
582518334Speter	    if (DECL_NAME (y) == DECL_NAME (TREE_CHAIN (x)))
582618334Speter	      break;
582718334Speter	    if (y == x)
582818334Speter	      break;
582918334Speter	    y = TREE_CHAIN (y);
583018334Speter	  }
583118334Speter	if (DECL_NAME (y) == DECL_NAME (TREE_CHAIN (x)))
583218334Speter	  {
583318334Speter	    error_with_decl (TREE_CHAIN (x), "duplicate member `%s'");
583418334Speter	    TREE_CHAIN (x) = TREE_CHAIN (TREE_CHAIN (x));
583518334Speter	  }
583690075Sobrien	else
583790075Sobrien	  x = TREE_CHAIN (x);
583818334Speter      }
583918334Speter
584018334Speter  /* Now we have the nearly final fieldlist.  Record it,
584118334Speter     then lay out the structure or union (including the fields).  */
584218334Speter
584318334Speter  TYPE_FIELDS (t) = fieldlist;
584418334Speter
584518334Speter  layout_type (t);
584618334Speter
584790075Sobrien  /* Delete all zero-width bit-fields from the fieldlist */
584890075Sobrien  {
584990075Sobrien    tree *fieldlistp = &fieldlist;
585090075Sobrien    while (*fieldlistp)
585190075Sobrien      if (TREE_CODE (*fieldlistp) == FIELD_DECL && DECL_INITIAL (*fieldlistp))
585290075Sobrien	*fieldlistp = TREE_CHAIN (*fieldlistp);
585390075Sobrien      else
585490075Sobrien	fieldlistp = &TREE_CHAIN (*fieldlistp);
585590075Sobrien  }
585618334Speter
585790075Sobrien  /* Now we have the truly final field list.
585890075Sobrien     Store it in this type and in the variants.  */
585918334Speter
586018334Speter  TYPE_FIELDS (t) = fieldlist;
586118334Speter
586218334Speter  for (x = TYPE_MAIN_VARIANT (t); x; x = TYPE_NEXT_VARIANT (x))
586318334Speter    {
586418334Speter      TYPE_FIELDS (x) = TYPE_FIELDS (t);
586518334Speter      TYPE_LANG_SPECIFIC (x) = TYPE_LANG_SPECIFIC (t);
586618334Speter      TYPE_ALIGN (x) = TYPE_ALIGN (t);
586790075Sobrien      TYPE_USER_ALIGN (x) = TYPE_USER_ALIGN (t);
586818334Speter    }
586918334Speter
587018334Speter  /* If this was supposed to be a transparent union, but we can't
587118334Speter     make it one, warn and turn off the flag.  */
587218334Speter  if (TREE_CODE (t) == UNION_TYPE
587318334Speter      && TYPE_TRANSPARENT_UNION (t)
587418334Speter      && TYPE_MODE (t) != DECL_MODE (TYPE_FIELDS (t)))
587518334Speter    {
587618334Speter      TYPE_TRANSPARENT_UNION (t) = 0;
587750397Sobrien      warning ("union cannot be made transparent");
587818334Speter    }
587918334Speter
588018334Speter  /* If this structure or union completes the type of any previous
588118334Speter     variable declaration, lay it out and output its rtl.  */
588218334Speter
588318334Speter  if (current_binding_level->n_incomplete != 0)
588418334Speter    {
588518334Speter      tree decl;
588618334Speter      for (decl = current_binding_level->names; decl; decl = TREE_CHAIN (decl))
588718334Speter	{
588890075Sobrien	  if (TYPE_MAIN_VARIANT (TREE_TYPE (decl)) == TYPE_MAIN_VARIANT (t)
588918334Speter	      && TREE_CODE (decl) != TYPE_DECL)
589018334Speter	    {
589118334Speter	      layout_decl (decl, 0);
589218334Speter	      /* This is a no-op in c-lang.c or something real in objc-actions.c.  */
589318334Speter	      maybe_objc_check_decl (decl);
589490075Sobrien	      rest_of_decl_compilation (decl, NULL, toplevel, 0);
589518334Speter	      if (! toplevel)
589618334Speter		expand_decl (decl);
589790075Sobrien	      if (--current_binding_level->n_incomplete == 0)
589890075Sobrien		break;
589918334Speter	    }
590090075Sobrien	  else if (!COMPLETE_TYPE_P (TREE_TYPE (decl))
590118334Speter		   && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
590218334Speter	    {
590318334Speter	      tree element = TREE_TYPE (decl);
590418334Speter	      while (TREE_CODE (element) == ARRAY_TYPE)
590518334Speter		element = TREE_TYPE (element);
590618334Speter	      if (element == t)
590790075Sobrien		{
590890075Sobrien		  layout_array_type (TREE_TYPE (decl));
590990075Sobrien		  if (TREE_CODE (decl) != TYPE_DECL)
591090075Sobrien		    {
591190075Sobrien		      layout_decl (decl, 0);
591290075Sobrien		      maybe_objc_check_decl (decl);
591390075Sobrien		      rest_of_decl_compilation (decl, NULL, toplevel, 0);
591490075Sobrien		      if (! toplevel)
591590075Sobrien			expand_decl (decl);
591690075Sobrien		    }
591790075Sobrien		  if (--current_binding_level->n_incomplete == 0)
591890075Sobrien		    break;
591990075Sobrien		}
592018334Speter	    }
592118334Speter	}
592218334Speter    }
592318334Speter
592418334Speter  /* Finish debugging output for this type.  */
592518334Speter  rest_of_type_compilation (t, toplevel);
592618334Speter
592718334Speter  return t;
592818334Speter}
592918334Speter
593018334Speter/* Lay out the type T, and its element type, and so on.  */
593118334Speter
593218334Speterstatic void
593318334Speterlayout_array_type (t)
593418334Speter     tree t;
593518334Speter{
593618334Speter  if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
593718334Speter    layout_array_type (TREE_TYPE (t));
593818334Speter  layout_type (t);
593918334Speter}
594018334Speter
594118334Speter/* Begin compiling the definition of an enumeration type.
594218334Speter   NAME is its name (or null if anonymous).
594318334Speter   Returns the type object, as yet incomplete.
594418334Speter   Also records info about it so that build_enumerator
594518334Speter   may be used to declare the individual values as they are read.  */
594618334Speter
594718334Spetertree
594818334Speterstart_enum (name)
594918334Speter     tree name;
595018334Speter{
595190075Sobrien  tree enumtype = 0;
595218334Speter
595318334Speter  /* If this is the real definition for a previous forward reference,
595418334Speter     fill in the contents in the same object that used to be the
595518334Speter     forward reference.  */
595618334Speter
595718334Speter  if (name != 0)
595818334Speter    enumtype = lookup_tag (ENUMERAL_TYPE, name, current_binding_level, 1);
595918334Speter
596018334Speter  if (enumtype == 0 || TREE_CODE (enumtype) != ENUMERAL_TYPE)
596118334Speter    {
596218334Speter      enumtype = make_node (ENUMERAL_TYPE);
596318334Speter      pushtag (name, enumtype);
596418334Speter    }
596518334Speter
596618334Speter  C_TYPE_BEING_DEFINED (enumtype) = 1;
596718334Speter
596818334Speter  if (TYPE_VALUES (enumtype) != 0)
596918334Speter    {
597018334Speter      /* This enum is a named one that has been declared already.  */
597118334Speter      error ("redeclaration of `enum %s'", IDENTIFIER_POINTER (name));
597218334Speter
597318334Speter      /* Completely replace its old definition.
597418334Speter	 The old enumerators remain defined, however.  */
597518334Speter      TYPE_VALUES (enumtype) = 0;
597618334Speter    }
597718334Speter
597818334Speter  enum_next_value = integer_zero_node;
597918334Speter  enum_overflow = 0;
598018334Speter
598150397Sobrien  if (flag_short_enums)
598250397Sobrien    TYPE_PACKED (enumtype) = 1;
598350397Sobrien
598418334Speter  return enumtype;
598518334Speter}
598618334Speter
598718334Speter/* After processing and defining all the values of an enumeration type,
598818334Speter   install their decls in the enumeration type and finish it off.
598918334Speter   ENUMTYPE is the type object, VALUES a list of decl-value pairs,
599018334Speter   and ATTRIBUTES are the specified attributes.
599118334Speter   Returns ENUMTYPE.  */
599218334Speter
599318334Spetertree
599418334Speterfinish_enum (enumtype, values, attributes)
599518334Speter     tree enumtype;
599618334Speter     tree values;
599718334Speter     tree attributes;
599818334Speter{
599990075Sobrien  tree pair, tem;
600090075Sobrien  tree minnode = 0, maxnode = 0, enum_value_type;
600190075Sobrien  int precision, unsign;
600290075Sobrien  int toplevel = (global_binding_level == current_binding_level);
600318334Speter
600418334Speter  if (in_parm_level_p ())
600518334Speter    warning ("enum defined inside parms");
600618334Speter
600790075Sobrien  decl_attributes (&enumtype, attributes, (int) ATTR_FLAG_TYPE_IN_PLACE);
600818334Speter
600918334Speter  /* Calculate the maximum value of any enumerator in this type.  */
601018334Speter
601118334Speter  if (values == error_mark_node)
601218334Speter    minnode = maxnode = integer_zero_node;
601318334Speter  else
601490075Sobrien    {
601590075Sobrien      minnode = maxnode = TREE_VALUE (values);
601690075Sobrien      for (pair = TREE_CHAIN (values); pair; pair = TREE_CHAIN (pair))
601790075Sobrien	{
601890075Sobrien	  tree value = TREE_VALUE (pair);
601990075Sobrien	  if (tree_int_cst_lt (maxnode, value))
602090075Sobrien	    maxnode = value;
602190075Sobrien	  if (tree_int_cst_lt (value, minnode))
602290075Sobrien	    minnode = value;
602390075Sobrien	}
602490075Sobrien    }
602518334Speter
602690075Sobrien  /* Construct the final type of this enumeration.  It is the same
602790075Sobrien     as one of the integral types - the narrowest one that fits, except
602890075Sobrien     that normally we only go as narrow as int - and signed iff any of
602990075Sobrien     the values are negative.  */
603090075Sobrien  unsign = (tree_int_cst_sgn (minnode) >= 0);
603190075Sobrien  precision = MAX (min_precision (minnode, unsign),
603290075Sobrien		   min_precision (maxnode, unsign));
603350397Sobrien  if (TYPE_PACKED (enumtype) || precision > TYPE_PRECISION (integer_type_node))
603450397Sobrien    {
603590075Sobrien      tree narrowest = type_for_size (precision, unsign);
603650397Sobrien      if (narrowest == 0)
603750397Sobrien	{
603850397Sobrien	  warning ("enumeration values exceed range of largest integer");
603950397Sobrien	  narrowest = long_long_integer_type_node;
604050397Sobrien	}
604150397Sobrien
604290075Sobrien      precision = TYPE_PRECISION (narrowest);
604350397Sobrien    }
604418334Speter  else
604590075Sobrien    precision = TYPE_PRECISION (integer_type_node);
604618334Speter
604790075Sobrien  if (precision == TYPE_PRECISION (integer_type_node))
604890075Sobrien    enum_value_type = type_for_size (precision, 0);
604990075Sobrien  else
605090075Sobrien    enum_value_type = enumtype;
605190075Sobrien
605290075Sobrien  TYPE_MIN_VALUE (enumtype) = minnode;
605390075Sobrien  TYPE_MAX_VALUE (enumtype) = maxnode;
605490075Sobrien  TYPE_PRECISION (enumtype) = precision;
605590075Sobrien  TREE_UNSIGNED (enumtype) = unsign;
605618334Speter  TYPE_SIZE (enumtype) = 0;
605718334Speter  layout_type (enumtype);
605818334Speter
605918334Speter  if (values != error_mark_node)
606018334Speter    {
606190075Sobrien      /* Change the type of the enumerators to be the enum type.  We
606290075Sobrien	 need to do this irrespective of the size of the enum, for
606390075Sobrien	 proper type checking.  Replace the DECL_INITIALs of the
606490075Sobrien	 enumerators, and the value slots of the list, with copies
606590075Sobrien	 that have the enum type; they cannot be modified in place
606690075Sobrien	 because they may be shared (e.g.  integer_zero_node) Finally,
606790075Sobrien	 change the purpose slots to point to the names of the decls.  */
606818334Speter      for (pair = values; pair; pair = TREE_CHAIN (pair))
606918334Speter	{
607090075Sobrien	  tree enu = TREE_PURPOSE (pair);
607190075Sobrien
607290075Sobrien	  TREE_TYPE (enu) = enumtype;
607390075Sobrien	  DECL_SIZE (enu) = TYPE_SIZE (enumtype);
607490075Sobrien	  DECL_SIZE_UNIT (enu) = TYPE_SIZE_UNIT (enumtype);
607590075Sobrien	  DECL_ALIGN (enu) = TYPE_ALIGN (enumtype);
607690075Sobrien	  DECL_USER_ALIGN (enu) = TYPE_USER_ALIGN (enumtype);
607790075Sobrien	  DECL_MODE (enu) = TYPE_MODE (enumtype);
607890075Sobrien
607990075Sobrien	  /* The ISO C Standard mandates enumerators to have type int,
608090075Sobrien	     even though the underlying type of an enum type is
608190075Sobrien	     unspecified.  Here we convert any enumerators that fit in
608290075Sobrien	     an int to type int, to avoid promotions to unsigned types
608390075Sobrien	     when comparing integers with enumerators that fit in the
608490075Sobrien	     int range.  When -pedantic is given, build_enumerator()
608590075Sobrien	     would have already taken care of those that don't fit.  */
608690075Sobrien	  if (int_fits_type_p (DECL_INITIAL (enu), enum_value_type))
608790075Sobrien	    DECL_INITIAL (enu) = convert (enum_value_type, DECL_INITIAL (enu));
608890075Sobrien	  else
608990075Sobrien	    DECL_INITIAL (enu) = convert (enumtype, DECL_INITIAL (enu));
609090075Sobrien
609190075Sobrien	  TREE_PURPOSE (pair) = DECL_NAME (enu);
609290075Sobrien	  TREE_VALUE (pair) = DECL_INITIAL (enu);
609318334Speter	}
609418334Speter
609518334Speter      TYPE_VALUES (enumtype) = values;
609618334Speter    }
609718334Speter
609818334Speter  /* Fix up all variant types of this enum type.  */
609918334Speter  for (tem = TYPE_MAIN_VARIANT (enumtype); tem; tem = TYPE_NEXT_VARIANT (tem))
610018334Speter    {
610190075Sobrien      if (tem == enumtype)
610290075Sobrien	continue;
610318334Speter      TYPE_VALUES (tem) = TYPE_VALUES (enumtype);
610418334Speter      TYPE_MIN_VALUE (tem) = TYPE_MIN_VALUE (enumtype);
610518334Speter      TYPE_MAX_VALUE (tem) = TYPE_MAX_VALUE (enumtype);
610618334Speter      TYPE_SIZE (tem) = TYPE_SIZE (enumtype);
610750397Sobrien      TYPE_SIZE_UNIT (tem) = TYPE_SIZE_UNIT (enumtype);
610818334Speter      TYPE_MODE (tem) = TYPE_MODE (enumtype);
610918334Speter      TYPE_PRECISION (tem) = TYPE_PRECISION (enumtype);
611018334Speter      TYPE_ALIGN (tem) = TYPE_ALIGN (enumtype);
611190075Sobrien      TYPE_USER_ALIGN (tem) = TYPE_USER_ALIGN (enumtype);
611218334Speter      TREE_UNSIGNED (tem) = TREE_UNSIGNED (enumtype);
611318334Speter    }
611418334Speter
611518334Speter  /* Finish debugging output for this type.  */
611618334Speter  rest_of_type_compilation (enumtype, toplevel);
611718334Speter
611818334Speter  return enumtype;
611918334Speter}
612018334Speter
612118334Speter/* Build and install a CONST_DECL for one value of the
612218334Speter   current enumeration type (one that was begun with start_enum).
612318334Speter   Return a tree-list containing the CONST_DECL and its value.
612418334Speter   Assignment of sequential values by default is handled here.  */
612518334Speter
612618334Spetertree
612718334Speterbuild_enumerator (name, value)
612818334Speter     tree name, value;
612918334Speter{
613090075Sobrien  tree decl, type;
613118334Speter
613218334Speter  /* Validate and default VALUE.  */
613318334Speter
613418334Speter  /* Remove no-op casts from the value.  */
613518334Speter  if (value)
613618334Speter    STRIP_TYPE_NOPS (value);
613718334Speter
613818334Speter  if (value != 0)
613918334Speter    {
614018334Speter      if (TREE_CODE (value) == INTEGER_CST)
614118334Speter	{
614218334Speter	  value = default_conversion (value);
614318334Speter	  constant_expression_warning (value);
614418334Speter	}
614518334Speter      else
614618334Speter	{
614718334Speter	  error ("enumerator value for `%s' not integer constant",
614818334Speter		 IDENTIFIER_POINTER (name));
614918334Speter	  value = 0;
615018334Speter	}
615118334Speter    }
615218334Speter
615318334Speter  /* Default based on previous value.  */
615418334Speter  /* It should no longer be possible to have NON_LVALUE_EXPR
615518334Speter     in the default.  */
615618334Speter  if (value == 0)
615718334Speter    {
615818334Speter      value = enum_next_value;
615918334Speter      if (enum_overflow)
616018334Speter	error ("overflow in enumeration values");
616118334Speter    }
616218334Speter
616318334Speter  if (pedantic && ! int_fits_type_p (value, integer_type_node))
616418334Speter    {
616590075Sobrien      pedwarn ("ISO C restricts enumerator values to range of `int'");
616690075Sobrien      value = convert (integer_type_node, value);
616718334Speter    }
616818334Speter
616918334Speter  /* Set basis for default for next value.  */
617018334Speter  enum_next_value = build_binary_op (PLUS_EXPR, value, integer_one_node, 0);
617118334Speter  enum_overflow = tree_int_cst_lt (enum_next_value, value);
617218334Speter
617318334Speter  /* Now create a declaration for the enum value name.  */
617418334Speter
617518334Speter  type = TREE_TYPE (value);
617618334Speter  type = type_for_size (MAX (TYPE_PRECISION (type),
617718334Speter			     TYPE_PRECISION (integer_type_node)),
617818334Speter			((flag_traditional
617918334Speter			  || TYPE_PRECISION (type) >= TYPE_PRECISION (integer_type_node))
618018334Speter			 && TREE_UNSIGNED (type)));
618118334Speter
618218334Speter  decl = build_decl (CONST_DECL, name, type);
618390075Sobrien  DECL_INITIAL (decl) = convert (type, value);
618418334Speter  pushdecl (decl);
618518334Speter
618690075Sobrien  return tree_cons (decl, value, NULL_TREE);
618718334Speter}
618890075Sobrien
618918334Speter
619018334Speter/* Create the FUNCTION_DECL for a function definition.
619190075Sobrien   DECLSPECS, DECLARATOR and ATTRIBUTES are the parts of
619218334Speter   the declaration; they describe the function's name and the type it returns,
619318334Speter   but twisted together in a fashion that parallels the syntax of C.
619418334Speter
619518334Speter   This function creates a binding context for the function body
619618334Speter   as well as setting up the FUNCTION_DECL in current_function_decl.
619718334Speter
619818334Speter   Returns 1 on success.  If the DECLARATOR is not suitable for a function
619918334Speter   (it defines a datum instead), we return 0, which tells
620090075Sobrien   yyparse to report a parse error.  */
620118334Speter
620218334Speterint
620390075Sobrienstart_function (declspecs, declarator, attributes)
620490075Sobrien     tree declarator, declspecs, attributes;
620518334Speter{
620618334Speter  tree decl1, old_decl;
620718334Speter  tree restype;
620818334Speter  int old_immediate_size_expand = immediate_size_expand;
620918334Speter
621050397Sobrien  current_function_returns_value = 0;  /* Assume, until we see it does.  */
621118334Speter  current_function_returns_null = 0;
621296263Sobrien  current_function_returns_abnormally = 0;
621318334Speter  warn_about_return_type = 0;
621418334Speter  current_extern_inline = 0;
621518334Speter  c_function_varargs = 0;
621618334Speter  named_labels = 0;
621718334Speter  shadowed_labels = 0;
621818334Speter
621918334Speter  /* Don't expand any sizes in the return type of the function.  */
622018334Speter  immediate_size_expand = 0;
622118334Speter
622296263Sobrien  decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, 1);
622318334Speter
622418334Speter  /* If the declarator is not suitable for a function definition,
622518334Speter     cause a syntax error.  */
622618334Speter  if (decl1 == 0)
622750397Sobrien    {
622850397Sobrien      immediate_size_expand = old_immediate_size_expand;
622950397Sobrien      return 0;
623050397Sobrien    }
623118334Speter
623290075Sobrien  decl_attributes (&decl1, attributes, 0);
623318334Speter
623496263Sobrien  /* If #pragma weak was used, mark the decl weak now.  */
623596263Sobrien  if (current_binding_level == global_binding_level)
623696263Sobrien    maybe_apply_pragma_weak (decl1);
623796263Sobrien
623890075Sobrien  if (DECL_DECLARED_INLINE_P (decl1)
623990075Sobrien      && DECL_UNINLINABLE (decl1)
624090075Sobrien      && lookup_attribute ("noinline", DECL_ATTRIBUTES (decl1)))
624190075Sobrien    warning_with_decl (decl1,
624290075Sobrien		       "inline function `%s' given attribute noinline");
624390075Sobrien
624418334Speter  announce_function (decl1);
624518334Speter
624690075Sobrien  if (!COMPLETE_OR_VOID_TYPE_P (TREE_TYPE (TREE_TYPE (decl1))))
624718334Speter    {
624890075Sobrien      error ("return type is an incomplete type");
624918334Speter      /* Make it return void instead.  */
625018334Speter      TREE_TYPE (decl1)
625118334Speter	= build_function_type (void_type_node,
625218334Speter			       TYPE_ARG_TYPES (TREE_TYPE (decl1)));
625318334Speter    }
625418334Speter
625518334Speter  if (warn_about_return_type)
625690075Sobrien    pedwarn_c99 ("return type defaults to `int'");
625718334Speter
625818334Speter  /* Save the parm names or decls from this function's declarator
625918334Speter     where store_parm_decls will find them.  */
626018334Speter  current_function_parms = last_function_parms;
626118334Speter  current_function_parm_tags = last_function_parm_tags;
626218334Speter
626318334Speter  /* Make the init_value nonzero so pushdecl knows this is not tentative.
626418334Speter     error_mark_node is replaced below (in poplevel) with the BLOCK.  */
626518334Speter  DECL_INITIAL (decl1) = error_mark_node;
626618334Speter
626718334Speter  /* If this definition isn't a prototype and we had a prototype declaration
626818334Speter     before, copy the arg type info from that prototype.
626918334Speter     But not if what we had before was a builtin function.  */
627018334Speter  old_decl = lookup_name_current_level (DECL_NAME (decl1));
627118334Speter  if (old_decl != 0 && TREE_CODE (TREE_TYPE (old_decl)) == FUNCTION_TYPE
627218334Speter      && !DECL_BUILT_IN (old_decl)
627318334Speter      && (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (decl1)))
627418334Speter	  == TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (old_decl))))
627518334Speter      && TYPE_ARG_TYPES (TREE_TYPE (decl1)) == 0)
627618334Speter    {
627718334Speter      TREE_TYPE (decl1) = TREE_TYPE (old_decl);
627818334Speter      current_function_prototype_file = DECL_SOURCE_FILE (old_decl);
627918334Speter      current_function_prototype_line = DECL_SOURCE_LINE (old_decl);
628018334Speter    }
628118334Speter
628218334Speter  /* If there is no explicit declaration, look for any out-of-scope implicit
628318334Speter     declarations.  */
628418334Speter  if (old_decl == 0)
628518334Speter    old_decl = IDENTIFIER_IMPLICIT_DECL (DECL_NAME (decl1));
628618334Speter
628718334Speter  /* Optionally warn of old-fashioned def with no previous prototype.  */
628818334Speter  if (warn_strict_prototypes
628918334Speter      && TYPE_ARG_TYPES (TREE_TYPE (decl1)) == 0
629090075Sobrien      && !(old_decl != 0
629190075Sobrien	   && (TYPE_ARG_TYPES (TREE_TYPE (old_decl)) != 0
629290075Sobrien	       || (DECL_BUILT_IN (old_decl)
629390075Sobrien		   && ! C_DECL_ANTICIPATED (old_decl)))))
629418334Speter    warning ("function declaration isn't a prototype");
629518334Speter  /* Optionally warn of any global def with no previous prototype.  */
629618334Speter  else if (warn_missing_prototypes
629718334Speter	   && TREE_PUBLIC (decl1)
629890075Sobrien	   && !(old_decl != 0
629990075Sobrien		&& (TYPE_ARG_TYPES (TREE_TYPE (old_decl)) != 0
630090075Sobrien		    || (DECL_BUILT_IN (old_decl)
630190075Sobrien			&& ! C_DECL_ANTICIPATED (old_decl))))
630290075Sobrien	   && ! MAIN_NAME_P (DECL_NAME (decl1)))
630318334Speter    warning_with_decl (decl1, "no previous prototype for `%s'");
630418334Speter  /* Optionally warn of any def with no previous prototype
630518334Speter     if the function has already been used.  */
630618334Speter  else if (warn_missing_prototypes
630718334Speter	   && old_decl != 0 && TREE_USED (old_decl)
630818334Speter	   && TYPE_ARG_TYPES (TREE_TYPE (old_decl)) == 0)
630918334Speter    warning_with_decl (decl1,
631090075Sobrien		       "`%s' was used with no prototype before its definition");
631118334Speter  /* Optionally warn of any global def with no previous declaration.  */
631218334Speter  else if (warn_missing_declarations
631318334Speter	   && TREE_PUBLIC (decl1)
631418334Speter	   && old_decl == 0
631590075Sobrien	   && ! MAIN_NAME_P (DECL_NAME (decl1)))
631618334Speter    warning_with_decl (decl1, "no previous declaration for `%s'");
631718334Speter  /* Optionally warn of any def with no previous declaration
631818334Speter     if the function has already been used.  */
631918334Speter  else if (warn_missing_declarations
632018334Speter	   && old_decl != 0 && TREE_USED (old_decl)
632118334Speter	   && old_decl == IDENTIFIER_IMPLICIT_DECL (DECL_NAME (decl1)))
632218334Speter    warning_with_decl (decl1,
632390075Sobrien		       "`%s' was used with no declaration before its definition");
632418334Speter
632518334Speter  /* This is a definition, not a reference.
632618334Speter     So normally clear DECL_EXTERNAL.
632718334Speter     However, `extern inline' acts like a declaration
632818334Speter     except for defining how to inline.  So set DECL_EXTERNAL in that case.  */
632918334Speter  DECL_EXTERNAL (decl1) = current_extern_inline;
633018334Speter
633118334Speter  /* This function exists in static storage.
633218334Speter     (This does not mean `static' in the C sense!)  */
633318334Speter  TREE_STATIC (decl1) = 1;
633418334Speter
633518334Speter  /* A nested function is not global.  */
633618334Speter  if (current_function_decl != 0)
633718334Speter    TREE_PUBLIC (decl1) = 0;
633818334Speter
633990075Sobrien  /* Warn for unlikely, improbable, or stupid declarations of `main'.  */
634090075Sobrien  if (warn_main > 0 && MAIN_NAME_P (DECL_NAME (decl1)))
634150397Sobrien    {
634250397Sobrien      tree args;
634350397Sobrien      int argct = 0;
634450397Sobrien
634550397Sobrien      if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (decl1)))
634690075Sobrien	  != integer_type_node)
634750397Sobrien	pedwarn_with_decl (decl1, "return type of `%s' is not `int'");
634850397Sobrien
634950397Sobrien      for (args = TYPE_ARG_TYPES (TREE_TYPE (decl1)); args;
635050397Sobrien	   args = TREE_CHAIN (args))
635150397Sobrien	{
635250397Sobrien	  tree type = args ? TREE_VALUE (args) : 0;
635350397Sobrien
635450397Sobrien	  if (type == void_type_node)
635550397Sobrien	    break;
635650397Sobrien
635750397Sobrien	  ++argct;
635850397Sobrien	  switch (argct)
635950397Sobrien	    {
636050397Sobrien	    case 1:
636150397Sobrien	      if (TYPE_MAIN_VARIANT (type) != integer_type_node)
636250397Sobrien		pedwarn_with_decl (decl1,
636350397Sobrien				   "first argument of `%s' should be `int'");
636450397Sobrien	      break;
636550397Sobrien
636650397Sobrien	    case 2:
636750397Sobrien	      if (TREE_CODE (type) != POINTER_TYPE
636850397Sobrien		  || TREE_CODE (TREE_TYPE (type)) != POINTER_TYPE
636950397Sobrien		  || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type)))
637050397Sobrien		      != char_type_node))
637150397Sobrien		pedwarn_with_decl (decl1,
637290075Sobrien				   "second argument of `%s' should be `char **'");
637350397Sobrien	      break;
637450397Sobrien
637550397Sobrien	    case 3:
637650397Sobrien	      if (TREE_CODE (type) != POINTER_TYPE
637750397Sobrien		  || TREE_CODE (TREE_TYPE (type)) != POINTER_TYPE
637850397Sobrien		  || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type)))
637950397Sobrien		      != char_type_node))
638050397Sobrien		pedwarn_with_decl (decl1,
638190075Sobrien				   "third argument of `%s' should probably be `char **'");
638250397Sobrien	      break;
638350397Sobrien	    }
638450397Sobrien	}
638550397Sobrien
638650397Sobrien      /* It is intentional that this message does not mention the third
638790075Sobrien	 argument because it's only mentioned in an appendix of the
638890075Sobrien	 standard.  */
638950397Sobrien      if (argct > 0 && (argct < 2 || argct > 3))
639050397Sobrien	pedwarn_with_decl (decl1, "`%s' takes only zero or two arguments");
639150397Sobrien
639250397Sobrien      if (! TREE_PUBLIC (decl1))
639350397Sobrien	pedwarn_with_decl (decl1, "`%s' is normally a non-static function");
639450397Sobrien    }
639550397Sobrien
639618334Speter  /* Record the decl so that the function name is defined.
639718334Speter     If we already have a decl for this name, and it is a FUNCTION_DECL,
639818334Speter     use the old decl.  */
639918334Speter
640018334Speter  current_function_decl = pushdecl (decl1);
640118334Speter
640218334Speter  pushlevel (0);
640318334Speter  declare_parm_level (1);
640418334Speter  current_binding_level->subblocks_tag_transparent = 1;
640518334Speter
640690075Sobrien  make_decl_rtl (current_function_decl, NULL);
640718334Speter
640818334Speter  restype = TREE_TYPE (TREE_TYPE (current_function_decl));
640918334Speter  /* Promote the value to int before returning it.  */
641090075Sobrien  if (c_promoting_integer_type_p (restype))
641118334Speter    {
641218334Speter      /* It retains unsignedness if traditional
641318334Speter	 or if not really getting wider.  */
641418334Speter      if (TREE_UNSIGNED (restype)
641518334Speter	  && (flag_traditional
641618334Speter	      || (TYPE_PRECISION (restype)
641718334Speter		  == TYPE_PRECISION (integer_type_node))))
641818334Speter	restype = unsigned_type_node;
641918334Speter      else
642018334Speter	restype = integer_type_node;
642118334Speter    }
642218334Speter  DECL_RESULT (current_function_decl)
642318334Speter    = build_decl (RESULT_DECL, NULL_TREE, restype);
642418334Speter
642518334Speter  /* If this fcn was already referenced via a block-scope `extern' decl
642618334Speter     (or an implicit decl), propagate certain information about the usage.  */
642718334Speter  if (TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (current_function_decl)))
642818334Speter    TREE_ADDRESSABLE (current_function_decl) = 1;
642918334Speter
643018334Speter  immediate_size_expand = old_immediate_size_expand;
643118334Speter
643290075Sobrien  start_fname_decls ();
643390075Sobrien
643418334Speter  return 1;
643518334Speter}
643618334Speter
643718334Speter/* Record that this function is going to be a varargs function.
643818334Speter   This is called before store_parm_decls, which is too early
643918334Speter   to call mark_varargs directly.  */
644018334Speter
644118334Spetervoid
644218334Speterc_mark_varargs ()
644318334Speter{
644418334Speter  c_function_varargs = 1;
644518334Speter}
644618334Speter
644718334Speter/* Store the parameter declarations into the current function declaration.
644818334Speter   This is called after parsing the parameter declarations, before
644918334Speter   digesting the body of the function.
645018334Speter
645118334Speter   For an old-style definition, modify the function's type
645218334Speter   to specify at least the number of arguments.  */
645318334Speter
645418334Spetervoid
645518334Speterstore_parm_decls ()
645618334Speter{
645790075Sobrien  tree fndecl = current_function_decl;
645890075Sobrien  tree parm;
645918334Speter
646018334Speter  /* This is either a chain of PARM_DECLs (if a prototype was used)
646118334Speter     or a list of IDENTIFIER_NODEs (for an old-fashioned C definition).  */
646218334Speter  tree specparms = current_function_parms;
646318334Speter
646418334Speter  /* This is a list of types declared among parms in a prototype.  */
646518334Speter  tree parmtags = current_function_parm_tags;
646618334Speter
646718334Speter  /* This is a chain of PARM_DECLs from old-style parm declarations.  */
646890075Sobrien  tree parmdecls = getdecls ();
646918334Speter
647018334Speter  /* This is a chain of any other decls that came in among the parm
647118334Speter     declarations.  If a parm is declared with  enum {foo, bar} x;
647218334Speter     then CONST_DECLs for foo and bar are put here.  */
647318334Speter  tree nonparms = 0;
647418334Speter
647590075Sobrien  /* The function containing FNDECL, if any.  */
647690075Sobrien  tree context = decl_function_context (fndecl);
647790075Sobrien
647818334Speter  /* Nonzero if this definition is written with a prototype.  */
647918334Speter  int prototype = 0;
648018334Speter
648190075Sobrien  int saved_warn_shadow = warn_shadow;
648290075Sobrien
648390075Sobrien  /* Don't re-emit shadow warnings.  */
648490075Sobrien  warn_shadow = 0;
648590075Sobrien
648618334Speter  if (specparms != 0 && TREE_CODE (specparms) != TREE_LIST)
648718334Speter    {
648818334Speter      /* This case is when the function was defined with an ANSI prototype.
648918334Speter	 The parms already have decls, so we need not do anything here
649018334Speter	 except record them as in effect
649118334Speter	 and complain if any redundant old-style parm decls were written.  */
649218334Speter
649390075Sobrien      tree next;
649418334Speter      tree others = 0;
649518334Speter
649618334Speter      prototype = 1;
649718334Speter
649818334Speter      if (parmdecls != 0)
649918334Speter	{
650018334Speter	  tree decl, link;
650118334Speter
650218334Speter	  error_with_decl (fndecl,
650318334Speter			   "parm types given both in parmlist and separately");
650418334Speter	  /* Get rid of the erroneous decls; don't keep them on
650518334Speter	     the list of parms, since they might not be PARM_DECLs.  */
650618334Speter	  for (decl = current_binding_level->names;
650718334Speter	       decl; decl = TREE_CHAIN (decl))
650818334Speter	    if (DECL_NAME (decl))
650918334Speter	      IDENTIFIER_LOCAL_VALUE (DECL_NAME (decl)) = 0;
651018334Speter	  for (link = current_binding_level->shadowed;
651118334Speter	       link; link = TREE_CHAIN (link))
651218334Speter	    IDENTIFIER_LOCAL_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link);
651318334Speter	  current_binding_level->names = 0;
651418334Speter	  current_binding_level->shadowed = 0;
651518334Speter	}
651618334Speter
651718334Speter      specparms = nreverse (specparms);
651818334Speter      for (parm = specparms; parm; parm = next)
651918334Speter	{
652018334Speter	  next = TREE_CHAIN (parm);
652118334Speter	  if (TREE_CODE (parm) == PARM_DECL)
652218334Speter	    {
652318334Speter	      if (DECL_NAME (parm) == 0)
652418334Speter		error_with_decl (parm, "parameter name omitted");
652590075Sobrien	      else if (TREE_CODE (TREE_TYPE (parm)) != ERROR_MARK
652690075Sobrien		       && VOID_TYPE_P (TREE_TYPE (parm)))
652718334Speter		{
652818334Speter		  error_with_decl (parm, "parameter `%s' declared void");
652918334Speter		  /* Change the type to error_mark_node so this parameter
653018334Speter		     will be ignored by assign_parms.  */
653118334Speter		  TREE_TYPE (parm) = error_mark_node;
653218334Speter		}
653318334Speter	      pushdecl (parm);
653418334Speter	    }
653518334Speter	  else
653618334Speter	    {
653718334Speter	      /* If we find an enum constant or a type tag,
653818334Speter		 put it aside for the moment.  */
653918334Speter	      TREE_CHAIN (parm) = 0;
654018334Speter	      others = chainon (others, parm);
654118334Speter	    }
654218334Speter	}
654318334Speter
654418334Speter      /* Get the decls in their original chain order
654518334Speter	 and record in the function.  */
654618334Speter      DECL_ARGUMENTS (fndecl) = getdecls ();
654718334Speter
654818334Speter#if 0
654918334Speter      /* If this function takes a variable number of arguments,
655018334Speter	 add a phony parameter to the end of the parm list,
655118334Speter	 to represent the position of the first unnamed argument.  */
655218334Speter      if (TREE_VALUE (tree_last (TYPE_ARG_TYPES (TREE_TYPE (fndecl))))
655318334Speter	  != void_type_node)
655418334Speter	{
655518334Speter	  tree dummy = build_decl (PARM_DECL, NULL_TREE, void_type_node);
655618334Speter	  /* Let's hope the address of the unnamed parm
655718334Speter	     won't depend on its type.  */
655818334Speter	  TREE_TYPE (dummy) = integer_type_node;
655918334Speter	  DECL_ARG_TYPE (dummy) = integer_type_node;
656090075Sobrien	  DECL_ARGUMENTS (fndecl) = chainon (DECL_ARGUMENTS (fndecl), dummy);
656118334Speter	}
656218334Speter#endif
656318334Speter
656418334Speter      /* Now pushdecl the enum constants.  */
656518334Speter      for (parm = others; parm; parm = next)
656618334Speter	{
656718334Speter	  next = TREE_CHAIN (parm);
656818334Speter	  if (DECL_NAME (parm) == 0)
656918334Speter	    ;
657018334Speter	  else if (TYPE_MAIN_VARIANT (TREE_TYPE (parm)) == void_type_node)
657118334Speter	    ;
657218334Speter	  else if (TREE_CODE (parm) != PARM_DECL)
657318334Speter	    pushdecl (parm);
657418334Speter	}
657518334Speter
657618334Speter      storetags (chainon (parmtags, gettags ()));
657718334Speter    }
657818334Speter  else
657918334Speter    {
658018334Speter      /* SPECPARMS is an identifier list--a chain of TREE_LIST nodes
658118334Speter	 each with a parm name as the TREE_VALUE.
658218334Speter
658318334Speter	 PARMDECLS is a chain of declarations for parameters.
658418334Speter	 Warning! It can also contain CONST_DECLs which are not parameters
658518334Speter	 but are names of enumerators of any enum types
658618334Speter	 declared among the parameters.
658718334Speter
658818334Speter	 First match each formal parameter name with its declaration.
658918334Speter	 Associate decls with the names and store the decls
659018334Speter	 into the TREE_PURPOSE slots.  */
659118334Speter
659290075Sobrien      /* We use DECL_WEAK as a flag to show which parameters have been
659390075Sobrien	 seen already since it is not used on PARM_DECL or CONST_DECL.  */
659418334Speter      for (parm = parmdecls; parm; parm = TREE_CHAIN (parm))
659590075Sobrien	DECL_WEAK (parm) = 0;
659618334Speter
659718334Speter      for (parm = specparms; parm; parm = TREE_CHAIN (parm))
659818334Speter	{
659990075Sobrien	  tree tail, found = NULL;
660018334Speter
660118334Speter	  if (TREE_VALUE (parm) == 0)
660218334Speter	    {
660390075Sobrien	      error_with_decl (fndecl,
660490075Sobrien			       "parameter name missing from parameter list");
660518334Speter	      TREE_PURPOSE (parm) = 0;
660618334Speter	      continue;
660718334Speter	    }
660818334Speter
660918334Speter	  /* See if any of the parmdecls specifies this parm by name.
661018334Speter	     Ignore any enumerator decls.  */
661118334Speter	  for (tail = parmdecls; tail; tail = TREE_CHAIN (tail))
661218334Speter	    if (DECL_NAME (tail) == TREE_VALUE (parm)
661318334Speter		&& TREE_CODE (tail) == PARM_DECL)
661418334Speter	      {
661518334Speter		found = tail;
661618334Speter		break;
661718334Speter	      }
661818334Speter
661918334Speter	  /* If declaration already marked, we have a duplicate name.
662090075Sobrien	     Complain, and don't use this decl twice.  */
662190075Sobrien	  if (found && DECL_WEAK (found))
662218334Speter	    {
662318334Speter	      error_with_decl (found, "multiple parameters named `%s'");
662418334Speter	      found = 0;
662518334Speter	    }
662618334Speter
662718334Speter	  /* If the declaration says "void", complain and ignore it.  */
662890075Sobrien	  if (found && VOID_TYPE_P (TREE_TYPE (found)))
662918334Speter	    {
663018334Speter	      error_with_decl (found, "parameter `%s' declared void");
663118334Speter	      TREE_TYPE (found) = integer_type_node;
663218334Speter	      DECL_ARG_TYPE (found) = integer_type_node;
663318334Speter	      layout_decl (found, 0);
663418334Speter	    }
663518334Speter
663618334Speter	  /* Traditionally, a parm declared float is actually a double.  */
663718334Speter	  if (found && flag_traditional
663818334Speter	      && TYPE_MAIN_VARIANT (TREE_TYPE (found)) == float_type_node)
663918334Speter	    {
664018334Speter	      TREE_TYPE (found) = double_type_node;
664118334Speter	      DECL_ARG_TYPE (found) = double_type_node;
664218334Speter	      layout_decl (found, 0);
664318334Speter	    }
664418334Speter
664518334Speter	  /* If no declaration found, default to int.  */
664618334Speter	  if (!found)
664718334Speter	    {
664818334Speter	      found = build_decl (PARM_DECL, TREE_VALUE (parm),
664918334Speter				  integer_type_node);
665018334Speter	      DECL_ARG_TYPE (found) = TREE_TYPE (found);
665118334Speter	      DECL_SOURCE_LINE (found) = DECL_SOURCE_LINE (fndecl);
665218334Speter	      DECL_SOURCE_FILE (found) = DECL_SOURCE_FILE (fndecl);
665390075Sobrien	      if (flag_isoc99)
665490075Sobrien		pedwarn_with_decl (found, "type of `%s' defaults to `int'");
665590075Sobrien	      else if (extra_warnings)
665618334Speter		warning_with_decl (found, "type of `%s' defaults to `int'");
665718334Speter	      pushdecl (found);
665818334Speter	    }
665918334Speter
666018334Speter	  TREE_PURPOSE (parm) = found;
666118334Speter
666290075Sobrien	  /* Mark this decl as "already found".  */
666390075Sobrien	  DECL_WEAK (found) = 1;
666418334Speter	}
666518334Speter
666618334Speter      /* Put anything which is on the parmdecls chain and which is
666718334Speter	 not a PARM_DECL onto the list NONPARMS.  (The types of
666818334Speter	 non-parm things which might appear on the list include
666918334Speter	 enumerators and NULL-named TYPE_DECL nodes.) Complain about
667018334Speter	 any actual PARM_DECLs not matched with any names.  */
667118334Speter
667218334Speter      nonparms = 0;
667390075Sobrien      for (parm = parmdecls; parm;)
667418334Speter	{
667518334Speter	  tree next = TREE_CHAIN (parm);
667618334Speter	  TREE_CHAIN (parm) = 0;
667718334Speter
667818334Speter	  if (TREE_CODE (parm) != PARM_DECL)
667918334Speter	    nonparms = chainon (nonparms, parm);
668018334Speter	  else
668118334Speter	    {
668218334Speter	      /* Complain about args with incomplete types.  */
668390075Sobrien	      if (!COMPLETE_TYPE_P (TREE_TYPE (parm)))
668490075Sobrien		{
668590075Sobrien		  error_with_decl (parm, "parameter `%s' has incomplete type");
668690075Sobrien		  TREE_TYPE (parm) = error_mark_node;
668790075Sobrien		}
668818334Speter
668990075Sobrien	      if (! DECL_WEAK (parm))
669090075Sobrien		{
669190075Sobrien		  error_with_decl (parm,
669290075Sobrien				   "declaration for parameter `%s' but no such parameter");
669318334Speter	          /* Pretend the parameter was not missing.
669418334Speter		     This gets us to a standard state and minimizes
669518334Speter		     further error messages.  */
669690075Sobrien		  specparms
669718334Speter		    = chainon (specparms,
669818334Speter			       tree_cons (parm, NULL_TREE, NULL_TREE));
669918334Speter		}
670018334Speter	    }
670118334Speter
670218334Speter	  parm = next;
670318334Speter	}
670418334Speter
670590075Sobrien      /* Chain the declarations together in the order of the list of
670690075Sobrien         names.  Store that chain in the function decl, replacing the
670790075Sobrien         list of names.  */
670818334Speter      parm = specparms;
670918334Speter      DECL_ARGUMENTS (fndecl) = 0;
671018334Speter      {
671190075Sobrien	tree last;
671218334Speter	for (last = 0; parm; parm = TREE_CHAIN (parm))
671318334Speter	  if (TREE_PURPOSE (parm))
671418334Speter	    {
671518334Speter	      if (last == 0)
671618334Speter		DECL_ARGUMENTS (fndecl) = TREE_PURPOSE (parm);
671718334Speter	      else
671818334Speter		TREE_CHAIN (last) = TREE_PURPOSE (parm);
671918334Speter	      last = TREE_PURPOSE (parm);
672018334Speter	      TREE_CHAIN (last) = 0;
672118334Speter	    }
672218334Speter      }
672318334Speter
672418334Speter      /* If there was a previous prototype,
672518334Speter	 set the DECL_ARG_TYPE of each argument according to
672618334Speter	 the type previously specified, and report any mismatches.  */
672718334Speter
672818334Speter      if (TYPE_ARG_TYPES (TREE_TYPE (fndecl)))
672918334Speter	{
673090075Sobrien	  tree type;
673118334Speter	  for (parm = DECL_ARGUMENTS (fndecl),
673218334Speter	       type = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
673318334Speter	       parm || (type && (TYPE_MAIN_VARIANT (TREE_VALUE (type))
673418334Speter				 != void_type_node));
673518334Speter	       parm = TREE_CHAIN (parm), type = TREE_CHAIN (type))
673618334Speter	    {
673718334Speter	      if (parm == 0 || type == 0
673818334Speter		  || TYPE_MAIN_VARIANT (TREE_VALUE (type)) == void_type_node)
673918334Speter		{
674018334Speter		  error ("number of arguments doesn't match prototype");
674118334Speter		  error_with_file_and_line (current_function_prototype_file,
674218334Speter					    current_function_prototype_line,
674318334Speter					    "prototype declaration");
674418334Speter		  break;
674518334Speter		}
674690075Sobrien	      /* Type for passing arg must be consistent with that
674790075Sobrien		 declared for the arg.  ISO C says we take the unqualified
674890075Sobrien		 type for parameters declared with qualified type.  */
674990075Sobrien	      if (! comptypes (TYPE_MAIN_VARIANT (DECL_ARG_TYPE (parm)),
675090075Sobrien			       TYPE_MAIN_VARIANT (TREE_VALUE (type))))
675118334Speter		{
675218334Speter		  if (TYPE_MAIN_VARIANT (TREE_TYPE (parm))
675318334Speter		      == TYPE_MAIN_VARIANT (TREE_VALUE (type)))
675418334Speter		    {
675518334Speter		      /* Adjust argument to match prototype.  E.g. a previous
675618334Speter			 `int foo(float);' prototype causes
675718334Speter			 `int foo(x) float x; {...}' to be treated like
675818334Speter			 `int foo(float x) {...}'.  This is particularly
675918334Speter			 useful for argument types like uid_t.  */
676018334Speter		      DECL_ARG_TYPE (parm) = TREE_TYPE (parm);
676190075Sobrien
676290075Sobrien		      if (PROMOTE_PROTOTYPES
676390075Sobrien			  && INTEGRAL_TYPE_P (TREE_TYPE (parm))
676418334Speter			  && TYPE_PRECISION (TREE_TYPE (parm))
676518334Speter			  < TYPE_PRECISION (integer_type_node))
676618334Speter			DECL_ARG_TYPE (parm) = integer_type_node;
676790075Sobrien
676818334Speter		      if (pedantic)
676918334Speter			{
677018334Speter			  pedwarn ("promoted argument `%s' doesn't match prototype",
677118334Speter				   IDENTIFIER_POINTER (DECL_NAME (parm)));
677218334Speter			  warning_with_file_and_line
677318334Speter			    (current_function_prototype_file,
677418334Speter			     current_function_prototype_line,
677518334Speter			     "prototype declaration");
677618334Speter			}
677718334Speter		    }
677818334Speter		  /* If -traditional, allow `int' argument to match
677918334Speter		     `unsigned' prototype.  */
678018334Speter		  else if (! (flag_traditional
678118334Speter			      && TYPE_MAIN_VARIANT (TREE_TYPE (parm)) == integer_type_node
678218334Speter			      && TYPE_MAIN_VARIANT (TREE_VALUE (type)) == unsigned_type_node))
678318334Speter		    {
678418334Speter		      error ("argument `%s' doesn't match prototype",
678518334Speter			     IDENTIFIER_POINTER (DECL_NAME (parm)));
678618334Speter		      error_with_file_and_line (current_function_prototype_file,
678718334Speter						current_function_prototype_line,
678818334Speter						"prototype declaration");
678918334Speter		    }
679018334Speter		}
679118334Speter	    }
679218334Speter	  TYPE_ACTUAL_ARG_TYPES (TREE_TYPE (fndecl)) = 0;
679318334Speter	}
679418334Speter
679518334Speter      /* Otherwise, create a prototype that would match.  */
679618334Speter
679718334Speter      else
679818334Speter	{
679918334Speter	  tree actual = 0, last = 0, type;
680018334Speter
680118334Speter	  for (parm = DECL_ARGUMENTS (fndecl); parm; parm = TREE_CHAIN (parm))
680218334Speter	    {
680390075Sobrien	      type = tree_cons (NULL_TREE, DECL_ARG_TYPE (parm), NULL_TREE);
680418334Speter	      if (last)
680518334Speter		TREE_CHAIN (last) = type;
680618334Speter	      else
680718334Speter		actual = type;
680818334Speter	      last = type;
680918334Speter	    }
681090075Sobrien	  type = tree_cons (NULL_TREE, void_type_node, NULL_TREE);
681118334Speter	  if (last)
681218334Speter	    TREE_CHAIN (last) = type;
681318334Speter	  else
681418334Speter	    actual = type;
681518334Speter
681618334Speter	  /* We are going to assign a new value for the TYPE_ACTUAL_ARG_TYPES
681718334Speter	     of the type of this function, but we need to avoid having this
681818334Speter	     affect the types of other similarly-typed functions, so we must
681918334Speter	     first force the generation of an identical (but separate) type
682018334Speter	     node for the relevant function type.  The new node we create
682118334Speter	     will be a variant of the main variant of the original function
682218334Speter	     type.  */
682318334Speter
682418334Speter	  TREE_TYPE (fndecl) = build_type_copy (TREE_TYPE (fndecl));
682518334Speter
682618334Speter	  TYPE_ACTUAL_ARG_TYPES (TREE_TYPE (fndecl)) = actual;
682718334Speter	}
682818334Speter
682918334Speter      /* Now store the final chain of decls for the arguments
683018334Speter	 as the decl-chain of the current lexical scope.
683118334Speter	 Put the enumerators in as well, at the front so that
683218334Speter	 DECL_ARGUMENTS is not modified.  */
683318334Speter
683418334Speter      storedecls (chainon (nonparms, DECL_ARGUMENTS (fndecl)));
683518334Speter    }
683618334Speter
683718334Speter  /* Make sure the binding level for the top of the function body
683818334Speter     gets a BLOCK if there are any in the function.
683918334Speter     Otherwise, the dbx output is wrong.  */
684018334Speter
684118334Speter  keep_next_if_subblocks = 1;
684218334Speter
684318334Speter  /* ??? This might be an improvement,
684418334Speter     but needs to be thought about some more.  */
684518334Speter#if 0
684618334Speter  keep_next_level_flag = 1;
684718334Speter#endif
684818334Speter
684918334Speter  /* Write a record describing this function definition to the prototypes
685018334Speter     file (if requested).  */
685118334Speter
685218334Speter  gen_aux_info_record (fndecl, 1, 0, prototype);
685318334Speter
685418334Speter  /* Initialize the RTL code for the function.  */
685518334Speter  init_function_start (fndecl, input_filename, lineno);
685618334Speter
685790075Sobrien  /* Begin the statement tree for this function.  */
685890075Sobrien  begin_stmt_tree (&DECL_SAVED_TREE (current_function_decl));
685918334Speter
686090075Sobrien  /* If this is a nested function, save away the sizes of any
686190075Sobrien     variable-size types so that we can expand them when generating
686290075Sobrien     RTL.  */
686390075Sobrien  if (context)
686418334Speter    {
686590075Sobrien      tree t;
686618334Speter
686790075Sobrien      DECL_LANG_SPECIFIC (fndecl)->pending_sizes
686890075Sobrien	= nreverse (get_pending_sizes ());
686990075Sobrien      for (t = DECL_LANG_SPECIFIC (fndecl)->pending_sizes;
687090075Sobrien	   t;
687190075Sobrien	   t = TREE_CHAIN (t))
687290075Sobrien	SAVE_EXPR_CONTEXT (TREE_VALUE (t)) = context;
687318334Speter    }
687418334Speter
687590075Sobrien  /* This function is being processed in whole-function mode.  */
687690075Sobrien  cfun->x_whole_function_mode_p = 1;
687718334Speter
687890075Sobrien  /* Even though we're inside a function body, we still don't want to
687990075Sobrien     call expand_expr to calculate the size of a variable-sized array.
688090075Sobrien     We haven't necessarily assigned RTL to all variables yet, so it's
688190075Sobrien     not safe to try to expand expressions involving them.  */
688290075Sobrien  immediate_size_expand = 0;
688390075Sobrien  cfun->x_dont_save_pending_sizes_p = 1;
688418334Speter
688590075Sobrien  warn_shadow = saved_warn_shadow;
688618334Speter}
688718334Speter
688818334Speter/* Finish up a function declaration and compile that function
688918334Speter   all the way to assembler language output.  The free the storage
689018334Speter   for the function definition.
689118334Speter
689218334Speter   This is called after parsing the body of the function definition.
689318334Speter
689496263Sobrien   NESTED is nonzero if the function being finished is nested in another.
689596263Sobrien   CAN_DEFER_P is nonzero if the function may be deferred.  */
689618334Speter
689718334Spetervoid
689896263Sobrienfinish_function (nested, can_defer_p)
689918334Speter     int nested;
690096263Sobrien     int can_defer_p;
690118334Speter{
690290075Sobrien  tree fndecl = current_function_decl;
690318334Speter
690496263Sobrien#if 0
690596263Sobrien  /* This caused &foo to be of type ptr-to-const-function which then
690696263Sobrien     got a warning when stored in a ptr-to-function variable.  */
690796263Sobrien  TREE_READONLY (fndecl) = 1;
690896263Sobrien#endif
690918334Speter
691018334Speter  poplevel (1, 0, 1);
691118334Speter  BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
691218334Speter
691318334Speter  /* Must mark the RESULT_DECL as being in this function.  */
691418334Speter
691518334Speter  DECL_CONTEXT (DECL_RESULT (fndecl)) = fndecl;
691618334Speter
691718334Speter  /* Obey `register' declarations if `setjmp' is called in this fn.  */
691818334Speter  if (flag_traditional && current_function_calls_setjmp)
691918334Speter    {
692018334Speter      setjmp_protect (DECL_INITIAL (fndecl));
692118334Speter      setjmp_protect_args ();
692218334Speter    }
692318334Speter
692490075Sobrien  if (MAIN_NAME_P (DECL_NAME (fndecl)) && flag_hosted)
692518334Speter    {
692618334Speter      if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (fndecl)))
692718334Speter	  != integer_type_node)
692850397Sobrien	{
692952284Sobrien	  /* If warn_main is 1 (-Wmain) or 2 (-Wall), we have already warned.
693090075Sobrien	     If warn_main is -1 (-Wno-main) we don't want to be warned.  */
693150397Sobrien	  if (! warn_main)
693250397Sobrien	    pedwarn_with_decl (fndecl, "return type of `%s' is not `int'");
693350397Sobrien	}
693418334Speter      else
693518334Speter	{
693650397Sobrien#ifdef DEFAULT_MAIN_RETURN
693718334Speter	  /* Make it so that `main' always returns success by default.  */
693818334Speter	  DEFAULT_MAIN_RETURN;
693990075Sobrien#else
694090075Sobrien	  if (flag_isoc99)
694190075Sobrien	    c_expand_return (integer_zero_node);
694250397Sobrien#endif
694318334Speter	}
694418334Speter    }
694590075Sobrien
694690075Sobrien  finish_fname_decls ();
694718334Speter
694890075Sobrien  /* Tie off the statement tree for this function.  */
694990075Sobrien  finish_stmt_tree (&DECL_SAVED_TREE (fndecl));
695096263Sobrien
695196263Sobrien  /* Complain if there's just no return statement.  */
695296263Sobrien  if (warn_return_type
695396263Sobrien      && TREE_CODE (TREE_TYPE (TREE_TYPE (fndecl))) != VOID_TYPE
695496263Sobrien      && !current_function_returns_value && !current_function_returns_null
695596263Sobrien      /* Don't complain if we abort.  */
695696263Sobrien      && !current_function_returns_abnormally
695796263Sobrien      /* Don't warn for main().  */
695896263Sobrien      && !MAIN_NAME_P (DECL_NAME (fndecl))
695996263Sobrien      /* Or if they didn't actually specify a return type.  */
696096263Sobrien      && !C_FUNCTION_IMPLICIT_INT (fndecl)
696196263Sobrien      /* Normally, with -Wreturn-type, flow will complain.  Unless we're an
696296263Sobrien	 inline function, as we might never be compiled separately.  */
696396263Sobrien      && DECL_INLINE (fndecl))
696496263Sobrien    warning ("no return statement in function returning non-void");
696596263Sobrien
696690075Sobrien  /* Clear out memory we no longer need.  */
696790075Sobrien  free_after_parsing (cfun);
696890075Sobrien  /* Since we never call rest_of_compilation, we never clear
696990075Sobrien     CFUN.  Do so explicitly.  */
697090075Sobrien  free_after_compilation (cfun);
697190075Sobrien  cfun = NULL;
697290075Sobrien
697390075Sobrien  if (! nested)
697490075Sobrien    {
697590075Sobrien      /* Generate RTL for the body of this function.  */
697696263Sobrien      c_expand_body (fndecl, nested, can_defer_p);
697796263Sobrien
697890075Sobrien      /* Let the error reporting routines know that we're outside a
697990075Sobrien	 function.  For a nested function, this value is used in
698090075Sobrien	 pop_c_function_context and then reset via pop_function_context.  */
698190075Sobrien      current_function_decl = NULL;
698290075Sobrien    }
698390075Sobrien}
698490075Sobrien
698590075Sobrien/* Generate the RTL for a deferred function FNDECL.  */
698690075Sobrien
698790075Sobrienvoid
698890075Sobrienc_expand_deferred_function (fndecl)
698990075Sobrien     tree fndecl;
699090075Sobrien{
699190075Sobrien  /* DECL_INLINE or DECL_RESULT might got cleared after the inline
699290075Sobrien     function was deferred, e.g. in duplicate_decls.  */
699390075Sobrien  if (DECL_INLINE (fndecl) && DECL_RESULT (fndecl))
699490075Sobrien    {
699590075Sobrien      c_expand_body (fndecl, 0, 0);
699690075Sobrien      current_function_decl = NULL;
699790075Sobrien    }
699890075Sobrien}
699990075Sobrien
700090075Sobrien/* Generate the RTL for the body of FNDECL.  If NESTED_P is non-zero,
700190075Sobrien   then we are already in the process of generating RTL for another
700290075Sobrien   function.  If can_defer_p is zero, we won't attempt to defer the
700390075Sobrien   generation of RTL.  */
700490075Sobrien
700590075Sobrienstatic void
700690075Sobrienc_expand_body (fndecl, nested_p, can_defer_p)
700790075Sobrien     tree fndecl;
700890075Sobrien     int nested_p, can_defer_p;
700990075Sobrien{
701090075Sobrien  int uninlinable = 1;
701190075Sobrien
701290075Sobrien  /* There's no reason to do any of the work here if we're only doing
701390075Sobrien     semantic analysis; this code just generates RTL.  */
701490075Sobrien  if (flag_syntax_only)
701590075Sobrien    return;
701690075Sobrien
701790075Sobrien  if (flag_inline_trees)
701890075Sobrien    {
701990075Sobrien      /* First, cache whether the current function is inlinable.  Some
702090075Sobrien         predicates depend on cfun and current_function_decl to
702190075Sobrien         function completely.  */
702290075Sobrien      timevar_push (TV_INTEGRATION);
702390075Sobrien      uninlinable = ! tree_inlinable_function_p (fndecl);
702490075Sobrien
702590075Sobrien      if (! uninlinable && can_defer_p
702690075Sobrien	  /* Save function tree for inlining.  Should return 0 if the
702790075Sobrien             language does not support function deferring or the
702890075Sobrien             function could not be deferred.  */
702990075Sobrien	  && defer_fn (fndecl))
703090075Sobrien	{
703190075Sobrien	  /* Let the back-end know that this function exists.  */
703290075Sobrien	  (*debug_hooks->deferred_inline_function) (fndecl);
703390075Sobrien          timevar_pop (TV_INTEGRATION);
703490075Sobrien	  return;
703590075Sobrien	}
703690075Sobrien
703790075Sobrien      /* Then, inline any functions called in it.  */
703890075Sobrien      optimize_inline_calls (fndecl);
703990075Sobrien      timevar_pop (TV_INTEGRATION);
704090075Sobrien    }
704190075Sobrien
704290075Sobrien  timevar_push (TV_EXPAND);
704390075Sobrien
704490075Sobrien  if (nested_p)
704590075Sobrien    {
704690075Sobrien      /* Make sure that we will evaluate variable-sized types involved
704790075Sobrien	 in our function's type.  */
704890075Sobrien      expand_pending_sizes (DECL_LANG_SPECIFIC (fndecl)->pending_sizes);
704990075Sobrien      /* Squirrel away our current state.  */
705090075Sobrien      push_function_context ();
705190075Sobrien    }
705290075Sobrien
705390075Sobrien  /* Initialize the RTL code for the function.  */
705490075Sobrien  current_function_decl = fndecl;
705590075Sobrien  input_filename = DECL_SOURCE_FILE (fndecl);
705690075Sobrien  init_function_start (fndecl, input_filename, DECL_SOURCE_LINE (fndecl));
705790075Sobrien
705890075Sobrien  /* This function is being processed in whole-function mode.  */
705990075Sobrien  cfun->x_whole_function_mode_p = 1;
706090075Sobrien
706190075Sobrien  /* Even though we're inside a function body, we still don't want to
706290075Sobrien     call expand_expr to calculate the size of a variable-sized array.
706390075Sobrien     We haven't necessarily assigned RTL to all variables yet, so it's
706490075Sobrien     not safe to try to expand expressions involving them.  */
706590075Sobrien  immediate_size_expand = 0;
706690075Sobrien  cfun->x_dont_save_pending_sizes_p = 1;
706790075Sobrien
706890075Sobrien  /* If this is a varargs function, inform function.c.  */
706990075Sobrien  if (c_function_varargs)
707090075Sobrien    mark_varargs ();
707190075Sobrien
707290075Sobrien  /* Set up parameters and prepare for return, for the function.  */
707390075Sobrien  expand_function_start (fndecl, 0);
707490075Sobrien
707590075Sobrien  /* If this function is `main', emit a call to `__main'
707690075Sobrien     to run global initializers, etc.  */
707790075Sobrien  if (DECL_NAME (fndecl)
707890075Sobrien      && MAIN_NAME_P (DECL_NAME (fndecl))
707990075Sobrien      && DECL_CONTEXT (fndecl) == NULL_TREE)
708090075Sobrien    expand_main_function ();
708190075Sobrien
708290075Sobrien  /* Generate the RTL for this function.  */
708390075Sobrien  expand_stmt (DECL_SAVED_TREE (fndecl));
708490075Sobrien  if (uninlinable)
708590075Sobrien    {
708690075Sobrien      /* Allow the body of the function to be garbage collected.  */
708790075Sobrien      DECL_SAVED_TREE (fndecl) = NULL_TREE;
708890075Sobrien    }
708990075Sobrien
709090075Sobrien  /* We hard-wired immediate_size_expand to zero above.
709190075Sobrien     expand_function_end will decrement this variable.  So, we set the
709290075Sobrien     variable to one here, so that after the decrement it will remain
709390075Sobrien     zero.  */
709490075Sobrien  immediate_size_expand = 1;
709590075Sobrien
709690075Sobrien  /* Allow language dialects to perform special processing.  */
709790075Sobrien  if (lang_expand_function_end)
709890075Sobrien    (*lang_expand_function_end) ();
709990075Sobrien
710018334Speter  /* Generate rtl for function exit.  */
710118334Speter  expand_function_end (input_filename, lineno, 0);
710218334Speter
710390075Sobrien  /* If this is a nested function, protect the local variables in the stack
710490075Sobrien     above us from being collected while we're compiling this function.  */
710590075Sobrien  if (nested_p)
710690075Sobrien    ggc_push_context ();
710718334Speter
710818334Speter  /* Run the optimizers and output the assembler code for this function.  */
710918334Speter  rest_of_compilation (fndecl);
711018334Speter
711190075Sobrien  /* Undo the GC context switch.  */
711290075Sobrien  if (nested_p)
711390075Sobrien    ggc_pop_context ();
711418334Speter
711518334Speter  /* With just -W, complain only if function returns both with
711618334Speter     and without a value.  */
711790075Sobrien  if (extra_warnings
711890075Sobrien      && current_function_returns_value
711990075Sobrien      && current_function_returns_null)
712018334Speter    warning ("this function may return with or without a value");
712118334Speter
712218334Speter  /* If requested, warn about function definitions where the function will
712318334Speter     return a value (usually of some struct or union type) which itself will
712418334Speter     take up a lot of stack space.  */
712518334Speter
712618334Speter  if (warn_larger_than && !DECL_EXTERNAL (fndecl) && TREE_TYPE (fndecl))
712718334Speter    {
712890075Sobrien      tree ret_type = TREE_TYPE (TREE_TYPE (fndecl));
712918334Speter
713090075Sobrien      if (ret_type && TYPE_SIZE_UNIT (ret_type)
713190075Sobrien	  && TREE_CODE (TYPE_SIZE_UNIT (ret_type)) == INTEGER_CST
713290075Sobrien	  && 0 < compare_tree_int (TYPE_SIZE_UNIT (ret_type),
713390075Sobrien				   larger_than_size))
713418334Speter	{
713590075Sobrien	  unsigned int size_as_int
713690075Sobrien	    = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (ret_type));
713718334Speter
713890075Sobrien	  if (compare_tree_int (TYPE_SIZE_UNIT (ret_type), size_as_int) == 0)
713990075Sobrien	    warning_with_decl (fndecl,
714090075Sobrien			       "size of return value of `%s' is %u bytes",
714190075Sobrien			       size_as_int);
714290075Sobrien	  else
714390075Sobrien	    warning_with_decl (fndecl,
714490075Sobrien			       "size of return value of `%s' is larger than %d bytes",
714590075Sobrien			       larger_than_size);
714618334Speter	}
714718334Speter    }
714818334Speter
714990075Sobrien  if (DECL_SAVED_INSNS (fndecl) == 0 && ! nested_p
715090075Sobrien      && ! flag_inline_trees)
715118334Speter    {
715290075Sobrien      /* Stop pointing to the local nodes about to be freed.
715390075Sobrien	 But DECL_INITIAL must remain nonzero so we know this
715490075Sobrien	 was an actual function definition.
715590075Sobrien	 For a nested function, this is done in pop_c_function_context.
715690075Sobrien	 If rest_of_compilation set this to 0, leave it 0.  */
715718334Speter      if (DECL_INITIAL (fndecl) != 0)
715818334Speter	DECL_INITIAL (fndecl) = error_mark_node;
715990075Sobrien
716018334Speter      DECL_ARGUMENTS (fndecl) = 0;
716118334Speter    }
716218334Speter
716318334Speter  if (DECL_STATIC_CONSTRUCTOR (fndecl))
716418334Speter    {
716590075Sobrien      if (targetm.have_ctors_dtors)
716690075Sobrien	(* targetm.asm_out.constructor) (XEXP (DECL_RTL (fndecl), 0),
716790075Sobrien				         DEFAULT_INIT_PRIORITY);
716818334Speter      else
716990075Sobrien	static_ctors = tree_cons (NULL_TREE, fndecl, static_ctors);
717018334Speter    }
717190075Sobrien
717218334Speter  if (DECL_STATIC_DESTRUCTOR (fndecl))
717318334Speter    {
717490075Sobrien      if (targetm.have_ctors_dtors)
717590075Sobrien	(* targetm.asm_out.destructor) (XEXP (DECL_RTL (fndecl), 0),
717690075Sobrien				        DEFAULT_INIT_PRIORITY);
717718334Speter      else
717890075Sobrien	static_dtors = tree_cons (NULL_TREE, fndecl, static_dtors);
717918334Speter    }
718018334Speter
718190075Sobrien  if (nested_p)
718290075Sobrien    /* Return to the enclosing function.  */
718390075Sobrien    pop_function_context ();
718490075Sobrien  timevar_pop (TV_EXPAND);
718590075Sobrien}
718690075Sobrien
718790075Sobrien/* Check the declarations given in a for-loop for satisfying the C99
718890075Sobrien   constraints.  */
718990075Sobrienvoid
719090075Sobriencheck_for_loop_decls ()
719190075Sobrien{
719290075Sobrien  tree t;
719390075Sobrien
719490075Sobrien  if (!flag_isoc99)
719518334Speter    {
719690075Sobrien      /* If we get here, declarations have been used in a for loop without
719790075Sobrien	 the C99 for loop scope.  This doesn't make much sense, so don't
719890075Sobrien	 allow it.  */
719990075Sobrien      error ("`for' loop initial declaration used outside C99 mode");
720090075Sobrien      return;
720118334Speter    }
720290075Sobrien  /* C99 subclause 6.8.5 paragraph 3:
720390075Sobrien
720490075Sobrien       [#3]  The  declaration  part  of  a for statement shall only
720590075Sobrien       declare identifiers for objects having storage class auto or
720690075Sobrien       register.
720790075Sobrien
720890075Sobrien     It isn't clear whether, in this sentence, "identifiers" binds to
720990075Sobrien     "shall only declare" or to "objects" - that is, whether all identifiers
721090075Sobrien     declared must be identifiers for objects, or whether the restriction
721190075Sobrien     only applies to those that are.  (A question on this in comp.std.c
721290075Sobrien     in November 2000 received no answer.)  We implement the strictest
721390075Sobrien     interpretation, to avoid creating an extension which later causes
721490075Sobrien     problems.  */
721590075Sobrien
721690075Sobrien  for (t = gettags (); t; t = TREE_CHAIN (t))
721790075Sobrien    {
721890075Sobrien      if (TREE_PURPOSE (t) != 0)
721990075Sobrien        {
722090075Sobrien          enum tree_code code = TREE_CODE (TREE_VALUE (t));
722190075Sobrien
722290075Sobrien          if (code == RECORD_TYPE)
722390075Sobrien            error ("`struct %s' declared in `for' loop initial declaration",
722490075Sobrien                   IDENTIFIER_POINTER (TREE_PURPOSE (t)));
722590075Sobrien          else if (code == UNION_TYPE)
722690075Sobrien            error ("`union %s' declared in `for' loop initial declaration",
722790075Sobrien                   IDENTIFIER_POINTER (TREE_PURPOSE (t)));
722890075Sobrien          else
722990075Sobrien            error ("`enum %s' declared in `for' loop initial declaration",
723090075Sobrien                   IDENTIFIER_POINTER (TREE_PURPOSE (t)));
723190075Sobrien        }
723290075Sobrien    }
723390075Sobrien
723490075Sobrien  for (t = getdecls (); t; t = TREE_CHAIN (t))
723590075Sobrien    {
723690075Sobrien      if (TREE_CODE (t) != VAR_DECL && DECL_NAME (t))
723790075Sobrien	error_with_decl (t, "declaration of non-variable `%s' in `for' loop initial declaration");
723890075Sobrien      else if (TREE_STATIC (t))
723990075Sobrien	error_with_decl (t, "declaration of static variable `%s' in `for' loop initial declaration");
724090075Sobrien      else if (DECL_EXTERNAL (t))
724190075Sobrien	error_with_decl (t, "declaration of `extern' variable `%s' in `for' loop initial declaration");
724290075Sobrien    }
724318334Speter}
724418334Speter
724518334Speter/* Save and restore the variables in this file and elsewhere
724618334Speter   that keep track of the progress of compilation of the current function.
724718334Speter   Used for nested functions.  */
724818334Speter
724990075Sobrienstruct c_language_function
725018334Speter{
725190075Sobrien  struct language_function base;
725218334Speter  tree named_labels;
725318334Speter  tree shadowed_labels;
725418334Speter  int returns_value;
725518334Speter  int returns_null;
725696263Sobrien  int returns_abnormally;
725718334Speter  int warn_about_return_type;
725818334Speter  int extern_inline;
725918334Speter  struct binding_level *binding_level;
726018334Speter};
726118334Speter
726218334Speter/* Save and reinitialize the variables
726318334Speter   used during compilation of a C function.  */
726418334Speter
726518334Spetervoid
726690075Sobrienpush_c_function_context (f)
726790075Sobrien     struct function *f;
726818334Speter{
726990075Sobrien  struct c_language_function *p;
727090075Sobrien  p = ((struct c_language_function *)
727190075Sobrien       xmalloc (sizeof (struct c_language_function)));
727290075Sobrien  f->language = (struct language_function *) p;
727318334Speter
727490075Sobrien  p->base.x_stmt_tree = c_stmt_tree;
727590075Sobrien  p->base.x_scope_stmt_stack = c_scope_stmt_stack;
727618334Speter  p->named_labels = named_labels;
727718334Speter  p->shadowed_labels = shadowed_labels;
727818334Speter  p->returns_value = current_function_returns_value;
727918334Speter  p->returns_null = current_function_returns_null;
728096263Sobrien  p->returns_abnormally = current_function_returns_abnormally;
728118334Speter  p->warn_about_return_type = warn_about_return_type;
728218334Speter  p->extern_inline = current_extern_inline;
728318334Speter  p->binding_level = current_binding_level;
728418334Speter}
728518334Speter
728618334Speter/* Restore the variables used during compilation of a C function.  */
728718334Speter
728818334Spetervoid
728990075Sobrienpop_c_function_context (f)
729090075Sobrien     struct function *f;
729118334Speter{
729290075Sobrien  struct c_language_function *p
729390075Sobrien    = (struct c_language_function *) f->language;
729418334Speter  tree link;
729518334Speter
729618334Speter  /* Bring back all the labels that were shadowed.  */
729718334Speter  for (link = shadowed_labels; link; link = TREE_CHAIN (link))
729818334Speter    if (DECL_NAME (TREE_VALUE (link)) != 0)
729918334Speter      IDENTIFIER_LABEL_VALUE (DECL_NAME (TREE_VALUE (link)))
730018334Speter	= TREE_VALUE (link);
730118334Speter
730290075Sobrien  if (DECL_SAVED_INSNS (current_function_decl) == 0
730390075Sobrien      && DECL_SAVED_TREE (current_function_decl) == NULL_TREE)
730418334Speter    {
730518334Speter      /* Stop pointing to the local nodes about to be freed.  */
730618334Speter      /* But DECL_INITIAL must remain nonzero so we know this
730718334Speter	 was an actual function definition.  */
730818334Speter      DECL_INITIAL (current_function_decl) = error_mark_node;
730918334Speter      DECL_ARGUMENTS (current_function_decl) = 0;
731018334Speter    }
731118334Speter
731290075Sobrien  c_stmt_tree = p->base.x_stmt_tree;
731390075Sobrien  c_scope_stmt_stack = p->base.x_scope_stmt_stack;
731418334Speter  named_labels = p->named_labels;
731518334Speter  shadowed_labels = p->shadowed_labels;
731618334Speter  current_function_returns_value = p->returns_value;
731718334Speter  current_function_returns_null = p->returns_null;
731896263Sobrien  current_function_returns_abnormally = p->returns_abnormally;
731918334Speter  warn_about_return_type = p->warn_about_return_type;
732018334Speter  current_extern_inline = p->extern_inline;
732118334Speter  current_binding_level = p->binding_level;
732218334Speter
732318334Speter  free (p);
732490075Sobrien  f->language = 0;
732518334Speter}
732618334Speter
732790075Sobrien/* Mark the language specific parts of F for GC.  */
732818334Speter
732918334Spetervoid
733090075Sobrienmark_c_function_context (f)
733190075Sobrien     struct function *f;
733290075Sobrien{
733390075Sobrien  struct c_language_function *p
733490075Sobrien    = (struct c_language_function *) f->language;
733590075Sobrien
733690075Sobrien  if (p == 0)
733790075Sobrien    return;
733890075Sobrien
733990075Sobrien  mark_c_language_function (&p->base);
734090075Sobrien  ggc_mark_tree (p->shadowed_labels);
734190075Sobrien  ggc_mark_tree (p->named_labels);
734290075Sobrien  mark_binding_level (&p->binding_level);
734390075Sobrien}
734490075Sobrien
734590075Sobrien/* Copy the DECL_LANG_SPECIFIC data associated with NODE.  */
734690075Sobrien
734790075Sobrienvoid
734890075Sobriencopy_lang_decl (decl)
734990075Sobrien     tree decl;
735090075Sobrien{
735190075Sobrien  struct lang_decl *ld;
735290075Sobrien
735390075Sobrien  if (!DECL_LANG_SPECIFIC (decl))
735490075Sobrien    return;
735590075Sobrien
735690075Sobrien  ld = (struct lang_decl *) ggc_alloc (sizeof (struct lang_decl));
735790075Sobrien  memcpy ((char *) ld, (char *) DECL_LANG_SPECIFIC (decl),
735890075Sobrien	  sizeof (struct lang_decl));
735990075Sobrien  DECL_LANG_SPECIFIC (decl) = ld;
736090075Sobrien}
736190075Sobrien
736290075Sobrien/* Mark the language specific bits in T for GC.  */
736390075Sobrien
736490075Sobrienvoid
736590075Sobrienlang_mark_tree (t)
736690075Sobrien     tree t;
736790075Sobrien{
736890075Sobrien  if (TREE_CODE (t) == IDENTIFIER_NODE)
736990075Sobrien    {
737090075Sobrien      struct lang_identifier *i = (struct lang_identifier *) t;
737190075Sobrien      ggc_mark_tree (i->global_value);
737290075Sobrien      ggc_mark_tree (i->local_value);
737390075Sobrien      ggc_mark_tree (i->label_value);
737490075Sobrien      ggc_mark_tree (i->implicit_decl);
737590075Sobrien      ggc_mark_tree (i->error_locus);
737690075Sobrien      ggc_mark_tree (i->limbo_value);
737790075Sobrien    }
737890075Sobrien  else if (TYPE_P (t) && TYPE_LANG_SPECIFIC (t))
737990075Sobrien    ggc_mark (TYPE_LANG_SPECIFIC (t));
738090075Sobrien  else if (DECL_P (t) && DECL_LANG_SPECIFIC (t))
738190075Sobrien    {
738290075Sobrien      ggc_mark (DECL_LANG_SPECIFIC (t));
738390075Sobrien      c_mark_lang_decl (&DECL_LANG_SPECIFIC (t)->base);
738490075Sobrien      ggc_mark_tree (DECL_LANG_SPECIFIC (t)->pending_sizes);
738590075Sobrien    }
738690075Sobrien}
738790075Sobrien
738890075Sobrien/* The functions below are required for functionality of doing
738990075Sobrien   function at once processing in the C front end. Currently these
739090075Sobrien   functions are not called from anywhere in the C front end, but as
739190075Sobrien   these changes continue, that will change.  */
739290075Sobrien
739390075Sobrien/* Returns non-zero if the current statement is a full expression,
739490075Sobrien   i.e. temporaries created during that statement should be destroyed
739590075Sobrien   at the end of the statement.  */
739690075Sobrien
739790075Sobrienint
739890075Sobrienstmts_are_full_exprs_p ()
739990075Sobrien{
740090075Sobrien  return 0;
740190075Sobrien}
740290075Sobrien
740390075Sobrien/* Returns the stmt_tree (if any) to which statements are currently
740490075Sobrien   being added.  If there is no active statement-tree, NULL is
740590075Sobrien   returned.  */
740690075Sobrien
740790075Sobrienstmt_tree
740890075Sobriencurrent_stmt_tree ()
740990075Sobrien{
741090075Sobrien  return &c_stmt_tree;
741190075Sobrien}
741290075Sobrien
741390075Sobrien/* Returns the stack of SCOPE_STMTs for the current function.  */
741490075Sobrien
741590075Sobrientree *
741690075Sobriencurrent_scope_stmt_stack ()
741790075Sobrien{
741890075Sobrien  return &c_scope_stmt_stack;
741990075Sobrien}
742090075Sobrien
742190075Sobrien/* Nonzero if TYPE is an anonymous union or struct type.  Always 0 in
742290075Sobrien   C.  */
742390075Sobrien
742490075Sobrienint
742590075Sobrienanon_aggr_type_p (node)
742650397Sobrien     tree node ATTRIBUTE_UNUSED;
742718334Speter{
742890075Sobrien  return 0;
742918334Speter}
743090075Sobrien
743190075Sobrien/* Dummy function in place of callback used by C++.  */
743290075Sobrien
743390075Sobrienvoid
743490075Sobrienextract_interface_info ()
743590075Sobrien{
743690075Sobrien}
743790075Sobrien
743890075Sobrien/* Return a new COMPOUND_STMT, after adding it to the current
743990075Sobrien   statement tree.  */
744090075Sobrien
744190075Sobrientree
744290075Sobrienc_begin_compound_stmt ()
744390075Sobrien{
744490075Sobrien  tree stmt;
744590075Sobrien
744690075Sobrien  /* Create the COMPOUND_STMT.  */
744790075Sobrien  stmt = add_stmt (build_stmt (COMPOUND_STMT, NULL_TREE));
744890075Sobrien
744990075Sobrien  return stmt;
745090075Sobrien}
745190075Sobrien
745290075Sobrien/* Expand T (a DECL_STMT) if it declares an entity not handled by the
745390075Sobrien   common code.  */
745490075Sobrien
745590075Sobrienvoid
745690075Sobrienc_expand_decl_stmt (t)
745790075Sobrien     tree t;
745890075Sobrien{
745990075Sobrien  tree decl = DECL_STMT_DECL (t);
746090075Sobrien
746190075Sobrien  /* Expand nested functions.  */
746290075Sobrien  if (TREE_CODE (decl) == FUNCTION_DECL
746390075Sobrien      && DECL_CONTEXT (decl) == current_function_decl
746490075Sobrien      && DECL_SAVED_TREE (decl))
746590075Sobrien    c_expand_body (decl, /*nested_p=*/1, /*can_defer_p=*/0);
746690075Sobrien}
746790075Sobrien
746890075Sobrien/* Return the IDENTIFIER_GLOBAL_VALUE of T, for use in common code, since
746990075Sobrien   the definition of IDENTIFIER_GLOBAL_VALUE is different for C and C++.  */
747090075Sobrien
747190075Sobrientree
747290075Sobrienidentifier_global_value	(t)
747390075Sobrien     tree t;
747490075Sobrien{
747590075Sobrien  return IDENTIFIER_GLOBAL_VALUE (t);
747690075Sobrien}
747790075Sobrien
747890075Sobrien/* Record a builtin type for C.  If NAME is non-NULL, it is the name used;
747990075Sobrien   otherwise the name is found in ridpointers from RID_INDEX.  */
748090075Sobrien
748190075Sobrienvoid
748290075Sobrienrecord_builtin_type (rid_index, name, type)
748390075Sobrien     enum rid rid_index;
748490075Sobrien     const char *name;
748590075Sobrien     tree type;
748690075Sobrien{
748790075Sobrien  tree id;
748890075Sobrien  if (name == 0)
748990075Sobrien    id = ridpointers[(int) rid_index];
749090075Sobrien  else
749190075Sobrien    id = get_identifier (name);
749290075Sobrien  pushdecl (build_decl (TYPE_DECL, id, type));
749390075Sobrien}
749490075Sobrien
749590075Sobrien/* Build the void_list_node (void_type_node having been created).  */
749690075Sobrientree
749790075Sobrienbuild_void_list_node ()
749890075Sobrien{
749990075Sobrien  tree t = build_tree_list (NULL_TREE, void_type_node);
750090075Sobrien  return t;
750190075Sobrien}
7502