c-decl.c revision 96549
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
2296549Sobrien/* $FreeBSD: head/contrib/gcc/c-decl.c 96549 2002-05-14 00:30:25Z obrien $ */
2396549Sobrien
2418334Speter/* Process declarations and symbol lookup for C front end.
2518334Speter   Also constructs types; the standard scalar types at initialization,
2618334Speter   and structure, union, array and enum types when they are declared.  */
2718334Speter
2818334Speter/* ??? not all decl nodes are given the most useful possible
2918334Speter   line numbers.  For example, the CONST_DECLs for enum values.  */
3018334Speter
3118334Speter#include "config.h"
3250397Sobrien#include "system.h"
3390075Sobrien#include "intl.h"
3418334Speter#include "tree.h"
3590075Sobrien#include "tree-inline.h"
3690075Sobrien#include "rtl.h"
3718334Speter#include "flags.h"
3890075Sobrien#include "function.h"
3918334Speter#include "output.h"
4090075Sobrien#include "expr.h"
4118334Speter#include "c-tree.h"
4218334Speter#include "c-lex.h"
4350397Sobrien#include "toplev.h"
4490075Sobrien#include "ggc.h"
4590075Sobrien#include "tm_p.h"
4650397Sobrien#include "cpplib.h"
4790075Sobrien#include "target.h"
4890075Sobrien#include "debug.h"
4990075Sobrien#include "timevar.h"
5090075Sobrien#include "c-common.h"
5196263Sobrien#include "c-pragma.h"
5250397Sobrien
5318334Speter/* In grokdeclarator, distinguish syntactic contexts of declarators.  */
5418334Speterenum decl_context
5518334Speter{ NORMAL,			/* Ordinary declaration */
5618334Speter  FUNCDEF,			/* Function definition */
5718334Speter  PARM,				/* Declaration of parm before function body */
5818334Speter  FIELD,			/* Declaration inside struct or union */
5996263Sobrien  BITFIELD,			/* Likewise but with specified width */
6018334Speter  TYPENAME};			/* Typename (inside cast or sizeof)  */
6118334Speter
6218334Speter
6318334Speter/* Nonzero if we have seen an invalid cross reference
6418334Speter   to a struct, union, or enum, but not yet printed the message.  */
6518334Speter
6618334Spetertree pending_invalid_xref;
6718334Speter/* File and line to appear in the eventual error message.  */
6890075Sobrienconst char *pending_invalid_xref_file;
6918334Speterint pending_invalid_xref_line;
7018334Speter
7118334Speter/* While defining an enum type, this is 1 plus the last enumerator
7218334Speter   constant value.  Note that will do not have to save this or `enum_overflow'
7318334Speter   around nested function definition since such a definition could only
7418334Speter   occur in an enum value expression and we don't use these variables in
7518334Speter   that case.  */
7618334Speter
7718334Speterstatic tree enum_next_value;
7818334Speter
7918334Speter/* Nonzero means that there was overflow computing enum_next_value.  */
8018334Speter
8118334Speterstatic int enum_overflow;
8218334Speter
8318334Speter/* Parsing a function declarator leaves a list of parameter names
8418334Speter   or a chain or parameter decls here.  */
8518334Speter
8618334Speterstatic tree last_function_parms;
8718334Speter
8818334Speter/* Parsing a function declarator leaves here a chain of structure
8918334Speter   and enum types declared in the parmlist.  */
9018334Speter
9118334Speterstatic tree last_function_parm_tags;
9218334Speter
9318334Speter/* After parsing the declarator that starts a function definition,
9418334Speter   `start_function' puts here the list of parameter names or chain of decls.
9518334Speter   `store_parm_decls' finds it here.  */
9618334Speter
9718334Speterstatic tree current_function_parms;
9818334Speter
9918334Speter/* Similar, for last_function_parm_tags.  */
10018334Speterstatic tree current_function_parm_tags;
10118334Speter
10218334Speter/* Similar, for the file and line that the prototype came from if this is
10318334Speter   an old-style definition.  */
10490075Sobrienstatic const char *current_function_prototype_file;
10518334Speterstatic int current_function_prototype_line;
10618334Speter
10790075Sobrien/* The current statement tree.  */
10890075Sobrien
10990075Sobrienstatic struct stmt_tree_s c_stmt_tree;
11090075Sobrien
11190075Sobrien/* The current scope statement stack.  */
11290075Sobrien
11390075Sobrienstatic tree c_scope_stmt_stack;
11490075Sobrien
11518334Speter/* A list (chain of TREE_LIST nodes) of all LABEL_DECLs in the function
11618334Speter   that have names.  Here so we can clear out their names' definitions
11718334Speter   at the end of the function.  */
11818334Speter
11918334Speterstatic tree named_labels;
12018334Speter
12118334Speter/* A list of LABEL_DECLs from outer contexts that are currently shadowed.  */
12218334Speter
12318334Speterstatic tree shadowed_labels;
12418334Speter
12518334Speter/* Nonzero when store_parm_decls is called indicates a varargs function.
12618334Speter   Value not meaningful after store_parm_decls.  */
12718334Speter
12818334Speterstatic int c_function_varargs;
12918334Speter
13018334Speter/* Set to 0 at beginning of a function definition, set to 1 if
13118334Speter   a return statement that specifies a return value is seen.  */
13218334Speter
13318334Speterint current_function_returns_value;
13418334Speter
13518334Speter/* Set to 0 at beginning of a function definition, set to 1 if
13618334Speter   a return statement with no argument is seen.  */
13718334Speter
13818334Speterint current_function_returns_null;
13918334Speter
14096263Sobrien/* Set to 0 at beginning of a function definition, set to 1 if
14196263Sobrien   a call to a noreturn function is seen.  */
14296263Sobrien
14396263Sobrienint current_function_returns_abnormally;
14496263Sobrien
14518334Speter/* Set to nonzero by `grokdeclarator' for a function
14618334Speter   whose return type is defaulted, if warnings for this are desired.  */
14718334Speter
14818334Speterstatic int warn_about_return_type;
14918334Speter
15018334Speter/* Nonzero when starting a function declared `extern inline'.  */
15118334Speter
15218334Speterstatic int current_extern_inline;
15318334Speter
15418334Speter/* For each binding contour we allocate a binding_level structure
15518334Speter * which records the names defined in that contour.
15618334Speter * Contours include:
15718334Speter *  0) the global one
15818334Speter *  1) one for each function definition,
15918334Speter *     where internal declarations of the parameters appear.
16018334Speter *  2) one for each compound statement,
16118334Speter *     to record its declarations.
16218334Speter *
16318334Speter * The current meaning of a name can be found by searching the levels from
16418334Speter * the current one out to the global one.
16518334Speter */
16618334Speter
16718334Speter/* Note that the information in the `names' component of the global contour
16818334Speter   is duplicated in the IDENTIFIER_GLOBAL_VALUEs of all identifiers.  */
16918334Speter
17018334Speterstruct binding_level
17118334Speter  {
17218334Speter    /* A chain of _DECL nodes for all variables, constants, functions,
17318334Speter       and typedef types.  These are in the reverse of the order supplied.
17418334Speter     */
17518334Speter    tree names;
17618334Speter
17718334Speter    /* A list of structure, union and enum definitions,
17818334Speter     * for looking up tag names.
17918334Speter     * It is a chain of TREE_LIST nodes, each of whose TREE_PURPOSE is a name,
18018334Speter     * or NULL_TREE; and whose TREE_VALUE is a RECORD_TYPE, UNION_TYPE,
18118334Speter     * or ENUMERAL_TYPE node.
18218334Speter     */
18318334Speter    tree tags;
18418334Speter
18518334Speter    /* For each level, a list of shadowed outer-level local definitions
18618334Speter       to be restored when this level is popped.
18718334Speter       Each link is a TREE_LIST whose TREE_PURPOSE is an identifier and
18818334Speter       whose TREE_VALUE is its old definition (a kind of ..._DECL node).  */
18918334Speter    tree shadowed;
19018334Speter
19118334Speter    /* For each level (except not the global one),
19218334Speter       a chain of BLOCK nodes for all the levels
19318334Speter       that were entered and exited one level down.  */
19418334Speter    tree blocks;
19518334Speter
19618334Speter    /* The BLOCK node for this level, if one has been preallocated.
19718334Speter       If 0, the BLOCK is allocated (if needed) when the level is popped.  */
19818334Speter    tree this_block;
19918334Speter
20018334Speter    /* The binding level which this one is contained in (inherits from).  */
20118334Speter    struct binding_level *level_chain;
20218334Speter
20318334Speter    /* Nonzero for the level that holds the parameters of a function.  */
20418334Speter    char parm_flag;
20518334Speter
20618334Speter    /* Nonzero if this level "doesn't exist" for tags.  */
20718334Speter    char tag_transparent;
20818334Speter
20918334Speter    /* Nonzero if sublevels of this level "don't exist" for tags.
21018334Speter       This is set in the parm level of a function definition
21118334Speter       while reading the function body, so that the outermost block
21218334Speter       of the function body will be tag-transparent.  */
21318334Speter    char subblocks_tag_transparent;
21418334Speter
21518334Speter    /* Nonzero means make a BLOCK for this level regardless of all else.  */
21618334Speter    char keep;
21718334Speter
21818334Speter    /* Nonzero means make a BLOCK if this level has any subblocks.  */
21918334Speter    char keep_if_subblocks;
22018334Speter
22190075Sobrien    /* Number of decls in `names' that have incomplete
22218334Speter       structure or union types.  */
22318334Speter    int n_incomplete;
22418334Speter
22518334Speter    /* A list of decls giving the (reversed) specified order of parms,
22618334Speter       not including any forward-decls in the parmlist.
22718334Speter       This is so we can put the parms in proper order for assign_parms.  */
22818334Speter    tree parm_order;
22918334Speter  };
23018334Speter
23118334Speter#define NULL_BINDING_LEVEL (struct binding_level *) NULL
23290075Sobrien
23318334Speter/* The binding level currently in effect.  */
23418334Speter
23518334Speterstatic struct binding_level *current_binding_level;
23618334Speter
23718334Speter/* A chain of binding_level structures awaiting reuse.  */
23818334Speter
23918334Speterstatic struct binding_level *free_binding_level;
24018334Speter
24118334Speter/* The outermost binding level, for names of file scope.
24218334Speter   This is created when the compiler is started and exists
24318334Speter   through the entire run.  */
24418334Speter
24518334Speterstatic struct binding_level *global_binding_level;
24618334Speter
24718334Speter/* Binding level structures are initialized by copying this one.  */
24818334Speter
24918334Speterstatic struct binding_level clear_binding_level
25018334Speter  = {NULL, NULL, NULL, NULL, NULL, NULL_BINDING_LEVEL, 0, 0, 0, 0, 0, 0,
25118334Speter     NULL};
25218334Speter
25318334Speter/* Nonzero means unconditionally make a BLOCK for the next level pushed.  */
25418334Speter
25518334Speterstatic int keep_next_level_flag;
25618334Speter
25718334Speter/* Nonzero means make a BLOCK for the next level pushed
25818334Speter   if it has subblocks.  */
25918334Speter
26018334Speterstatic int keep_next_if_subblocks;
26190075Sobrien
26218334Speter/* The chain of outer levels of label scopes.
26318334Speter   This uses the same data structure used for binding levels,
26418334Speter   but it works differently: each link in the chain records
26518334Speter   saved values of named_labels and shadowed_labels for
26618334Speter   a label binding level outside the current one.  */
26718334Speter
26818334Speterstatic struct binding_level *label_level_chain;
26918334Speter
27018334Speter/* Functions called automatically at the beginning and end of execution.  */
27118334Speter
27218334Spetertree static_ctors, static_dtors;
27318334Speter
27418334Speter/* Forward declarations.  */
27518334Speter
27690075Sobrienstatic struct binding_level * make_binding_level	PARAMS ((void));
27790075Sobrienstatic void mark_binding_level		PARAMS ((void *));
27890075Sobrienstatic void clear_limbo_values		PARAMS ((tree));
27990075Sobrienstatic int duplicate_decls		PARAMS ((tree, tree, int));
28090075Sobrienstatic int redeclaration_error_message	PARAMS ((tree, tree));
28190075Sobrienstatic void storedecls			PARAMS ((tree));
28290075Sobrienstatic void storetags			PARAMS ((tree));
28390075Sobrienstatic tree lookup_tag			PARAMS ((enum tree_code, tree,
28490075Sobrien						 struct binding_level *, int));
28590075Sobrienstatic tree lookup_tag_reverse		PARAMS ((tree));
28690075Sobrienstatic tree grokdeclarator		PARAMS ((tree, tree, enum decl_context,
28796263Sobrien						 int));
28890075Sobrienstatic tree grokparms			PARAMS ((tree, int));
28990075Sobrienstatic void layout_array_type		PARAMS ((tree));
29090075Sobrienstatic tree c_make_fname_decl           PARAMS ((tree, int));
29190075Sobrienstatic void c_expand_body               PARAMS ((tree, int, int));
29290075Sobrienstatic void warn_if_shadowing		PARAMS ((tree, tree));
29318334Speter
29418334Speter/* C-specific option variables.  */
29518334Speter
29618334Speter/* Nonzero means allow type mismatches in conditional expressions;
29790075Sobrien   just make their values `void'.  */
29818334Speter
29918334Speterint flag_cond_mismatch;
30018334Speter
30118334Speter/* Nonzero means don't recognize the keyword `asm'.  */
30218334Speter
30318334Speterint flag_no_asm;
30418334Speter
30590075Sobrien/* Nonzero means do some things the same way PCC does.  */
30618334Speter
30790075Sobrienint flag_traditional;
30818334Speter
30990075Sobrien/* Nonzero means enable C89 Amendment 1 features.  */
31018334Speter
31190075Sobrienint flag_isoc94 = 0;
31218334Speter
31390075Sobrien/* Nonzero means use the ISO C99 dialect of C.  */
31418334Speter
31590075Sobrienint flag_isoc99 = 0;
31618334Speter
31796549Sobrien/* Nonzero means allow the BSD kernel printf enhancments.  */
31896549Sobrien
31996549Sobrienint flag_bsd_format = 0;
32096549Sobrien
32150397Sobrien/* Nonzero means that we have builtin functions, and main is an int */
32250397Sobrien
32350397Sobrienint flag_hosted = 1;
32450397Sobrien
32590075Sobrien/* Nonzero means add default format_arg attributes for functions not
32690075Sobrien   in ISO C.  */
32790075Sobrien
32890075Sobrienint flag_noniso_default_format_attributes = 1;
32990075Sobrien
33018334Speter/* Nonzero means to allow single precision math even if we're generally
33150397Sobrien   being traditional.  */
33218334Speterint flag_allow_single_precision = 0;
33318334Speter
33496263Sobrien/* Nonzero means to treat bitfields as signed unless they say `unsigned'.  */
33518334Speter
33618334Speterint flag_signed_bitfields = 1;
33718334Speterint explicit_flag_signed_bitfields = 0;
33818334Speter
33990075Sobrien/* Nonzero means warn about use of implicit int.  */
34018334Speter
34150397Sobrienint warn_implicit_int;
34218334Speter
34350397Sobrien/* Nonzero means warn about usage of long long when `-pedantic'.  */
34450397Sobrien
34550397Sobrienint warn_long_long = 1;
34650397Sobrien
34750397Sobrien/* Nonzero means message about use of implicit function declarations;
34890075Sobrien 1 means warning; 2 means error.  */
34950397Sobrien
35090075Sobrienint mesg_implicit_function_declaration = -1;
35150397Sobrien
35218334Speter/* Nonzero means give string constants the type `const char *'
35318334Speter   to get extra warnings from them.  These warnings will be too numerous
35418334Speter   to be useful, except in thoroughly ANSIfied programs.  */
35518334Speter
35652284Sobrienint flag_const_strings;
35718334Speter
35818334Speter/* Nonzero means warn about pointer casts that can drop a type qualifier
35918334Speter   from the pointer target type.  */
36018334Speter
36118334Speterint warn_cast_qual;
36218334Speter
36318334Speter/* Nonzero means warn when casting a function call to a type that does
36418334Speter   not match the return type (e.g. (float)sqrt() or (anything*)malloc()
36518334Speter   when there is no previous declaration of sqrt or malloc.  */
36618334Speter
36718334Speterint warn_bad_function_cast;
36818334Speter
36990075Sobrien/* Warn about functions which might be candidates for format attributes.  */
37052284Sobrien
37190075Sobrienint warn_missing_format_attribute;
37252284Sobrien
37318334Speter/* Warn about traditional constructs whose meanings changed in ANSI C.  */
37418334Speter
37518334Speterint warn_traditional;
37618334Speter
37718334Speter/* Nonzero means warn about sizeof(function) or addition/subtraction
37818334Speter   of function pointers.  */
37918334Speter
38018334Speterint warn_pointer_arith;
38118334Speter
38218334Speter/* Nonzero means warn for non-prototype function decls
38318334Speter   or non-prototyped defs without previous prototype.  */
38418334Speter
38518334Speterint warn_strict_prototypes;
38618334Speter
38718334Speter/* Nonzero means warn for any global function def
38818334Speter   without separate previous prototype decl.  */
38918334Speter
39018334Speterint warn_missing_prototypes;
39118334Speter
39218334Speter/* Nonzero means warn for any global function def
39318334Speter   without separate previous decl.  */
39418334Speter
39518334Speterint warn_missing_declarations;
39618334Speter
39718334Speter/* Nonzero means warn about multiple (redundant) decls for the same single
39818334Speter   variable or function.  */
39918334Speter
40018334Speterint warn_redundant_decls = 0;
40118334Speter
40218334Speter/* Nonzero means warn about extern declarations of objects not at
40318334Speter   file-scope level and about *all* declarations of functions (whether
40418334Speter   extern or static) not at file-scope level.  Note that we exclude
40518334Speter   implicit function declarations.  To get warnings about those, use
40618334Speter   -Wimplicit.  */
40718334Speter
40818334Speterint warn_nested_externs = 0;
40918334Speter
41018334Speter/* Warn about a subscript that has type char.  */
41118334Speter
41218334Speterint warn_char_subscripts = 0;
41318334Speter
41418334Speter/* Warn if a type conversion is done that might have confusing results.  */
41518334Speter
41618334Speterint warn_conversion;
41718334Speter
41818334Speter/* Warn if adding () is suggested.  */
41918334Speter
42018334Speterint warn_parentheses;
42118334Speter
42218334Speter/* Warn if initializer is not completely bracketed.  */
42318334Speter
42418334Speterint warn_missing_braces;
42518334Speter
42650397Sobrien/* Warn if main is suspicious.  */
42718334Speter
42850397Sobrienint warn_main;
42950397Sobrien
43050397Sobrien/* Warn about #pragma directives that are not recognised.  */
43150397Sobrien
43290075Sobrienint warn_unknown_pragmas = 0; /* Tri state variable.  */
43350397Sobrien
43450397Sobrien/* Warn about comparison of signed and unsigned values.
43550397Sobrien   If -1, neither -Wsign-compare nor -Wno-sign-compare has been specified.  */
43650397Sobrien
43750397Sobrienint warn_sign_compare = -1;
43850397Sobrien
43990075Sobrien/* Warn about testing equality of floating point numbers.  */
44090075Sobrien
44190075Sobrienint warn_float_equal = 0;
44290075Sobrien
44350397Sobrien/* Nonzero means warn about use of multicharacter literals.  */
44450397Sobrien
44550397Sobrienint warn_multichar = 1;
44650397Sobrien
44750397Sobrien/* Nonzero means `$' can be in an identifier.  */
44850397Sobrien
44918334Speter#ifndef DOLLARS_IN_IDENTIFIERS
45018334Speter#define DOLLARS_IN_IDENTIFIERS 1
45118334Speter#endif
45250397Sobrienint dollars_in_ident = DOLLARS_IN_IDENTIFIERS;
45318334Speter
45490075Sobrien/* States indicating how grokdeclarator() should handle declspecs marked
45590075Sobrien   with __attribute__((deprecated)).  An object declared as
45690075Sobrien   __attribute__((deprecated)) suppresses warnings of uses of other
45790075Sobrien   deprecated items.  */
45890075Sobrien
45990075Sobrienenum deprecated_states {
46090075Sobrien  DEPRECATED_NORMAL,
46190075Sobrien  DEPRECATED_SUPPRESS
46290075Sobrien};
46390075Sobrien
46490075Sobrienstatic enum deprecated_states deprecated_state = DEPRECATED_NORMAL;
46590075Sobrien
46618334Speter/* Decode the string P as a language-specific option for C.
46790075Sobrien   Return the number of strings consumed.  Should not complain
46890075Sobrien   if it does not recognise the option.  */
46990075Sobrien
47018334Speterint
47150397Sobrienc_decode_option (argc, argv)
47252284Sobrien     int argc ATTRIBUTE_UNUSED;
47350397Sobrien     char **argv;
47418334Speter{
47550397Sobrien  int strings_processed;
47650397Sobrien  char *p = argv[0];
47750397Sobrien
47890075Sobrien  strings_processed = cpp_handle_option (parse_in, argc, argv, 0);
47990075Sobrien
48018334Speter  if (!strcmp (p, "-ftraditional") || !strcmp (p, "-traditional"))
48118334Speter    {
48290075Sobrien      warning ("-traditional is deprecated and may be removed");
48318334Speter      flag_traditional = 1;
48418334Speter      flag_writable_strings = 1;
48518334Speter    }
48618334Speter  else if (!strcmp (p, "-fallow-single-precision"))
48718334Speter    flag_allow_single_precision = 1;
48850397Sobrien  else if (!strcmp (p, "-fhosted") || !strcmp (p, "-fno-freestanding"))
48950397Sobrien    {
49050397Sobrien      flag_hosted = 1;
49150397Sobrien      flag_no_builtin = 0;
49250397Sobrien    }
49350397Sobrien  else if (!strcmp (p, "-ffreestanding") || !strcmp (p, "-fno-hosted"))
49450397Sobrien    {
49550397Sobrien      flag_hosted = 0;
49650397Sobrien      flag_no_builtin = 1;
49750397Sobrien      /* warn_main will be 2 if set by -Wall, 1 if set by -Wmain */
49850397Sobrien      if (warn_main == 2)
49950397Sobrien	warn_main = 0;
50050397Sobrien    }
50118334Speter  else if (!strcmp (p, "-fnotraditional") || !strcmp (p, "-fno-traditional"))
50218334Speter    {
50318334Speter      flag_traditional = 0;
50418334Speter      flag_writable_strings = 0;
50518334Speter    }
50652284Sobrien  else if (!strncmp (p, "-std=", 5))
50752284Sobrien    {
50852284Sobrien      /* Select the appropriate language standard.  We currently
50952284Sobrien	 recognize:
51052284Sobrien	 -std=iso9899:1990	same as -ansi
51152284Sobrien	 -std=iso9899:199409	ISO C as modified in amend. 1
51290075Sobrien	 -std=iso9899:1999	ISO C 99
51352284Sobrien	 -std=c89		same as -std=iso9899:1990
51490075Sobrien	 -std=c99		same as -std=iso9899:1999
51552284Sobrien	 -std=gnu89		default, iso9899:1990 + gnu extensions
51690075Sobrien	 -std=gnu99		iso9899:1999 + gnu extensions
51796549Sobrien	 -std=bsd		iso9899:1999 + BSD kernel printf extensions
51852284Sobrien      */
51990075Sobrien      const char *const argstart = &p[5];
52052284Sobrien
52152284Sobrien      if (!strcmp (argstart, "iso9899:1990")
52252284Sobrien	  || !strcmp (argstart, "c89"))
52352284Sobrien	{
52452284Sobrien	iso_1990:
52590075Sobrien	  flag_isoc94 = 0;
52690075Sobrien	iso_1994:
52752284Sobrien	  flag_traditional = 0;
52852284Sobrien	  flag_writable_strings = 0;
52952284Sobrien	  flag_no_asm = 1;
53052284Sobrien	  flag_no_nonansi_builtin = 1;
53190075Sobrien	  flag_noniso_default_format_attributes = 0;
53290075Sobrien	  flag_isoc99 = 0;
53396549Sobrien	  flag_bsd_format = 0;
53452284Sobrien	}
53552284Sobrien      else if (!strcmp (argstart, "iso9899:199409"))
53652284Sobrien	{
53790075Sobrien	  flag_isoc94 = 1;
53890075Sobrien	  goto iso_1994;
53952284Sobrien	}
54052284Sobrien      else if (!strcmp (argstart, "iso9899:199x")
54190075Sobrien	       || !strcmp (argstart, "iso9899:1999")
54290075Sobrien	       || !strcmp (argstart, "c9x")
54390075Sobrien	       || !strcmp (argstart, "c99"))
54452284Sobrien	{
54552284Sobrien	  flag_traditional = 0;
54652284Sobrien	  flag_writable_strings = 0;
54752284Sobrien	  flag_no_asm = 1;
54852284Sobrien	  flag_no_nonansi_builtin = 1;
54990075Sobrien	  flag_noniso_default_format_attributes = 0;
55090075Sobrien	  flag_isoc99 = 1;
55190075Sobrien	  flag_isoc94 = 1;
55296549Sobrien	  flag_bsd_format = 0;
55352284Sobrien	}
55452284Sobrien      else if (!strcmp (argstart, "gnu89"))
55552284Sobrien	{
55652284Sobrien	  flag_traditional = 0;
55752284Sobrien	  flag_writable_strings = 0;
55852284Sobrien	  flag_no_asm = 0;
55952284Sobrien	  flag_no_nonansi_builtin = 0;
56090075Sobrien	  flag_noniso_default_format_attributes = 1;
56190075Sobrien	  flag_isoc99 = 0;
56290075Sobrien	  flag_isoc94 = 0;
56396549Sobrien	  flag_bsd_format = 0;
56452284Sobrien	}
56590075Sobrien      else if (!strcmp (argstart, "gnu9x") || !strcmp (argstart, "gnu99"))
56652284Sobrien	{
56752284Sobrien	  flag_traditional = 0;
56852284Sobrien	  flag_writable_strings = 0;
56952284Sobrien	  flag_no_asm = 0;
57052284Sobrien	  flag_no_nonansi_builtin = 0;
57190075Sobrien	  flag_noniso_default_format_attributes = 1;
57290075Sobrien	  flag_isoc99 = 1;
57390075Sobrien	  flag_isoc94 = 1;
57496549Sobrien	  flag_bsd_format = 0;
57552284Sobrien	}
57696549Sobrien      else if (!strcmp (argstart, "bsd"))
57796549Sobrien	{
57896549Sobrien	  flag_traditional = 0;
57996549Sobrien	  flag_writable_strings = 0;
58096549Sobrien	  flag_no_asm = 0;
58196549Sobrien	  flag_no_nonansi_builtin = 0;
58296549Sobrien	  flag_noniso_default_format_attributes = 1;
58396549Sobrien	  flag_isoc99 = 0;
58496549Sobrien	  flag_isoc94 = 0;
58596549Sobrien	  flag_isoc94 = 0;
58696549Sobrien	  flag_bsd_format = 1;
58796549Sobrien	}
58852284Sobrien      else
58952284Sobrien	error ("unknown C standard `%s'", argstart);
59052284Sobrien    }
59118334Speter  else if (!strcmp (p, "-fdollars-in-identifiers"))
59250397Sobrien    dollars_in_ident = 1;
59318334Speter  else if (!strcmp (p, "-fno-dollars-in-identifiers"))
59418334Speter    dollars_in_ident = 0;
59518334Speter  else if (!strcmp (p, "-fsigned-char"))
59618334Speter    flag_signed_char = 1;
59718334Speter  else if (!strcmp (p, "-funsigned-char"))
59818334Speter    flag_signed_char = 0;
59918334Speter  else if (!strcmp (p, "-fno-signed-char"))
60018334Speter    flag_signed_char = 0;
60118334Speter  else if (!strcmp (p, "-fno-unsigned-char"))
60218334Speter    flag_signed_char = 1;
60318334Speter  else if (!strcmp (p, "-fsigned-bitfields")
60418334Speter	   || !strcmp (p, "-fno-unsigned-bitfields"))
60518334Speter    {
60618334Speter      flag_signed_bitfields = 1;
60718334Speter      explicit_flag_signed_bitfields = 1;
60818334Speter    }
60918334Speter  else if (!strcmp (p, "-funsigned-bitfields")
61018334Speter	   || !strcmp (p, "-fno-signed-bitfields"))
61118334Speter    {
61218334Speter      flag_signed_bitfields = 0;
61318334Speter      explicit_flag_signed_bitfields = 1;
61418334Speter    }
61518334Speter  else if (!strcmp (p, "-fshort-enums"))
61618334Speter    flag_short_enums = 1;
61718334Speter  else if (!strcmp (p, "-fno-short-enums"))
61818334Speter    flag_short_enums = 0;
61990075Sobrien  else if (!strcmp (p, "-fshort-wchar"))
62090075Sobrien    flag_short_wchar = 1;
62190075Sobrien  else if (!strcmp (p, "-fno-short-wchar"))
62290075Sobrien    flag_short_wchar = 0;
62318334Speter  else if (!strcmp (p, "-fcond-mismatch"))
62418334Speter    flag_cond_mismatch = 1;
62518334Speter  else if (!strcmp (p, "-fno-cond-mismatch"))
62618334Speter    flag_cond_mismatch = 0;
62718334Speter  else if (!strcmp (p, "-fshort-double"))
62818334Speter    flag_short_double = 1;
62918334Speter  else if (!strcmp (p, "-fno-short-double"))
63018334Speter    flag_short_double = 0;
63118334Speter  else if (!strcmp (p, "-fasm"))
63218334Speter    flag_no_asm = 0;
63318334Speter  else if (!strcmp (p, "-fno-asm"))
63418334Speter    flag_no_asm = 1;
63518334Speter  else if (!strcmp (p, "-fbuiltin"))
63618334Speter    flag_no_builtin = 0;
63718334Speter  else if (!strcmp (p, "-fno-builtin"))
63818334Speter    flag_no_builtin = 1;
63990075Sobrien  else if (!strncmp (p, "-fno-builtin-", strlen ("-fno-builtin-")))
64090075Sobrien    disable_builtin_function (p + strlen ("-fno-builtin-"));
64190075Sobrien  else if (p[0] == '-' && p[1] == 'f' && dump_switch_p (p + 2))
64290075Sobrien    ;
64318334Speter  else if (!strcmp (p, "-ansi"))
64452284Sobrien    goto iso_1990;
64550397Sobrien  else if (!strcmp (p, "-Werror-implicit-function-declaration"))
64650397Sobrien    mesg_implicit_function_declaration = 2;
64750397Sobrien  else if (!strcmp (p, "-Wimplicit-function-declaration"))
64850397Sobrien    mesg_implicit_function_declaration = 1;
64950397Sobrien  else if (!strcmp (p, "-Wno-implicit-function-declaration"))
65050397Sobrien    mesg_implicit_function_declaration = 0;
65150397Sobrien  else if (!strcmp (p, "-Wimplicit-int"))
65250397Sobrien    warn_implicit_int = 1;
65350397Sobrien  else if (!strcmp (p, "-Wno-implicit-int"))
65450397Sobrien    warn_implicit_int = 0;
65518334Speter  else if (!strcmp (p, "-Wimplicit"))
65650397Sobrien    {
65750397Sobrien      warn_implicit_int = 1;
65850397Sobrien      if (mesg_implicit_function_declaration != 2)
65990075Sobrien	mesg_implicit_function_declaration = 1;
66050397Sobrien    }
66118334Speter  else if (!strcmp (p, "-Wno-implicit"))
66250397Sobrien    warn_implicit_int = 0, mesg_implicit_function_declaration = 0;
66350397Sobrien  else if (!strcmp (p, "-Wlong-long"))
66450397Sobrien    warn_long_long = 1;
66550397Sobrien  else if (!strcmp (p, "-Wno-long-long"))
66650397Sobrien    warn_long_long = 0;
66718334Speter  else if (!strcmp (p, "-Wwrite-strings"))
66852284Sobrien    flag_const_strings = 1;
66918334Speter  else if (!strcmp (p, "-Wno-write-strings"))
67052284Sobrien    flag_const_strings = 0;
67118334Speter  else if (!strcmp (p, "-Wcast-qual"))
67218334Speter    warn_cast_qual = 1;
67318334Speter  else if (!strcmp (p, "-Wno-cast-qual"))
67418334Speter    warn_cast_qual = 0;
67518334Speter  else if (!strcmp (p, "-Wbad-function-cast"))
67618334Speter    warn_bad_function_cast = 1;
67718334Speter  else if (!strcmp (p, "-Wno-bad-function-cast"))
67818334Speter    warn_bad_function_cast = 0;
67952284Sobrien  else if (!strcmp (p, "-Wno-missing-noreturn"))
68052284Sobrien    warn_missing_noreturn = 0;
68190075Sobrien  else if (!strcmp (p, "-Wmissing-format-attribute"))
68290075Sobrien    warn_missing_format_attribute = 1;
68390075Sobrien  else if (!strcmp (p, "-Wno-missing-format-attribute"))
68490075Sobrien    warn_missing_format_attribute = 0;
68518334Speter  else if (!strcmp (p, "-Wpointer-arith"))
68618334Speter    warn_pointer_arith = 1;
68718334Speter  else if (!strcmp (p, "-Wno-pointer-arith"))
68818334Speter    warn_pointer_arith = 0;
68918334Speter  else if (!strcmp (p, "-Wstrict-prototypes"))
69018334Speter    warn_strict_prototypes = 1;
69118334Speter  else if (!strcmp (p, "-Wno-strict-prototypes"))
69218334Speter    warn_strict_prototypes = 0;
69318334Speter  else if (!strcmp (p, "-Wmissing-prototypes"))
69418334Speter    warn_missing_prototypes = 1;
69518334Speter  else if (!strcmp (p, "-Wno-missing-prototypes"))
69618334Speter    warn_missing_prototypes = 0;
69718334Speter  else if (!strcmp (p, "-Wmissing-declarations"))
69818334Speter    warn_missing_declarations = 1;
69918334Speter  else if (!strcmp (p, "-Wno-missing-declarations"))
70018334Speter    warn_missing_declarations = 0;
70118334Speter  else if (!strcmp (p, "-Wredundant-decls"))
70218334Speter    warn_redundant_decls = 1;
70318334Speter  else if (!strcmp (p, "-Wno-redundant-decls"))
70418334Speter    warn_redundant_decls = 0;
70518334Speter  else if (!strcmp (p, "-Wnested-externs"))
70618334Speter    warn_nested_externs = 1;
70718334Speter  else if (!strcmp (p, "-Wno-nested-externs"))
70818334Speter    warn_nested_externs = 0;
70918334Speter  else if (!strcmp (p, "-Wtraditional"))
71018334Speter    warn_traditional = 1;
71118334Speter  else if (!strcmp (p, "-Wno-traditional"))
71218334Speter    warn_traditional = 0;
71390075Sobrien  else if (!strncmp (p, "-Wformat=", 9))
71490075Sobrien    set_Wformat (atoi (p + 9));
71518334Speter  else if (!strcmp (p, "-Wformat"))
71690075Sobrien    set_Wformat (1);
71718334Speter  else if (!strcmp (p, "-Wno-format"))
71890075Sobrien    set_Wformat (0);
71990075Sobrien  else if (!strcmp (p, "-Wformat-y2k"))
72090075Sobrien    warn_format_y2k = 1;
72190075Sobrien  else if (!strcmp (p, "-Wno-format-y2k"))
72290075Sobrien    warn_format_y2k = 0;
72390075Sobrien  else if (!strcmp (p, "-Wformat-extra-args"))
72490075Sobrien    warn_format_extra_args = 1;
72590075Sobrien  else if (!strcmp (p, "-Wno-format-extra-args"))
72690075Sobrien    warn_format_extra_args = 0;
72790075Sobrien  else if (!strcmp (p, "-Wformat-nonliteral"))
72890075Sobrien    warn_format_nonliteral = 1;
72990075Sobrien  else if (!strcmp (p, "-Wno-format-nonliteral"))
73090075Sobrien    warn_format_nonliteral = 0;
73190075Sobrien  else if (!strcmp (p, "-Wformat-security"))
73290075Sobrien    warn_format_security = 1;
73390075Sobrien  else if (!strcmp (p, "-Wno-format-security"))
73490075Sobrien    warn_format_security = 0;
73518334Speter  else if (!strcmp (p, "-Wchar-subscripts"))
73618334Speter    warn_char_subscripts = 1;
73718334Speter  else if (!strcmp (p, "-Wno-char-subscripts"))
73818334Speter    warn_char_subscripts = 0;
73918334Speter  else if (!strcmp (p, "-Wconversion"))
74018334Speter    warn_conversion = 1;
74118334Speter  else if (!strcmp (p, "-Wno-conversion"))
74218334Speter    warn_conversion = 0;
74318334Speter  else if (!strcmp (p, "-Wparentheses"))
74418334Speter    warn_parentheses = 1;
74518334Speter  else if (!strcmp (p, "-Wno-parentheses"))
74618334Speter    warn_parentheses = 0;
74718334Speter  else if (!strcmp (p, "-Wreturn-type"))
74818334Speter    warn_return_type = 1;
74918334Speter  else if (!strcmp (p, "-Wno-return-type"))
75018334Speter    warn_return_type = 0;
75190075Sobrien  else if (!strcmp (p, "-Wsequence-point"))
75290075Sobrien    warn_sequence_point = 1;
75390075Sobrien  else if (!strcmp (p, "-Wno-sequence-point"))
75490075Sobrien    warn_sequence_point = 0;
75518334Speter  else if (!strcmp (p, "-Wcomment"))
75618334Speter    ; /* cpp handles this one.  */
75718334Speter  else if (!strcmp (p, "-Wno-comment"))
75818334Speter    ; /* cpp handles this one.  */
75918334Speter  else if (!strcmp (p, "-Wcomments"))
76018334Speter    ; /* cpp handles this one.  */
76118334Speter  else if (!strcmp (p, "-Wno-comments"))
76218334Speter    ; /* cpp handles this one.  */
76318334Speter  else if (!strcmp (p, "-Wtrigraphs"))
76418334Speter    ; /* cpp handles this one.  */
76518334Speter  else if (!strcmp (p, "-Wno-trigraphs"))
76618334Speter    ; /* cpp handles this one.  */
76750397Sobrien  else if (!strcmp (p, "-Wundef"))
76850397Sobrien    ; /* cpp handles this one.  */
76950397Sobrien  else if (!strcmp (p, "-Wno-undef"))
77050397Sobrien    ; /* cpp handles this one.  */
77118334Speter  else if (!strcmp (p, "-Wimport"))
77218334Speter    ; /* cpp handles this one.  */
77318334Speter  else if (!strcmp (p, "-Wno-import"))
77418334Speter    ; /* cpp handles this one.  */
77518334Speter  else if (!strcmp (p, "-Wmissing-braces"))
77618334Speter    warn_missing_braces = 1;
77718334Speter  else if (!strcmp (p, "-Wno-missing-braces"))
77818334Speter    warn_missing_braces = 0;
77950397Sobrien  else if (!strcmp (p, "-Wmain"))
78050397Sobrien    warn_main = 1;
78150397Sobrien  else if (!strcmp (p, "-Wno-main"))
78252284Sobrien    warn_main = -1;
78350397Sobrien  else if (!strcmp (p, "-Wsign-compare"))
78450397Sobrien    warn_sign_compare = 1;
78550397Sobrien  else if (!strcmp (p, "-Wno-sign-compare"))
78650397Sobrien    warn_sign_compare = 0;
78790075Sobrien  else if (!strcmp (p, "-Wfloat-equal"))
78890075Sobrien    warn_float_equal = 1;
78990075Sobrien  else if (!strcmp (p, "-Wno-float-equal"))
79090075Sobrien    warn_float_equal = 0;
79150397Sobrien  else if (!strcmp (p, "-Wmultichar"))
79250397Sobrien    warn_multichar = 1;
79350397Sobrien  else if (!strcmp (p, "-Wno-multichar"))
79450397Sobrien    warn_multichar = 0;
79590075Sobrien  else if (!strcmp (p, "-Wdiv-by-zero"))
79690075Sobrien    warn_div_by_zero = 1;
79790075Sobrien  else if (!strcmp (p, "-Wno-div-by-zero"))
79890075Sobrien    warn_div_by_zero = 0;
79950397Sobrien  else if (!strcmp (p, "-Wunknown-pragmas"))
80050397Sobrien    /* Set to greater than 1, so that even unknown pragmas in system
80150397Sobrien       headers will be warned about.  */
80250397Sobrien    warn_unknown_pragmas = 2;
80350397Sobrien  else if (!strcmp (p, "-Wno-unknown-pragmas"))
80450397Sobrien    warn_unknown_pragmas = 0;
80518334Speter  else if (!strcmp (p, "-Wall"))
80618334Speter    {
80718334Speter      /* We save the value of warn_uninitialized, since if they put
80818334Speter	 -Wuninitialized on the command line, we need to generate a
80918334Speter	 warning about not using it without also specifying -O.  */
81018334Speter      if (warn_uninitialized != 1)
81118334Speter	warn_uninitialized = 2;
81250397Sobrien      warn_implicit_int = 1;
81350397Sobrien      mesg_implicit_function_declaration = 1;
81418334Speter      warn_return_type = 1;
81590075Sobrien      set_Wunused (1);
81618334Speter      warn_switch = 1;
81790075Sobrien      set_Wformat (1);
81818334Speter      warn_char_subscripts = 1;
81918334Speter      warn_parentheses = 1;
82090075Sobrien      warn_sequence_point = 1;
82118334Speter      warn_missing_braces = 1;
82250397Sobrien      /* We set this to 2 here, but 1 in -Wmain, so -ffreestanding can turn
82350397Sobrien	 it off only if it's not explicit.  */
82450397Sobrien      warn_main = 2;
82550397Sobrien      /* Only warn about unknown pragmas that are not in system headers.  */
82650397Sobrien      warn_unknown_pragmas = 1;
82718334Speter    }
82818334Speter  else
82950397Sobrien    return strings_processed;
83018334Speter
83118334Speter  return 1;
83218334Speter}
83318334Speter
83418334Spetervoid
83590075Sobrienc_print_identifier (file, node, indent)
83618334Speter     FILE *file;
83718334Speter     tree node;
83818334Speter     int indent;
83918334Speter{
84018334Speter  print_node (file, "global", IDENTIFIER_GLOBAL_VALUE (node), indent + 4);
84118334Speter  print_node (file, "local", IDENTIFIER_LOCAL_VALUE (node), indent + 4);
84218334Speter  print_node (file, "label", IDENTIFIER_LABEL_VALUE (node), indent + 4);
84318334Speter  print_node (file, "implicit", IDENTIFIER_IMPLICIT_DECL (node), indent + 4);
84418334Speter  print_node (file, "error locus", IDENTIFIER_ERROR_LOCUS (node), indent + 4);
84518334Speter  print_node (file, "limbo value", IDENTIFIER_LIMBO_VALUE (node), indent + 4);
84690075Sobrien  if (C_IS_RESERVED_WORD (node))
84790075Sobrien    {
84890075Sobrien      tree rid = ridpointers[C_RID_CODE (node)];
84990075Sobrien      indent_to (file, indent + 4);
85090075Sobrien      fprintf (file, "rid ");
85190075Sobrien      fprintf (file, HOST_PTR_PRINTF, (void *)rid);
85290075Sobrien      fprintf (file, " \"%s\"", IDENTIFIER_POINTER (rid));
85390075Sobrien    }
85418334Speter}
85518334Speter
85618334Speter/* Hook called at end of compilation to assume 1 elt
85790075Sobrien   for a top-level tentative array defn that wasn't complete before.  */
85890075Sobrien
85918334Spetervoid
86018334Speterfinish_incomplete_decl (decl)
86118334Speter     tree decl;
86218334Speter{
86350397Sobrien  if (TREE_CODE (decl) == VAR_DECL)
86418334Speter    {
86518334Speter      tree type = TREE_TYPE (decl);
86650397Sobrien      if (type != error_mark_node
86750397Sobrien	  && TREE_CODE (type) == ARRAY_TYPE
86890075Sobrien	  && ! DECL_EXTERNAL (decl)
86950397Sobrien	  && TYPE_DOMAIN (type) == 0)
87018334Speter	{
87190075Sobrien	  warning_with_decl (decl, "array `%s' assumed to have one element");
87250397Sobrien
87318334Speter	  complete_array_type (type, NULL_TREE, 1);
87418334Speter
87518334Speter	  layout_decl (decl, 0);
87618334Speter	}
87718334Speter    }
87818334Speter}
87918334Speter
88018334Speter/* Create a new `struct binding_level'.  */
88118334Speter
88290075Sobrienstatic struct binding_level *
88318334Spetermake_binding_level ()
88418334Speter{
88518334Speter  /* NOSTRICT */
88618334Speter  return (struct binding_level *) xmalloc (sizeof (struct binding_level));
88718334Speter}
88818334Speter
88918334Speter/* Nonzero if we are currently in the global binding level.  */
89018334Speter
89118334Speterint
89218334Speterglobal_bindings_p ()
89318334Speter{
89418334Speter  return current_binding_level == global_binding_level;
89518334Speter}
89618334Speter
89718334Spetervoid
89818334Speterkeep_next_level ()
89918334Speter{
90018334Speter  keep_next_level_flag = 1;
90118334Speter}
90218334Speter
90318334Speter/* Nonzero if the current level needs to have a BLOCK made.  */
90418334Speter
90518334Speterint
90618334Speterkept_level_p ()
90718334Speter{
90818334Speter  return ((current_binding_level->keep_if_subblocks
90918334Speter	   && current_binding_level->blocks != 0)
91018334Speter	  || current_binding_level->keep
91118334Speter	  || current_binding_level->names != 0
91218334Speter	  || (current_binding_level->tags != 0
91318334Speter	      && !current_binding_level->tag_transparent));
91418334Speter}
91518334Speter
91618334Speter/* Identify this binding level as a level of parameters.
91718334Speter   DEFINITION_FLAG is 1 for a definition, 0 for a declaration.
91818334Speter   But it turns out there is no way to pass the right value for
91918334Speter   DEFINITION_FLAG, so we ignore it.  */
92018334Speter
92118334Spetervoid
92218334Speterdeclare_parm_level (definition_flag)
92352284Sobrien     int definition_flag ATTRIBUTE_UNUSED;
92418334Speter{
92518334Speter  current_binding_level->parm_flag = 1;
92618334Speter}
92718334Speter
92818334Speter/* Nonzero if currently making parm declarations.  */
92918334Speter
93018334Speterint
93118334Speterin_parm_level_p ()
93218334Speter{
93318334Speter  return current_binding_level->parm_flag;
93418334Speter}
93518334Speter
93618334Speter/* Enter a new binding level.
93718334Speter   If TAG_TRANSPARENT is nonzero, do so only for the name space of variables,
93818334Speter   not for that of tags.  */
93918334Speter
94018334Spetervoid
94118334Speterpushlevel (tag_transparent)
94218334Speter     int tag_transparent;
94318334Speter{
94490075Sobrien  struct binding_level *newlevel = NULL_BINDING_LEVEL;
94518334Speter
94618334Speter  /* If this is the top level of a function,
94718334Speter     just make sure that NAMED_LABELS is 0.  */
94818334Speter
94918334Speter  if (current_binding_level == global_binding_level)
95018334Speter    {
95118334Speter      named_labels = 0;
95218334Speter    }
95318334Speter
95418334Speter  /* Reuse or create a struct for this binding level.  */
95518334Speter
95618334Speter  if (free_binding_level)
95718334Speter    {
95818334Speter      newlevel = free_binding_level;
95918334Speter      free_binding_level = free_binding_level->level_chain;
96018334Speter    }
96118334Speter  else
96218334Speter    {
96318334Speter      newlevel = make_binding_level ();
96418334Speter    }
96518334Speter
96618334Speter  /* Add this level to the front of the chain (stack) of levels that
96718334Speter     are active.  */
96818334Speter
96918334Speter  *newlevel = clear_binding_level;
97018334Speter  newlevel->tag_transparent
97118334Speter    = (tag_transparent
97218334Speter       || (current_binding_level
97318334Speter	   ? current_binding_level->subblocks_tag_transparent
97418334Speter	   : 0));
97518334Speter  newlevel->level_chain = current_binding_level;
97618334Speter  current_binding_level = newlevel;
97718334Speter  newlevel->keep = keep_next_level_flag;
97818334Speter  keep_next_level_flag = 0;
97918334Speter  newlevel->keep_if_subblocks = keep_next_if_subblocks;
98018334Speter  keep_next_if_subblocks = 0;
98118334Speter}
98218334Speter
98390075Sobrien/* Clear the limbo values of all identifiers defined in BLOCK or a subblock.  */
98450397Sobrien
98550397Sobrienstatic void
98650397Sobrienclear_limbo_values (block)
98750397Sobrien     tree block;
98850397Sobrien{
98950397Sobrien  tree tem;
99050397Sobrien
99150397Sobrien  for (tem = BLOCK_VARS (block); tem; tem = TREE_CHAIN (tem))
99250397Sobrien    if (DECL_NAME (tem) != 0)
99350397Sobrien      IDENTIFIER_LIMBO_VALUE (DECL_NAME (tem)) = 0;
99450397Sobrien
99550397Sobrien  for (tem = BLOCK_SUBBLOCKS (block); tem; tem = TREE_CHAIN (tem))
99650397Sobrien    clear_limbo_values (tem);
99750397Sobrien}
99890075Sobrien
99918334Speter/* Exit a binding level.
100018334Speter   Pop the level off, and restore the state of the identifier-decl mappings
100118334Speter   that were in effect when this level was entered.
100218334Speter
100318334Speter   If KEEP is nonzero, this level had explicit declarations, so
100418334Speter   and create a "block" (a BLOCK node) for the level
100518334Speter   to record its declarations and subblocks for symbol table output.
100618334Speter
100718334Speter   If FUNCTIONBODY is nonzero, this level is the body of a function,
100818334Speter   so create a block as if KEEP were set and also clear out all
100918334Speter   label names.
101018334Speter
101118334Speter   If REVERSE is nonzero, reverse the order of decls before putting
101218334Speter   them into the BLOCK.  */
101318334Speter
101418334Spetertree
101518334Speterpoplevel (keep, reverse, functionbody)
101618334Speter     int keep;
101718334Speter     int reverse;
101818334Speter     int functionbody;
101918334Speter{
102090075Sobrien  tree link;
102118334Speter  /* The chain of decls was accumulated in reverse order.
102218334Speter     Put it into forward order, just for cleanliness.  */
102318334Speter  tree decls;
102418334Speter  tree tags = current_binding_level->tags;
102518334Speter  tree subblocks = current_binding_level->blocks;
102618334Speter  tree block = 0;
102718334Speter  tree decl;
102818334Speter  int block_previously_created;
102918334Speter
103018334Speter  keep |= current_binding_level->keep;
103118334Speter
103218334Speter  /* This warning is turned off because it causes warnings for
103318334Speter     declarations like `extern struct foo *x'.  */
103418334Speter#if 0
103518334Speter  /* Warn about incomplete structure types in this level.  */
103618334Speter  for (link = tags; link; link = TREE_CHAIN (link))
103790075Sobrien    if (!COMPLETE_TYPE_P (TREE_VALUE (link)))
103818334Speter      {
103918334Speter	tree type = TREE_VALUE (link);
104052284Sobrien	tree type_name = TYPE_NAME (type);
104152284Sobrien	char *id = IDENTIFIER_POINTER (TREE_CODE (type_name) == IDENTIFIER_NODE
104252284Sobrien				       ? type_name
104352284Sobrien				       : DECL_NAME (type_name));
104418334Speter	switch (TREE_CODE (type))
104518334Speter	  {
104618334Speter	  case RECORD_TYPE:
104752284Sobrien	    error ("`struct %s' incomplete in scope ending here", id);
104818334Speter	    break;
104918334Speter	  case UNION_TYPE:
105052284Sobrien	    error ("`union %s' incomplete in scope ending here", id);
105118334Speter	    break;
105218334Speter	  case ENUMERAL_TYPE:
105352284Sobrien	    error ("`enum %s' incomplete in scope ending here", id);
105418334Speter	    break;
105518334Speter	  }
105618334Speter      }
105718334Speter#endif /* 0 */
105818334Speter
105918334Speter  /* Get the decls in the order they were written.
106018334Speter     Usually current_binding_level->names is in reverse order.
106118334Speter     But parameter decls were previously put in forward order.  */
106218334Speter
106318334Speter  if (reverse)
106418334Speter    current_binding_level->names
106518334Speter      = decls = nreverse (current_binding_level->names);
106618334Speter  else
106718334Speter    decls = current_binding_level->names;
106818334Speter
106918334Speter  /* Output any nested inline functions within this block
107018334Speter     if they weren't already output.  */
107118334Speter
107218334Speter  for (decl = decls; decl; decl = TREE_CHAIN (decl))
107318334Speter    if (TREE_CODE (decl) == FUNCTION_DECL
107418334Speter	&& ! TREE_ASM_WRITTEN (decl)
107518334Speter	&& DECL_INITIAL (decl) != 0
107618334Speter	&& TREE_ADDRESSABLE (decl))
107718334Speter      {
107818334Speter	/* If this decl was copied from a file-scope decl
107918334Speter	   on account of a block-scope extern decl,
108018334Speter	   propagate TREE_ADDRESSABLE to the file-scope decl.
108118334Speter
108218334Speter	   DECL_ABSTRACT_ORIGIN can be set to itself if warn_return_type is
108318334Speter	   true, since then the decl goes through save_for_inline_copying.  */
108418334Speter	if (DECL_ABSTRACT_ORIGIN (decl) != 0
108518334Speter	    && DECL_ABSTRACT_ORIGIN (decl) != decl)
108618334Speter	  TREE_ADDRESSABLE (DECL_ABSTRACT_ORIGIN (decl)) = 1;
108718334Speter      }
108818334Speter
108990075Sobrien  /* We used to warn about unused variables in expand_end_bindings,
109090075Sobrien     i.e. while generating RTL.  But in function-at-a-time mode we may
109190075Sobrien     choose to never expand a function at all (e.g. auto inlining), so
109290075Sobrien     we do this explicitly now.  */
109390075Sobrien  warn_about_unused_variables (getdecls ());
109490075Sobrien
109518334Speter  /* If there were any declarations or structure tags in that level,
109618334Speter     or if this level is a function body,
109718334Speter     create a BLOCK to record them for the life of this function.  */
109818334Speter
109918334Speter  block = 0;
110018334Speter  block_previously_created = (current_binding_level->this_block != 0);
110118334Speter  if (block_previously_created)
110218334Speter    block = current_binding_level->this_block;
110318334Speter  else if (keep || functionbody
110418334Speter	   || (current_binding_level->keep_if_subblocks && subblocks != 0))
110518334Speter    block = make_node (BLOCK);
110618334Speter  if (block != 0)
110718334Speter    {
110818334Speter      BLOCK_VARS (block) = decls;
110918334Speter      BLOCK_SUBBLOCKS (block) = subblocks;
111018334Speter    }
111118334Speter
111218334Speter  /* In each subblock, record that this is its superior.  */
111318334Speter
111418334Speter  for (link = subblocks; link; link = TREE_CHAIN (link))
111518334Speter    BLOCK_SUPERCONTEXT (link) = block;
111618334Speter
111718334Speter  /* Clear out the meanings of the local variables of this level.  */
111818334Speter
111918334Speter  for (link = decls; link; link = TREE_CHAIN (link))
112018334Speter    {
112118334Speter      if (DECL_NAME (link) != 0)
112218334Speter	{
112318334Speter	  /* If the ident. was used or addressed via a local extern decl,
112418334Speter	     don't forget that fact.  */
112518334Speter	  if (DECL_EXTERNAL (link))
112618334Speter	    {
112718334Speter	      if (TREE_USED (link))
112818334Speter		TREE_USED (DECL_NAME (link)) = 1;
112918334Speter	      if (TREE_ADDRESSABLE (link))
113018334Speter		TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (link)) = 1;
113118334Speter	    }
113218334Speter	  IDENTIFIER_LOCAL_VALUE (DECL_NAME (link)) = 0;
113318334Speter	}
113418334Speter    }
113518334Speter
113618334Speter  /* Restore all name-meanings of the outer levels
113718334Speter     that were shadowed by this level.  */
113818334Speter
113918334Speter  for (link = current_binding_level->shadowed; link; link = TREE_CHAIN (link))
114018334Speter    IDENTIFIER_LOCAL_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link);
114118334Speter
114218334Speter  /* If the level being exited is the top level of a function,
114318334Speter     check over all the labels, and clear out the current
114418334Speter     (function local) meanings of their names.  */
114518334Speter
114618334Speter  if (functionbody)
114718334Speter    {
114850397Sobrien      clear_limbo_values (block);
114950397Sobrien
115018334Speter      /* If this is the top level block of a function,
115118334Speter	 the vars are the function's parameters.
115218334Speter	 Don't leave them in the BLOCK because they are
115318334Speter	 found in the FUNCTION_DECL instead.  */
115418334Speter
115518334Speter      BLOCK_VARS (block) = 0;
115618334Speter
115718334Speter      /* Clear out the definitions of all label names,
115818334Speter	 since their scopes end here,
115918334Speter	 and add them to BLOCK_VARS.  */
116018334Speter
116118334Speter      for (link = named_labels; link; link = TREE_CHAIN (link))
116218334Speter	{
116390075Sobrien	  tree label = TREE_VALUE (link);
116418334Speter
116518334Speter	  if (DECL_INITIAL (label) == 0)
116618334Speter	    {
116718334Speter	      error_with_decl (label, "label `%s' used but not defined");
116818334Speter	      /* Avoid crashing later.  */
116918334Speter	      define_label (input_filename, lineno,
117018334Speter			    DECL_NAME (label));
117118334Speter	    }
117290075Sobrien	  else if (warn_unused_label && !TREE_USED (label))
117318334Speter	    warning_with_decl (label, "label `%s' defined but not used");
117418334Speter	  IDENTIFIER_LABEL_VALUE (DECL_NAME (label)) = 0;
117518334Speter
117618334Speter	  /* Put the labels into the "variables" of the
117718334Speter	     top-level block, so debugger can see them.  */
117818334Speter	  TREE_CHAIN (label) = BLOCK_VARS (block);
117918334Speter	  BLOCK_VARS (block) = label;
118018334Speter	}
118118334Speter    }
118218334Speter
118318334Speter  /* Pop the current level, and free the structure for reuse.  */
118418334Speter
118518334Speter  {
118690075Sobrien    struct binding_level *level = current_binding_level;
118718334Speter    current_binding_level = current_binding_level->level_chain;
118818334Speter
118918334Speter    level->level_chain = free_binding_level;
119018334Speter    free_binding_level = level;
119118334Speter  }
119218334Speter
119318334Speter  /* Dispose of the block that we just made inside some higher level.  */
119418334Speter  if (functionbody)
119518334Speter    DECL_INITIAL (current_function_decl) = block;
119618334Speter  else if (block)
119718334Speter    {
119818334Speter      if (!block_previously_created)
119990075Sobrien	current_binding_level->blocks
120090075Sobrien	  = chainon (current_binding_level->blocks, block);
120118334Speter    }
120218334Speter  /* If we did not make a block for the level just exited,
120318334Speter     any blocks made for inner levels
120418334Speter     (since they cannot be recorded as subblocks in that level)
120518334Speter     must be carried forward so they will later become subblocks
120618334Speter     of something else.  */
120718334Speter  else if (subblocks)
120818334Speter    current_binding_level->blocks
120918334Speter      = chainon (current_binding_level->blocks, subblocks);
121018334Speter
121118334Speter  /* Set the TYPE_CONTEXTs for all of the tagged types belonging to this
121218334Speter     binding contour so that they point to the appropriate construct, i.e.
121318334Speter     either to the current FUNCTION_DECL node, or else to the BLOCK node
121418334Speter     we just constructed.
121518334Speter
121618334Speter     Note that for tagged types whose scope is just the formal parameter
121718334Speter     list for some function type specification, we can't properly set
121818334Speter     their TYPE_CONTEXTs here, because we don't have a pointer to the
121918334Speter     appropriate FUNCTION_TYPE node readily available to us.  For those
122018334Speter     cases, the TYPE_CONTEXTs of the relevant tagged type nodes get set
122118334Speter     in `grokdeclarator' as soon as we have created the FUNCTION_TYPE
122218334Speter     node which will represent the "scope" for these "parameter list local"
122390075Sobrien     tagged types.  */
122418334Speter
122518334Speter  if (functionbody)
122618334Speter    for (link = tags; link; link = TREE_CHAIN (link))
122718334Speter      TYPE_CONTEXT (TREE_VALUE (link)) = current_function_decl;
122818334Speter  else if (block)
122918334Speter    for (link = tags; link; link = TREE_CHAIN (link))
123018334Speter      TYPE_CONTEXT (TREE_VALUE (link)) = block;
123118334Speter
123218334Speter  if (block)
123318334Speter    TREE_USED (block) = 1;
123490075Sobrien
123518334Speter  return block;
123618334Speter}
123718334Speter
123818334Speter/* Insert BLOCK at the end of the list of subblocks of the
123918334Speter   current binding level.  This is used when a BIND_EXPR is expanded,
124018334Speter   to handle the BLOCK node inside the BIND_EXPR.  */
124118334Speter
124218334Spetervoid
124318334Speterinsert_block (block)
124418334Speter     tree block;
124518334Speter{
124618334Speter  TREE_USED (block) = 1;
124718334Speter  current_binding_level->blocks
124818334Speter    = chainon (current_binding_level->blocks, block);
124918334Speter}
125018334Speter
125118334Speter/* Set the BLOCK node for the innermost scope
125218334Speter   (the one we are currently in).  */
125318334Speter
125418334Spetervoid
125518334Speterset_block (block)
125690075Sobrien     tree block;
125718334Speter{
125818334Speter  current_binding_level->this_block = block;
125990075Sobrien  current_binding_level->names = chainon (current_binding_level->names,
126090075Sobrien					  BLOCK_VARS (block));
126190075Sobrien  current_binding_level->blocks = chainon (current_binding_level->blocks,
126290075Sobrien					   BLOCK_SUBBLOCKS (block));
126318334Speter}
126418334Speter
126518334Spetervoid
126618334Speterpush_label_level ()
126718334Speter{
126890075Sobrien  struct binding_level *newlevel;
126918334Speter
127018334Speter  /* Reuse or create a struct for this binding level.  */
127118334Speter
127218334Speter  if (free_binding_level)
127318334Speter    {
127418334Speter      newlevel = free_binding_level;
127518334Speter      free_binding_level = free_binding_level->level_chain;
127618334Speter    }
127718334Speter  else
127818334Speter    {
127918334Speter      newlevel = make_binding_level ();
128018334Speter    }
128118334Speter
128218334Speter  /* Add this level to the front of the chain (stack) of label levels.  */
128318334Speter
128418334Speter  newlevel->level_chain = label_level_chain;
128518334Speter  label_level_chain = newlevel;
128618334Speter
128718334Speter  newlevel->names = named_labels;
128818334Speter  newlevel->shadowed = shadowed_labels;
128918334Speter  named_labels = 0;
129018334Speter  shadowed_labels = 0;
129118334Speter}
129218334Speter
129318334Spetervoid
129418334Speterpop_label_level ()
129518334Speter{
129690075Sobrien  struct binding_level *level = label_level_chain;
129718334Speter  tree link, prev;
129818334Speter
129918334Speter  /* Clear out the definitions of the declared labels in this level.
130018334Speter     Leave in the list any ordinary, non-declared labels.  */
130118334Speter  for (link = named_labels, prev = 0; link;)
130218334Speter    {
130318334Speter      if (C_DECLARED_LABEL_FLAG (TREE_VALUE (link)))
130418334Speter	{
130518334Speter	  if (DECL_SOURCE_LINE (TREE_VALUE (link)) == 0)
130618334Speter	    {
130718334Speter	      error_with_decl (TREE_VALUE (link),
130818334Speter			       "label `%s' used but not defined");
130918334Speter	      /* Avoid crashing later.  */
131018334Speter	      define_label (input_filename, lineno,
131118334Speter			    DECL_NAME (TREE_VALUE (link)));
131218334Speter	    }
131390075Sobrien	  else if (warn_unused_label && !TREE_USED (TREE_VALUE (link)))
131490075Sobrien	    warning_with_decl (TREE_VALUE (link),
131518334Speter			       "label `%s' defined but not used");
131618334Speter	  IDENTIFIER_LABEL_VALUE (DECL_NAME (TREE_VALUE (link))) = 0;
131718334Speter
131818334Speter	  /* Delete this element from the list.  */
131918334Speter	  link = TREE_CHAIN (link);
132018334Speter	  if (prev)
132118334Speter	    TREE_CHAIN (prev) = link;
132218334Speter	  else
132318334Speter	    named_labels = link;
132418334Speter	}
132518334Speter      else
132618334Speter	{
132718334Speter	  prev = link;
132818334Speter	  link = TREE_CHAIN (link);
132918334Speter	}
133018334Speter    }
133118334Speter
133218334Speter  /* Bring back all the labels that were shadowed.  */
133318334Speter  for (link = shadowed_labels; link; link = TREE_CHAIN (link))
133418334Speter    if (DECL_NAME (TREE_VALUE (link)) != 0)
133518334Speter      IDENTIFIER_LABEL_VALUE (DECL_NAME (TREE_VALUE (link)))
133618334Speter	= TREE_VALUE (link);
133718334Speter
133818334Speter  named_labels = chainon (named_labels, level->names);
133918334Speter  shadowed_labels = level->shadowed;
134018334Speter
134118334Speter  /* Pop the current level, and free the structure for reuse.  */
134218334Speter  label_level_chain = label_level_chain->level_chain;
134318334Speter  level->level_chain = free_binding_level;
134418334Speter  free_binding_level = level;
134518334Speter}
134618334Speter
134718334Speter/* Push a definition or a declaration of struct, union or enum tag "name".
134818334Speter   "type" should be the type node.
134918334Speter   We assume that the tag "name" is not already defined.
135018334Speter
135118334Speter   Note that the definition may really be just a forward reference.
135218334Speter   In that case, the TYPE_SIZE will be zero.  */
135318334Speter
135418334Spetervoid
135518334Speterpushtag (name, type)
135618334Speter     tree name, type;
135718334Speter{
135890075Sobrien  struct binding_level *b;
135918334Speter
136018334Speter  /* Find the proper binding level for this type tag.  */
136118334Speter
136218334Speter  for (b = current_binding_level; b->tag_transparent; b = b->level_chain)
136318334Speter    continue;
136418334Speter
136518334Speter  if (name)
136618334Speter    {
136718334Speter      /* Record the identifier as the type's name if it has none.  */
136818334Speter
136918334Speter      if (TYPE_NAME (type) == 0)
137018334Speter	TYPE_NAME (type) = name;
137118334Speter    }
137218334Speter
137390075Sobrien  b->tags = tree_cons (name, type, b->tags);
137418334Speter
137518334Speter  /* Create a fake NULL-named TYPE_DECL node whose TREE_TYPE will be the
137618334Speter     tagged type we just added to the current binding level.  This fake
137718334Speter     NULL-named TYPE_DECL node helps dwarfout.c to know when it needs
137818334Speter     to output a representation of a tagged type, and it also gives
137918334Speter     us a convenient place to record the "scope start" address for the
138018334Speter     tagged type.  */
138118334Speter
138218334Speter  TYPE_STUB_DECL (type) = pushdecl (build_decl (TYPE_DECL, NULL_TREE, type));
138350397Sobrien
138450397Sobrien  /* An approximation for now, so we can tell this is a function-scope tag.
138550397Sobrien     This will be updated in poplevel.  */
138650397Sobrien  TYPE_CONTEXT (type) = DECL_CONTEXT (TYPE_STUB_DECL (type));
138718334Speter}
138818334Speter
138918334Speter/* Handle when a new declaration NEWDECL
139018334Speter   has the same name as an old one OLDDECL
139118334Speter   in the same binding contour.
139218334Speter   Prints an error message if appropriate.
139318334Speter
139418334Speter   If safely possible, alter OLDDECL to look like NEWDECL, and return 1.
139550397Sobrien   Otherwise, return 0.
139618334Speter
139750397Sobrien   When DIFFERENT_BINDING_LEVEL is true, NEWDECL is an external declaration,
139850397Sobrien   and OLDDECL is in an outer binding level and should thus not be changed.  */
139950397Sobrien
140018334Speterstatic int
140150397Sobrienduplicate_decls (newdecl, olddecl, different_binding_level)
140290075Sobrien     tree newdecl, olddecl;
140350397Sobrien     int different_binding_level;
140418334Speter{
140518334Speter  int types_match = comptypes (TREE_TYPE (newdecl), TREE_TYPE (olddecl));
140618334Speter  int new_is_definition = (TREE_CODE (newdecl) == FUNCTION_DECL
140718334Speter			   && DECL_INITIAL (newdecl) != 0);
140818334Speter  tree oldtype = TREE_TYPE (olddecl);
140918334Speter  tree newtype = TREE_TYPE (newdecl);
141052284Sobrien  int errmsg = 0;
141118334Speter
141290075Sobrien  if (DECL_P (olddecl))
141390075Sobrien    {
141490075Sobrien      if (TREE_CODE (newdecl) == FUNCTION_DECL
141590075Sobrien	  && TREE_CODE (olddecl) == FUNCTION_DECL
141690075Sobrien	  && (DECL_UNINLINABLE (newdecl) || DECL_UNINLINABLE (olddecl)))
141790075Sobrien	{
141890075Sobrien	  if (DECL_DECLARED_INLINE_P (newdecl)
141990075Sobrien	      && DECL_UNINLINABLE (newdecl)
142090075Sobrien	      && lookup_attribute ("noinline", DECL_ATTRIBUTES (newdecl)))
142190075Sobrien	    /* Already warned elsewhere.  */;
142290075Sobrien	  else if (DECL_DECLARED_INLINE_P (olddecl)
142390075Sobrien		   && DECL_UNINLINABLE (olddecl)
142490075Sobrien		   && lookup_attribute ("noinline", DECL_ATTRIBUTES (olddecl)))
142590075Sobrien	    /* Already warned.  */;
142690075Sobrien	  else if (DECL_DECLARED_INLINE_P (newdecl)
142790075Sobrien		   && ! DECL_DECLARED_INLINE_P (olddecl)
142890075Sobrien		   && DECL_UNINLINABLE (olddecl)
142990075Sobrien		   && lookup_attribute ("noinline", DECL_ATTRIBUTES (olddecl)))
143090075Sobrien	    {
143190075Sobrien	      warning_with_decl (newdecl,
143290075Sobrien				 "function `%s' redeclared as inline");
143390075Sobrien	      warning_with_decl (olddecl,
143490075Sobrien				 "previous declaration of function `%s' with attribute noinline");
143590075Sobrien	    }
143690075Sobrien	  else if (DECL_DECLARED_INLINE_P (olddecl)
143790075Sobrien		   && DECL_UNINLINABLE (newdecl)
143890075Sobrien		   && lookup_attribute ("noinline", DECL_ATTRIBUTES (newdecl)))
143990075Sobrien	    {
144090075Sobrien	      warning_with_decl (newdecl,
144190075Sobrien				 "function `%s' redeclared with attribute noinline");
144290075Sobrien	      warning_with_decl (olddecl,
144390075Sobrien				 "previous declaration of function `%s' was inline");
144490075Sobrien	    }
144590075Sobrien	}
144618334Speter
144790075Sobrien      DECL_ATTRIBUTES (newdecl)
144890075Sobrien	= (*targetm.merge_decl_attributes) (olddecl, newdecl);
144990075Sobrien    }
145090075Sobrien
145118334Speter  if (TREE_CODE (newtype) == ERROR_MARK
145218334Speter      || TREE_CODE (oldtype) == ERROR_MARK)
145318334Speter    types_match = 0;
145418334Speter
145518334Speter  /* New decl is completely inconsistent with the old one =>
145618334Speter     tell caller to replace the old one.
145718334Speter     This is always an error except in the case of shadowing a builtin.  */
145818334Speter  if (TREE_CODE (olddecl) != TREE_CODE (newdecl))
145918334Speter    {
146018334Speter      if (TREE_CODE (olddecl) == FUNCTION_DECL
146118334Speter	  && (DECL_BUILT_IN (olddecl)
146218334Speter	      || DECL_BUILT_IN_NONANSI (olddecl)))
146318334Speter	{
146418334Speter	  /* If you declare a built-in or predefined function name as static,
146518334Speter	     the old definition is overridden,
146618334Speter	     but optionally warn this was a bad choice of name.  */
146718334Speter	  if (!TREE_PUBLIC (newdecl))
146818334Speter	    {
146918334Speter	      if (!warn_shadow)
147018334Speter		;
147118334Speter	      else if (DECL_BUILT_IN (olddecl))
147218334Speter		warning_with_decl (newdecl, "shadowing built-in function `%s'");
147318334Speter	      else
147418334Speter		warning_with_decl (newdecl, "shadowing library function `%s'");
147518334Speter	    }
147618334Speter	  /* Likewise, if the built-in is not ansi, then programs can
147718334Speter	     override it even globally without an error.  */
147818334Speter	  else if (! DECL_BUILT_IN (olddecl))
147918334Speter	    warning_with_decl (newdecl,
148018334Speter			       "library function `%s' declared as non-function");
148118334Speter
148218334Speter	  else if (DECL_BUILT_IN_NONANSI (olddecl))
148318334Speter	    warning_with_decl (newdecl,
148418334Speter			       "built-in function `%s' declared as non-function");
148518334Speter	  else
148618334Speter	    warning_with_decl (newdecl,
148790075Sobrien			       "built-in function `%s' declared as non-function");
148818334Speter	}
148918334Speter      else
149018334Speter	{
149118334Speter	  error_with_decl (newdecl, "`%s' redeclared as different kind of symbol");
149218334Speter	  error_with_decl (olddecl, "previous declaration of `%s'");
149318334Speter	}
149418334Speter
149518334Speter      return 0;
149618334Speter    }
149718334Speter
149818334Speter  /* For real parm decl following a forward decl,
149918334Speter     return 1 so old decl will be reused.  */
150018334Speter  if (types_match && TREE_CODE (newdecl) == PARM_DECL
150118334Speter      && TREE_ASM_WRITTEN (olddecl) && ! TREE_ASM_WRITTEN (newdecl))
150218334Speter    return 1;
150318334Speter
150418334Speter  /* The new declaration is the same kind of object as the old one.
150518334Speter     The declarations may partially match.  Print warnings if they don't
150618334Speter     match enough.  Ultimately, copy most of the information from the new
150718334Speter     decl to the old one, and keep using the old one.  */
150818334Speter
150918334Speter  if (flag_traditional && TREE_CODE (newdecl) == FUNCTION_DECL
151018334Speter      && IDENTIFIER_IMPLICIT_DECL (DECL_NAME (newdecl)) == olddecl
151118334Speter      && DECL_INITIAL (olddecl) == 0)
151218334Speter    /* If -traditional, avoid error for redeclaring fcn
151318334Speter       after implicit decl.  */
151418334Speter    ;
151518334Speter  else if (TREE_CODE (olddecl) == FUNCTION_DECL
151618334Speter	   && DECL_BUILT_IN (olddecl))
151718334Speter    {
151818334Speter      /* A function declaration for a built-in function.  */
151918334Speter      if (!TREE_PUBLIC (newdecl))
152018334Speter	{
152118334Speter	  /* If you declare a built-in function name as static, the
152218334Speter	     built-in definition is overridden,
152318334Speter	     but optionally warn this was a bad choice of name.  */
152418334Speter	  if (warn_shadow)
152518334Speter	    warning_with_decl (newdecl, "shadowing built-in function `%s'");
152618334Speter	  /* Discard the old built-in function.  */
152718334Speter	  return 0;
152818334Speter	}
152918334Speter      else if (!types_match)
153018334Speter	{
153190075Sobrien	  /* Accept the return type of the new declaration if same modes.  */
153250397Sobrien	  tree oldreturntype = TREE_TYPE (oldtype);
153350397Sobrien	  tree newreturntype = TREE_TYPE (newtype);
153418334Speter
153590075Sobrien	  if (TYPE_MODE (oldreturntype) == TYPE_MODE (newreturntype))
153618334Speter	    {
153718334Speter	      /* Function types may be shared, so we can't just modify
153818334Speter		 the return type of olddecl's function type.  */
153950397Sobrien	      tree trytype
154018334Speter		= build_function_type (newreturntype,
154150397Sobrien				       TYPE_ARG_TYPES (oldtype));
154290075Sobrien	      trytype = build_type_attribute_variant (trytype,
154390075Sobrien						      TYPE_ATTRIBUTES (oldtype));
154490075Sobrien
154550397Sobrien              types_match = comptypes (newtype, trytype);
154618334Speter	      if (types_match)
154750397Sobrien		oldtype = trytype;
154818334Speter	    }
154918334Speter	  /* Accept harmless mismatch in first argument type also.
155090075Sobrien	     This is for the ffs and fprintf builtins.  */
155118334Speter	  if (TYPE_ARG_TYPES (TREE_TYPE (newdecl)) != 0
155250397Sobrien	      && TYPE_ARG_TYPES (oldtype) != 0
155350397Sobrien	      && TREE_VALUE (TYPE_ARG_TYPES (newtype)) != 0
155450397Sobrien	      && TREE_VALUE (TYPE_ARG_TYPES (oldtype)) != 0
155550397Sobrien	      && (TYPE_MODE (TREE_VALUE (TYPE_ARG_TYPES (newtype)))
155650397Sobrien		  == TYPE_MODE (TREE_VALUE (TYPE_ARG_TYPES (oldtype)))))
155718334Speter	    {
155818334Speter	      /* Function types may be shared, so we can't just modify
155918334Speter		 the return type of olddecl's function type.  */
156050397Sobrien	      tree trytype
156150397Sobrien		= build_function_type (TREE_TYPE (oldtype),
156290075Sobrien				       tree_cons (NULL_TREE,
156350397Sobrien						  TREE_VALUE (TYPE_ARG_TYPES (newtype)),
156450397Sobrien						  TREE_CHAIN (TYPE_ARG_TYPES (oldtype))));
156590075Sobrien	      trytype = build_type_attribute_variant (trytype,
156690075Sobrien						      TYPE_ATTRIBUTES (oldtype));
156790075Sobrien
156890075Sobrien	      types_match = comptypes (newtype, trytype);
156918334Speter	      if (types_match)
157050397Sobrien		oldtype = trytype;
157118334Speter	    }
157250397Sobrien	  if (! different_binding_level)
157350397Sobrien	    TREE_TYPE (olddecl) = oldtype;
157418334Speter	}
157596263Sobrien      else if (TYPE_ARG_TYPES (oldtype) == NULL
157696263Sobrien	       && TYPE_ARG_TYPES (newtype) != NULL)
157796263Sobrien	{
157896263Sobrien	  /* For bcmp, bzero, fputs the builtin type has arguments not
157996263Sobrien	     specified.  Use the ones from the prototype so that type checking
158096263Sobrien	     is done for them.  */
158196263Sobrien	  tree trytype
158296263Sobrien	    = build_function_type (TREE_TYPE (oldtype),
158396263Sobrien				   TYPE_ARG_TYPES (newtype));
158496263Sobrien	  trytype = build_type_attribute_variant (trytype,
158596263Sobrien						  TYPE_ATTRIBUTES (oldtype));
158696263Sobrien
158796263Sobrien	  oldtype = trytype;
158896263Sobrien	  if (! different_binding_level)
158996263Sobrien	    TREE_TYPE (olddecl) = oldtype;
159096263Sobrien	}
159118334Speter      if (!types_match)
159218334Speter	{
159318334Speter	  /* If types don't match for a built-in, throw away the built-in.  */
159418334Speter	  warning_with_decl (newdecl, "conflicting types for built-in function `%s'");
159518334Speter	  return 0;
159618334Speter	}
159718334Speter    }
159818334Speter  else if (TREE_CODE (olddecl) == FUNCTION_DECL
159918334Speter	   && DECL_SOURCE_LINE (olddecl) == 0)
160018334Speter    {
160118334Speter      /* A function declaration for a predeclared function
160218334Speter	 that isn't actually built in.  */
160318334Speter      if (!TREE_PUBLIC (newdecl))
160418334Speter	{
160518334Speter	  /* If you declare it as static, the
160618334Speter	     default definition is overridden.  */
160718334Speter	  return 0;
160818334Speter	}
160918334Speter      else if (!types_match)
161018334Speter	{
161118334Speter	  /* If the types don't match, preserve volatility indication.
161218334Speter	     Later on, we will discard everything else about the
161318334Speter	     default declaration.  */
161418334Speter	  TREE_THIS_VOLATILE (newdecl) |= TREE_THIS_VOLATILE (olddecl);
161518334Speter	}
161618334Speter    }
161718334Speter  /* Permit char *foo () to match void *foo (...) if not pedantic,
161818334Speter     if one of them came from a system header file.  */
161918334Speter  else if (!types_match
162018334Speter	   && TREE_CODE (olddecl) == FUNCTION_DECL
162118334Speter	   && TREE_CODE (newdecl) == FUNCTION_DECL
162218334Speter	   && TREE_CODE (TREE_TYPE (oldtype)) == POINTER_TYPE
162318334Speter	   && TREE_CODE (TREE_TYPE (newtype)) == POINTER_TYPE
162418334Speter	   && (DECL_IN_SYSTEM_HEADER (olddecl)
162518334Speter	       || DECL_IN_SYSTEM_HEADER (newdecl))
162618334Speter	   && ((TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (newtype))) == void_type_node
162718334Speter		&& TYPE_ARG_TYPES (oldtype) == 0
162818334Speter		&& self_promoting_args_p (TYPE_ARG_TYPES (newtype))
162918334Speter		&& TREE_TYPE (TREE_TYPE (oldtype)) == char_type_node)
163018334Speter	       ||
163118334Speter	       (TREE_TYPE (TREE_TYPE (newtype)) == char_type_node
163218334Speter		&& TYPE_ARG_TYPES (newtype) == 0
163318334Speter		&& self_promoting_args_p (TYPE_ARG_TYPES (oldtype))
163418334Speter		&& TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (oldtype))) == void_type_node)))
163518334Speter    {
163618334Speter      if (pedantic)
163718334Speter	pedwarn_with_decl (newdecl, "conflicting types for `%s'");
163818334Speter      /* Make sure we keep void * as ret type, not char *.  */
163918334Speter      if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (oldtype))) == void_type_node)
164018334Speter	TREE_TYPE (newdecl) = newtype = oldtype;
164118334Speter
164218334Speter      /* Set DECL_IN_SYSTEM_HEADER, so that if we see another declaration
164318334Speter	 we will come back here again.  */
164418334Speter      DECL_IN_SYSTEM_HEADER (newdecl) = 1;
164518334Speter    }
164618334Speter  else if (!types_match
164718334Speter	   /* Permit char *foo (int, ...); followed by char *foo ();
164818334Speter	      if not pedantic.  */
164918334Speter	   && ! (TREE_CODE (olddecl) == FUNCTION_DECL
165018334Speter		 && ! pedantic
165118334Speter		 /* Return types must still match.  */
165218334Speter		 && comptypes (TREE_TYPE (oldtype),
165318334Speter			       TREE_TYPE (newtype))
165418334Speter		 && TYPE_ARG_TYPES (newtype) == 0))
165518334Speter    {
165618334Speter      error_with_decl (newdecl, "conflicting types for `%s'");
165718334Speter      /* Check for function type mismatch
165818334Speter	 involving an empty arglist vs a nonempty one.  */
165918334Speter      if (TREE_CODE (olddecl) == FUNCTION_DECL
166018334Speter	  && comptypes (TREE_TYPE (oldtype),
166118334Speter			TREE_TYPE (newtype))
166218334Speter	  && ((TYPE_ARG_TYPES (oldtype) == 0
166318334Speter	       && DECL_INITIAL (olddecl) == 0)
166418334Speter	      ||
166518334Speter	      (TYPE_ARG_TYPES (newtype) == 0
166618334Speter	       && DECL_INITIAL (newdecl) == 0)))
166718334Speter	{
166818334Speter	  /* Classify the problem further.  */
166990075Sobrien	  tree t = TYPE_ARG_TYPES (oldtype);
167018334Speter	  if (t == 0)
167118334Speter	    t = TYPE_ARG_TYPES (newtype);
167218334Speter	  for (; t; t = TREE_CHAIN (t))
167318334Speter	    {
167490075Sobrien	      tree type = TREE_VALUE (t);
167518334Speter
167618334Speter	      if (TREE_CHAIN (t) == 0
167718334Speter		  && TYPE_MAIN_VARIANT (type) != void_type_node)
167818334Speter		{
167990075Sobrien		  error ("a parameter list with an ellipsis can't match an empty parameter name list declaration");
168018334Speter		  break;
168118334Speter		}
168218334Speter
168390075Sobrien	      if (simple_type_promotes_to (type) != NULL_TREE)
168418334Speter		{
168590075Sobrien		  error ("an argument type that has a default promotion can't match an empty parameter name list declaration");
168618334Speter		  break;
168718334Speter		}
168818334Speter	    }
168918334Speter	}
169018334Speter      error_with_decl (olddecl, "previous declaration of `%s'");
169118334Speter    }
169218334Speter  else
169318334Speter    {
169418334Speter      errmsg = redeclaration_error_message (newdecl, olddecl);
169518334Speter      if (errmsg)
169618334Speter	{
169752284Sobrien	  switch (errmsg)
169852284Sobrien	    {
169952284Sobrien	    case 1:
170052284Sobrien	      error_with_decl (newdecl, "redefinition of `%s'");
170152284Sobrien	      break;
170252284Sobrien	    case 2:
170352284Sobrien	      error_with_decl (newdecl, "redeclaration of `%s'");
170452284Sobrien	      break;
170552284Sobrien	    case 3:
170652284Sobrien	      error_with_decl (newdecl, "conflicting declarations of `%s'");
170752284Sobrien	      break;
170852284Sobrien	    default:
170952284Sobrien	      abort ();
171052284Sobrien	    }
171152284Sobrien
171218334Speter	  error_with_decl (olddecl,
171318334Speter			   ((DECL_INITIAL (olddecl)
171418334Speter			     && current_binding_level == global_binding_level)
171518334Speter			    ? "`%s' previously defined here"
171618334Speter			    : "`%s' previously declared here"));
171796263Sobrien	  return 0;
171818334Speter	}
171918334Speter      else if (TREE_CODE (newdecl) == TYPE_DECL
172090075Sobrien               && (DECL_IN_SYSTEM_HEADER (olddecl)
172118334Speter                   || DECL_IN_SYSTEM_HEADER (newdecl)))
172218334Speter	{
172318334Speter	  warning_with_decl (newdecl, "redefinition of `%s'");
172490075Sobrien	  warning_with_decl
172518334Speter	    (olddecl,
172618334Speter	     ((DECL_INITIAL (olddecl)
172718334Speter	       && current_binding_level == global_binding_level)
172818334Speter	      ? "`%s' previously defined here"
172918334Speter	      : "`%s' previously declared here"));
173018334Speter	}
173118334Speter      else if (TREE_CODE (olddecl) == FUNCTION_DECL
173218334Speter	       && DECL_INITIAL (olddecl) != 0
173318334Speter	       && TYPE_ARG_TYPES (oldtype) == 0
173418334Speter	       && TYPE_ARG_TYPES (newtype) != 0
173518334Speter	       && TYPE_ACTUAL_ARG_TYPES (oldtype) != 0)
173618334Speter	{
173790075Sobrien	  tree type, parm;
173890075Sobrien	  int nargs;
173918334Speter	  /* Prototype decl follows defn w/o prototype.  */
174018334Speter
174118334Speter	  for (parm = TYPE_ACTUAL_ARG_TYPES (oldtype),
174218334Speter	       type = TYPE_ARG_TYPES (newtype),
174318334Speter	       nargs = 1;
174452284Sobrien	       ;
174518334Speter	       parm = TREE_CHAIN (parm), type = TREE_CHAIN (type), nargs++)
174618334Speter	    {
174718334Speter	      if (TYPE_MAIN_VARIANT (TREE_VALUE (parm)) == void_type_node
174852284Sobrien		  && TYPE_MAIN_VARIANT (TREE_VALUE (type)) == void_type_node)
174952284Sobrien		{
175052284Sobrien		  warning_with_decl (newdecl, "prototype for `%s' follows");
175152284Sobrien		  warning_with_decl (olddecl, "non-prototype definition here");
175252284Sobrien		  break;
175352284Sobrien		}
175452284Sobrien	      if (TYPE_MAIN_VARIANT (TREE_VALUE (parm)) == void_type_node
175518334Speter		  || TYPE_MAIN_VARIANT (TREE_VALUE (type)) == void_type_node)
175618334Speter		{
175790075Sobrien		  error_with_decl (newdecl,
175890075Sobrien				   "prototype for `%s' follows and number of arguments doesn't match");
175952284Sobrien		  error_with_decl (olddecl, "non-prototype definition here");
176052284Sobrien		  errmsg = 1;
176118334Speter		  break;
176218334Speter		}
176318334Speter	      /* Type for passing arg must be consistent
176418334Speter		 with that declared for the arg.  */
176518334Speter	      if (! comptypes (TREE_VALUE (parm), TREE_VALUE (type))
176618334Speter		  /* If -traditional, allow `unsigned int' instead of `int'
176718334Speter		     in the prototype.  */
176818334Speter		  && (! (flag_traditional
176918334Speter			 && TYPE_MAIN_VARIANT (TREE_VALUE (parm)) == integer_type_node
177018334Speter			 && TYPE_MAIN_VARIANT (TREE_VALUE (type)) == unsigned_type_node)))
177118334Speter		{
177252284Sobrien		  error_with_decl (newdecl,
177352284Sobrien				   "prototype for `%s' follows and argument %d doesn't match",
177452284Sobrien				   nargs);
177552284Sobrien		  error_with_decl (olddecl, "non-prototype definition here");
177652284Sobrien		  errmsg = 1;
177718334Speter		  break;
177818334Speter		}
177918334Speter	    }
178018334Speter	}
178118334Speter      /* Warn about mismatches in various flags.  */
178218334Speter      else
178318334Speter	{
178418334Speter	  /* Warn if function is now inline
178518334Speter	     but was previously declared not inline and has been called.  */
178618334Speter	  if (TREE_CODE (olddecl) == FUNCTION_DECL
178790075Sobrien	      && ! DECL_DECLARED_INLINE_P (olddecl)
178890075Sobrien	      && DECL_DECLARED_INLINE_P (newdecl)
178918334Speter	      && TREE_USED (olddecl))
179018334Speter	    warning_with_decl (newdecl,
179118334Speter			       "`%s' declared inline after being called");
179218334Speter	  if (TREE_CODE (olddecl) == FUNCTION_DECL
179390075Sobrien	      && ! DECL_DECLARED_INLINE_P (olddecl)
179490075Sobrien	      && DECL_DECLARED_INLINE_P (newdecl)
179518334Speter	      && DECL_INITIAL (olddecl) != 0)
179618334Speter	    warning_with_decl (newdecl,
179718334Speter			       "`%s' declared inline after its definition");
179818334Speter
179918334Speter	  /* If pedantic, warn when static declaration follows a non-static
180018334Speter	     declaration.  Otherwise, do so only for functions.  */
180118334Speter	  if ((pedantic || TREE_CODE (olddecl) == FUNCTION_DECL)
180218334Speter	      && TREE_PUBLIC (olddecl)
180318334Speter	      && !TREE_PUBLIC (newdecl))
180418334Speter	    warning_with_decl (newdecl, "static declaration for `%s' follows non-static");
180518334Speter
180652284Sobrien	  /* If warn_traditional, warn when a non-static function
180790075Sobrien	     declaration follows a static one.  */
180890075Sobrien	  if (warn_traditional && !in_system_header
180952284Sobrien	      && TREE_CODE (olddecl) == FUNCTION_DECL
181052284Sobrien	      && !TREE_PUBLIC (olddecl)
181152284Sobrien	      && TREE_PUBLIC (newdecl))
181252284Sobrien	    warning_with_decl (newdecl, "non-static declaration for `%s' follows static");
181352284Sobrien
181418334Speter	  /* Warn when const declaration follows a non-const
181518334Speter	     declaration, but not for functions.  */
181618334Speter	  if (TREE_CODE (olddecl) != FUNCTION_DECL
181718334Speter	      && !TREE_READONLY (olddecl)
181818334Speter	      && TREE_READONLY (newdecl))
181918334Speter	    warning_with_decl (newdecl, "const declaration for `%s' follows non-const");
182018334Speter	  /* These bits are logically part of the type, for variables.
182118334Speter	     But not for functions
182218334Speter	     (where qualifiers are not valid ANSI anyway).  */
182318334Speter	  else if (pedantic && TREE_CODE (olddecl) != FUNCTION_DECL
182418334Speter	      && (TREE_READONLY (newdecl) != TREE_READONLY (olddecl)
182518334Speter		  || TREE_THIS_VOLATILE (newdecl) != TREE_THIS_VOLATILE (olddecl)))
182618334Speter	    pedwarn_with_decl (newdecl, "type qualifiers for `%s' conflict with previous decl");
182718334Speter	}
182818334Speter    }
182918334Speter
183018334Speter  /* Optionally warn about more than one declaration for the same name.  */
183118334Speter  if (errmsg == 0 && warn_redundant_decls && DECL_SOURCE_LINE (olddecl) != 0
183250397Sobrien      /* Don't warn about a function declaration
183318334Speter	 followed by a definition.  */
183418334Speter      && !(TREE_CODE (newdecl) == FUNCTION_DECL && DECL_INITIAL (newdecl) != 0
183518334Speter	   && DECL_INITIAL (olddecl) == 0)
183618334Speter      /* Don't warn about extern decl followed by (tentative) definition.  */
183718334Speter      && !(DECL_EXTERNAL (olddecl) && ! DECL_EXTERNAL (newdecl)))
183818334Speter    {
183918334Speter      warning_with_decl (newdecl, "redundant redeclaration of `%s' in same scope");
184018334Speter      warning_with_decl (olddecl, "previous declaration of `%s'");
184118334Speter    }
184218334Speter
184318334Speter  /* Copy all the DECL_... slots specified in the new decl
184418334Speter     except for any that we copy here from the old type.
184518334Speter
184618334Speter     Past this point, we don't change OLDTYPE and NEWTYPE
184718334Speter     even if we change the types of NEWDECL and OLDDECL.  */
184818334Speter
184918334Speter  if (types_match)
185018334Speter    {
185150397Sobrien      /* When copying info to olddecl, we store into write_olddecl
185250397Sobrien	 instead.  This allows us to avoid modifying olddecl when
185350397Sobrien	 different_binding_level is true.  */
185450397Sobrien      tree write_olddecl = different_binding_level ? newdecl : olddecl;
185550397Sobrien
185618334Speter      /* Merge the data types specified in the two decls.  */
185718334Speter      if (TREE_CODE (newdecl) != FUNCTION_DECL || !DECL_BUILT_IN (olddecl))
185850397Sobrien	{
185950397Sobrien	  if (different_binding_level)
186090075Sobrien	    {
186190075Sobrien	      if (TYPE_ARG_TYPES (oldtype) != 0
186290075Sobrien		  && TYPE_ARG_TYPES (newtype) == 0)
186390075Sobrien		TREE_TYPE (newdecl) = common_type (newtype, oldtype);
186490075Sobrien	      else
186590075Sobrien		TREE_TYPE (newdecl)
186690075Sobrien		  = build_type_attribute_variant
186790075Sobrien		    (newtype,
186890075Sobrien		     merge_attributes (TYPE_ATTRIBUTES (newtype),
186990075Sobrien				       TYPE_ATTRIBUTES (oldtype)));
187090075Sobrien	    }
187150397Sobrien	  else
187250397Sobrien	    TREE_TYPE (newdecl)
187350397Sobrien	      = TREE_TYPE (olddecl)
187450397Sobrien		= common_type (newtype, oldtype);
187550397Sobrien	}
187618334Speter
187718334Speter      /* Lay the type out, unless already done.  */
187818334Speter      if (oldtype != TREE_TYPE (newdecl))
187918334Speter	{
188018334Speter	  if (TREE_TYPE (newdecl) != error_mark_node)
188118334Speter	    layout_type (TREE_TYPE (newdecl));
188218334Speter	  if (TREE_CODE (newdecl) != FUNCTION_DECL
188318334Speter	      && TREE_CODE (newdecl) != TYPE_DECL
188418334Speter	      && TREE_CODE (newdecl) != CONST_DECL)
188518334Speter	    layout_decl (newdecl, 0);
188618334Speter	}
188718334Speter      else
188818334Speter	{
188918334Speter	  /* Since the type is OLDDECL's, make OLDDECL's size go with.  */
189018334Speter	  DECL_SIZE (newdecl) = DECL_SIZE (olddecl);
189190075Sobrien	  DECL_SIZE_UNIT (newdecl) = DECL_SIZE_UNIT (olddecl);
189257844Sobrien	  DECL_MODE (newdecl) = DECL_MODE (olddecl);
189318334Speter	  if (TREE_CODE (olddecl) != FUNCTION_DECL)
189418334Speter	    if (DECL_ALIGN (olddecl) > DECL_ALIGN (newdecl))
189590075Sobrien	      {
189690075Sobrien		DECL_ALIGN (newdecl) = DECL_ALIGN (olddecl);
189790075Sobrien		DECL_USER_ALIGN (newdecl) |= DECL_ALIGN (olddecl);
189890075Sobrien	      }
189918334Speter	}
190018334Speter
190118334Speter      /* Keep the old rtl since we can safely use it.  */
190290075Sobrien      COPY_DECL_RTL (olddecl, newdecl);
190318334Speter
190418334Speter      /* Merge the type qualifiers.  */
190590075Sobrien      if (TREE_CODE (olddecl) == FUNCTION_DECL
190690075Sobrien	  && DECL_BUILT_IN_NONANSI (olddecl) && TREE_THIS_VOLATILE (olddecl)
190790075Sobrien	  && ! TREE_THIS_VOLATILE (newdecl))
190850397Sobrien	TREE_THIS_VOLATILE (write_olddecl) = 0;
190990075Sobrien
191018334Speter      if (TREE_READONLY (newdecl))
191150397Sobrien	TREE_READONLY (write_olddecl) = 1;
191290075Sobrien
191318334Speter      if (TREE_THIS_VOLATILE (newdecl))
191418334Speter	{
191550397Sobrien	  TREE_THIS_VOLATILE (write_olddecl) = 1;
191690075Sobrien	  if (TREE_CODE (newdecl) == VAR_DECL
191790075Sobrien	      /* If an automatic variable is re-declared in the same
191890075Sobrien		 function scope, but the old declaration was not
191990075Sobrien		 volatile, make_var_volatile() would crash because the
192090075Sobrien		 variable would have been assigned to a pseudo, not a
192190075Sobrien		 MEM.  Since this duplicate declaration is invalid
192290075Sobrien		 anyway, we just skip the call.  */
192390075Sobrien	      && errmsg == 0)
192418334Speter	    make_var_volatile (newdecl);
192518334Speter	}
192618334Speter
192750397Sobrien      /* Keep source location of definition rather than declaration.  */
192850397Sobrien      /* When called with different_binding_level set, keep the old
192950397Sobrien	 information so that meaningful diagnostics can be given.  */
193050397Sobrien      if (DECL_INITIAL (newdecl) == 0 && DECL_INITIAL (olddecl) != 0
193150397Sobrien	  && ! different_binding_level)
193218334Speter	{
193318334Speter	  DECL_SOURCE_LINE (newdecl) = DECL_SOURCE_LINE (olddecl);
193418334Speter	  DECL_SOURCE_FILE (newdecl) = DECL_SOURCE_FILE (olddecl);
193518334Speter	}
193618334Speter
193718334Speter      /* Merge the unused-warning information.  */
193818334Speter      if (DECL_IN_SYSTEM_HEADER (olddecl))
193918334Speter	DECL_IN_SYSTEM_HEADER (newdecl) = 1;
194018334Speter      else if (DECL_IN_SYSTEM_HEADER (newdecl))
194150397Sobrien	DECL_IN_SYSTEM_HEADER (write_olddecl) = 1;
194218334Speter
194318334Speter      /* Merge the initialization information.  */
194450397Sobrien      /* When called with different_binding_level set, don't copy over
194550397Sobrien	 DECL_INITIAL, so that we don't accidentally change function
194650397Sobrien	 declarations into function definitions.  */
194750397Sobrien      if (DECL_INITIAL (newdecl) == 0 && ! different_binding_level)
194818334Speter	DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
194918334Speter
195018334Speter      /* Merge the section attribute.
195118334Speter         We want to issue an error if the sections conflict but that must be
195218334Speter	 done later in decl_attributes since we are called before attributes
195318334Speter	 are assigned.  */
195418334Speter      if (DECL_SECTION_NAME (newdecl) == NULL_TREE)
195518334Speter	DECL_SECTION_NAME (newdecl) = DECL_SECTION_NAME (olddecl);
195618334Speter
195790075Sobrien      /* Copy the assembler name.
195890075Sobrien	 Currently, it can only be defined in the prototype.  */
195990075Sobrien      COPY_DECL_ASSEMBLER_NAME (olddecl, newdecl);
196090075Sobrien
196118334Speter      if (TREE_CODE (newdecl) == FUNCTION_DECL)
196218334Speter	{
196318334Speter	  DECL_STATIC_CONSTRUCTOR(newdecl) |= DECL_STATIC_CONSTRUCTOR(olddecl);
196418334Speter	  DECL_STATIC_DESTRUCTOR (newdecl) |= DECL_STATIC_DESTRUCTOR (olddecl);
196590075Sobrien	  DECL_NO_LIMIT_STACK (newdecl) |= DECL_NO_LIMIT_STACK (olddecl);
196652284Sobrien	  DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (newdecl)
196752284Sobrien	    |= DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (olddecl);
196818334Speter	}
196918334Speter    }
197018334Speter  /* If cannot merge, then use the new type and qualifiers,
197118334Speter     and don't preserve the old rtl.  */
197250397Sobrien  else if (! different_binding_level)
197318334Speter    {
197418334Speter      TREE_TYPE (olddecl) = TREE_TYPE (newdecl);
197518334Speter      TREE_READONLY (olddecl) = TREE_READONLY (newdecl);
197618334Speter      TREE_THIS_VOLATILE (olddecl) = TREE_THIS_VOLATILE (newdecl);
197718334Speter      TREE_SIDE_EFFECTS (olddecl) = TREE_SIDE_EFFECTS (newdecl);
197818334Speter    }
197918334Speter
198018334Speter  /* Merge the storage class information.  */
198196263Sobrien  merge_weak (newdecl, olddecl);
198296263Sobrien
198318334Speter  /* For functions, static overrides non-static.  */
198418334Speter  if (TREE_CODE (newdecl) == FUNCTION_DECL)
198518334Speter    {
198618334Speter      TREE_PUBLIC (newdecl) &= TREE_PUBLIC (olddecl);
198718334Speter      /* This is since we don't automatically
198818334Speter	 copy the attributes of NEWDECL into OLDDECL.  */
198950397Sobrien      /* No need to worry about different_binding_level here because
199050397Sobrien	 then TREE_PUBLIC (newdecl) was true.  */
199118334Speter      TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl);
199218334Speter      /* If this clears `static', clear it in the identifier too.  */
199318334Speter      if (! TREE_PUBLIC (olddecl))
199418334Speter	TREE_PUBLIC (DECL_NAME (olddecl)) = 0;
199518334Speter    }
199618334Speter  if (DECL_EXTERNAL (newdecl))
199718334Speter    {
199890075Sobrien      if (! different_binding_level)
199990075Sobrien	{
200090075Sobrien	  /* Don't mess with these flags on local externs; they remain
200190075Sobrien	     external even if there's a declaration at file scope which
200290075Sobrien	     isn't.  */
200390075Sobrien	  TREE_STATIC (newdecl) = TREE_STATIC (olddecl);
200490075Sobrien	  DECL_EXTERNAL (newdecl) = DECL_EXTERNAL (olddecl);
200590075Sobrien	}
200618334Speter      /* An extern decl does not override previous storage class.  */
200718334Speter      TREE_PUBLIC (newdecl) = TREE_PUBLIC (olddecl);
200850397Sobrien      if (! DECL_EXTERNAL (newdecl))
200950397Sobrien	DECL_CONTEXT (newdecl) = DECL_CONTEXT (olddecl);
201018334Speter    }
201118334Speter  else
201218334Speter    {
201318334Speter      TREE_STATIC (olddecl) = TREE_STATIC (newdecl);
201418334Speter      TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl);
201518334Speter    }
201618334Speter
201750397Sobrien  if (TREE_CODE (newdecl) == FUNCTION_DECL)
201818334Speter    {
201990075Sobrien      /* If we're redefining a function previously defined as extern
202090075Sobrien	 inline, make sure we emit debug info for the inline before we
202190075Sobrien	 throw it away, in case it was inlined into a function that hasn't
202290075Sobrien	 been written out yet.  */
202390075Sobrien      if (new_is_definition && DECL_INITIAL (olddecl) && TREE_USED (olddecl))
202490075Sobrien	{
202590075Sobrien	  (*debug_hooks->outlining_inline_function) (olddecl);
202690075Sobrien
202790075Sobrien	  /* The new defn must not be inline.  */
202890075Sobrien	  DECL_INLINE (newdecl) = 0;
202990075Sobrien	  DECL_UNINLINABLE (newdecl) = 1;
203090075Sobrien	}
203190075Sobrien      else
203290075Sobrien	{
203390075Sobrien	  /* If either decl says `inline', this fn is inline,
203490075Sobrien	     unless its definition was passed already.  */
203590075Sobrien	  if (DECL_DECLARED_INLINE_P (newdecl)
203690075Sobrien	      || DECL_DECLARED_INLINE_P (olddecl))
203790075Sobrien	    DECL_DECLARED_INLINE_P (newdecl) = 1;
203890075Sobrien
203990075Sobrien	  DECL_UNINLINABLE (newdecl) = DECL_UNINLINABLE (olddecl)
204090075Sobrien	    = (DECL_UNINLINABLE (newdecl) || DECL_UNINLINABLE (olddecl));
204190075Sobrien	}
204290075Sobrien
204318334Speter      if (DECL_BUILT_IN (olddecl))
204418334Speter	{
204550397Sobrien	  /* Get rid of any built-in function if new arg types don't match it
204650397Sobrien	     or if we have a function definition.  */
204750397Sobrien	  if (! types_match || new_is_definition)
204850397Sobrien	    {
204950397Sobrien	      if (! different_binding_level)
205050397Sobrien		{
205150397Sobrien		  TREE_TYPE (olddecl) = TREE_TYPE (newdecl);
205290075Sobrien		  DECL_BUILT_IN_CLASS (olddecl) = NOT_BUILT_IN;
205350397Sobrien		}
205450397Sobrien	    }
205550397Sobrien	  else
205650397Sobrien	    {
205750397Sobrien	      /* If redeclaring a builtin function, and not a definition,
205850397Sobrien		 it stays built in.  */
205990075Sobrien	      DECL_BUILT_IN_CLASS (newdecl) = DECL_BUILT_IN_CLASS (olddecl);
206050397Sobrien	      DECL_FUNCTION_CODE (newdecl) = DECL_FUNCTION_CODE (olddecl);
206150397Sobrien	    }
206218334Speter	}
206390075Sobrien
206450397Sobrien      /* Also preserve various other info from the definition.  */
206550397Sobrien      if (! new_is_definition)
206650397Sobrien	{
206750397Sobrien	  DECL_RESULT (newdecl) = DECL_RESULT (olddecl);
206850397Sobrien	  /* When called with different_binding_level set, don't copy over
206950397Sobrien	     DECL_INITIAL, so that we don't accidentally change function
207050397Sobrien	     declarations into function definitions.  */
207150397Sobrien	  if (! different_binding_level)
207250397Sobrien	    DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
207350397Sobrien	  DECL_SAVED_INSNS (newdecl) = DECL_SAVED_INSNS (olddecl);
207490075Sobrien	  DECL_SAVED_TREE (newdecl) = DECL_SAVED_TREE (olddecl);
207590075Sobrien	  DECL_NUM_STMTS (newdecl) = DECL_NUM_STMTS (olddecl);
207650397Sobrien	  DECL_ARGUMENTS (newdecl) = DECL_ARGUMENTS (olddecl);
207790075Sobrien
207890075Sobrien	  /* Set DECL_INLINE on the declaration if we've got a body
207990075Sobrien	     from which to instantiate.  */
208090075Sobrien	  if (DECL_INLINE (olddecl) && ! DECL_UNINLINABLE (newdecl))
208190075Sobrien	    {
208290075Sobrien	      DECL_INLINE (newdecl) = 1;
208390075Sobrien	      DECL_ABSTRACT_ORIGIN (newdecl)
208490075Sobrien		= (different_binding_level
208590075Sobrien		   ? DECL_ORIGIN (olddecl)
208690075Sobrien		   : DECL_ABSTRACT_ORIGIN (olddecl));
208790075Sobrien	    }
208850397Sobrien	}
208990075Sobrien      else
209090075Sobrien	{
209190075Sobrien	  /* If a previous declaration said inline, mark the
209290075Sobrien	     definition as inlinable.  */
209390075Sobrien	  if (DECL_DECLARED_INLINE_P (newdecl)
209490075Sobrien	      && ! DECL_UNINLINABLE (newdecl))
209590075Sobrien	    DECL_INLINE (newdecl) = 1;
209690075Sobrien	}
209750397Sobrien    }
209850397Sobrien  if (different_binding_level)
209990075Sobrien    return 0;
210018334Speter
210118334Speter  /* Copy most of the decl-specific fields of NEWDECL into OLDDECL.
210250397Sobrien     But preserve OLDDECL's DECL_UID.  */
210318334Speter  {
210490075Sobrien    unsigned olddecl_uid = DECL_UID (olddecl);
210518334Speter
210690075Sobrien    memcpy ((char *) olddecl + sizeof (struct tree_common),
210790075Sobrien	    (char *) newdecl + sizeof (struct tree_common),
210890075Sobrien	    sizeof (struct tree_decl) - sizeof (struct tree_common));
210918334Speter    DECL_UID (olddecl) = olddecl_uid;
211018334Speter  }
211118334Speter
211250397Sobrien  /* NEWDECL contains the merged attribute lists.
211350397Sobrien     Update OLDDECL to be the same.  */
211490075Sobrien  DECL_ATTRIBUTES (olddecl) = DECL_ATTRIBUTES (newdecl);
211550397Sobrien
211618334Speter  return 1;
211718334Speter}
211818334Speter
211990075Sobrien/* Check whether decl-node X shadows an existing declaration.
212090075Sobrien   OLDLOCAL is the old IDENTIFIER_LOCAL_VALUE of the DECL_NAME of X,
212190075Sobrien   which might be a NULL_TREE.  */
212290075Sobrienstatic void
212390075Sobrienwarn_if_shadowing (x, oldlocal)
212490075Sobrien     tree x, oldlocal;
212590075Sobrien{
212690075Sobrien  tree name;
212790075Sobrien
212890075Sobrien  if (DECL_EXTERNAL (x))
212990075Sobrien    return;
213090075Sobrien
213190075Sobrien  name = DECL_NAME (x);
213290075Sobrien
213390075Sobrien  /* Warn if shadowing an argument at the top level of the body.  */
213490075Sobrien  if (oldlocal != 0
213590075Sobrien      /* This warning doesn't apply to the parms of a nested fcn.  */
213690075Sobrien      && ! current_binding_level->parm_flag
213790075Sobrien      /* Check that this is one level down from the parms.  */
213890075Sobrien      && current_binding_level->level_chain->parm_flag
213990075Sobrien      /* Check that the decl being shadowed
214090075Sobrien	 comes from the parm level, one level up.  */
214190075Sobrien      && chain_member (oldlocal, current_binding_level->level_chain->names))
214290075Sobrien    {
214390075Sobrien      if (TREE_CODE (oldlocal) == PARM_DECL)
214490075Sobrien	pedwarn ("declaration of `%s' shadows a parameter",
214590075Sobrien		 IDENTIFIER_POINTER (name));
214690075Sobrien      else
214790075Sobrien	pedwarn ("declaration of `%s' shadows a symbol from the parameter list",
214890075Sobrien		 IDENTIFIER_POINTER (name));
214990075Sobrien    }
215090075Sobrien  /* Maybe warn if shadowing something else.  */
215190075Sobrien  else if (warn_shadow
215290075Sobrien	   /* No shadow warnings for internally generated vars.  */
215390075Sobrien	   && DECL_SOURCE_LINE (x) != 0
215490075Sobrien	   /* No shadow warnings for vars made for inlining.  */
215590075Sobrien	   && ! DECL_FROM_INLINE (x))
215690075Sobrien    {
215790075Sobrien      if (TREE_CODE (x) == PARM_DECL
215890075Sobrien	  && current_binding_level->level_chain->parm_flag)
215990075Sobrien	/* Don't warn about the parm names in function declarator
216090075Sobrien	   within a function declarator.
216190075Sobrien	   It would be nice to avoid warning in any function
216290075Sobrien	   declarator in a declaration, as opposed to a definition,
216390075Sobrien	   but there is no way to tell it's not a definition.  */
216490075Sobrien	;
216590075Sobrien      else if (oldlocal)
216690075Sobrien	{
216790075Sobrien	  if (TREE_CODE (oldlocal) == PARM_DECL)
216890075Sobrien	    shadow_warning ("a parameter", name, oldlocal);
216990075Sobrien	  else
217090075Sobrien	    shadow_warning ("a previous local", name, oldlocal);
217190075Sobrien	}
217290075Sobrien      else if (IDENTIFIER_GLOBAL_VALUE (name) != 0
217390075Sobrien	       && IDENTIFIER_GLOBAL_VALUE (name) != error_mark_node)
217490075Sobrien	shadow_warning ("a global declaration", name,
217590075Sobrien			IDENTIFIER_GLOBAL_VALUE (name));
217690075Sobrien    }
217790075Sobrien}
217890075Sobrien
217918334Speter/* Record a decl-node X as belonging to the current lexical scope.
218018334Speter   Check for errors (such as an incompatible declaration for the same
218118334Speter   name already seen in the same scope).
218218334Speter
218318334Speter   Returns either X or an old decl for the same name.
218418334Speter   If an old decl is returned, it may have been smashed
218518334Speter   to agree with what X says.  */
218618334Speter
218718334Spetertree
218818334Speterpushdecl (x)
218918334Speter     tree x;
219018334Speter{
219190075Sobrien  tree t;
219290075Sobrien  tree name = DECL_NAME (x);
219390075Sobrien  struct binding_level *b = current_binding_level;
219418334Speter
219590075Sobrien  /* Functions need the lang_decl data.  */
219690075Sobrien  if (TREE_CODE (x) == FUNCTION_DECL && ! DECL_LANG_SPECIFIC (x))
219790075Sobrien    DECL_LANG_SPECIFIC (x) = (struct lang_decl *)
219890075Sobrien      ggc_alloc_cleared (sizeof (struct lang_decl));
219990075Sobrien
220018334Speter  DECL_CONTEXT (x) = current_function_decl;
220118334Speter  /* A local extern declaration for a function doesn't constitute nesting.
220218334Speter     A local auto declaration does, since it's a forward decl
220318334Speter     for a nested function coming later.  */
220490075Sobrien  if ((TREE_CODE (x) == FUNCTION_DECL || TREE_CODE (x) == VAR_DECL)
220590075Sobrien      && DECL_INITIAL (x) == 0 && DECL_EXTERNAL (x))
220618334Speter    DECL_CONTEXT (x) = 0;
220718334Speter
220818334Speter  if (name)
220918334Speter    {
221050397Sobrien      int different_binding_level = 0;
221118334Speter
221290075Sobrien      if (warn_nested_externs
221390075Sobrien	  && DECL_EXTERNAL (x)
221490075Sobrien	  && b != global_binding_level
221590075Sobrien	  && x != IDENTIFIER_IMPLICIT_DECL (name)
221690075Sobrien	  /* No error messages for __FUNCTION__ and __PRETTY_FUNCTION__.  */
221790075Sobrien	  && !DECL_IN_SYSTEM_HEADER (x))
221890075Sobrien	warning ("nested extern declaration of `%s'",
221990075Sobrien		 IDENTIFIER_POINTER (name));
222090075Sobrien
222150397Sobrien      t = lookup_name_current_level (name);
222218334Speter      /* Don't type check externs here when -traditional.  This is so that
222318334Speter	 code with conflicting declarations inside blocks will get warnings
222418334Speter	 not errors.  X11 for instance depends on this.  */
222550397Sobrien      if (! t && DECL_EXTERNAL (x) && TREE_PUBLIC (x) && ! flag_traditional)
222650397Sobrien	{
222796263Sobrien	  t = IDENTIFIER_GLOBAL_VALUE (name);
222850397Sobrien	  /* Type decls at global scope don't conflict with externs declared
222950397Sobrien	     inside lexical blocks.  */
223096263Sobrien	  if (! t || TREE_CODE (t) == TYPE_DECL)
223196263Sobrien	    /* If there's no visible global declaration, try for an
223296263Sobrien               invisible one.  */
223396263Sobrien	    t = IDENTIFIER_LIMBO_VALUE (name);
223450397Sobrien	  different_binding_level = 1;
223550397Sobrien	}
223618334Speter      if (t != 0 && t == error_mark_node)
223718334Speter	/* error_mark_node is 0 for a while during initialization!  */
223818334Speter	{
223918334Speter	  t = 0;
224018334Speter	  error_with_decl (x, "`%s' used prior to declaration");
224118334Speter	}
224218334Speter
224350397Sobrien      /* If this decl is `static' and an implicit decl was seen previously,
224450397Sobrien	 warn.  But don't complain if -traditional,
224550397Sobrien	 since traditional compilers don't complain.  */
224650397Sobrien      if (! flag_traditional && TREE_PUBLIC (name)
224750397Sobrien	  /* Don't test for DECL_EXTERNAL, because grokdeclarator
224850397Sobrien	     sets this for all functions.  */
224950397Sobrien	  && ! TREE_PUBLIC (x)
225050397Sobrien	  && (TREE_CODE (x) == FUNCTION_DECL || b == global_binding_level)
225150397Sobrien	  /* We used to warn also for explicit extern followed by static,
225250397Sobrien	     but sometimes you need to do it that way.  */
225350397Sobrien	  && IDENTIFIER_IMPLICIT_DECL (name) != 0)
225418334Speter	{
225550397Sobrien	  pedwarn ("`%s' was declared implicitly `extern' and later `static'",
225650397Sobrien		   IDENTIFIER_POINTER (name));
225750397Sobrien	  pedwarn_with_file_and_line
225850397Sobrien	    (DECL_SOURCE_FILE (IDENTIFIER_IMPLICIT_DECL (name)),
225950397Sobrien	     DECL_SOURCE_LINE (IDENTIFIER_IMPLICIT_DECL (name)),
226050397Sobrien	     "previous declaration of `%s'",
226150397Sobrien	     IDENTIFIER_POINTER (name));
226250397Sobrien	  TREE_THIS_VOLATILE (name) = 1;
226350397Sobrien	}
226450397Sobrien
226550397Sobrien      if (t != 0 && duplicate_decls (x, t, different_binding_level))
226650397Sobrien	{
226718334Speter	  if (TREE_CODE (t) == PARM_DECL)
226818334Speter	    {
226918334Speter	      /* Don't allow more than one "real" duplicate
227018334Speter		 of a forward parm decl.  */
227118334Speter	      TREE_ASM_WRITTEN (t) = TREE_ASM_WRITTEN (x);
227218334Speter	      return t;
227318334Speter	    }
227450397Sobrien	  return t;
227518334Speter	}
227618334Speter
227718334Speter      /* If we are processing a typedef statement, generate a whole new
227818334Speter	 ..._TYPE node (which will be just an variant of the existing
227918334Speter	 ..._TYPE node with identical properties) and then install the
228018334Speter	 TYPE_DECL node generated to represent the typedef name as the
228118334Speter	 TYPE_NAME of this brand new (duplicate) ..._TYPE node.
228218334Speter
228318334Speter	 The whole point here is to end up with a situation where each
228418334Speter	 and every ..._TYPE node the compiler creates will be uniquely
228518334Speter	 associated with AT MOST one node representing a typedef name.
228618334Speter	 This way, even though the compiler substitutes corresponding
228718334Speter	 ..._TYPE nodes for TYPE_DECL (i.e. "typedef name") nodes very
228818334Speter	 early on, later parts of the compiler can always do the reverse
228918334Speter	 translation and get back the corresponding typedef name.  For
229018334Speter	 example, given:
229118334Speter
229218334Speter		typedef struct S MY_TYPE;
229318334Speter		MY_TYPE object;
229418334Speter
229518334Speter	 Later parts of the compiler might only know that `object' was of
229650397Sobrien	 type `struct S' if it were not for code just below.  With this
229718334Speter	 code however, later parts of the compiler see something like:
229818334Speter
229918334Speter		struct S' == struct S
230018334Speter		typedef struct S' MY_TYPE;
230118334Speter		struct S' object;
230218334Speter
230318334Speter	 And they can then deduce (from the node for type struct S') that
230418334Speter	 the original object declaration was:
230518334Speter
230618334Speter		MY_TYPE object;
230718334Speter
230818334Speter	 Being able to do this is important for proper support of protoize,
230918334Speter	 and also for generating precise symbolic debugging information
231018334Speter	 which takes full account of the programmer's (typedef) vocabulary.
231118334Speter
231218334Speter         Obviously, we don't want to generate a duplicate ..._TYPE node if
231318334Speter	 the TYPE_DECL node that we are now processing really represents a
231418334Speter	 standard built-in type.
231518334Speter
231618334Speter         Since all standard types are effectively declared at line zero
231718334Speter         in the source file, we can easily check to see if we are working
231818334Speter         on a standard type by checking the current value of lineno.  */
231918334Speter
232018334Speter      if (TREE_CODE (x) == TYPE_DECL)
232190075Sobrien	{
232290075Sobrien	  if (DECL_SOURCE_LINE (x) == 0)
232390075Sobrien	    {
232418334Speter	      if (TYPE_NAME (TREE_TYPE (x)) == 0)
232590075Sobrien		TYPE_NAME (TREE_TYPE (x)) = x;
232690075Sobrien	    }
232790075Sobrien	  else if (TREE_TYPE (x) != error_mark_node
232850397Sobrien		   && DECL_ORIGINAL_TYPE (x) == NULL_TREE)
232990075Sobrien	    {
233090075Sobrien	      tree tt = TREE_TYPE (x);
233150397Sobrien	      DECL_ORIGINAL_TYPE (x) = tt;
233290075Sobrien	      tt = build_type_copy (tt);
233390075Sobrien	      TYPE_NAME (tt) = x;
233490075Sobrien	      TREE_USED (tt) = TREE_USED (x);
233590075Sobrien	      TREE_TYPE (x) = tt;
233690075Sobrien	    }
233790075Sobrien	}
233818334Speter
233918334Speter      /* Multiple external decls of the same identifier ought to match.
234018334Speter	 Check against both global declarations (when traditional) and out of
234118334Speter	 scope (limbo) block level declarations.
234218334Speter
234318334Speter	 We get warnings about inline functions where they are defined.
234418334Speter	 Avoid duplicate warnings where they are used.  */
234590075Sobrien      if (TREE_PUBLIC (x)
234690075Sobrien	  && ! (TREE_CODE (x) == FUNCTION_DECL && DECL_INLINE (x)))
234718334Speter	{
234818334Speter	  tree decl;
234918334Speter
235018334Speter	  if (flag_traditional && IDENTIFIER_GLOBAL_VALUE (name) != 0
235118334Speter	      && (DECL_EXTERNAL (IDENTIFIER_GLOBAL_VALUE (name))
235218334Speter		  || TREE_PUBLIC (IDENTIFIER_GLOBAL_VALUE (name))))
235318334Speter	    decl = IDENTIFIER_GLOBAL_VALUE (name);
235418334Speter	  else if (IDENTIFIER_LIMBO_VALUE (name) != 0)
235518334Speter	    /* Decls in limbo are always extern, so no need to check that.  */
235618334Speter	    decl = IDENTIFIER_LIMBO_VALUE (name);
235718334Speter	  else
235818334Speter	    decl = 0;
235918334Speter
236018334Speter	  if (decl && ! comptypes (TREE_TYPE (x), TREE_TYPE (decl))
236118334Speter	      /* If old decl is built-in, we already warned if we should.  */
236218334Speter	      && !DECL_BUILT_IN (decl))
236318334Speter	    {
236418334Speter	      pedwarn_with_decl (x,
236518334Speter				 "type mismatch with previous external decl");
236618334Speter	      pedwarn_with_decl (decl, "previous external decl of `%s'");
236718334Speter	    }
236818334Speter	}
236918334Speter
237018334Speter      /* If a function has had an implicit declaration, and then is defined,
237118334Speter	 make sure they are compatible.  */
237218334Speter
237318334Speter      if (IDENTIFIER_IMPLICIT_DECL (name) != 0
237418334Speter	  && IDENTIFIER_GLOBAL_VALUE (name) == 0
237518334Speter	  && TREE_CODE (x) == FUNCTION_DECL
237618334Speter	  && ! comptypes (TREE_TYPE (x),
237718334Speter			  TREE_TYPE (IDENTIFIER_IMPLICIT_DECL (name))))
237818334Speter	{
237918334Speter	  warning_with_decl (x, "type mismatch with previous implicit declaration");
238018334Speter	  warning_with_decl (IDENTIFIER_IMPLICIT_DECL (name),
238118334Speter			     "previous implicit declaration of `%s'");
238218334Speter	}
238318334Speter
238418334Speter      /* In PCC-compatibility mode, extern decls of vars with no current decl
238518334Speter	 take effect at top level no matter where they are.  */
238618334Speter      if (flag_traditional && DECL_EXTERNAL (x)
238718334Speter	  && lookup_name (name) == 0)
238818334Speter	{
238918334Speter	  tree type = TREE_TYPE (x);
239018334Speter
239118334Speter	  /* But don't do this if the type contains temporary nodes.  */
239218334Speter	  while (type)
239318334Speter	    {
239418334Speter	      if (type == error_mark_node)
239518334Speter		break;
239690075Sobrien	      if (TYPE_CONTEXT (type))
239718334Speter		{
239818334Speter		  warning_with_decl (x, "type of external `%s' is not global");
239918334Speter		  /* By exiting the loop early, we leave TYPE nonzero,
240018334Speter		     and thus prevent globalization of the decl.  */
240118334Speter		  break;
240218334Speter		}
240318334Speter	      else if (TREE_CODE (type) == FUNCTION_TYPE
240418334Speter		       && TYPE_ARG_TYPES (type) != 0)
240518334Speter		/* The types might not be truly local,
240618334Speter		   but the list of arg types certainly is temporary.
240718334Speter		   Since prototypes are nontraditional,
240818334Speter		   ok not to do the traditional thing.  */
240918334Speter		break;
241018334Speter	      type = TREE_TYPE (type);
241118334Speter	    }
241218334Speter
241318334Speter	  if (type == 0)
241418334Speter	    b = global_binding_level;
241518334Speter	}
241618334Speter
241718334Speter      /* This name is new in its binding level.
241818334Speter	 Install the new declaration and return it.  */
241918334Speter      if (b == global_binding_level)
242018334Speter	{
242118334Speter	  /* Install a global value.  */
242290075Sobrien
242318334Speter	  /* If the first global decl has external linkage,
242418334Speter	     warn if we later see static one.  */
242518334Speter	  if (IDENTIFIER_GLOBAL_VALUE (name) == 0 && TREE_PUBLIC (x))
242618334Speter	    TREE_PUBLIC (name) = 1;
242718334Speter
242818334Speter	  IDENTIFIER_GLOBAL_VALUE (name) = x;
242918334Speter
243018334Speter	  /* We no longer care about any previous block level declarations.  */
243118334Speter	  IDENTIFIER_LIMBO_VALUE (name) = 0;
243218334Speter
243318334Speter	  /* Don't forget if the function was used via an implicit decl.  */
243418334Speter	  if (IDENTIFIER_IMPLICIT_DECL (name)
243518334Speter	      && TREE_USED (IDENTIFIER_IMPLICIT_DECL (name)))
243618334Speter	    TREE_USED (x) = 1, TREE_USED (name) = 1;
243718334Speter
243818334Speter	  /* Don't forget if its address was taken in that way.  */
243918334Speter	  if (IDENTIFIER_IMPLICIT_DECL (name)
244018334Speter	      && TREE_ADDRESSABLE (IDENTIFIER_IMPLICIT_DECL (name)))
244118334Speter	    TREE_ADDRESSABLE (x) = 1;
244218334Speter
244318334Speter	  /* Warn about mismatches against previous implicit decl.  */
244418334Speter	  if (IDENTIFIER_IMPLICIT_DECL (name) != 0
244518334Speter	      /* If this real decl matches the implicit, don't complain.  */
244618334Speter	      && ! (TREE_CODE (x) == FUNCTION_DECL
244718334Speter		    && (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (x)))
244818334Speter			== integer_type_node)))
244918334Speter	    pedwarn ("`%s' was previously implicitly declared to return `int'",
245018334Speter		     IDENTIFIER_POINTER (name));
245118334Speter
245218334Speter	  /* If this decl is `static' and an `extern' was seen previously,
245318334Speter	     that is erroneous.  */
245418334Speter	  if (TREE_PUBLIC (name)
245518334Speter	      && ! TREE_PUBLIC (x) && ! DECL_EXTERNAL (x))
245618334Speter	    {
245718334Speter	      /* Okay to redeclare an ANSI built-in as static.  */
245818334Speter	      if (t != 0 && DECL_BUILT_IN (t))
245918334Speter		;
246018334Speter	      /* Okay to declare a non-ANSI built-in as anything.  */
246118334Speter	      else if (t != 0 && DECL_BUILT_IN_NONANSI (t))
246218334Speter		;
246350397Sobrien	      /* Okay to have global type decl after an earlier extern
246450397Sobrien		 declaration inside a lexical block.  */
246550397Sobrien	      else if (TREE_CODE (x) == TYPE_DECL)
246650397Sobrien		;
246718334Speter	      else if (IDENTIFIER_IMPLICIT_DECL (name))
246850397Sobrien		{
246950397Sobrien		  if (! TREE_THIS_VOLATILE (name))
247050397Sobrien		    pedwarn ("`%s' was declared implicitly `extern' and later `static'",
247150397Sobrien			     IDENTIFIER_POINTER (name));
247250397Sobrien		}
247318334Speter	      else
247418334Speter		pedwarn ("`%s' was declared `extern' and later `static'",
247518334Speter			 IDENTIFIER_POINTER (name));
247618334Speter	    }
247718334Speter	}
247818334Speter      else
247918334Speter	{
248018334Speter	  /* Here to install a non-global value.  */
248118334Speter	  tree oldlocal = IDENTIFIER_LOCAL_VALUE (name);
248218334Speter	  tree oldglobal = IDENTIFIER_GLOBAL_VALUE (name);
248390075Sobrien
248418334Speter	  IDENTIFIER_LOCAL_VALUE (name) = x;
248518334Speter
248618334Speter	  /* If this is an extern function declaration, see if we
248718334Speter	     have a global definition or declaration for the function.  */
248818334Speter	  if (oldlocal == 0
248918334Speter	      && oldglobal != 0
249018334Speter	      && TREE_CODE (x) == FUNCTION_DECL
249190075Sobrien	      && TREE_CODE (oldglobal) == FUNCTION_DECL
249290075Sobrien	      && DECL_EXTERNAL (x)
249390075Sobrien	      && ! DECL_DECLARED_INLINE_P (x))
249418334Speter	    {
249518334Speter	      /* We have one.  Their types must agree.  */
249618334Speter	      if (! comptypes (TREE_TYPE (x),
249718334Speter			       TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (name))))
249818334Speter		pedwarn_with_decl (x, "extern declaration of `%s' doesn't match global one");
249918334Speter	      else
250018334Speter		{
250118334Speter		  /* Inner extern decl is inline if global one is.
250218334Speter		     Copy enough to really inline it.  */
250390075Sobrien		  if (DECL_DECLARED_INLINE_P (oldglobal))
250418334Speter		    {
250590075Sobrien		      DECL_DECLARED_INLINE_P (x)
250690075Sobrien		        = DECL_DECLARED_INLINE_P (oldglobal);
250718334Speter		      DECL_INLINE (x) = DECL_INLINE (oldglobal);
250818334Speter		      DECL_INITIAL (x) = (current_function_decl == oldglobal
250918334Speter					  ? 0 : DECL_INITIAL (oldglobal));
251018334Speter		      DECL_SAVED_INSNS (x) = DECL_SAVED_INSNS (oldglobal);
251190075Sobrien		      DECL_NUM_STMTS (x) = DECL_NUM_STMTS (oldglobal);
251218334Speter		      DECL_ARGUMENTS (x) = DECL_ARGUMENTS (oldglobal);
251318334Speter		      DECL_RESULT (x) = DECL_RESULT (oldglobal);
251418334Speter		      TREE_ASM_WRITTEN (x) = TREE_ASM_WRITTEN (oldglobal);
251590075Sobrien		      DECL_ABSTRACT_ORIGIN (x)
251690075Sobrien			= DECL_ABSTRACT_ORIGIN (oldglobal);
251718334Speter		    }
251818334Speter		  /* Inner extern decl is built-in if global one is.  */
251918334Speter		  if (DECL_BUILT_IN (oldglobal))
252018334Speter		    {
252190075Sobrien		      DECL_BUILT_IN_CLASS (x) = DECL_BUILT_IN_CLASS (oldglobal);
252218334Speter		      DECL_FUNCTION_CODE (x) = DECL_FUNCTION_CODE (oldglobal);
252318334Speter		    }
252418334Speter		  /* Keep the arg types from a file-scope fcn defn.  */
252518334Speter		  if (TYPE_ARG_TYPES (TREE_TYPE (oldglobal)) != 0
252618334Speter		      && DECL_INITIAL (oldglobal)
252718334Speter		      && TYPE_ARG_TYPES (TREE_TYPE (x)) == 0)
252818334Speter		    TREE_TYPE (x) = TREE_TYPE (oldglobal);
252918334Speter		}
253018334Speter	    }
253118334Speter
253290075Sobrien#if 0
253390075Sobrien	  /* This case is probably sometimes the right thing to do.  */
253418334Speter	  /* If we have a local external declaration,
253518334Speter	     then any file-scope declaration should not
253618334Speter	     have been static.  */
253718334Speter	  if (oldlocal == 0 && oldglobal != 0
253818334Speter	      && !TREE_PUBLIC (oldglobal)
253918334Speter	      && DECL_EXTERNAL (x) && TREE_PUBLIC (x))
254018334Speter	    warning ("`%s' locally external but globally static",
254118334Speter		     IDENTIFIER_POINTER (name));
254218334Speter#endif
254318334Speter
254418334Speter	  /* If we have a local external declaration,
254518334Speter	     and no file-scope declaration has yet been seen,
254618334Speter	     then if we later have a file-scope decl it must not be static.  */
254718334Speter	  if (oldlocal == 0
254818334Speter	      && DECL_EXTERNAL (x)
254918334Speter	      && TREE_PUBLIC (x))
255018334Speter	    {
255150397Sobrien	      if (oldglobal == 0)
255290075Sobrien		TREE_PUBLIC (name) = 1;
255318334Speter
255418334Speter	      /* Save this decl, so that we can do type checking against
255518334Speter		 other decls after it falls out of scope.
255618334Speter
255718334Speter		 Only save it once.  This prevents temporary decls created in
255818334Speter		 expand_inline_function from being used here, since this
255918334Speter		 will have been set when the inline function was parsed.
256018334Speter		 It also helps give slightly better warnings.  */
256118334Speter	      if (IDENTIFIER_LIMBO_VALUE (name) == 0)
256218334Speter		IDENTIFIER_LIMBO_VALUE (name) = x;
256318334Speter	    }
256418334Speter
256590075Sobrien	  warn_if_shadowing (x, oldlocal);
256618334Speter
256718334Speter	  /* If storing a local value, there may already be one (inherited).
256818334Speter	     If so, record it for restoration when this binding level ends.  */
256918334Speter	  if (oldlocal != 0)
257018334Speter	    b->shadowed = tree_cons (name, oldlocal, b->shadowed);
257118334Speter	}
257218334Speter
257390075Sobrien      /* Keep count of variables in this level with incomplete type.
257490075Sobrien	 If the input is erroneous, we can have error_mark in the type
257590075Sobrien	 slot (e.g. "f(void a, ...)") - that doesn't count as an
257690075Sobrien	 incomplete type.  */
257790075Sobrien      if (TREE_TYPE (x) != error_mark_node
257890075Sobrien	  && !COMPLETE_TYPE_P (TREE_TYPE (x)))
257990075Sobrien	{
258090075Sobrien	  tree element = TREE_TYPE (x);
258190075Sobrien
258290075Sobrien	  while (TREE_CODE (element) == ARRAY_TYPE)
258390075Sobrien	    element = TREE_TYPE (element);
258490075Sobrien	  if (TREE_CODE (element) == RECORD_TYPE
258590075Sobrien	      || TREE_CODE (element) == UNION_TYPE)
258690075Sobrien	    ++b->n_incomplete;
258790075Sobrien	}
258818334Speter    }
258918334Speter
259018334Speter  /* Put decls on list in reverse order.
259118334Speter     We will reverse them later if necessary.  */
259218334Speter  TREE_CHAIN (x) = b->names;
259318334Speter  b->names = x;
259418334Speter
259518334Speter  return x;
259618334Speter}
259718334Speter
259818334Speter/* Like pushdecl, only it places X in GLOBAL_BINDING_LEVEL, if appropriate.  */
259918334Speter
260018334Spetertree
260118334Speterpushdecl_top_level (x)
260218334Speter     tree x;
260318334Speter{
260490075Sobrien  tree t;
260590075Sobrien  struct binding_level *b = current_binding_level;
260618334Speter
260718334Speter  current_binding_level = global_binding_level;
260818334Speter  t = pushdecl (x);
260918334Speter  current_binding_level = b;
261018334Speter  return t;
261118334Speter}
261218334Speter
261318334Speter/* Generate an implicit declaration for identifier FUNCTIONID
261418334Speter   as a function of type int ().  Print a warning if appropriate.  */
261518334Speter
261618334Spetertree
261718334Speterimplicitly_declare (functionid)
261818334Speter     tree functionid;
261918334Speter{
262090075Sobrien  tree decl;
262118334Speter  int traditional_warning = 0;
262218334Speter  /* Only one "implicit declaration" warning per identifier.  */
262318334Speter  int implicit_warning;
262418334Speter
262518334Speter  /* We used to reuse an old implicit decl here,
262618334Speter     but this loses with inline functions because it can clobber
262718334Speter     the saved decl chains.  */
262890075Sobrien#if 0
262990075Sobrien  if (IDENTIFIER_IMPLICIT_DECL (functionid) != 0)
263018334Speter    decl = IDENTIFIER_IMPLICIT_DECL (functionid);
263190075Sobrien  else
263290075Sobrien#endif
263318334Speter    decl = build_decl (FUNCTION_DECL, functionid, default_function_type);
263418334Speter
263518334Speter  /* Warn of implicit decl following explicit local extern decl.
263618334Speter     This is probably a program designed for traditional C.  */
263718334Speter  if (TREE_PUBLIC (functionid) && IDENTIFIER_GLOBAL_VALUE (functionid) == 0)
263818334Speter    traditional_warning = 1;
263918334Speter
264018334Speter  /* Warn once of an implicit declaration.  */
264118334Speter  implicit_warning = (IDENTIFIER_IMPLICIT_DECL (functionid) == 0);
264218334Speter
264318334Speter  DECL_EXTERNAL (decl) = 1;
264418334Speter  TREE_PUBLIC (decl) = 1;
264518334Speter
264618334Speter  /* Record that we have an implicit decl and this is it.  */
264718334Speter  IDENTIFIER_IMPLICIT_DECL (functionid) = decl;
264818334Speter
264918334Speter  /* ANSI standard says implicit declarations are in the innermost block.
265018334Speter     So we record the decl in the standard fashion.
265118334Speter     If flag_traditional is set, pushdecl does it top-level.  */
265218334Speter  pushdecl (decl);
265318334Speter
265418334Speter  /* This is a no-op in c-lang.c or something real in objc-actions.c.  */
265518334Speter  maybe_objc_check_decl (decl);
265618334Speter
265790075Sobrien  rest_of_decl_compilation (decl, NULL, 0, 0);
265818334Speter
265990075Sobrien  if (implicit_warning)
266090075Sobrien    implicit_decl_warning (functionid);
266118334Speter  else if (warn_traditional && traditional_warning)
266218334Speter    warning ("function `%s' was previously declared within a block",
266318334Speter	     IDENTIFIER_POINTER (functionid));
266418334Speter
266518334Speter  /* Write a record describing this implicit function declaration to the
266618334Speter     prototypes file (if requested).  */
266718334Speter
266818334Speter  gen_aux_info_record (decl, 0, 1, 0);
266918334Speter
267090075Sobrien  /* Possibly apply some default attributes to this implicit declaration.  */
267190075Sobrien  decl_attributes (&decl, NULL_TREE, 0);
267218334Speter
267318334Speter  return decl;
267418334Speter}
267518334Speter
267690075Sobrienvoid
267790075Sobrienimplicit_decl_warning (id)
267890075Sobrien     tree id;
267990075Sobrien{
268090075Sobrien  const char *name = IDENTIFIER_POINTER (id);
268190075Sobrien  if (mesg_implicit_function_declaration == 2)
268290075Sobrien    error ("implicit declaration of function `%s'", name);
268390075Sobrien  else if (mesg_implicit_function_declaration == 1)
268490075Sobrien    warning ("implicit declaration of function `%s'", name);
268590075Sobrien}
268690075Sobrien
268718334Speter/* Return zero if the declaration NEWDECL is valid
268818334Speter   when the declaration OLDDECL (assumed to be for the same name)
268918334Speter   has already been seen.
269052284Sobrien   Otherwise return 1 if NEWDECL is a redefinition, 2 if it is a redeclaration,
269152284Sobrien   and 3 if it is a conflicting declaration.  */
269218334Speter
269352284Sobrienstatic int
269418334Speterredeclaration_error_message (newdecl, olddecl)
269518334Speter     tree newdecl, olddecl;
269618334Speter{
269718334Speter  if (TREE_CODE (newdecl) == TYPE_DECL)
269818334Speter    {
269918334Speter      if (flag_traditional && TREE_TYPE (newdecl) == TREE_TYPE (olddecl))
270018334Speter	return 0;
270118334Speter      /* pushdecl creates distinct types for TYPE_DECLs by calling
270218334Speter	 build_type_copy, so the above comparison generally fails.  We do
270318334Speter	 another test against the TYPE_MAIN_VARIANT of the olddecl, which
270418334Speter	 is equivalent to what this code used to do before the build_type_copy
270518334Speter	 call.  The variant type distinction should not matter for traditional
270618334Speter	 code, because it doesn't have type qualifiers.  */
270790075Sobrien      if (flag_traditional
270818334Speter	  && TYPE_MAIN_VARIANT (TREE_TYPE (olddecl)) == TREE_TYPE (newdecl))
270918334Speter	return 0;
271018334Speter      if (DECL_IN_SYSTEM_HEADER (olddecl) || DECL_IN_SYSTEM_HEADER (newdecl))
271118334Speter	return 0;
271252284Sobrien      return 1;
271318334Speter    }
271418334Speter  else if (TREE_CODE (newdecl) == FUNCTION_DECL)
271518334Speter    {
271618334Speter      /* Declarations of functions can insist on internal linkage
271718334Speter	 but they can't be inconsistent with internal linkage,
271818334Speter	 so there can be no error on that account.
271918334Speter	 However defining the same name twice is no good.  */
272018334Speter      if (DECL_INITIAL (olddecl) != 0 && DECL_INITIAL (newdecl) != 0
272118334Speter	  /* However, defining once as extern inline and a second
272218334Speter	     time in another way is ok.  */
272390075Sobrien	  && ! (DECL_DECLARED_INLINE_P (olddecl) && DECL_EXTERNAL (olddecl)
272490075Sobrien	       && ! (DECL_DECLARED_INLINE_P (newdecl)
272590075Sobrien		     && DECL_EXTERNAL (newdecl))))
272652284Sobrien	return 1;
272718334Speter      return 0;
272818334Speter    }
272990075Sobrien  else if (DECL_CONTEXT (newdecl) == NULL_TREE)
273018334Speter    {
273118334Speter      /* Objects declared at top level:  */
273218334Speter      /* If at least one is a reference, it's ok.  */
273318334Speter      if (DECL_EXTERNAL (newdecl) || DECL_EXTERNAL (olddecl))
273418334Speter	return 0;
273518334Speter      /* Reject two definitions.  */
273618334Speter      if (DECL_INITIAL (olddecl) != 0 && DECL_INITIAL (newdecl) != 0)
273752284Sobrien	return 1;
273818334Speter      /* Now we have two tentative defs, or one tentative and one real def.  */
273918334Speter      /* Insist that the linkage match.  */
274018334Speter      if (TREE_PUBLIC (olddecl) != TREE_PUBLIC (newdecl))
274152284Sobrien	return 3;
274218334Speter      return 0;
274318334Speter    }
274418334Speter  else if (current_binding_level->parm_flag
274518334Speter	   && TREE_ASM_WRITTEN (olddecl) && !TREE_ASM_WRITTEN (newdecl))
274618334Speter    return 0;
274718334Speter  else
274818334Speter    {
274918334Speter      /* Newdecl has block scope.  If olddecl has block scope also, then
275018334Speter	 reject two definitions, and reject a definition together with an
275118334Speter	 external reference.  Otherwise, it is OK, because newdecl must
275218334Speter	 be an extern reference to olddecl.  */
275318334Speter      if (!(DECL_EXTERNAL (newdecl) && DECL_EXTERNAL (olddecl))
275418334Speter	  && DECL_CONTEXT (newdecl) == DECL_CONTEXT (olddecl))
275552284Sobrien	return 2;
275618334Speter      return 0;
275718334Speter    }
275818334Speter}
275918334Speter
276018334Speter/* Get the LABEL_DECL corresponding to identifier ID as a label.
276118334Speter   Create one if none exists so far for the current function.
276218334Speter   This function is called for both label definitions and label references.  */
276318334Speter
276418334Spetertree
276518334Speterlookup_label (id)
276618334Speter     tree id;
276718334Speter{
276890075Sobrien  tree decl = IDENTIFIER_LABEL_VALUE (id);
276918334Speter
277018334Speter  if (current_function_decl == 0)
277118334Speter    {
277218334Speter      error ("label %s referenced outside of any function",
277318334Speter	     IDENTIFIER_POINTER (id));
277418334Speter      return 0;
277518334Speter    }
277618334Speter
277718334Speter  /* Use a label already defined or ref'd with this name.  */
277818334Speter  if (decl != 0)
277918334Speter    {
278018334Speter      /* But not if it is inherited and wasn't declared to be inheritable.  */
278118334Speter      if (DECL_CONTEXT (decl) != current_function_decl
278218334Speter	  && ! C_DECLARED_LABEL_FLAG (decl))
278318334Speter	return shadow_label (id);
278418334Speter      return decl;
278518334Speter    }
278618334Speter
278718334Speter  decl = build_decl (LABEL_DECL, id, void_type_node);
278818334Speter
278918334Speter  /* A label not explicitly declared must be local to where it's ref'd.  */
279018334Speter  DECL_CONTEXT (decl) = current_function_decl;
279118334Speter
279218334Speter  DECL_MODE (decl) = VOIDmode;
279318334Speter
279418334Speter  /* Say where one reference is to the label,
279518334Speter     for the sake of the error if it is not defined.  */
279618334Speter  DECL_SOURCE_LINE (decl) = lineno;
279718334Speter  DECL_SOURCE_FILE (decl) = input_filename;
279818334Speter
279918334Speter  IDENTIFIER_LABEL_VALUE (id) = decl;
280018334Speter
280118334Speter  named_labels = tree_cons (NULL_TREE, decl, named_labels);
280218334Speter
280318334Speter  return decl;
280418334Speter}
280518334Speter
280618334Speter/* Make a label named NAME in the current function,
280718334Speter   shadowing silently any that may be inherited from containing functions
280818334Speter   or containing scopes.
280918334Speter
281018334Speter   Note that valid use, if the label being shadowed
281118334Speter   comes from another scope in the same function,
281218334Speter   requires calling declare_nonlocal_label right away.  */
281318334Speter
281418334Spetertree
281518334Spetershadow_label (name)
281618334Speter     tree name;
281718334Speter{
281890075Sobrien  tree decl = IDENTIFIER_LABEL_VALUE (name);
281918334Speter
282018334Speter  if (decl != 0)
282118334Speter    {
282290075Sobrien      tree dup;
282318334Speter
282418334Speter      /* Check to make sure that the label hasn't already been declared
282518334Speter	 at this label scope */
282618334Speter      for (dup = named_labels; dup; dup = TREE_CHAIN (dup))
282718334Speter	if (TREE_VALUE (dup) == decl)
282818334Speter	  {
282990075Sobrien	    error ("duplicate label declaration `%s'",
283018334Speter		   IDENTIFIER_POINTER (name));
283118334Speter	    error_with_decl (TREE_VALUE (dup),
283218334Speter			     "this is a previous declaration");
283318334Speter	    /* Just use the previous declaration.  */
283418334Speter	    return lookup_label (name);
283518334Speter	  }
283618334Speter
283718334Speter      shadowed_labels = tree_cons (NULL_TREE, decl, shadowed_labels);
283818334Speter      IDENTIFIER_LABEL_VALUE (name) = decl = 0;
283918334Speter    }
284018334Speter
284118334Speter  return lookup_label (name);
284218334Speter}
284318334Speter
284418334Speter/* Define a label, specifying the location in the source file.
284518334Speter   Return the LABEL_DECL node for the label, if the definition is valid.
284618334Speter   Otherwise return 0.  */
284718334Speter
284818334Spetertree
284918334Speterdefine_label (filename, line, name)
285090075Sobrien     const char *filename;
285118334Speter     int line;
285218334Speter     tree name;
285318334Speter{
285418334Speter  tree decl = lookup_label (name);
285518334Speter
285618334Speter  /* If label with this name is known from an outer context, shadow it.  */
285718334Speter  if (decl != 0 && DECL_CONTEXT (decl) != current_function_decl)
285818334Speter    {
285918334Speter      shadowed_labels = tree_cons (NULL_TREE, decl, shadowed_labels);
286018334Speter      IDENTIFIER_LABEL_VALUE (name) = 0;
286118334Speter      decl = lookup_label (name);
286218334Speter    }
286318334Speter
286490075Sobrien  if (warn_traditional && !in_system_header && lookup_name (name))
286590075Sobrien    warning_with_file_and_line (filename, line,
286690075Sobrien				"traditional C lacks a separate namespace for labels, identifier `%s' conflicts",
286790075Sobrien				IDENTIFIER_POINTER (name));
286890075Sobrien
286918334Speter  if (DECL_INITIAL (decl) != 0)
287018334Speter    {
287190075Sobrien      error_with_file_and_line (filename, line, "duplicate label `%s'",
287290075Sobrien				IDENTIFIER_POINTER (name));
287318334Speter      return 0;
287418334Speter    }
287518334Speter  else
287618334Speter    {
287718334Speter      /* Mark label as having been defined.  */
287818334Speter      DECL_INITIAL (decl) = error_mark_node;
287918334Speter      /* Say where in the source.  */
288018334Speter      DECL_SOURCE_FILE (decl) = filename;
288118334Speter      DECL_SOURCE_LINE (decl) = line;
288218334Speter      return decl;
288318334Speter    }
288418334Speter}
288518334Speter
288618334Speter/* Return the list of declarations of the current level.
288718334Speter   Note that this list is in reverse order unless/until
288818334Speter   you nreverse it; and when you do nreverse it, you must
288918334Speter   store the result back using `storedecls' or you will lose.  */
289018334Speter
289118334Spetertree
289218334Spetergetdecls ()
289318334Speter{
289418334Speter  return current_binding_level->names;
289518334Speter}
289618334Speter
289718334Speter/* Return the list of type-tags (for structs, etc) of the current level.  */
289818334Speter
289918334Spetertree
290018334Spetergettags ()
290118334Speter{
290218334Speter  return current_binding_level->tags;
290318334Speter}
290418334Speter
290518334Speter/* Store the list of declarations of the current level.
290618334Speter   This is done for the parameter declarations of a function being defined,
290718334Speter   after they are modified in the light of any missing parameters.  */
290818334Speter
290918334Speterstatic void
291018334Speterstoredecls (decls)
291118334Speter     tree decls;
291218334Speter{
291318334Speter  current_binding_level->names = decls;
291418334Speter}
291518334Speter
291618334Speter/* Similarly, store the list of tags of the current level.  */
291718334Speter
291818334Speterstatic void
291918334Speterstoretags (tags)
292018334Speter     tree tags;
292118334Speter{
292218334Speter  current_binding_level->tags = tags;
292318334Speter}
292418334Speter
292518334Speter/* Given NAME, an IDENTIFIER_NODE,
292618334Speter   return the structure (or union or enum) definition for that name.
292718334Speter   Searches binding levels from BINDING_LEVEL up to the global level.
292818334Speter   If THISLEVEL_ONLY is nonzero, searches only the specified context
292918334Speter   (but skips any tag-transparent contexts to find one that is
293018334Speter   meaningful for tags).
293118334Speter   CODE says which kind of type the caller wants;
293218334Speter   it is RECORD_TYPE or UNION_TYPE or ENUMERAL_TYPE.
293318334Speter   If the wrong kind of type is found, an error is reported.  */
293418334Speter
293518334Speterstatic tree
293618334Speterlookup_tag (code, name, binding_level, thislevel_only)
293718334Speter     enum tree_code code;
293818334Speter     struct binding_level *binding_level;
293918334Speter     tree name;
294018334Speter     int thislevel_only;
294118334Speter{
294290075Sobrien  struct binding_level *level;
294390075Sobrien  int thislevel = 1;
294418334Speter
294518334Speter  for (level = binding_level; level; level = level->level_chain)
294618334Speter    {
294790075Sobrien      tree tail;
294818334Speter      for (tail = level->tags; tail; tail = TREE_CHAIN (tail))
294918334Speter	{
295018334Speter	  if (TREE_PURPOSE (tail) == name)
295118334Speter	    {
295218334Speter	      if (TREE_CODE (TREE_VALUE (tail)) != code)
295318334Speter		{
295418334Speter		  /* Definition isn't the kind we were looking for.  */
295518334Speter		  pending_invalid_xref = name;
295618334Speter		  pending_invalid_xref_file = input_filename;
295718334Speter		  pending_invalid_xref_line = lineno;
295890075Sobrien		  /* If in the same binding level as a declaration as a tag
295990075Sobrien		     of a different type, this must not be allowed to
296090075Sobrien		     shadow that tag, so give the error immediately.
296190075Sobrien		     (For example, "struct foo; union foo;" is invalid.)  */
296290075Sobrien		  if (thislevel)
296390075Sobrien		    pending_xref_error ();
296418334Speter		}
296518334Speter	      return TREE_VALUE (tail);
296618334Speter	    }
296718334Speter	}
296890075Sobrien      if (! level->tag_transparent)
296990075Sobrien	{
297090075Sobrien	  if (thislevel_only)
297190075Sobrien	    return NULL_TREE;
297290075Sobrien	  thislevel = 0;
297390075Sobrien	}
297418334Speter    }
297518334Speter  return NULL_TREE;
297618334Speter}
297718334Speter
297818334Speter/* Print an error message now
297918334Speter   for a recent invalid struct, union or enum cross reference.
298018334Speter   We don't print them immediately because they are not invalid
298118334Speter   when used in the `struct foo;' construct for shadowing.  */
298218334Speter
298318334Spetervoid
298418334Speterpending_xref_error ()
298518334Speter{
298618334Speter  if (pending_invalid_xref != 0)
298718334Speter    error_with_file_and_line (pending_invalid_xref_file,
298818334Speter			      pending_invalid_xref_line,
298918334Speter			      "`%s' defined as wrong kind of tag",
299018334Speter			      IDENTIFIER_POINTER (pending_invalid_xref));
299118334Speter  pending_invalid_xref = 0;
299218334Speter}
299318334Speter
299418334Speter/* Given a type, find the tag that was defined for it and return the tag name.
299518334Speter   Otherwise return 0.  */
299618334Speter
299718334Speterstatic tree
299818334Speterlookup_tag_reverse (type)
299918334Speter     tree type;
300018334Speter{
300190075Sobrien  struct binding_level *level;
300218334Speter
300318334Speter  for (level = current_binding_level; level; level = level->level_chain)
300418334Speter    {
300590075Sobrien      tree tail;
300618334Speter      for (tail = level->tags; tail; tail = TREE_CHAIN (tail))
300718334Speter	{
300818334Speter	  if (TREE_VALUE (tail) == type)
300918334Speter	    return TREE_PURPOSE (tail);
301018334Speter	}
301118334Speter    }
301218334Speter  return NULL_TREE;
301318334Speter}
301418334Speter
301518334Speter/* Look up NAME in the current binding level and its superiors
301618334Speter   in the namespace of variables, functions and typedefs.
301718334Speter   Return a ..._DECL node of some kind representing its definition,
301818334Speter   or return 0 if it is undefined.  */
301918334Speter
302018334Spetertree
302118334Speterlookup_name (name)
302218334Speter     tree name;
302318334Speter{
302490075Sobrien  tree val;
302590075Sobrien
302618334Speter  if (current_binding_level != global_binding_level
302718334Speter      && IDENTIFIER_LOCAL_VALUE (name))
302818334Speter    val = IDENTIFIER_LOCAL_VALUE (name);
302918334Speter  else
303018334Speter    val = IDENTIFIER_GLOBAL_VALUE (name);
303118334Speter  return val;
303218334Speter}
303318334Speter
303418334Speter/* Similar to `lookup_name' but look only at current binding level.  */
303518334Speter
303618334Spetertree
303718334Speterlookup_name_current_level (name)
303818334Speter     tree name;
303918334Speter{
304090075Sobrien  tree t;
304118334Speter
304218334Speter  if (current_binding_level == global_binding_level)
304318334Speter    return IDENTIFIER_GLOBAL_VALUE (name);
304418334Speter
304518334Speter  if (IDENTIFIER_LOCAL_VALUE (name) == 0)
304618334Speter    return 0;
304718334Speter
304818334Speter  for (t = current_binding_level->names; t; t = TREE_CHAIN (t))
304918334Speter    if (DECL_NAME (t) == name)
305018334Speter      break;
305118334Speter
305218334Speter  return t;
305318334Speter}
305418334Speter
305590075Sobrien/* Mark ARG for GC.  */
305690075Sobrien
305790075Sobrienstatic void
305890075Sobrienmark_binding_level (arg)
305990075Sobrien     void *arg;
306090075Sobrien{
306190075Sobrien  struct binding_level *level = *(struct binding_level **) arg;
306290075Sobrien
306390075Sobrien  for (; level != 0; level = level->level_chain)
306490075Sobrien    {
306590075Sobrien      ggc_mark_tree (level->names);
306690075Sobrien      ggc_mark_tree (level->tags);
306790075Sobrien      ggc_mark_tree (level->shadowed);
306890075Sobrien      ggc_mark_tree (level->blocks);
306990075Sobrien      ggc_mark_tree (level->this_block);
307090075Sobrien      ggc_mark_tree (level->parm_order);
307190075Sobrien    }
307290075Sobrien}
307390075Sobrien
307418334Speter/* Create the predefined scalar types of C,
307550397Sobrien   and some nodes representing standard constants (0, 1, (void *) 0).
307618334Speter   Initialize the global binding level.
307718334Speter   Make definitions for built-in primitive functions.  */
307818334Speter
307918334Spetervoid
308090075Sobrienc_init_decl_processing ()
308118334Speter{
308290075Sobrien  tree endlink;
308390075Sobrien  tree ptr_ftype_void, ptr_ftype_ptr;
308418334Speter
308590075Sobrien  /* Adds some ggc roots, and reserved words for c-parse.in.  */
308690075Sobrien  c_parse_init ();
308790075Sobrien
308818334Speter  current_function_decl = NULL;
308918334Speter  named_labels = NULL;
309018334Speter  current_binding_level = NULL_BINDING_LEVEL;
309118334Speter  free_binding_level = NULL_BINDING_LEVEL;
309290075Sobrien
309390075Sobrien  /* Make the binding_level structure for global names.  */
309490075Sobrien  pushlevel (0);
309518334Speter  global_binding_level = current_binding_level;
309618334Speter
309790075Sobrien  build_common_tree_nodes (flag_signed_char);
309818334Speter
309990075Sobrien  c_common_nodes_and_builtins ();
310018334Speter
310118334Speter  boolean_type_node = integer_type_node;
310218334Speter  boolean_true_node = integer_one_node;
310318334Speter  boolean_false_node = integer_zero_node;
310418334Speter
310596263Sobrien  c_bool_type_node = make_unsigned_type (BOOL_TYPE_SIZE);
310690075Sobrien  TREE_SET_CODE (c_bool_type_node, BOOLEAN_TYPE);
310790075Sobrien  TYPE_MAX_VALUE (c_bool_type_node) = build_int_2 (1, 0);
310890075Sobrien  TREE_TYPE (TYPE_MAX_VALUE (c_bool_type_node)) = c_bool_type_node;
310990075Sobrien  TYPE_PRECISION (c_bool_type_node) = 1;
311090075Sobrien  pushdecl (build_decl (TYPE_DECL, get_identifier ("_Bool"),
311190075Sobrien			c_bool_type_node));
311290075Sobrien  c_bool_false_node = build_int_2 (0, 0);
311390075Sobrien  TREE_TYPE (c_bool_false_node) = c_bool_type_node;
311490075Sobrien  c_bool_true_node = build_int_2 (1, 0);
311590075Sobrien  TREE_TYPE (c_bool_true_node) = c_bool_type_node;
311618334Speter
311790075Sobrien  endlink = void_list_node;
311850397Sobrien  ptr_ftype_void = build_function_type (ptr_type_node, endlink);
311950397Sobrien  ptr_ftype_ptr
312050397Sobrien    = build_function_type (ptr_type_node,
312150397Sobrien			   tree_cons (NULL_TREE, ptr_type_node, endlink));
312250397Sobrien
312390075Sobrien  /* Types which are common to the fortran compiler and libf2c.  When
312490075Sobrien     changing these, you also need to be concerned with f/com.h.  */
312518334Speter
312690075Sobrien  if (TYPE_PRECISION (float_type_node)
312790075Sobrien      == TYPE_PRECISION (long_integer_type_node))
312890075Sobrien    {
312990075Sobrien      g77_integer_type_node = long_integer_type_node;
313090075Sobrien      g77_uinteger_type_node = long_unsigned_type_node;
313190075Sobrien    }
313290075Sobrien  else if (TYPE_PRECISION (float_type_node)
313390075Sobrien	   == TYPE_PRECISION (integer_type_node))
313490075Sobrien    {
313590075Sobrien      g77_integer_type_node = integer_type_node;
313690075Sobrien      g77_uinteger_type_node = unsigned_type_node;
313790075Sobrien    }
313890075Sobrien  else
313990075Sobrien    g77_integer_type_node = g77_uinteger_type_node = NULL_TREE;
314018334Speter
314190075Sobrien  if (g77_integer_type_node != NULL_TREE)
314290075Sobrien    {
314390075Sobrien      pushdecl (build_decl (TYPE_DECL, get_identifier ("__g77_integer"),
314490075Sobrien			    g77_integer_type_node));
314590075Sobrien      pushdecl (build_decl (TYPE_DECL, get_identifier ("__g77_uinteger"),
314690075Sobrien			    g77_uinteger_type_node));
314790075Sobrien    }
314818334Speter
314990075Sobrien  if (TYPE_PRECISION (float_type_node) * 2
315090075Sobrien      == TYPE_PRECISION (long_integer_type_node))
315190075Sobrien    {
315290075Sobrien      g77_longint_type_node = long_integer_type_node;
315390075Sobrien      g77_ulongint_type_node = long_unsigned_type_node;
315490075Sobrien    }
315590075Sobrien  else if (TYPE_PRECISION (float_type_node) * 2
315690075Sobrien	   == TYPE_PRECISION (long_long_integer_type_node))
315790075Sobrien    {
315890075Sobrien      g77_longint_type_node = long_long_integer_type_node;
315990075Sobrien      g77_ulongint_type_node = long_long_unsigned_type_node;
316090075Sobrien    }
316190075Sobrien  else
316290075Sobrien    g77_longint_type_node = g77_ulongint_type_node = NULL_TREE;
316350397Sobrien
316490075Sobrien  if (g77_longint_type_node != NULL_TREE)
316518334Speter    {
316690075Sobrien      pushdecl (build_decl (TYPE_DECL, get_identifier ("__g77_longint"),
316790075Sobrien			    g77_longint_type_node));
316890075Sobrien      pushdecl (build_decl (TYPE_DECL, get_identifier ("__g77_ulongint"),
316990075Sobrien			    g77_ulongint_type_node));
317018334Speter    }
317118334Speter
317290075Sobrien  pedantic_lvalues = pedantic;
317318334Speter
317490075Sobrien  make_fname_decl = c_make_fname_decl;
317590075Sobrien  start_fname_decls ();
317618334Speter
317790075Sobrien  incomplete_decl_finalize_hook = finish_incomplete_decl;
317818334Speter
317990075Sobrien  /* Record our roots.  */
318018334Speter
318190075Sobrien  ggc_add_tree_root (c_global_trees, CTI_MAX);
318290075Sobrien  ggc_add_root (&c_stmt_tree, 1, sizeof c_stmt_tree, mark_stmt_tree);
318390075Sobrien  ggc_add_tree_root (&c_scope_stmt_stack, 1);
318490075Sobrien  ggc_add_tree_root (&named_labels, 1);
318590075Sobrien  ggc_add_tree_root (&shadowed_labels, 1);
318690075Sobrien  ggc_add_root (&current_binding_level, 1, sizeof current_binding_level,
318790075Sobrien		mark_binding_level);
318890075Sobrien  ggc_add_root (&label_level_chain, 1, sizeof label_level_chain,
318990075Sobrien		mark_binding_level);
319090075Sobrien  ggc_add_tree_root (&static_ctors, 1);
319190075Sobrien  ggc_add_tree_root (&static_dtors, 1);
319290075Sobrien}
319318334Speter
319490075Sobrien/* Create the VAR_DECL for __FUNCTION__ etc. ID is the name to give the
319590075Sobrien   decl, NAME is the initialization string and TYPE_DEP indicates whether
319690075Sobrien   NAME depended on the type of the function.  As we don't yet implement
319790075Sobrien   delayed emission of static data, we mark the decl as emitted
319890075Sobrien   so it is not placed in the output.  Anything using it must therefore pull
319990075Sobrien   out the STRING_CST initializer directly.  This does mean that these names
320090075Sobrien   are string merging candidates, which is wrong for C99's __func__.  FIXME.  */
320118334Speter
320290075Sobrienstatic tree
320390075Sobrienc_make_fname_decl (id, type_dep)
320490075Sobrien     tree id;
320590075Sobrien     int type_dep;
320690075Sobrien{
320790075Sobrien  const char *name = fname_as_string (type_dep);
320890075Sobrien  tree decl, type, init;
320990075Sobrien  size_t length = strlen (name);
321018334Speter
321190075Sobrien  type =  build_array_type
321290075Sobrien          (build_qualified_type (char_type_node, TYPE_QUAL_CONST),
321390075Sobrien	   build_index_type (size_int (length)));
321418334Speter
321590075Sobrien  decl = build_decl (VAR_DECL, id, type);
321690075Sobrien  /* We don't push the decl, so have to set its context here.  */
321790075Sobrien  DECL_CONTEXT (decl) = current_function_decl;
321890075Sobrien
321990075Sobrien  TREE_STATIC (decl) = 1;
322090075Sobrien  TREE_READONLY (decl) = 1;
322190075Sobrien  DECL_ARTIFICIAL (decl) = 1;
322290075Sobrien
322390075Sobrien  init = build_string (length + 1, name);
322490075Sobrien  TREE_TYPE (init) = type;
322590075Sobrien  DECL_INITIAL (decl) = init;
322618334Speter
322790075Sobrien  TREE_USED (decl) = 1;
322890075Sobrien
322990075Sobrien  finish_decl (decl, init, NULL_TREE);
323018334Speter
323190075Sobrien  return decl;
323218334Speter}
323318334Speter
323418334Speter/* Return a definition for a builtin function named NAME and whose data type
323518334Speter   is TYPE.  TYPE should be a function type with argument types.
323618334Speter   FUNCTION_CODE tells later passes how to compile calls to this function.
323718334Speter   See tree.h for its possible values.
323818334Speter
323918334Speter   If LIBRARY_NAME is nonzero, use that for DECL_ASSEMBLER_NAME,
324018334Speter   the name to be called if we can't opencode the function.  */
324118334Speter
324218334Spetertree
324390075Sobrienbuiltin_function (name, type, function_code, class, library_name)
324452284Sobrien     const char *name;
324518334Speter     tree type;
324690075Sobrien     int function_code;
324790075Sobrien     enum built_in_class class;
324852284Sobrien     const char *library_name;
324918334Speter{
325018334Speter  tree decl = build_decl (FUNCTION_DECL, get_identifier (name), type);
325118334Speter  DECL_EXTERNAL (decl) = 1;
325218334Speter  TREE_PUBLIC (decl) = 1;
325318334Speter  /* If -traditional, permit redefining a builtin function any way you like.
325418334Speter     (Though really, if the program redefines these functions,
325518334Speter     it probably won't work right unless compiled with -fno-builtin.)  */
325618334Speter  if (flag_traditional && name[0] != '_')
325718334Speter    DECL_BUILT_IN_NONANSI (decl) = 1;
325818334Speter  if (library_name)
325990075Sobrien    SET_DECL_ASSEMBLER_NAME (decl, get_identifier (library_name));
326090075Sobrien  make_decl_rtl (decl, NULL);
326118334Speter  pushdecl (decl);
326290075Sobrien  DECL_BUILT_IN_CLASS (decl) = class;
326390075Sobrien  DECL_FUNCTION_CODE (decl) = function_code;
326490075Sobrien
326596263Sobrien  /* The return builtins leave the current function.  */
326696263Sobrien  if (function_code == BUILT_IN_RETURN || function_code == BUILT_IN_EH_RETURN)
326796263Sobrien    TREE_THIS_VOLATILE (decl) = 1;
326896263Sobrien
326918334Speter  /* Warn if a function in the namespace for users
327018334Speter     is used without an occasion to consider it declared.  */
327118334Speter  if (name[0] != '_' || name[1] != '_')
327218334Speter    C_DECL_ANTICIPATED (decl) = 1;
327318334Speter
327490075Sobrien  /* Possibly apply some default attributes to this built-in function.  */
327590075Sobrien  decl_attributes (&decl, NULL_TREE, 0);
327690075Sobrien
327718334Speter  return decl;
327818334Speter}
327990075Sobrien
328090075Sobrien/* Apply default attributes to a function, if a system function with default
328190075Sobrien   attributes.  */
328290075Sobrien
328390075Sobrienvoid
328490075Sobrieninsert_default_attributes (decl)
328590075Sobrien     tree decl;
328690075Sobrien{
328790075Sobrien  if (!TREE_PUBLIC (decl))
328890075Sobrien    return;
328990075Sobrien  c_common_insert_default_attributes (decl);
329090075Sobrien}
329118334Speter
329218334Speter/* Called when a declaration is seen that contains no names to declare.
329318334Speter   If its type is a reference to a structure, union or enum inherited
329418334Speter   from a containing scope, shadow that tag name for the current scope
329518334Speter   with a forward reference.
329618334Speter   If its type defines a new named structure or union
329718334Speter   or defines an enum, it is valid but we need not do anything here.
329818334Speter   Otherwise, it is an error.  */
329918334Speter
330018334Spetervoid
330118334Spetershadow_tag (declspecs)
330218334Speter     tree declspecs;
330318334Speter{
330418334Speter  shadow_tag_warned (declspecs, 0);
330518334Speter}
330618334Speter
330718334Spetervoid
330818334Spetershadow_tag_warned (declspecs, warned)
330918334Speter     tree declspecs;
331018334Speter     int warned;
331118334Speter     /* 1 => we have done a pedwarn.  2 => we have done a warning, but
331218334Speter	no pedwarn.  */
331318334Speter{
331418334Speter  int found_tag = 0;
331590075Sobrien  tree link;
331650397Sobrien  tree specs, attrs;
331718334Speter
331818334Speter  pending_invalid_xref = 0;
331918334Speter
332050397Sobrien  /* Remove the attributes from declspecs, since they will confuse the
332150397Sobrien     following code.  */
332250397Sobrien  split_specs_attrs (declspecs, &specs, &attrs);
332350397Sobrien
332450397Sobrien  for (link = specs; link; link = TREE_CHAIN (link))
332518334Speter    {
332690075Sobrien      tree value = TREE_VALUE (link);
332790075Sobrien      enum tree_code code = TREE_CODE (value);
332818334Speter
332918334Speter      if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
333018334Speter	/* Used to test also that TYPE_SIZE (value) != 0.
333118334Speter	   That caused warning for `struct foo;' at top level in the file.  */
333218334Speter	{
333390075Sobrien	  tree name = lookup_tag_reverse (value);
333490075Sobrien	  tree t;
333518334Speter
333618334Speter	  found_tag++;
333718334Speter
333818334Speter	  if (name == 0)
333918334Speter	    {
334018334Speter	      if (warned != 1 && code != ENUMERAL_TYPE)
334118334Speter		/* Empty unnamed enum OK */
334218334Speter		{
334318334Speter		  pedwarn ("unnamed struct/union that defines no instances");
334418334Speter		  warned = 1;
334518334Speter		}
334618334Speter	    }
334718334Speter	  else
334818334Speter	    {
334918334Speter	      t = lookup_tag (code, name, current_binding_level, 1);
335018334Speter
335118334Speter	      if (t == 0)
335218334Speter		{
335318334Speter		  t = make_node (code);
335418334Speter		  pushtag (name, t);
335518334Speter		}
335618334Speter	    }
335718334Speter	}
335818334Speter      else
335918334Speter	{
336018334Speter	  if (!warned && ! in_system_header)
336118334Speter	    {
336218334Speter	      warning ("useless keyword or type name in empty declaration");
336318334Speter	      warned = 2;
336418334Speter	    }
336518334Speter	}
336618334Speter    }
336718334Speter
336818334Speter  if (found_tag > 1)
336918334Speter    error ("two types specified in one empty declaration");
337018334Speter
337118334Speter  if (warned != 1)
337218334Speter    {
337318334Speter      if (found_tag == 0)
337418334Speter	pedwarn ("empty declaration");
337518334Speter    }
337618334Speter}
337718334Speter
337890075Sobrien/* Construct an array declarator.  EXPR is the expression inside [], or
337990075Sobrien   NULL_TREE.  QUALS are the type qualifiers inside the [] (to be applied
338090075Sobrien   to the pointer to which a parameter array is converted).  STATIC_P is
338190075Sobrien   non-zero if "static" is inside the [], zero otherwise.  VLA_UNSPEC_P
338290075Sobrien   is non-zero is the array is [*], a VLA of unspecified length which is
338390075Sobrien   nevertheless a complete type (not currently implemented by GCC),
338490075Sobrien   zero otherwise.  The declarator is constructed as an ARRAY_REF
338590075Sobrien   (to be decoded by grokdeclarator), whose operand 0 is what's on the
338690075Sobrien   left of the [] (filled by in set_array_declarator_type) and operand 1
338790075Sobrien   is the expression inside; whose TREE_TYPE is the type qualifiers and
338890075Sobrien   which has TREE_STATIC set if "static" is used.  */
338990075Sobrien
339090075Sobrientree
339190075Sobrienbuild_array_declarator (expr, quals, static_p, vla_unspec_p)
339290075Sobrien     tree expr;
339390075Sobrien     tree quals;
339490075Sobrien     int static_p;
339590075Sobrien     int vla_unspec_p;
339690075Sobrien{
339790075Sobrien  tree decl;
339890075Sobrien  decl = build_nt (ARRAY_REF, NULL_TREE, expr);
339990075Sobrien  TREE_TYPE (decl) = quals;
340090075Sobrien  TREE_STATIC (decl) = (static_p ? 1 : 0);
340190075Sobrien  if (pedantic && !flag_isoc99)
340290075Sobrien    {
340390075Sobrien      if (static_p || quals != NULL_TREE)
340490075Sobrien	pedwarn ("ISO C89 does not support `static' or type qualifiers in parameter array declarators");
340590075Sobrien      if (vla_unspec_p)
340690075Sobrien	pedwarn ("ISO C89 does not support `[*]' array declarators");
340790075Sobrien    }
340890075Sobrien  if (vla_unspec_p)
340990075Sobrien    warning ("GCC does not yet properly implement `[*]' array declarators");
341090075Sobrien  return decl;
341190075Sobrien}
341290075Sobrien
341390075Sobrien/* Set the type of an array declarator.  DECL is the declarator, as
341490075Sobrien   constructed by build_array_declarator; TYPE is what appears on the left
341590075Sobrien   of the [] and goes in operand 0.  ABSTRACT_P is non-zero if it is an
341690075Sobrien   abstract declarator, zero otherwise; this is used to reject static and
341790075Sobrien   type qualifiers in abstract declarators, where they are not in the
341890075Sobrien   C99 grammar.  */
341990075Sobrien
342090075Sobrientree
342190075Sobrienset_array_declarator_type (decl, type, abstract_p)
342290075Sobrien     tree decl;
342390075Sobrien     tree type;
342490075Sobrien     int abstract_p;
342590075Sobrien{
342690075Sobrien  TREE_OPERAND (decl, 0) = type;
342790075Sobrien  if (abstract_p && (TREE_TYPE (decl) != NULL_TREE || TREE_STATIC (decl)))
342890075Sobrien    error ("static or type qualifiers in abstract declarator");
342990075Sobrien  return decl;
343090075Sobrien}
343190075Sobrien
343218334Speter/* Decode a "typename", such as "int **", returning a ..._TYPE node.  */
343318334Speter
343418334Spetertree
343518334Spetergroktypename (typename)
343618334Speter     tree typename;
343718334Speter{
343890075Sobrien  tree specs, attrs;
343990075Sobrien
344018334Speter  if (TREE_CODE (typename) != TREE_LIST)
344118334Speter    return typename;
344290075Sobrien
344390075Sobrien  split_specs_attrs (TREE_PURPOSE (typename), &specs, &attrs);
344490075Sobrien
344596263Sobrien  typename = grokdeclarator (TREE_VALUE (typename), specs, TYPENAME, 0);
344690075Sobrien
344790075Sobrien  /* Apply attributes.  */
344890075Sobrien  decl_attributes (&typename, attrs, 0);
344990075Sobrien
345090075Sobrien  return typename;
345118334Speter}
345218334Speter
345318334Speter/* Return a PARM_DECL node for a given pair of specs and declarator.  */
345418334Speter
345518334Spetertree
345618334Spetergroktypename_in_parm_context (typename)
345718334Speter     tree typename;
345818334Speter{
345918334Speter  if (TREE_CODE (typename) != TREE_LIST)
346018334Speter    return typename;
346118334Speter  return grokdeclarator (TREE_VALUE (typename),
346218334Speter			 TREE_PURPOSE (typename),
346396263Sobrien			 PARM, 0);
346418334Speter}
346518334Speter
346618334Speter/* Decode a declarator in an ordinary declaration or data definition.
346718334Speter   This is called as soon as the type information and variable name
346818334Speter   have been parsed, before parsing the initializer if any.
346918334Speter   Here we create the ..._DECL node, fill in its type,
347018334Speter   and put it on the list of decls for the current context.
347118334Speter   The ..._DECL node is returned as the value.
347218334Speter
347318334Speter   Exception: for arrays where the length is not specified,
347418334Speter   the type is left null, to be filled in by `finish_decl'.
347518334Speter
347618334Speter   Function definitions do not come here; they go to start_function
347718334Speter   instead.  However, external and forward declarations of functions
347818334Speter   do go through here.  Structure field declarations are done by
347918334Speter   grokfield and not through here.  */
348018334Speter
348118334Spetertree
348290075Sobrienstart_decl (declarator, declspecs, initialized, attributes)
348318334Speter     tree declarator, declspecs;
348418334Speter     int initialized;
348590075Sobrien     tree attributes;
348618334Speter{
348790075Sobrien  tree decl;
348890075Sobrien  tree tem;
348990075Sobrien
349090075Sobrien  /* An object declared as __attribute__((deprecated)) suppresses
349190075Sobrien     warnings of uses of other deprecated items.  */
349290075Sobrien  if (lookup_attribute ("deprecated", attributes))
349390075Sobrien    deprecated_state = DEPRECATED_SUPPRESS;
349418334Speter
349590075Sobrien  decl = grokdeclarator (declarator, declspecs,
349696263Sobrien			 NORMAL, initialized);
349790075Sobrien
349890075Sobrien  deprecated_state = DEPRECATED_NORMAL;
349918334Speter
350090075Sobrien  if (warn_main > 0 && TREE_CODE (decl) != FUNCTION_DECL
350190075Sobrien      && MAIN_NAME_P (DECL_NAME (decl)))
350250397Sobrien    warning_with_decl (decl, "`%s' is usually a function");
350350397Sobrien
350418334Speter  if (initialized)
350518334Speter    /* Is it valid for this decl to have an initializer at all?
350618334Speter       If not, set INITIALIZED to zero, which will indirectly
350718334Speter       tell `finish_decl' to ignore the initializer once it is parsed.  */
350818334Speter    switch (TREE_CODE (decl))
350918334Speter      {
351018334Speter      case TYPE_DECL:
351118334Speter	/* typedef foo = bar  means give foo the same type as bar.
351218334Speter	   We haven't parsed bar yet, so `finish_decl' will fix that up.
351318334Speter	   Any other case of an initialization in a TYPE_DECL is an error.  */
351418334Speter	if (pedantic || list_length (declspecs) > 1)
351518334Speter	  {
351618334Speter	    error ("typedef `%s' is initialized",
351718334Speter		   IDENTIFIER_POINTER (DECL_NAME (decl)));
351818334Speter	    initialized = 0;
351918334Speter	  }
352018334Speter	break;
352118334Speter
352218334Speter      case FUNCTION_DECL:
352318334Speter	error ("function `%s' is initialized like a variable",
352418334Speter	       IDENTIFIER_POINTER (DECL_NAME (decl)));
352518334Speter	initialized = 0;
352618334Speter	break;
352718334Speter
352818334Speter      case PARM_DECL:
352918334Speter	/* DECL_INITIAL in a PARM_DECL is really DECL_ARG_TYPE.  */
353018334Speter	error ("parameter `%s' is initialized",
353118334Speter	       IDENTIFIER_POINTER (DECL_NAME (decl)));
353218334Speter	initialized = 0;
353318334Speter	break;
353418334Speter
353518334Speter      default:
353618334Speter	/* Don't allow initializations for incomplete types
353718334Speter	   except for arrays which might be completed by the initialization.  */
353890075Sobrien
353990075Sobrien	/* This can happen if the array size is an undefined macro.  We already
354090075Sobrien	   gave a warning, so we don't need another one.  */
354190075Sobrien	if (TREE_TYPE (decl) == error_mark_node)
354290075Sobrien	  initialized = 0;
354390075Sobrien	else if (COMPLETE_TYPE_P (TREE_TYPE (decl)))
354418334Speter	  {
354518334Speter	    /* A complete type is ok if size is fixed.  */
354618334Speter
354718334Speter	    if (TREE_CODE (TYPE_SIZE (TREE_TYPE (decl))) != INTEGER_CST
354818334Speter		|| C_DECL_VARIABLE_SIZE (decl))
354918334Speter	      {
355018334Speter		error ("variable-sized object may not be initialized");
355118334Speter		initialized = 0;
355218334Speter	      }
355318334Speter	  }
355418334Speter	else if (TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE)
355518334Speter	  {
355618334Speter	    error ("variable `%s' has initializer but incomplete type",
355718334Speter		   IDENTIFIER_POINTER (DECL_NAME (decl)));
355818334Speter	    initialized = 0;
355918334Speter	  }
356090075Sobrien	else if (!COMPLETE_TYPE_P (TREE_TYPE (TREE_TYPE (decl))))
356118334Speter	  {
356218334Speter	    error ("elements of array `%s' have incomplete type",
356318334Speter		   IDENTIFIER_POINTER (DECL_NAME (decl)));
356418334Speter	    initialized = 0;
356518334Speter	  }
356618334Speter      }
356718334Speter
356818334Speter  if (initialized)
356918334Speter    {
357090075Sobrien#if 0
357190075Sobrien      /* Seems redundant with grokdeclarator.  */
357218334Speter      if (current_binding_level != global_binding_level
357318334Speter	  && DECL_EXTERNAL (decl)
357418334Speter	  && TREE_CODE (decl) != FUNCTION_DECL)
357518334Speter	warning ("declaration of `%s' has `extern' and is initialized",
357618334Speter		 IDENTIFIER_POINTER (DECL_NAME (decl)));
357718334Speter#endif
357818334Speter      DECL_EXTERNAL (decl) = 0;
357918334Speter      if (current_binding_level == global_binding_level)
358018334Speter	TREE_STATIC (decl) = 1;
358118334Speter
358218334Speter      /* Tell `pushdecl' this is an initialized decl
358318334Speter	 even though we don't yet have the initializer expression.
358418334Speter	 Also tell `finish_decl' it may store the real initializer.  */
358518334Speter      DECL_INITIAL (decl) = error_mark_node;
358618334Speter    }
358718334Speter
358818334Speter  /* If this is a function declaration, write a record describing it to the
358918334Speter     prototypes file (if requested).  */
359018334Speter
359118334Speter  if (TREE_CODE (decl) == FUNCTION_DECL)
359218334Speter    gen_aux_info_record (decl, 0, 0, TYPE_ARG_TYPES (TREE_TYPE (decl)) != 0);
359318334Speter
359450397Sobrien  /* ANSI specifies that a tentative definition which is not merged with
359550397Sobrien     a non-tentative definition behaves exactly like a definition with an
359650397Sobrien     initializer equal to zero.  (Section 3.7.2)
359750397Sobrien     -fno-common gives strict ANSI behavior.  Usually you don't want it.
359850397Sobrien     This matters only for variables with external linkage.  */
359950397Sobrien  if (! flag_no_common || ! TREE_PUBLIC (decl))
360050397Sobrien    DECL_COMMON (decl) = 1;
360118334Speter
360218334Speter  /* Set attributes here so if duplicate decl, will have proper attributes.  */
360390075Sobrien  decl_attributes (&decl, attributes, 0);
360418334Speter
360596263Sobrien  /* If #pragma weak was used, mark the decl weak now.  */
360696263Sobrien  if (current_binding_level == global_binding_level)
360796263Sobrien    maybe_apply_pragma_weak (decl);
360896263Sobrien
360990075Sobrien  if (TREE_CODE (decl) == FUNCTION_DECL
361090075Sobrien      && DECL_DECLARED_INLINE_P (decl)
361190075Sobrien      && DECL_UNINLINABLE (decl)
361290075Sobrien      && lookup_attribute ("noinline", DECL_ATTRIBUTES (decl)))
361390075Sobrien    warning_with_decl (decl,
361490075Sobrien		       "inline function `%s' given attribute noinline");
361590075Sobrien
361618334Speter  /* Add this decl to the current binding level.
361718334Speter     TEM may equal DECL or it may be a previous decl of the same name.  */
361818334Speter  tem = pushdecl (decl);
361918334Speter
362018334Speter  /* For a local variable, define the RTL now.  */
362118334Speter  if (current_binding_level != global_binding_level
362218334Speter      /* But not if this is a duplicate decl
362318334Speter	 and we preserved the rtl from the previous one
362418334Speter	 (which may or may not happen).  */
362590075Sobrien      && !DECL_RTL_SET_P (tem)
362690075Sobrien      && !DECL_CONTEXT (tem))
362718334Speter    {
362890075Sobrien      if (TREE_TYPE (tem) != error_mark_node
362990075Sobrien	  && COMPLETE_TYPE_P (TREE_TYPE (tem)))
363018334Speter	expand_decl (tem);
363118334Speter      else if (TREE_CODE (TREE_TYPE (tem)) == ARRAY_TYPE
363218334Speter	       && DECL_INITIAL (tem) != 0)
363318334Speter	expand_decl (tem);
363418334Speter    }
363518334Speter
363618334Speter  return tem;
363718334Speter}
363818334Speter
363918334Speter/* Finish processing of a declaration;
364018334Speter   install its initial value.
364118334Speter   If the length of an array type is not known before,
364218334Speter   it must be determined now, from the initial value, or it is an error.  */
364318334Speter
364418334Spetervoid
364518334Speterfinish_decl (decl, init, asmspec_tree)
364618334Speter     tree decl, init;
364718334Speter     tree asmspec_tree;
364818334Speter{
364990075Sobrien  tree type = TREE_TYPE (decl);
365018334Speter  int was_incomplete = (DECL_SIZE (decl) == 0);
365190075Sobrien  const char *asmspec = 0;
365218334Speter
365390075Sobrien  /* If a name was specified, get the string.  */
365496263Sobrien  if (current_binding_level == global_binding_level)
365596263Sobrien    asmspec_tree = maybe_apply_renaming_pragma (decl, asmspec_tree);
365618334Speter  if (asmspec_tree)
365718334Speter    asmspec = TREE_STRING_POINTER (asmspec_tree);
365818334Speter
365918334Speter  /* If `start_decl' didn't like having an initialization, ignore it now.  */
366018334Speter  if (init != 0 && DECL_INITIAL (decl) == 0)
366118334Speter    init = 0;
366290075Sobrien
366318334Speter  /* Don't crash if parm is initialized.  */
366418334Speter  if (TREE_CODE (decl) == PARM_DECL)
366518334Speter    init = 0;
366618334Speter
366718334Speter  if (init)
366818334Speter    {
366918334Speter      if (TREE_CODE (decl) != TYPE_DECL)
367018334Speter	store_init_value (decl, init);
367118334Speter      else
367218334Speter	{
367318334Speter	  /* typedef foo = bar; store the type of bar as the type of foo.  */
367418334Speter	  TREE_TYPE (decl) = TREE_TYPE (init);
367518334Speter	  DECL_INITIAL (decl) = init = 0;
367618334Speter	}
367718334Speter    }
367818334Speter
367918334Speter  /* Deduce size of array from initialization, if not already known */
368018334Speter  if (TREE_CODE (type) == ARRAY_TYPE
368118334Speter      && TYPE_DOMAIN (type) == 0
368218334Speter      && TREE_CODE (decl) != TYPE_DECL)
368318334Speter    {
368418334Speter      int do_default
368518334Speter	= (TREE_STATIC (decl)
368618334Speter	   /* Even if pedantic, an external linkage array
368718334Speter	      may have incomplete type at first.  */
368818334Speter	   ? pedantic && !TREE_PUBLIC (decl)
368918334Speter	   : !DECL_EXTERNAL (decl));
369018334Speter      int failure
369118334Speter	= complete_array_type (type, DECL_INITIAL (decl), do_default);
369218334Speter
369318334Speter      /* Get the completed type made by complete_array_type.  */
369418334Speter      type = TREE_TYPE (decl);
369518334Speter
369618334Speter      if (failure == 1)
369718334Speter	error_with_decl (decl, "initializer fails to determine size of `%s'");
369818334Speter
369990075Sobrien      else if (failure == 2)
370018334Speter	{
370118334Speter	  if (do_default)
370218334Speter	    error_with_decl (decl, "array size missing in `%s'");
370318334Speter	  /* If a `static' var's size isn't known,
370418334Speter	     make it extern as well as static, so it does not get
370518334Speter	     allocated.
370618334Speter	     If it is not `static', then do not mark extern;
370718334Speter	     finish_incomplete_decl will give it a default size
370818334Speter	     and it will get allocated.  */
370918334Speter	  else if (!pedantic && TREE_STATIC (decl) && ! TREE_PUBLIC (decl))
371018334Speter	    DECL_EXTERNAL (decl) = 1;
371118334Speter	}
371218334Speter
371318334Speter      /* TYPE_MAX_VALUE is always one less than the number of elements
371418334Speter	 in the array, because we start counting at zero.  Therefore,
371518334Speter	 warn only if the value is less than zero.  */
371690075Sobrien      else if (pedantic && TYPE_DOMAIN (type) != 0
371790075Sobrien	      && tree_int_cst_sgn (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) < 0)
371818334Speter	error_with_decl (decl, "zero or negative size array `%s'");
371918334Speter
372018334Speter      layout_decl (decl, 0);
372118334Speter    }
372218334Speter
372318334Speter  if (TREE_CODE (decl) == VAR_DECL)
372418334Speter    {
372590075Sobrien      if (DECL_SIZE (decl) == 0 && TREE_TYPE (decl) != error_mark_node
372690075Sobrien	  && COMPLETE_TYPE_P (TREE_TYPE (decl)))
372718334Speter	layout_decl (decl, 0);
372818334Speter
372918334Speter      if (DECL_SIZE (decl) == 0
373090075Sobrien	  /* Don't give an error if we already gave one earlier.  */
373190075Sobrien	  && TREE_TYPE (decl) != error_mark_node
373218334Speter	  && (TREE_STATIC (decl)
373318334Speter	      ?
373418334Speter		/* A static variable with an incomplete type
373518334Speter		   is an error if it is initialized.
373618334Speter		   Also if it is not file scope.
373718334Speter		   Otherwise, let it through, but if it is not `extern'
373818334Speter		   then it may cause an error message later.  */
373950397Sobrien		(DECL_INITIAL (decl) != 0
374090075Sobrien		 || DECL_CONTEXT (decl) != 0)
374118334Speter	      :
374218334Speter		/* An automatic variable with an incomplete type
374318334Speter		   is an error.  */
374418334Speter		!DECL_EXTERNAL (decl)))
374518334Speter	{
374618334Speter	  error_with_decl (decl, "storage size of `%s' isn't known");
374718334Speter	  TREE_TYPE (decl) = error_mark_node;
374818334Speter	}
374918334Speter
375018334Speter      if ((DECL_EXTERNAL (decl) || TREE_STATIC (decl))
375118334Speter	  && DECL_SIZE (decl) != 0)
375218334Speter	{
375318334Speter	  if (TREE_CODE (DECL_SIZE (decl)) == INTEGER_CST)
375418334Speter	    constant_expression_warning (DECL_SIZE (decl));
375518334Speter	  else
375618334Speter	    error_with_decl (decl, "storage size of `%s' isn't constant");
375718334Speter	}
375850397Sobrien
375990075Sobrien      if (TREE_USED (type))
376050397Sobrien	TREE_USED (decl) = 1;
376118334Speter    }
376218334Speter
376318334Speter  /* If this is a function and an assembler name is specified, it isn't
376418334Speter     builtin any more.  Also reset DECL_RTL so we can give it its new
376518334Speter     name.  */
376618334Speter  if (TREE_CODE (decl) == FUNCTION_DECL && asmspec)
376790075Sobrien    {
376890075Sobrien      DECL_BUILT_IN_CLASS (decl) = NOT_BUILT_IN;
376990075Sobrien      SET_DECL_RTL (decl, NULL_RTX);
377090075Sobrien      SET_DECL_ASSEMBLER_NAME (decl, get_identifier (asmspec));
377190075Sobrien    }
377218334Speter
377318334Speter  /* Output the assembler code and/or RTL code for variables and functions,
377418334Speter     unless the type is an undefined structure or union.
377518334Speter     If not, it will get done when the type is completed.  */
377618334Speter
377718334Speter  if (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == FUNCTION_DECL)
377818334Speter    {
377990075Sobrien      /* This is a no-op in c-lang.c or something real in objc-actions.c.  */
378090075Sobrien      maybe_objc_check_decl (decl);
378190075Sobrien
378290075Sobrien      if (!DECL_CONTEXT (decl))
378318334Speter	{
378490075Sobrien	  if (DECL_INITIAL (decl) == NULL_TREE
378590075Sobrien	      || DECL_INITIAL (decl) == error_mark_node)
378690075Sobrien	    /* Don't output anything
378790075Sobrien	       when a tentative file-scope definition is seen.
378890075Sobrien	       But at end of compilation, do output code for them.  */
378990075Sobrien	    DECL_DEFER_OUTPUT (decl) = 1;
379050397Sobrien	  rest_of_decl_compilation (decl, asmspec,
379150397Sobrien				    (DECL_CONTEXT (decl) == 0
379290075Sobrien				     || TREE_ASM_WRITTEN (decl)), 0);
379318334Speter	}
379418334Speter      else
379518334Speter	{
379690075Sobrien	  /* This is a local variable.  If there is an ASMSPEC, the
379790075Sobrien	     user has requested that we handle it specially.  */
379890075Sobrien	  if (asmspec)
379990075Sobrien	    {
380090075Sobrien	      /* In conjunction with an ASMSPEC, the `register'
380190075Sobrien		 keyword indicates that we should place the variable
380290075Sobrien		 in a particular register.  */
380390075Sobrien	      if (DECL_REGISTER (decl))
380490075Sobrien		DECL_C_HARD_REGISTER (decl) = 1;
380590075Sobrien
380690075Sobrien	      /* If this is not a static variable, issue a warning.
380790075Sobrien		 It doesn't make any sense to give an ASMSPEC for an
380890075Sobrien		 ordinary, non-register local variable.  Historically,
380990075Sobrien		 GCC has accepted -- but ignored -- the ASMSPEC in
381090075Sobrien		 this case.  */
381190075Sobrien	      if (TREE_CODE (decl) == VAR_DECL
381290075Sobrien		  && !DECL_REGISTER (decl)
381390075Sobrien		  && !TREE_STATIC (decl))
381490075Sobrien		warning_with_decl (decl,
381590075Sobrien				   "ignoring asm-specifier for non-static local variable `%s'");
381690075Sobrien	      else
381790075Sobrien		SET_DECL_ASSEMBLER_NAME (decl, get_identifier (asmspec));
381890075Sobrien	    }
381990075Sobrien
382090075Sobrien	  if (TREE_CODE (decl) != FUNCTION_DECL)
382190075Sobrien	    add_decl_stmt (decl);
382218334Speter	}
382390075Sobrien
382418334Speter      if (DECL_CONTEXT (decl) != 0)
382518334Speter	{
382618334Speter	  /* Recompute the RTL of a local array now
382718334Speter	     if it used to be an incomplete type.  */
382818334Speter	  if (was_incomplete
382918334Speter	      && ! TREE_STATIC (decl) && ! DECL_EXTERNAL (decl))
383018334Speter	    {
383118334Speter	      /* If we used it already as memory, it must stay in memory.  */
383218334Speter	      TREE_ADDRESSABLE (decl) = TREE_USED (decl);
383318334Speter	      /* If it's still incomplete now, no init will save it.  */
383418334Speter	      if (DECL_SIZE (decl) == 0)
383518334Speter		DECL_INITIAL (decl) = 0;
383618334Speter	    }
383718334Speter	}
383818334Speter    }
383918334Speter
384018334Speter  if (TREE_CODE (decl) == TYPE_DECL)
384118334Speter    {
384218334Speter      /* This is a no-op in c-lang.c or something real in objc-actions.c.  */
384318334Speter      maybe_objc_check_decl (decl);
384490075Sobrien      rest_of_decl_compilation (decl, NULL, DECL_CONTEXT (decl) == 0, 0);
384518334Speter    }
384618334Speter
384718334Speter  /* At the end of a declaration, throw away any variable type sizes
384818334Speter     of types defined inside that declaration.  There is no use
384918334Speter     computing them in the following function definition.  */
385018334Speter  if (current_binding_level == global_binding_level)
385118334Speter    get_pending_sizes ();
385218334Speter}
385318334Speter
385418334Speter/* If DECL has a cleanup, build and return that cleanup here.
385518334Speter   This is a callback called by expand_expr.  */
385618334Speter
385718334Spetertree
385818334Spetermaybe_build_cleanup (decl)
385950397Sobrien     tree decl ATTRIBUTE_UNUSED;
386018334Speter{
386118334Speter  /* There are no cleanups in C.  */
386218334Speter  return NULL_TREE;
386318334Speter}
386418334Speter
386518334Speter/* Given a parsed parameter declaration,
386618334Speter   decode it into a PARM_DECL and push that on the current binding level.
386718334Speter   Also, for the sake of forward parm decls,
386818334Speter   record the given order of parms in `parm_order'.  */
386918334Speter
387018334Spetervoid
387118334Speterpush_parm_decl (parm)
387218334Speter     tree parm;
387318334Speter{
387418334Speter  tree decl;
387518334Speter  int old_immediate_size_expand = immediate_size_expand;
387618334Speter  /* Don't try computing parm sizes now -- wait till fn is called.  */
387718334Speter  immediate_size_expand = 0;
387818334Speter
387918334Speter  decl = grokdeclarator (TREE_VALUE (TREE_PURPOSE (parm)),
388096263Sobrien			 TREE_PURPOSE (TREE_PURPOSE (parm)), PARM, 0);
388190075Sobrien  decl_attributes (&decl, TREE_VALUE (parm), 0);
388218334Speter
388318334Speter#if 0
388418334Speter  if (DECL_NAME (decl))
388518334Speter    {
388618334Speter      tree olddecl;
388718334Speter      olddecl = lookup_name (DECL_NAME (decl));
388818334Speter      if (pedantic && olddecl != 0 && TREE_CODE (olddecl) == TYPE_DECL)
388990075Sobrien	pedwarn_with_decl (decl,
389090075Sobrien			   "ISO C forbids parameter `%s' shadowing typedef");
389118334Speter    }
389218334Speter#endif
389318334Speter
389418334Speter  decl = pushdecl (decl);
389518334Speter
389618334Speter  immediate_size_expand = old_immediate_size_expand;
389718334Speter
389818334Speter  current_binding_level->parm_order
389918334Speter    = tree_cons (NULL_TREE, decl, current_binding_level->parm_order);
390018334Speter
390118334Speter  /* Add this decl to the current binding level.  */
390218334Speter  finish_decl (decl, NULL_TREE, NULL_TREE);
390318334Speter}
390418334Speter
390518334Speter/* Clear the given order of parms in `parm_order'.
390618334Speter   Used at start of parm list,
390718334Speter   and also at semicolon terminating forward decls.  */
390818334Speter
390918334Spetervoid
391018334Speterclear_parm_order ()
391118334Speter{
391218334Speter  current_binding_level->parm_order = NULL_TREE;
391318334Speter}
391418334Speter
391590075Sobrien/* Build a COMPOUND_LITERAL_EXPR.  TYPE is the type given in the compound
391690075Sobrien   literal, which may be an incomplete array type completed by the
391790075Sobrien   initializer; INIT is a CONSTRUCTOR that initializes the compound
391890075Sobrien   literal.  */
391990075Sobrien
392090075Sobrientree
392190075Sobrienbuild_compound_literal (type, init)
392290075Sobrien     tree type;
392390075Sobrien     tree init;
392490075Sobrien{
392590075Sobrien  /* We do not use start_decl here because we have a type, not a declarator;
392690075Sobrien     and do not use finish_decl because the decl should be stored inside
392790075Sobrien     the COMPOUND_LITERAL_EXPR rather than added elsewhere as a DECL_STMT.  */
392890075Sobrien  tree decl = build_decl (VAR_DECL, NULL_TREE, type);
392990075Sobrien  tree complit;
393090075Sobrien  tree stmt;
393190075Sobrien  DECL_EXTERNAL (decl) = 0;
393290075Sobrien  TREE_PUBLIC (decl) = 0;
393390075Sobrien  TREE_STATIC (decl) = (current_binding_level == global_binding_level);
393490075Sobrien  DECL_CONTEXT (decl) = current_function_decl;
393590075Sobrien  TREE_USED (decl) = 1;
393690075Sobrien  TREE_TYPE (decl) = type;
393790075Sobrien  store_init_value (decl, init);
393890075Sobrien
393990075Sobrien  if (TREE_CODE (type) == ARRAY_TYPE && !COMPLETE_TYPE_P (type))
394090075Sobrien    {
394190075Sobrien      int failure = complete_array_type (type, DECL_INITIAL (decl), 1);
394290075Sobrien      if (failure)
394390075Sobrien	abort ();
394490075Sobrien    }
394590075Sobrien
394690075Sobrien  type = TREE_TYPE (decl);
394790075Sobrien  if (type == error_mark_node || !COMPLETE_TYPE_P (type))
394890075Sobrien    return error_mark_node;
394990075Sobrien
395090075Sobrien  stmt = build_stmt (DECL_STMT, decl);
395190075Sobrien  complit = build1 (COMPOUND_LITERAL_EXPR, TREE_TYPE (decl), stmt);
395290075Sobrien  TREE_SIDE_EFFECTS (complit) = 1;
395390075Sobrien
395490075Sobrien  layout_decl (decl, 0);
395590075Sobrien
395690075Sobrien  if (TREE_STATIC (decl))
395790075Sobrien    {
395890075Sobrien      /* This decl needs a name for the assembler output.  We also need
395990075Sobrien	 a unique suffix to be added to the name, for which DECL_CONTEXT
396090075Sobrien	 must be set.  */
396190075Sobrien      DECL_NAME (decl) = get_identifier ("__compound_literal");
396290075Sobrien      DECL_CONTEXT (decl) = complit;
396390075Sobrien      rest_of_decl_compilation (decl, NULL, 1, 0);
396490075Sobrien      DECL_CONTEXT (decl) = NULL_TREE;
396590075Sobrien    }
396690075Sobrien
396790075Sobrien  return complit;
396890075Sobrien}
396990075Sobrien
397018334Speter/* Make TYPE a complete type based on INITIAL_VALUE.
397118334Speter   Return 0 if successful, 1 if INITIAL_VALUE can't be deciphered,
397218334Speter   2 if there was no information (in which case assume 1 if DO_DEFAULT).  */
397318334Speter
397418334Speterint
397518334Spetercomplete_array_type (type, initial_value, do_default)
397618334Speter     tree type;
397718334Speter     tree initial_value;
397818334Speter     int do_default;
397918334Speter{
398090075Sobrien  tree maxindex = NULL_TREE;
398118334Speter  int value = 0;
398218334Speter
398318334Speter  if (initial_value)
398418334Speter    {
398518334Speter      /* Note MAXINDEX  is really the maximum index,
398618334Speter	 one less than the size.  */
398718334Speter      if (TREE_CODE (initial_value) == STRING_CST)
398818334Speter	{
398918334Speter	  int eltsize
399018334Speter	    = int_size_in_bytes (TREE_TYPE (TREE_TYPE (initial_value)));
399118334Speter	  maxindex = build_int_2 ((TREE_STRING_LENGTH (initial_value)
399218334Speter				   / eltsize) - 1, 0);
399318334Speter	}
399418334Speter      else if (TREE_CODE (initial_value) == CONSTRUCTOR)
399518334Speter	{
399618334Speter	  tree elts = CONSTRUCTOR_ELTS (initial_value);
399790075Sobrien	  maxindex = build_int_2 (-1, -1);
399818334Speter	  for (; elts; elts = TREE_CHAIN (elts))
399918334Speter	    {
400018334Speter	      if (TREE_PURPOSE (elts))
400118334Speter		maxindex = TREE_PURPOSE (elts);
400218334Speter	      else
400390075Sobrien		maxindex = fold (build (PLUS_EXPR, integer_type_node,
400490075Sobrien					maxindex, integer_one_node));
400518334Speter	    }
400618334Speter	  maxindex = copy_node (maxindex);
400718334Speter	}
400818334Speter      else
400918334Speter	{
401018334Speter	  /* Make an error message unless that happened already.  */
401118334Speter	  if (initial_value != error_mark_node)
401218334Speter	    value = 1;
401318334Speter
401418334Speter	  /* Prevent further error messages.  */
401518334Speter	  maxindex = build_int_2 (0, 0);
401618334Speter	}
401718334Speter    }
401818334Speter
401918334Speter  if (!maxindex)
402018334Speter    {
402118334Speter      if (do_default)
402218334Speter	maxindex = build_int_2 (0, 0);
402318334Speter      value = 2;
402418334Speter    }
402518334Speter
402618334Speter  if (maxindex)
402718334Speter    {
402818334Speter      TYPE_DOMAIN (type) = build_index_type (maxindex);
402918334Speter      if (!TREE_TYPE (maxindex))
403018334Speter	TREE_TYPE (maxindex) = TYPE_DOMAIN (type);
403118334Speter    }
403218334Speter
403318334Speter  /* Lay out the type now that we can get the real answer.  */
403418334Speter
403518334Speter  layout_type (type);
403618334Speter
403718334Speter  return value;
403818334Speter}
403918334Speter
404018334Speter/* Given declspecs and a declarator,
404118334Speter   determine the name and type of the object declared
404218334Speter   and construct a ..._DECL node for it.
404318334Speter   (In one case we can return a ..._TYPE node instead.
404418334Speter    For invalid input we sometimes return 0.)
404518334Speter
404618334Speter   DECLSPECS is a chain of tree_list nodes whose value fields
404718334Speter    are the storage classes and type specifiers.
404818334Speter
404918334Speter   DECL_CONTEXT says which syntactic context this declaration is in:
405018334Speter     NORMAL for most contexts.  Make a VAR_DECL or FUNCTION_DECL or TYPE_DECL.
405118334Speter     FUNCDEF for a function definition.  Like NORMAL but a few different
405218334Speter      error messages in each case.  Return value may be zero meaning
405318334Speter      this definition is too screwy to try to parse.
405418334Speter     PARM for a parameter declaration (either within a function prototype
405518334Speter      or before a function body).  Make a PARM_DECL, or return void_type_node.
405618334Speter     TYPENAME if for a typename (in a cast or sizeof).
405718334Speter      Don't make a DECL node; just return the ..._TYPE node.
405818334Speter     FIELD for a struct or union field; make a FIELD_DECL.
405996263Sobrien     BITFIELD for a field with specified width.
406018334Speter   INITIALIZED is 1 if the decl has an initializer.
406118334Speter
406218334Speter   In the TYPENAME case, DECLARATOR is really an absolute declarator.
406318334Speter   It may also be so in the PARM case, for a prototype where the
406418334Speter   argument type is specified but not the name.
406518334Speter
406618334Speter   This function is where the complicated C meanings of `static'
406718334Speter   and `extern' are interpreted.  */
406818334Speter
406918334Speterstatic tree
407096263Sobriengrokdeclarator (declarator, declspecs, decl_context, initialized)
407118334Speter     tree declspecs;
407218334Speter     tree declarator;
407318334Speter     enum decl_context decl_context;
407418334Speter     int initialized;
407518334Speter{
407618334Speter  int specbits = 0;
407718334Speter  tree spec;
407818334Speter  tree type = NULL_TREE;
407918334Speter  int longlong = 0;
408018334Speter  int constp;
408152284Sobrien  int restrictp;
408218334Speter  int volatilep;
408352284Sobrien  int type_quals = TYPE_UNQUALIFIED;
408418334Speter  int inlinep;
408518334Speter  int explicit_int = 0;
408618334Speter  int explicit_char = 0;
408718334Speter  int defaulted_int = 0;
408818334Speter  tree typedef_decl = 0;
408996263Sobrien  const char *name;
409018334Speter  tree typedef_type = 0;
409118334Speter  int funcdef_flag = 0;
409218334Speter  enum tree_code innermost_code = ERROR_MARK;
409396263Sobrien  int bitfield = 0;
409418334Speter  int size_varies = 0;
409590075Sobrien  tree decl_attr = NULL_TREE;
409690075Sobrien  tree array_ptr_quals = NULL_TREE;
409790075Sobrien  int array_parm_static = 0;
409890075Sobrien  tree returned_attrs = NULL_TREE;
409918334Speter
410096263Sobrien  if (decl_context == BITFIELD)
410196263Sobrien    bitfield = 1, decl_context = FIELD;
410296263Sobrien
410318334Speter  if (decl_context == FUNCDEF)
410418334Speter    funcdef_flag = 1, decl_context = NORMAL;
410518334Speter
410618334Speter  /* Look inside a declarator for the name being declared
410718334Speter     and get it as a string, for an error message.  */
410818334Speter  {
410990075Sobrien    tree decl = declarator;
411018334Speter    name = 0;
411118334Speter
411218334Speter    while (decl)
411318334Speter      switch (TREE_CODE (decl))
411418334Speter	{
411518334Speter	case ARRAY_REF:
411618334Speter	case INDIRECT_REF:
411718334Speter	case CALL_EXPR:
411818334Speter	  innermost_code = TREE_CODE (decl);
411918334Speter	  decl = TREE_OPERAND (decl, 0);
412018334Speter	  break;
412118334Speter
412290075Sobrien	case TREE_LIST:
412390075Sobrien	  decl = TREE_VALUE (decl);
412490075Sobrien	  break;
412590075Sobrien
412618334Speter	case IDENTIFIER_NODE:
412718334Speter	  name = IDENTIFIER_POINTER (decl);
412818334Speter	  decl = 0;
412918334Speter	  break;
413018334Speter
413118334Speter	default:
413218334Speter	  abort ();
413318334Speter	}
413418334Speter    if (name == 0)
413518334Speter      name = "type name";
413618334Speter  }
413718334Speter
413818334Speter  /* A function definition's declarator must have the form of
413918334Speter     a function declarator.  */
414018334Speter
414118334Speter  if (funcdef_flag && innermost_code != CALL_EXPR)
414218334Speter    return 0;
414318334Speter
414418334Speter  /* Anything declared one level down from the top level
414518334Speter     must be one of the parameters of a function
414618334Speter     (because the body is at least two levels down).  */
414718334Speter
414818334Speter  /* If this looks like a function definition, make it one,
414918334Speter     even if it occurs where parms are expected.
415018334Speter     Then store_parm_decls will reject it and not use it as a parm.  */
415118334Speter  if (decl_context == NORMAL && !funcdef_flag
415218334Speter      && current_binding_level->parm_flag)
415318334Speter    decl_context = PARM;
415418334Speter
415518334Speter  /* Look through the decl specs and record which ones appear.
415618334Speter     Some typespecs are defined as built-in typenames.
415718334Speter     Others, the ones that are modifiers of other types,
415818334Speter     are represented by bits in SPECBITS: set the bits for
415918334Speter     the modifiers that appear.  Storage class keywords are also in SPECBITS.
416018334Speter
416118334Speter     If there is a typedef name or a type, store the type in TYPE.
416218334Speter     This includes builtin typedefs such as `int'.
416318334Speter
416418334Speter     Set EXPLICIT_INT or EXPLICIT_CHAR if the type is `int' or `char'
416518334Speter     and did not come from a user typedef.
416618334Speter
416718334Speter     Set LONGLONG if `long' is mentioned twice.  */
416818334Speter
416918334Speter  for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
417018334Speter    {
417190075Sobrien      tree id = TREE_VALUE (spec);
417218334Speter
417390075Sobrien      /* If the entire declaration is itself tagged as deprecated then
417490075Sobrien         suppress reports of deprecated items.  */
417590075Sobrien      if (id && TREE_DEPRECATED (id))
417690075Sobrien        {
417790075Sobrien	  if (deprecated_state != DEPRECATED_SUPPRESS)
417890075Sobrien	    warn_deprecated_use (id);
417990075Sobrien        }
418090075Sobrien
418118334Speter      if (id == ridpointers[(int) RID_INT])
418218334Speter	explicit_int = 1;
418318334Speter      if (id == ridpointers[(int) RID_CHAR])
418418334Speter	explicit_char = 1;
418518334Speter
418690075Sobrien      if (TREE_CODE (id) == IDENTIFIER_NODE && C_IS_RESERVED_WORD (id))
418790075Sobrien	{
418890075Sobrien	  enum rid i = C_RID_CODE (id);
418990075Sobrien	  if ((int) i <= (int) RID_LAST_MODIFIER)
419090075Sobrien	    {
419190075Sobrien	      if (i == RID_LONG && (specbits & (1 << (int) i)))
419290075Sobrien		{
419390075Sobrien		  if (longlong)
419490075Sobrien		    error ("`long long long' is too long for GCC");
419590075Sobrien		  else
419690075Sobrien		    {
419790075Sobrien		      if (pedantic && !flag_isoc99 && ! in_system_header
419890075Sobrien			  && warn_long_long)
419990075Sobrien			pedwarn ("ISO C89 does not support `long long'");
420090075Sobrien		      longlong = 1;
420190075Sobrien		    }
420290075Sobrien		}
420390075Sobrien	      else if (specbits & (1 << (int) i))
420490075Sobrien		pedwarn ("duplicate `%s'", IDENTIFIER_POINTER (id));
420590075Sobrien	      specbits |= 1 << (int) i;
420690075Sobrien	      goto found;
420790075Sobrien	    }
420890075Sobrien	}
420918334Speter      if (type)
421018334Speter	error ("two or more data types in declaration of `%s'", name);
421118334Speter      /* Actual typedefs come to us as TYPE_DECL nodes.  */
421218334Speter      else if (TREE_CODE (id) == TYPE_DECL)
421318334Speter	{
421490075Sobrien	  if (TREE_TYPE (id) == error_mark_node)
421590075Sobrien	    ; /* Allow the type to default to int to avoid cascading errors.  */
421690075Sobrien	  else
421790075Sobrien	    {
421890075Sobrien	      type = TREE_TYPE (id);
421990075Sobrien	      decl_attr = DECL_ATTRIBUTES (id);
422090075Sobrien	      typedef_decl = id;
422190075Sobrien	    }
422218334Speter	}
422318334Speter      /* Built-in types come as identifiers.  */
422418334Speter      else if (TREE_CODE (id) == IDENTIFIER_NODE)
422518334Speter	{
422690075Sobrien	  tree t = lookup_name (id);
422718334Speter	  if (TREE_TYPE (t) == error_mark_node)
422818334Speter	    ;
422918334Speter	  else if (!t || TREE_CODE (t) != TYPE_DECL)
423018334Speter	    error ("`%s' fails to be a typedef or built in type",
423118334Speter		   IDENTIFIER_POINTER (id));
423218334Speter	  else
423318334Speter	    {
423418334Speter	      type = TREE_TYPE (t);
423518334Speter	      typedef_decl = t;
423618334Speter	    }
423718334Speter	}
423818334Speter      else if (TREE_CODE (id) != ERROR_MARK)
423918334Speter	type = id;
424018334Speter
424190075Sobrien    found:
424290075Sobrien      ;
424318334Speter    }
424418334Speter
424518334Speter  typedef_type = type;
424618334Speter  if (type)
424718334Speter    size_varies = C_TYPE_VARIABLE_SIZE (type);
424818334Speter
424918334Speter  /* No type at all: default to `int', and set DEFAULTED_INT
425018334Speter     because it was not a user-defined typedef.  */
425118334Speter
425218334Speter  if (type == 0)
425318334Speter    {
425450397Sobrien      if ((! (specbits & ((1 << (int) RID_LONG) | (1 << (int) RID_SHORT)
425550397Sobrien			  | (1 << (int) RID_SIGNED)
425690075Sobrien			  | (1 << (int) RID_UNSIGNED)
425790075Sobrien			  | (1 << (int) RID_COMPLEX))))
425850397Sobrien	  /* Don't warn about typedef foo = bar.  */
425950397Sobrien	  && ! (specbits & (1 << (int) RID_TYPEDEF) && initialized)
426090075Sobrien	  && ! in_system_header)
426150397Sobrien	{
426290075Sobrien	  /* Issue a warning if this is an ISO C 99 program or if -Wreturn-type
426352284Sobrien	     and this is a function, or if -Wimplicit; prefer the former
426452284Sobrien	     warning since it is more explicit.  */
426590075Sobrien	  if ((warn_implicit_int || warn_return_type || flag_isoc99)
426690075Sobrien	      && funcdef_flag)
426750397Sobrien	    warn_about_return_type = 1;
426890075Sobrien	  else if (warn_implicit_int || flag_isoc99)
426990075Sobrien	    pedwarn_c99 ("type defaults to `int' in declaration of `%s'",
427090075Sobrien			 name);
427150397Sobrien	}
427250397Sobrien
427318334Speter      defaulted_int = 1;
427418334Speter      type = integer_type_node;
427518334Speter    }
427618334Speter
427718334Speter  /* Now process the modifiers that were specified
427818334Speter     and check for invalid combinations.  */
427918334Speter
428018334Speter  /* Long double is a special combination.  */
428118334Speter
428250397Sobrien  if ((specbits & 1 << (int) RID_LONG) && ! longlong
428318334Speter      && TYPE_MAIN_VARIANT (type) == double_type_node)
428418334Speter    {
428590075Sobrien      specbits &= ~(1 << (int) RID_LONG);
428618334Speter      type = long_double_type_node;
428718334Speter    }
428818334Speter
428918334Speter  /* Check all other uses of type modifiers.  */
429018334Speter
429118334Speter  if (specbits & ((1 << (int) RID_LONG) | (1 << (int) RID_SHORT)
429218334Speter		  | (1 << (int) RID_UNSIGNED) | (1 << (int) RID_SIGNED)))
429318334Speter    {
429418334Speter      int ok = 0;
429518334Speter
429650397Sobrien      if ((specbits & 1 << (int) RID_LONG)
429750397Sobrien	  && (specbits & 1 << (int) RID_SHORT))
429850397Sobrien	error ("both long and short specified for `%s'", name);
429918334Speter      else if (((specbits & 1 << (int) RID_LONG)
430018334Speter		|| (specbits & 1 << (int) RID_SHORT))
430118334Speter	       && explicit_char)
430218334Speter	error ("long or short specified with char for `%s'", name);
430318334Speter      else if (((specbits & 1 << (int) RID_LONG)
430418334Speter		|| (specbits & 1 << (int) RID_SHORT))
430518334Speter	       && TREE_CODE (type) == REAL_TYPE)
430650397Sobrien	{
430750397Sobrien	  static int already = 0;
430850397Sobrien
430950397Sobrien	  error ("long or short specified with floating type for `%s'", name);
431050397Sobrien	  if (! already && ! pedantic)
431150397Sobrien	    {
431250397Sobrien	      error ("the only valid combination is `long double'");
431350397Sobrien	      already = 1;
431450397Sobrien	    }
431550397Sobrien	}
431618334Speter      else if ((specbits & 1 << (int) RID_SIGNED)
431718334Speter	       && (specbits & 1 << (int) RID_UNSIGNED))
431850397Sobrien	error ("both signed and unsigned specified for `%s'", name);
431950397Sobrien      else if (TREE_CODE (type) != INTEGER_TYPE)
432050397Sobrien	error ("long, short, signed or unsigned invalid for `%s'", name);
432118334Speter      else
432218334Speter	{
432318334Speter	  ok = 1;
432418334Speter	  if (!explicit_int && !defaulted_int && !explicit_char && pedantic)
432518334Speter	    {
432618334Speter	      pedwarn ("long, short, signed or unsigned used invalidly for `%s'",
432718334Speter		       name);
432818334Speter	      if (flag_pedantic_errors)
432918334Speter		ok = 0;
433018334Speter	    }
433118334Speter	}
433218334Speter
433318334Speter      /* Discard the type modifiers if they are invalid.  */
433418334Speter      if (! ok)
433518334Speter	{
433618334Speter	  specbits &= ~((1 << (int) RID_LONG) | (1 << (int) RID_SHORT)
433718334Speter			| (1 << (int) RID_UNSIGNED) | (1 << (int) RID_SIGNED));
433818334Speter	  longlong = 0;
433918334Speter	}
434018334Speter    }
434118334Speter
434218334Speter  if ((specbits & (1 << (int) RID_COMPLEX))
434318334Speter      && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
434418334Speter    {
434518334Speter      error ("complex invalid for `%s'", name);
434690075Sobrien      specbits &= ~(1 << (int) RID_COMPLEX);
434718334Speter    }
434818334Speter
434918334Speter  /* Decide whether an integer type is signed or not.
435096263Sobrien     Optionally treat bitfields as signed by default.  */
435118334Speter  if (specbits & 1 << (int) RID_UNSIGNED
435296263Sobrien      /* Traditionally, all bitfields are unsigned.  */
435318334Speter      || (bitfield && flag_traditional
435418334Speter	  && (! explicit_flag_signed_bitfields || !flag_signed_bitfields))
435518334Speter      || (bitfield && ! flag_signed_bitfields
435618334Speter	  && (explicit_int || defaulted_int || explicit_char
435718334Speter	      /* A typedef for plain `int' without `signed'
435818334Speter		 can be controlled just like plain `int'.  */
435918334Speter	      || ! (typedef_decl != 0
436018334Speter		    && C_TYPEDEF_EXPLICITLY_SIGNED (typedef_decl)))
436118334Speter	  && TREE_CODE (type) != ENUMERAL_TYPE
436218334Speter	  && !(specbits & 1 << (int) RID_SIGNED)))
436318334Speter    {
436418334Speter      if (longlong)
436518334Speter	type = long_long_unsigned_type_node;
436618334Speter      else if (specbits & 1 << (int) RID_LONG)
436718334Speter	type = long_unsigned_type_node;
436818334Speter      else if (specbits & 1 << (int) RID_SHORT)
436918334Speter	type = short_unsigned_type_node;
437018334Speter      else if (type == char_type_node)
437118334Speter	type = unsigned_char_type_node;
437218334Speter      else if (typedef_decl)
437318334Speter	type = unsigned_type (type);
437418334Speter      else
437518334Speter	type = unsigned_type_node;
437618334Speter    }
437718334Speter  else if ((specbits & 1 << (int) RID_SIGNED)
437818334Speter	   && type == char_type_node)
437918334Speter    type = signed_char_type_node;
438018334Speter  else if (longlong)
438118334Speter    type = long_long_integer_type_node;
438218334Speter  else if (specbits & 1 << (int) RID_LONG)
438318334Speter    type = long_integer_type_node;
438418334Speter  else if (specbits & 1 << (int) RID_SHORT)
438518334Speter    type = short_integer_type_node;
438618334Speter
438718334Speter  if (specbits & 1 << (int) RID_COMPLEX)
438818334Speter    {
438990075Sobrien      if (pedantic && !flag_isoc99)
439090075Sobrien	pedwarn ("ISO C89 does not support complex types");
439118334Speter      /* If we just have "complex", it is equivalent to
439218334Speter	 "complex double", but if any modifiers at all are specified it is
439318334Speter	 the complex form of TYPE.  E.g, "complex short" is
439418334Speter	 "complex short int".  */
439518334Speter
439618334Speter      if (defaulted_int && ! longlong
439718334Speter	  && ! (specbits & ((1 << (int) RID_LONG) | (1 << (int) RID_SHORT)
439818334Speter			    | (1 << (int) RID_SIGNED)
439918334Speter			    | (1 << (int) RID_UNSIGNED))))
440090075Sobrien	{
440190075Sobrien	  if (pedantic)
440290075Sobrien	    pedwarn ("ISO C does not support plain `complex' meaning `double complex'");
440390075Sobrien	  type = complex_double_type_node;
440490075Sobrien	}
440518334Speter      else if (type == integer_type_node)
440690075Sobrien	{
440790075Sobrien	  if (pedantic)
440890075Sobrien	    pedwarn ("ISO C does not support complex integer types");
440990075Sobrien	  type = complex_integer_type_node;
441090075Sobrien	}
441118334Speter      else if (type == float_type_node)
441218334Speter	type = complex_float_type_node;
441318334Speter      else if (type == double_type_node)
441418334Speter	type = complex_double_type_node;
441518334Speter      else if (type == long_double_type_node)
441618334Speter	type = complex_long_double_type_node;
441718334Speter      else
441890075Sobrien	{
441990075Sobrien	  if (pedantic)
442090075Sobrien	    pedwarn ("ISO C does not support complex integer types");
442190075Sobrien	  type = build_complex_type (type);
442290075Sobrien	}
442318334Speter    }
442418334Speter
442552284Sobrien  /* Figure out the type qualifiers for the declaration.  There are
442652284Sobrien     two ways a declaration can become qualified.  One is something
442752284Sobrien     like `const int i' where the `const' is explicit.  Another is
442852284Sobrien     something like `typedef const int CI; CI i' where the type of the
442952284Sobrien     declaration contains the `const'.  */
443018334Speter  constp = !! (specbits & 1 << (int) RID_CONST) + TYPE_READONLY (type);
443152284Sobrien  restrictp = !! (specbits & 1 << (int) RID_RESTRICT) + TYPE_RESTRICT (type);
443218334Speter  volatilep = !! (specbits & 1 << (int) RID_VOLATILE) + TYPE_VOLATILE (type);
443318334Speter  inlinep = !! (specbits & (1 << (int) RID_INLINE));
443490075Sobrien  if (constp > 1 && ! flag_isoc99)
443518334Speter    pedwarn ("duplicate `const'");
443690075Sobrien  if (restrictp > 1 && ! flag_isoc99)
443752284Sobrien    pedwarn ("duplicate `restrict'");
443890075Sobrien  if (volatilep > 1 && ! flag_isoc99)
443918334Speter    pedwarn ("duplicate `volatile'");
444052284Sobrien  if (! flag_gen_aux_info && (TYPE_QUALS (type)))
444118334Speter    type = TYPE_MAIN_VARIANT (type);
444252284Sobrien  type_quals = ((constp ? TYPE_QUAL_CONST : 0)
444352284Sobrien		| (restrictp ? TYPE_QUAL_RESTRICT : 0)
444452284Sobrien		| (volatilep ? TYPE_QUAL_VOLATILE : 0));
444518334Speter
444618334Speter  /* Warn if two storage classes are given. Default to `auto'.  */
444718334Speter
444818334Speter  {
444918334Speter    int nclasses = 0;
445018334Speter
445118334Speter    if (specbits & 1 << (int) RID_AUTO) nclasses++;
445218334Speter    if (specbits & 1 << (int) RID_STATIC) nclasses++;
445318334Speter    if (specbits & 1 << (int) RID_EXTERN) nclasses++;
445418334Speter    if (specbits & 1 << (int) RID_REGISTER) nclasses++;
445518334Speter    if (specbits & 1 << (int) RID_TYPEDEF) nclasses++;
445618334Speter
445718334Speter    /* Warn about storage classes that are invalid for certain
445818334Speter       kinds of declarations (parameters, typenames, etc.).  */
445918334Speter
446018334Speter    if (nclasses > 1)
446118334Speter      error ("multiple storage classes in declaration of `%s'", name);
446218334Speter    else if (funcdef_flag
446318334Speter	     && (specbits
446418334Speter		 & ((1 << (int) RID_REGISTER)
446518334Speter		    | (1 << (int) RID_AUTO)
446618334Speter		    | (1 << (int) RID_TYPEDEF))))
446718334Speter      {
446818334Speter	if (specbits & 1 << (int) RID_AUTO
446918334Speter	    && (pedantic || current_binding_level == global_binding_level))
447018334Speter	  pedwarn ("function definition declared `auto'");
447118334Speter	if (specbits & 1 << (int) RID_REGISTER)
447218334Speter	  error ("function definition declared `register'");
447318334Speter	if (specbits & 1 << (int) RID_TYPEDEF)
447418334Speter	  error ("function definition declared `typedef'");
447590075Sobrien	specbits &= ~((1 << (int) RID_TYPEDEF) | (1 << (int) RID_REGISTER)
447690075Sobrien		      | (1 << (int) RID_AUTO));
447718334Speter      }
447818334Speter    else if (decl_context != NORMAL && nclasses > 0)
447918334Speter      {
448018334Speter	if (decl_context == PARM && specbits & 1 << (int) RID_REGISTER)
448118334Speter	  ;
448218334Speter	else
448318334Speter	  {
448490075Sobrien	    switch (decl_context)
448590075Sobrien	      {
448690075Sobrien	      case FIELD:
448790075Sobrien		error ("storage class specified for structure field `%s'",
448890075Sobrien		       name);
448990075Sobrien		break;
449090075Sobrien	      case PARM:
449190075Sobrien		error ("storage class specified for parameter `%s'", name);
449290075Sobrien		break;
449390075Sobrien	      default:
449490075Sobrien		error ("storage class specified for typename");
449590075Sobrien		break;
449690075Sobrien	      }
449790075Sobrien	    specbits &= ~((1 << (int) RID_TYPEDEF) | (1 << (int) RID_REGISTER)
449890075Sobrien			  | (1 << (int) RID_AUTO) | (1 << (int) RID_STATIC)
449990075Sobrien			  | (1 << (int) RID_EXTERN));
450018334Speter	  }
450118334Speter      }
450218334Speter    else if (specbits & 1 << (int) RID_EXTERN && initialized && ! funcdef_flag)
450318334Speter      {
450418334Speter	/* `extern' with initialization is invalid if not at top level.  */
450518334Speter	if (current_binding_level == global_binding_level)
450618334Speter	  warning ("`%s' initialized and declared `extern'", name);
450718334Speter	else
450818334Speter	  error ("`%s' has both `extern' and initializer", name);
450918334Speter      }
451018334Speter    else if (specbits & 1 << (int) RID_EXTERN && funcdef_flag
451118334Speter	     && current_binding_level != global_binding_level)
451218334Speter      error ("nested function `%s' declared `extern'", name);
451318334Speter    else if (current_binding_level == global_binding_level
451418334Speter	     && specbits & (1 << (int) RID_AUTO))
451518334Speter      error ("top-level declaration of `%s' specifies `auto'", name);
451618334Speter  }
451718334Speter
451818334Speter  /* Now figure out the structure of the declarator proper.
451918334Speter     Descend through it, creating more complex types, until we reach
452018334Speter     the declared identifier (or NULL_TREE, in an absolute declarator).  */
452118334Speter
452218334Speter  while (declarator && TREE_CODE (declarator) != IDENTIFIER_NODE)
452318334Speter    {
452418334Speter      if (type == error_mark_node)
452518334Speter	{
452618334Speter	  declarator = TREE_OPERAND (declarator, 0);
452718334Speter	  continue;
452818334Speter	}
452918334Speter
453018334Speter      /* Each level of DECLARATOR is either an ARRAY_REF (for ...[..]),
453118334Speter	 an INDIRECT_REF (for *...),
453218334Speter	 a CALL_EXPR (for ...(...)),
453390075Sobrien	 a TREE_LIST (for nested attributes),
453418334Speter	 an identifier (for the name being declared)
453518334Speter	 or a null pointer (for the place in an absolute declarator
453618334Speter	 where the name was omitted).
453718334Speter	 For the last two cases, we have just exited the loop.
453818334Speter
453918334Speter	 At this point, TYPE is the type of elements of an array,
454018334Speter	 or for a function to return, or for a pointer to point to.
454118334Speter	 After this sequence of ifs, TYPE is the type of the
454218334Speter	 array or function or pointer, and DECLARATOR has had its
454318334Speter	 outermost layer removed.  */
454418334Speter
454590075Sobrien      if (array_ptr_quals != NULL_TREE || array_parm_static)
454618334Speter	{
454790075Sobrien	  /* Only the innermost declarator (making a parameter be of
454890075Sobrien	     array type which is converted to pointer type)
454990075Sobrien	     may have static or type qualifiers.  */
455090075Sobrien	  error ("static or type qualifiers in non-parameter array declarator");
455190075Sobrien	  array_ptr_quals = NULL_TREE;
455290075Sobrien	  array_parm_static = 0;
455390075Sobrien	}
455490075Sobrien
455590075Sobrien      if (TREE_CODE (declarator) == TREE_LIST)
455690075Sobrien	{
455790075Sobrien	  /* We encode a declarator with embedded attributes using
455890075Sobrien	     a TREE_LIST.  */
455990075Sobrien	  tree attrs = TREE_PURPOSE (declarator);
456090075Sobrien	  tree inner_decl;
456190075Sobrien	  int attr_flags = 0;
456290075Sobrien	  declarator = TREE_VALUE (declarator);
456390075Sobrien	  inner_decl = declarator;
456490075Sobrien	  while (inner_decl != NULL_TREE
456590075Sobrien		 && TREE_CODE (inner_decl) == TREE_LIST)
456690075Sobrien	    inner_decl = TREE_VALUE (inner_decl);
456790075Sobrien	  if (inner_decl == NULL_TREE
456890075Sobrien	      || TREE_CODE (inner_decl) == IDENTIFIER_NODE)
456990075Sobrien	    attr_flags |= (int) ATTR_FLAG_DECL_NEXT;
457096263Sobrien	  else if (TREE_CODE (inner_decl) == CALL_EXPR)
457190075Sobrien	    attr_flags |= (int) ATTR_FLAG_FUNCTION_NEXT;
457296263Sobrien	  else if (TREE_CODE (inner_decl) == ARRAY_REF)
457390075Sobrien	    attr_flags |= (int) ATTR_FLAG_ARRAY_NEXT;
457490075Sobrien	  returned_attrs = decl_attributes (&type,
457590075Sobrien					    chainon (returned_attrs, attrs),
457690075Sobrien					    attr_flags);
457790075Sobrien	}
457890075Sobrien      else if (TREE_CODE (declarator) == ARRAY_REF)
457990075Sobrien	{
458090075Sobrien	  tree itype = NULL_TREE;
458190075Sobrien	  tree size = TREE_OPERAND (declarator, 1);
458218334Speter	  /* The index is a signed object `sizetype' bits wide.  */
458318334Speter	  tree index_type = signed_type (sizetype);
458418334Speter
458590075Sobrien	  array_ptr_quals = TREE_TYPE (declarator);
458690075Sobrien	  array_parm_static = TREE_STATIC (declarator);
458790075Sobrien
458818334Speter	  declarator = TREE_OPERAND (declarator, 0);
458918334Speter
459018334Speter	  /* Check for some types that there cannot be arrays of.  */
459118334Speter
459290075Sobrien	  if (VOID_TYPE_P (type))
459318334Speter	    {
459418334Speter	      error ("declaration of `%s' as array of voids", name);
459518334Speter	      type = error_mark_node;
459618334Speter	    }
459718334Speter
459818334Speter	  if (TREE_CODE (type) == FUNCTION_TYPE)
459918334Speter	    {
460018334Speter	      error ("declaration of `%s' as array of functions", name);
460118334Speter	      type = error_mark_node;
460218334Speter	    }
460318334Speter
460418334Speter	  if (size == error_mark_node)
460518334Speter	    type = error_mark_node;
460618334Speter
460718334Speter	  if (type == error_mark_node)
460818334Speter	    continue;
460918334Speter
461018334Speter	  /* If size was specified, set ITYPE to a range-type for that size.
461118334Speter	     Otherwise, ITYPE remains null.  finish_decl may figure it out
461218334Speter	     from an initial value.  */
461318334Speter
461418334Speter	  if (size)
461518334Speter	    {
461618334Speter	      /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue.  */
461718334Speter	      STRIP_TYPE_NOPS (size);
461818334Speter
461990075Sobrien	      if (! INTEGRAL_TYPE_P (TREE_TYPE (size)))
462018334Speter		{
462118334Speter		  error ("size of array `%s' has non-integer type", name);
462218334Speter		  size = integer_one_node;
462318334Speter		}
462418334Speter
462518334Speter	      if (pedantic && integer_zerop (size))
462690075Sobrien		pedwarn ("ISO C forbids zero-size array `%s'", name);
462718334Speter
462818334Speter	      if (TREE_CODE (size) == INTEGER_CST)
462918334Speter		{
463018334Speter		  constant_expression_warning (size);
463118334Speter		  if (tree_int_cst_sgn (size) < 0)
463218334Speter		    {
463318334Speter		      error ("size of array `%s' is negative", name);
463418334Speter		      size = integer_one_node;
463518334Speter		    }
463618334Speter		}
463718334Speter	      else
463818334Speter		{
463918334Speter		  /* Make sure the array size remains visibly nonconstant
464018334Speter		     even if it is (eg) a const variable with known value.  */
464118334Speter		  size_varies = 1;
464218334Speter
464318334Speter		  if (pedantic)
464418334Speter		    {
464518334Speter		      if (TREE_CONSTANT (size))
464690075Sobrien			pedwarn ("ISO C89 forbids array `%s' whose size can't be evaluated",
464790075Sobrien				 name);
464818334Speter		      else
464990075Sobrien			pedwarn ("ISO C89 forbids variable-size array `%s'",
465090075Sobrien				 name);
465118334Speter		    }
465218334Speter		}
465318334Speter
465490075Sobrien	      if (integer_zerop (size))
465550397Sobrien		{
465690075Sobrien		  /* A zero-length array cannot be represented with an
465790075Sobrien		     unsigned index type, which is what we'll get with
465890075Sobrien		     build_index_type.  Create an open-ended range instead.  */
465990075Sobrien		  itype = build_range_type (sizetype, size, NULL_TREE);
466050397Sobrien		}
466190075Sobrien	      else
466290075Sobrien		{
466390075Sobrien		  /* Compute the maximum valid index, that is, size - 1.
466490075Sobrien		     Do the calculation in index_type, so that if it is
466590075Sobrien		     a variable the computations will be done in the
466690075Sobrien		     proper mode.  */
466790075Sobrien	          itype = fold (build (MINUS_EXPR, index_type,
466890075Sobrien				       convert (index_type, size),
466990075Sobrien				       convert (index_type, size_one_node)));
467050397Sobrien
467190075Sobrien	          /* If that overflowed, the array is too big.
467290075Sobrien		     ??? While a size of INT_MAX+1 technically shouldn't
467390075Sobrien		     cause an overflow (because we subtract 1), the overflow
467490075Sobrien		     is recorded during the conversion to index_type, before
467590075Sobrien		     the subtraction.  Handling this case seems like an
467690075Sobrien		     unnecessary complication.  */
467790075Sobrien		  if (TREE_OVERFLOW (itype))
467890075Sobrien		    {
467990075Sobrien		      error ("size of array `%s' is too large", name);
468090075Sobrien		      type = error_mark_node;
468190075Sobrien		      continue;
468290075Sobrien		    }
468390075Sobrien
468490075Sobrien		  if (size_varies)
468590075Sobrien		    itype = variable_size (itype);
468690075Sobrien		  itype = build_index_type (itype);
468790075Sobrien		}
468818334Speter	    }
468990075Sobrien	  else if (decl_context == FIELD)
469090075Sobrien	    {
469190075Sobrien	      if (pedantic && !flag_isoc99 && !in_system_header)
469290075Sobrien		pedwarn ("ISO C89 does not support flexible array members");
469318334Speter
469490075Sobrien	      /* ISO C99 Flexible array members are effectively identical
469590075Sobrien		 to GCC's zero-length array extension.  */
469690075Sobrien	      itype = build_range_type (sizetype, size_zero_node, NULL_TREE);
469790075Sobrien	    }
469818334Speter
469990075Sobrien	  /* If pedantic, complain about arrays of incomplete types.  */
470090075Sobrien
470190075Sobrien	  if (pedantic && !COMPLETE_TYPE_P (type))
470290075Sobrien	    pedwarn ("array type has incomplete element type");
470390075Sobrien
470490075Sobrien#if 0
470590075Sobrien	  /* We shouldn't have a function type here at all!
470690075Sobrien	     Functions aren't allowed as array elements.  */
470718334Speter	  if (pedantic && TREE_CODE (type) == FUNCTION_TYPE
470818334Speter	      && (constp || volatilep))
470990075Sobrien	    pedwarn ("ISO C forbids const or volatile function types");
471018334Speter#endif
471118334Speter
471218334Speter	  /* Build the array type itself, then merge any constancy or
471318334Speter	     volatility into the target type.  We must do it in this order
471418334Speter	     to ensure that the TYPE_MAIN_VARIANT field of the array type
471518334Speter	     is set correctly.  */
471618334Speter
471718334Speter	  type = build_array_type (type, itype);
471852284Sobrien	  if (type_quals)
471952284Sobrien	    type = c_build_qualified_type (type, type_quals);
472018334Speter
472118334Speter	  if (size_varies)
472218334Speter	    C_TYPE_VARIABLE_SIZE (type) = 1;
472390075Sobrien
472490075Sobrien	  /* The GCC extension for zero-length arrays differs from
472590075Sobrien	     ISO flexible array members in that sizeof yields zero.  */
472690075Sobrien	  if (size && integer_zerop (size))
472790075Sobrien	    {
472890075Sobrien	      layout_type (type);
472990075Sobrien	      TYPE_SIZE (type) = bitsize_zero_node;
473090075Sobrien	      TYPE_SIZE_UNIT (type) = size_zero_node;
473190075Sobrien	    }
473290075Sobrien	  if (decl_context != PARM
473390075Sobrien	      && (array_ptr_quals != NULL_TREE || array_parm_static))
473490075Sobrien	    {
473590075Sobrien	      error ("static or type qualifiers in non-parameter array declarator");
473690075Sobrien	      array_ptr_quals = NULL_TREE;
473790075Sobrien	      array_parm_static = 0;
473890075Sobrien	    }
473918334Speter	}
474018334Speter      else if (TREE_CODE (declarator) == CALL_EXPR)
474118334Speter	{
474218334Speter	  tree arg_types;
474318334Speter
474418334Speter	  /* Declaring a function type.
474518334Speter	     Make sure we have a valid type for the function to return.  */
474618334Speter	  if (type == error_mark_node)
474718334Speter	    continue;
474818334Speter
474918334Speter	  size_varies = 0;
475018334Speter
475118334Speter	  /* Warn about some types functions can't return.  */
475218334Speter
475318334Speter	  if (TREE_CODE (type) == FUNCTION_TYPE)
475418334Speter	    {
475518334Speter	      error ("`%s' declared as function returning a function", name);
475618334Speter	      type = integer_type_node;
475718334Speter	    }
475818334Speter	  if (TREE_CODE (type) == ARRAY_TYPE)
475918334Speter	    {
476018334Speter	      error ("`%s' declared as function returning an array", name);
476118334Speter	      type = integer_type_node;
476218334Speter	    }
476318334Speter
476418334Speter#ifndef TRADITIONAL_RETURN_FLOAT
476518334Speter	  /* Traditionally, declaring return type float means double.  */
476618334Speter
476718334Speter	  if (flag_traditional && TYPE_MAIN_VARIANT (type) == float_type_node)
476818334Speter	    type = double_type_node;
476918334Speter#endif /* TRADITIONAL_RETURN_FLOAT */
477018334Speter
477118334Speter	  /* Construct the function type and go to the next
477218334Speter	     inner layer of declarator.  */
477318334Speter
477418334Speter	  arg_types = grokparms (TREE_OPERAND (declarator, 1),
477518334Speter				 funcdef_flag
477618334Speter				 /* Say it's a definition
477718334Speter				    only for the CALL_EXPR
477818334Speter				    closest to the identifier.  */
477918334Speter				 && TREE_CODE (TREE_OPERAND (declarator, 0)) == IDENTIFIER_NODE);
478052284Sobrien	  /* Type qualifiers before the return type of the function
478152284Sobrien	     qualify the return type, not the function type.  */
478252284Sobrien	  if (type_quals)
478390075Sobrien	    {
478490075Sobrien	      /* Type qualifiers on a function return type are normally
478590075Sobrien		 permitted by the standard but have no effect, so give a
478690075Sobrien		 warning at -W.  Qualifiers on a void return type have
478790075Sobrien		 meaning as a GNU extension, and are banned on function
478890075Sobrien		 definitions in ISO C.  FIXME: strictly we shouldn't
478990075Sobrien		 pedwarn for qualified void return types except on function
479090075Sobrien		 definitions, but not doing so could lead to the undesirable
479190075Sobrien		 state of a "volatile void" function return type not being
479290075Sobrien		 warned about, and a use of the function being compiled
479390075Sobrien		 with GNU semantics, with no diagnostics under -pedantic.  */
479490075Sobrien	      if (VOID_TYPE_P (type) && pedantic && !in_system_header)
479590075Sobrien		pedwarn ("ISO C forbids qualified void function return type");
479690075Sobrien	      else if (extra_warnings
479790075Sobrien		       && !(VOID_TYPE_P (type)
479890075Sobrien			    && type_quals == TYPE_QUAL_VOLATILE))
479990075Sobrien		warning ("type qualifiers ignored on function return type");
480090075Sobrien
480190075Sobrien	      type = c_build_qualified_type (type, type_quals);
480290075Sobrien	    }
480352284Sobrien	  type_quals = TYPE_UNQUALIFIED;
480418334Speter
480518334Speter	  type = build_function_type (type, arg_types);
480618334Speter	  declarator = TREE_OPERAND (declarator, 0);
480718334Speter
480818334Speter	  /* Set the TYPE_CONTEXTs for each tagged type which is local to
480918334Speter	     the formal parameter list of this FUNCTION_TYPE to point to
481018334Speter	     the FUNCTION_TYPE node itself.  */
481118334Speter
481218334Speter	  {
481390075Sobrien	    tree link;
481418334Speter
481550397Sobrien	    for (link = last_function_parm_tags;
481618334Speter		 link;
481718334Speter		 link = TREE_CHAIN (link))
481818334Speter	      TYPE_CONTEXT (TREE_VALUE (link)) = type;
481918334Speter	  }
482018334Speter	}
482118334Speter      else if (TREE_CODE (declarator) == INDIRECT_REF)
482218334Speter	{
482318334Speter	  /* Merge any constancy or volatility into the target type
482418334Speter	     for the pointer.  */
482518334Speter
482618334Speter	  if (pedantic && TREE_CODE (type) == FUNCTION_TYPE
482752284Sobrien	      && type_quals)
482890075Sobrien	    pedwarn ("ISO C forbids qualified function types");
482952284Sobrien	  if (type_quals)
483052284Sobrien	    type = c_build_qualified_type (type, type_quals);
483152284Sobrien	  type_quals = TYPE_UNQUALIFIED;
483218334Speter	  size_varies = 0;
483318334Speter
483418334Speter	  type = build_pointer_type (type);
483518334Speter
483618334Speter	  /* Process a list of type modifier keywords
483718334Speter	     (such as const or volatile) that were given inside the `*'.  */
483818334Speter
483918334Speter	  if (TREE_TYPE (declarator))
484018334Speter	    {
484190075Sobrien	      tree typemodlist;
484218334Speter	      int erred = 0;
484352284Sobrien
484452284Sobrien	      constp = 0;
484552284Sobrien	      volatilep = 0;
484652284Sobrien	      restrictp = 0;
484718334Speter	      for (typemodlist = TREE_TYPE (declarator); typemodlist;
484818334Speter		   typemodlist = TREE_CHAIN (typemodlist))
484918334Speter		{
485052284Sobrien		  tree qualifier = TREE_VALUE (typemodlist);
485152284Sobrien
485290075Sobrien		  if (C_IS_RESERVED_WORD (qualifier))
485318334Speter		    {
485490075Sobrien		      if (C_RID_CODE (qualifier) == RID_CONST)
485590075Sobrien			constp++;
485690075Sobrien		      else if (C_RID_CODE (qualifier) == RID_VOLATILE)
485790075Sobrien			volatilep++;
485890075Sobrien		      else if (C_RID_CODE (qualifier) == RID_RESTRICT)
485990075Sobrien			restrictp++;
486090075Sobrien		      else
486190075Sobrien			erred++;
486218334Speter		    }
486390075Sobrien		  else
486490075Sobrien		    erred++;
486518334Speter		}
486690075Sobrien
486790075Sobrien	      if (erred)
486890075Sobrien		error ("invalid type modifier within pointer declarator");
486990075Sobrien	      if (constp > 1 && ! flag_isoc99)
487018334Speter		pedwarn ("duplicate `const'");
487190075Sobrien	      if (volatilep > 1 && ! flag_isoc99)
487218334Speter		pedwarn ("duplicate `volatile'");
487390075Sobrien	      if (restrictp > 1 && ! flag_isoc99)
487452284Sobrien		pedwarn ("duplicate `restrict'");
487552284Sobrien
487652284Sobrien	      type_quals = ((constp ? TYPE_QUAL_CONST : 0)
487752284Sobrien			    | (restrictp ? TYPE_QUAL_RESTRICT : 0)
487852284Sobrien			    | (volatilep ? TYPE_QUAL_VOLATILE : 0));
487918334Speter	    }
488018334Speter
488118334Speter	  declarator = TREE_OPERAND (declarator, 0);
488218334Speter	}
488318334Speter      else
488418334Speter	abort ();
488518334Speter
488618334Speter    }
488718334Speter
488818334Speter  /* Now TYPE has the actual type.  */
488918334Speter
489050397Sobrien  /* Did array size calculations overflow?  */
489150397Sobrien
489250397Sobrien  if (TREE_CODE (type) == ARRAY_TYPE
489390075Sobrien      && COMPLETE_TYPE_P (type)
489450397Sobrien      && TREE_OVERFLOW (TYPE_SIZE (type)))
489590075Sobrien    {
489690075Sobrien      error ("size of array `%s' is too large", name);
489790075Sobrien      /* If we proceed with the array type as it is, we'll eventually
489890075Sobrien	 crash in tree_low_cst().  */
489990075Sobrien      type = error_mark_node;
490090075Sobrien    }
490150397Sobrien
490218334Speter  /* If this is declaring a typedef name, return a TYPE_DECL.  */
490318334Speter
490418334Speter  if (specbits & (1 << (int) RID_TYPEDEF))
490518334Speter    {
490618334Speter      tree decl;
490718334Speter      /* Note that the grammar rejects storage classes
490818334Speter	 in typenames, fields or parameters */
490918334Speter      if (pedantic && TREE_CODE (type) == FUNCTION_TYPE
491052284Sobrien	  && type_quals)
491190075Sobrien	pedwarn ("ISO C forbids qualified function types");
491252284Sobrien      if (type_quals)
491352284Sobrien	type = c_build_qualified_type (type, type_quals);
491418334Speter      decl = build_decl (TYPE_DECL, declarator, type);
491518334Speter      if ((specbits & (1 << (int) RID_SIGNED))
491618334Speter	  || (typedef_decl && C_TYPEDEF_EXPLICITLY_SIGNED (typedef_decl)))
491718334Speter	C_TYPEDEF_EXPLICITLY_SIGNED (decl) = 1;
491890075Sobrien      decl_attributes (&decl, returned_attrs, 0);
491918334Speter      return decl;
492018334Speter    }
492118334Speter
492218334Speter  /* Detect the case of an array type of unspecified size
492318334Speter     which came, as such, direct from a typedef name.
492418334Speter     We must copy the type, so that each identifier gets
492518334Speter     a distinct type, so that each identifier's size can be
492618334Speter     controlled separately by its own initializer.  */
492718334Speter
492818334Speter  if (type != 0 && typedef_type != 0
492990075Sobrien      && TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type) == 0
493090075Sobrien      && TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (typedef_type))
493118334Speter    {
493218334Speter      type = build_array_type (TREE_TYPE (type), 0);
493318334Speter      if (size_varies)
493418334Speter	C_TYPE_VARIABLE_SIZE (type) = 1;
493518334Speter    }
493618334Speter
493718334Speter  /* If this is a type name (such as, in a cast or sizeof),
493818334Speter     compute the type and return it now.  */
493918334Speter
494018334Speter  if (decl_context == TYPENAME)
494118334Speter    {
494218334Speter      /* Note that the grammar rejects storage classes
494318334Speter	 in typenames, fields or parameters */
494418334Speter      if (pedantic && TREE_CODE (type) == FUNCTION_TYPE
494552284Sobrien	  && type_quals)
494690075Sobrien	pedwarn ("ISO C forbids const or volatile function types");
494752284Sobrien      if (type_quals)
494852284Sobrien	type = c_build_qualified_type (type, type_quals);
494990075Sobrien      decl_attributes (&type, returned_attrs, 0);
495018334Speter      return type;
495118334Speter    }
495218334Speter
495318334Speter  /* Aside from typedefs and type names (handle above),
495418334Speter     `void' at top level (not within pointer)
495518334Speter     is allowed only in public variables.
495618334Speter     We don't complain about parms either, but that is because
495718334Speter     a better error message can be made later.  */
495818334Speter
495990075Sobrien  if (VOID_TYPE_P (type) && decl_context != PARM
496018334Speter      && ! ((decl_context != FIELD && TREE_CODE (type) != FUNCTION_TYPE)
496118334Speter	    && ((specbits & (1 << (int) RID_EXTERN))
496218334Speter		|| (current_binding_level == global_binding_level
496318334Speter		    && !(specbits
496418334Speter			 & ((1 << (int) RID_STATIC) | (1 << (int) RID_REGISTER)))))))
496518334Speter    {
496618334Speter      error ("variable or field `%s' declared void", name);
496718334Speter      type = integer_type_node;
496818334Speter    }
496918334Speter
497018334Speter  /* Now create the decl, which may be a VAR_DECL, a PARM_DECL
497118334Speter     or a FUNCTION_DECL, depending on DECL_CONTEXT and TYPE.  */
497218334Speter
497318334Speter  {
497490075Sobrien    tree decl;
497518334Speter
497618334Speter    if (decl_context == PARM)
497718334Speter      {
497890075Sobrien	tree type_as_written;
497990075Sobrien	tree promoted_type;
498018334Speter
498118334Speter	/* A parameter declared as an array of T is really a pointer to T.
498218334Speter	   One declared as a function is really a pointer to a function.  */
498318334Speter
498418334Speter	if (TREE_CODE (type) == ARRAY_TYPE)
498518334Speter	  {
498618334Speter	    /* Transfer const-ness of array into that of type pointed to.  */
498718334Speter	    type = TREE_TYPE (type);
498852284Sobrien	    if (type_quals)
498952284Sobrien	      type = c_build_qualified_type (type, type_quals);
499018334Speter	    type = build_pointer_type (type);
499152284Sobrien	    type_quals = TYPE_UNQUALIFIED;
499290075Sobrien	    if (array_ptr_quals)
499390075Sobrien	      {
499490075Sobrien		tree new_ptr_quals, new_ptr_attrs;
499590075Sobrien		int erred = 0;
499690075Sobrien		split_specs_attrs (array_ptr_quals, &new_ptr_quals, &new_ptr_attrs);
499790075Sobrien		/* We don't yet implement attributes in this context.  */
499890075Sobrien		if (new_ptr_attrs != NULL_TREE)
499990075Sobrien		  warning ("attributes in parameter array declarator ignored");
500090075Sobrien
500190075Sobrien		constp = 0;
500290075Sobrien		volatilep = 0;
500390075Sobrien		restrictp = 0;
500490075Sobrien		for (; new_ptr_quals; new_ptr_quals = TREE_CHAIN (new_ptr_quals))
500590075Sobrien		  {
500690075Sobrien		    tree qualifier = TREE_VALUE (new_ptr_quals);
500790075Sobrien
500890075Sobrien		    if (C_IS_RESERVED_WORD (qualifier))
500990075Sobrien		      {
501090075Sobrien			if (C_RID_CODE (qualifier) == RID_CONST)
501190075Sobrien			  constp++;
501290075Sobrien			else if (C_RID_CODE (qualifier) == RID_VOLATILE)
501390075Sobrien			  volatilep++;
501490075Sobrien			else if (C_RID_CODE (qualifier) == RID_RESTRICT)
501590075Sobrien			  restrictp++;
501690075Sobrien			else
501790075Sobrien			  erred++;
501890075Sobrien		      }
501990075Sobrien		    else
502090075Sobrien		      erred++;
502190075Sobrien		  }
502290075Sobrien
502390075Sobrien		if (erred)
502490075Sobrien		  error ("invalid type modifier within array declarator");
502590075Sobrien
502690075Sobrien		type_quals = ((constp ? TYPE_QUAL_CONST : 0)
502790075Sobrien			      | (restrictp ? TYPE_QUAL_RESTRICT : 0)
502890075Sobrien			      | (volatilep ? TYPE_QUAL_VOLATILE : 0));
502990075Sobrien	      }
503018334Speter	    size_varies = 0;
503118334Speter	  }
503218334Speter	else if (TREE_CODE (type) == FUNCTION_TYPE)
503318334Speter	  {
503452284Sobrien	    if (pedantic && type_quals)
503590075Sobrien	      pedwarn ("ISO C forbids qualified function types");
503652284Sobrien	    if (type_quals)
503752284Sobrien	      type = c_build_qualified_type (type, type_quals);
503818334Speter	    type = build_pointer_type (type);
503952284Sobrien	    type_quals = TYPE_UNQUALIFIED;
504018334Speter	  }
504190075Sobrien	else if (type_quals)
504290075Sobrien	  type = c_build_qualified_type (type, type_quals);
504390075Sobrien
504490075Sobrien	type_as_written = type;
504518334Speter
504618334Speter	decl = build_decl (PARM_DECL, declarator, type);
504718334Speter	if (size_varies)
504818334Speter	  C_DECL_VARIABLE_SIZE (decl) = 1;
504918334Speter
505018334Speter	/* Compute the type actually passed in the parmlist,
505118334Speter	   for the case where there is no prototype.
505218334Speter	   (For example, shorts and chars are passed as ints.)
505318334Speter	   When there is a prototype, this is overridden later.  */
505418334Speter
505590075Sobrien	if (type == error_mark_node)
505690075Sobrien	  promoted_type = type;
505790075Sobrien	else
505818334Speter	  {
505990075Sobrien	    promoted_type = simple_type_promotes_to (type);
506090075Sobrien	    if (! promoted_type)
506190075Sobrien	      promoted_type = type;
506218334Speter	  }
506318334Speter
506490075Sobrien	DECL_ARG_TYPE (decl) = promoted_type;
506518334Speter	DECL_ARG_TYPE_AS_WRITTEN (decl) = type_as_written;
506618334Speter      }
506718334Speter    else if (decl_context == FIELD)
506818334Speter      {
506918334Speter	/* Structure field.  It may not be a function.  */
507096263Sobrien
507118334Speter	if (TREE_CODE (type) == FUNCTION_TYPE)
507218334Speter	  {
507318334Speter	    error ("field `%s' declared as a function", name);
507418334Speter	    type = build_pointer_type (type);
507518334Speter	  }
507690075Sobrien	else if (TREE_CODE (type) != ERROR_MARK
507790075Sobrien	         && !COMPLETE_OR_UNBOUND_ARRAY_TYPE_P (type))
507818334Speter	  {
507918334Speter	    error ("field `%s' has incomplete type", name);
508018334Speter	    type = error_mark_node;
508118334Speter	  }
508218334Speter	/* Move type qualifiers down to element of an array.  */
508352284Sobrien	if (TREE_CODE (type) == ARRAY_TYPE && type_quals)
508418334Speter	  {
508552284Sobrien	    type = build_array_type (c_build_qualified_type (TREE_TYPE (type),
508652284Sobrien							     type_quals),
508718334Speter				     TYPE_DOMAIN (type));
508890075Sobrien#if 0
508990075Sobrien	    /* Leave the field const or volatile as well.  */
509052284Sobrien	    type_quals = TYPE_UNQUALIFIED;
509118334Speter#endif
509218334Speter	  }
509318334Speter	decl = build_decl (FIELD_DECL, declarator, type);
509490075Sobrien	DECL_NONADDRESSABLE_P (decl) = bitfield;
509590075Sobrien
509618334Speter	if (size_varies)
509718334Speter	  C_DECL_VARIABLE_SIZE (decl) = 1;
509818334Speter      }
509918334Speter    else if (TREE_CODE (type) == FUNCTION_TYPE)
510018334Speter      {
510118334Speter	/* Every function declaration is "external"
510218334Speter	   except for those which are inside a function body
510318334Speter	   in which `auto' is used.
510418334Speter	   That is a case not specified by ANSI C,
510518334Speter	   and we use it for forward declarations for nested functions.  */
510618334Speter	int extern_ref = (!(specbits & (1 << (int) RID_AUTO))
510718334Speter			  || current_binding_level == global_binding_level);
510818334Speter
510918334Speter	if (specbits & (1 << (int) RID_AUTO)
511018334Speter	    && (pedantic || current_binding_level == global_binding_level))
511118334Speter	  pedwarn ("invalid storage class for function `%s'", name);
511218334Speter	if (specbits & (1 << (int) RID_REGISTER))
511318334Speter	  error ("invalid storage class for function `%s'", name);
511418334Speter	/* Function declaration not at top level.
511518334Speter	   Storage classes other than `extern' are not allowed
511618334Speter	   and `extern' makes no difference.  */
511718334Speter	if (current_binding_level != global_binding_level
511818334Speter	    && (specbits & ((1 << (int) RID_STATIC) | (1 << (int) RID_INLINE)))
511918334Speter	    && pedantic)
512018334Speter	  pedwarn ("invalid storage class for function `%s'", name);
512118334Speter
512218334Speter	decl = build_decl (FUNCTION_DECL, declarator, type);
512390075Sobrien	decl = build_decl_attribute_variant (decl, decl_attr);
512418334Speter
512590075Sobrien	DECL_LANG_SPECIFIC (decl) = (struct lang_decl *)
512690075Sobrien	  ggc_alloc_cleared (sizeof (struct lang_decl));
512790075Sobrien
512852284Sobrien	if (pedantic && type_quals && ! DECL_IN_SYSTEM_HEADER (decl))
512990075Sobrien	  pedwarn ("ISO C forbids qualified function types");
513018334Speter
513152284Sobrien	/* GNU C interprets a `volatile void' return type to indicate
513252284Sobrien	   that the function does not return.  */
513352284Sobrien	if ((type_quals & TYPE_QUAL_VOLATILE)
513490075Sobrien	    && !VOID_TYPE_P (TREE_TYPE (TREE_TYPE (decl))))
513518334Speter	  warning ("`noreturn' function returns non-void value");
513618334Speter
513718334Speter	if (extern_ref)
513818334Speter	  DECL_EXTERNAL (decl) = 1;
513918334Speter	/* Record absence of global scope for `static' or `auto'.  */
514018334Speter	TREE_PUBLIC (decl)
514118334Speter	  = !(specbits & ((1 << (int) RID_STATIC) | (1 << (int) RID_AUTO)));
514218334Speter
514396263Sobrien	if (defaulted_int)
514496263Sobrien	  C_FUNCTION_IMPLICIT_INT (decl) = 1;
514596263Sobrien
514618334Speter	/* Record presence of `inline', if it is reasonable.  */
514790075Sobrien	if (MAIN_NAME_P (declarator))
514818334Speter	  {
514990075Sobrien	    if (inlinep)
515018334Speter	      warning ("cannot inline function `main'");
515190075Sobrien	  }
515290075Sobrien	else if (inlinep)
515390075Sobrien	  {
515490075Sobrien	    /* Assume that otherwise the function can be inlined.  */
515590075Sobrien	    DECL_DECLARED_INLINE_P (decl) = 1;
515618334Speter
515790075Sobrien	    /* Do not mark bare declarations as DECL_INLINE.  Doing so
515890075Sobrien	       in the presence of multiple declarations can result in
515990075Sobrien	       the abstract origin pointing between the declarations,
516090075Sobrien	       which will confuse dwarf2out.  */
516190075Sobrien	    if (initialized)
516290075Sobrien	      {
516390075Sobrien		DECL_INLINE (decl) = 1;
516490075Sobrien		if (specbits & (1 << (int) RID_EXTERN))
516590075Sobrien		  current_extern_inline = 1;
516690075Sobrien	      }
516718334Speter	  }
516890075Sobrien	/* If -finline-functions, assume it can be inlined.  This does
516990075Sobrien	   two things: let the function be deferred until it is actually
517090075Sobrien	   needed, and let dwarf2 know that the function is inlinable.  */
517190075Sobrien	else if (flag_inline_trees == 2 && initialized)
517290075Sobrien	  {
517390075Sobrien	    DECL_INLINE (decl) = 1;
517490075Sobrien	    DECL_DECLARED_INLINE_P (decl) = 0;
517590075Sobrien	  }
517618334Speter      }
517718334Speter    else
517818334Speter      {
517918334Speter	/* It's a variable.  */
518018334Speter	/* An uninitialized decl with `extern' is a reference.  */
518118334Speter	int extern_ref = !initialized && (specbits & (1 << (int) RID_EXTERN));
518218334Speter
518318334Speter	/* Move type qualifiers down to element of an array.  */
518452284Sobrien	if (TREE_CODE (type) == ARRAY_TYPE && type_quals)
518518334Speter	  {
518690075Sobrien	    int saved_align = TYPE_ALIGN(type);
518752284Sobrien	    type = build_array_type (c_build_qualified_type (TREE_TYPE (type),
518852284Sobrien							     type_quals),
518918334Speter				     TYPE_DOMAIN (type));
519090075Sobrien	    TYPE_ALIGN (type) = saved_align;
519118334Speter#if 0 /* Leave the variable const or volatile as well.  */
519252284Sobrien	    type_quals = TYPE_UNQUALIFIED;
519318334Speter#endif
519418334Speter	  }
519590075Sobrien	else if (type_quals)
519690075Sobrien	  type = c_build_qualified_type (type, type_quals);
519790075Sobrien
519818334Speter	decl = build_decl (VAR_DECL, declarator, type);
519918334Speter	if (size_varies)
520018334Speter	  C_DECL_VARIABLE_SIZE (decl) = 1;
520118334Speter
520218334Speter	if (inlinep)
520318334Speter	  pedwarn_with_decl (decl, "variable `%s' declared `inline'");
520418334Speter
520518334Speter	DECL_EXTERNAL (decl) = extern_ref;
520618334Speter	/* At top level, the presence of a `static' or `register' storage
520718334Speter	   class specifier, or the absence of all storage class specifiers
520818334Speter	   makes this declaration a definition (perhaps tentative).  Also,
520918334Speter	   the absence of both `static' and `register' makes it public.  */
521018334Speter	if (current_binding_level == global_binding_level)
521118334Speter	  {
521218334Speter	    TREE_PUBLIC (decl)
521318334Speter	      = !(specbits
521418334Speter		  & ((1 << (int) RID_STATIC) | (1 << (int) RID_REGISTER)));
521518334Speter	    TREE_STATIC (decl) = ! DECL_EXTERNAL (decl);
521618334Speter	  }
521718334Speter	/* Not at top level, only `static' makes a static definition.  */
521818334Speter	else
521918334Speter	  {
522018334Speter	    TREE_STATIC (decl) = (specbits & (1 << (int) RID_STATIC)) != 0;
522118334Speter	    TREE_PUBLIC (decl) = DECL_EXTERNAL (decl);
522218334Speter	  }
522318334Speter      }
522418334Speter
522518334Speter    /* Record `register' declaration for warnings on &
522618334Speter       and in case doing stupid register allocation.  */
522718334Speter
522818334Speter    if (specbits & (1 << (int) RID_REGISTER))
522918334Speter      DECL_REGISTER (decl) = 1;
523018334Speter
523118334Speter    /* Record constancy and volatility.  */
523252284Sobrien    c_apply_type_quals_to_decl (type_quals, decl);
523318334Speter
523418334Speter    /* If a type has volatile components, it should be stored in memory.
523518334Speter       Otherwise, the fact that those components are volatile
523618334Speter       will be ignored, and would even crash the compiler.  */
523718334Speter    if (C_TYPE_FIELDS_VOLATILE (TREE_TYPE (decl)))
523818334Speter      mark_addressable (decl);
523918334Speter
524090075Sobrien    decl_attributes (&decl, returned_attrs, 0);
524118334Speter
524218334Speter    return decl;
524318334Speter  }
524418334Speter}
524518334Speter
524618334Speter/* Decode the parameter-list info for a function type or function definition.
524718334Speter   The argument is the value returned by `get_parm_info' (or made in parse.y
524818334Speter   if there is an identifier list instead of a parameter decl list).
524918334Speter   These two functions are separate because when a function returns
525018334Speter   or receives functions then each is called multiple times but the order
525118334Speter   of calls is different.  The last call to `grokparms' is always the one
525218334Speter   that contains the formal parameter names of a function definition.
525318334Speter
525418334Speter   Store in `last_function_parms' a chain of the decls of parms.
525518334Speter   Also store in `last_function_parm_tags' a chain of the struct, union,
525618334Speter   and enum tags declared among the parms.
525718334Speter
525818334Speter   Return a list of arg types to use in the FUNCTION_TYPE for this function.
525918334Speter
526018334Speter   FUNCDEF_FLAG is nonzero for a function definition, 0 for
526118334Speter   a mere declaration.  A nonempty identifier-list gets an error message
526218334Speter   when FUNCDEF_FLAG is zero.  */
526318334Speter
526418334Speterstatic tree
526518334Spetergrokparms (parms_info, funcdef_flag)
526618334Speter     tree parms_info;
526718334Speter     int funcdef_flag;
526818334Speter{
526918334Speter  tree first_parm = TREE_CHAIN (parms_info);
527018334Speter
527118334Speter  last_function_parms = TREE_PURPOSE (parms_info);
527218334Speter  last_function_parm_tags = TREE_VALUE (parms_info);
527318334Speter
527418334Speter  if (warn_strict_prototypes && first_parm == 0 && !funcdef_flag
527518334Speter      && !in_system_header)
527618334Speter    warning ("function declaration isn't a prototype");
527718334Speter
527818334Speter  if (first_parm != 0
527918334Speter      && TREE_CODE (TREE_VALUE (first_parm)) == IDENTIFIER_NODE)
528018334Speter    {
528118334Speter      if (! funcdef_flag)
528218334Speter	pedwarn ("parameter names (without types) in function declaration");
528318334Speter
528418334Speter      last_function_parms = first_parm;
528518334Speter      return 0;
528618334Speter    }
528718334Speter  else
528818334Speter    {
528918334Speter      tree parm;
529018334Speter      tree typelt;
529118334Speter      /* We no longer test FUNCDEF_FLAG.
529218334Speter	 If the arg types are incomplete in a declaration,
529318334Speter	 they must include undefined tags.
529418334Speter	 These tags can never be defined in the scope of the declaration,
529518334Speter	 so the types can never be completed,
529618334Speter	 and no call can be compiled successfully.  */
529718334Speter#if 0
529818334Speter      /* In a fcn definition, arg types must be complete.  */
529918334Speter      if (funcdef_flag)
530018334Speter#endif
530118334Speter	for (parm = last_function_parms, typelt = first_parm;
530218334Speter	     parm;
530318334Speter	     parm = TREE_CHAIN (parm))
530418334Speter	  /* Skip over any enumeration constants declared here.  */
530518334Speter	  if (TREE_CODE (parm) == PARM_DECL)
530618334Speter	    {
530718334Speter	      /* Barf if the parameter itself has an incomplete type.  */
530818334Speter	      tree type = TREE_VALUE (typelt);
530990075Sobrien	      if (type == error_mark_node)
531090075Sobrien		continue;
531190075Sobrien	      if (!COMPLETE_TYPE_P (type))
531218334Speter		{
531318334Speter		  if (funcdef_flag && DECL_NAME (parm) != 0)
531418334Speter		    error ("parameter `%s' has incomplete type",
531518334Speter			   IDENTIFIER_POINTER (DECL_NAME (parm)));
531618334Speter		  else
531718334Speter		    warning ("parameter has incomplete type");
531818334Speter		  if (funcdef_flag)
531918334Speter		    {
532018334Speter		      TREE_VALUE (typelt) = error_mark_node;
532118334Speter		      TREE_TYPE (parm) = error_mark_node;
532218334Speter		    }
532318334Speter		}
532490075Sobrien#if 0
532590075Sobrien	      /* This has been replaced by parm_tags_warning, which
532690075Sobrien		 uses a more accurate criterion for what to warn
532790075Sobrien		 about.  */
532818334Speter	      else
532918334Speter		{
533018334Speter		  /* Now warn if is a pointer to an incomplete type.  */
533118334Speter		  while (TREE_CODE (type) == POINTER_TYPE
533218334Speter			 || TREE_CODE (type) == REFERENCE_TYPE)
533318334Speter		    type = TREE_TYPE (type);
533418334Speter		  type = TYPE_MAIN_VARIANT (type);
533590075Sobrien		  if (!COMPLETE_TYPE_P (type))
533618334Speter		    {
533718334Speter		      if (DECL_NAME (parm) != 0)
533818334Speter			warning ("parameter `%s' points to incomplete type",
533918334Speter				 IDENTIFIER_POINTER (DECL_NAME (parm)));
534018334Speter		      else
534118334Speter			warning ("parameter points to incomplete type");
534218334Speter		    }
534318334Speter		}
534418334Speter#endif
534518334Speter	      typelt = TREE_CHAIN (typelt);
534618334Speter	    }
534718334Speter
534890075Sobrien      return first_parm;
534918334Speter    }
535018334Speter}
535118334Speter
535218334Speter/* Return a tree_list node with info on a parameter list just parsed.
535318334Speter   The TREE_PURPOSE is a chain of decls of those parms.
535418334Speter   The TREE_VALUE is a list of structure, union and enum tags defined.
535518334Speter   The TREE_CHAIN is a list of argument types to go in the FUNCTION_TYPE.
535618334Speter   This tree_list node is later fed to `grokparms'.
535718334Speter
535818334Speter   VOID_AT_END nonzero means append `void' to the end of the type-list.
535918334Speter   Zero means the parmlist ended with an ellipsis so don't append `void'.  */
536018334Speter
536118334Spetertree
536218334Speterget_parm_info (void_at_end)
536318334Speter     int void_at_end;
536418334Speter{
536590075Sobrien  tree decl, t;
536690075Sobrien  tree types = 0;
536718334Speter  int erred = 0;
536818334Speter  tree tags = gettags ();
536918334Speter  tree parms = getdecls ();
537018334Speter  tree new_parms = 0;
537118334Speter  tree order = current_binding_level->parm_order;
537218334Speter
537390075Sobrien  /* Just `void' (and no ellipsis) is special.  There are really no parms.
537490075Sobrien     But if the `void' is qualified (by `const' or `volatile') or has a
537590075Sobrien     storage class specifier (`register'), then the behavior is undefined;
537690075Sobrien     by not counting it as the special case of `void' we will cause an
537790075Sobrien     error later.  Typedefs for `void' are OK (see DR#157).  */
537818334Speter  if (void_at_end && parms != 0
537918334Speter      && TREE_CHAIN (parms) == 0
538090075Sobrien      && VOID_TYPE_P (TREE_TYPE (parms))
538190075Sobrien      && ! TREE_THIS_VOLATILE (parms)
538290075Sobrien      && ! TREE_READONLY (parms)
538390075Sobrien      && ! DECL_REGISTER (parms)
538418334Speter      && DECL_NAME (parms) == 0)
538518334Speter    {
538618334Speter      parms = NULL_TREE;
538718334Speter      storedecls (NULL_TREE);
538890075Sobrien      return tree_cons (NULL_TREE, NULL_TREE,
538990075Sobrien			tree_cons (NULL_TREE, void_type_node, NULL_TREE));
539018334Speter    }
539118334Speter
539218334Speter  /* Extract enumerator values and other non-parms declared with the parms.
539318334Speter     Likewise any forward parm decls that didn't have real parm decls.  */
539490075Sobrien  for (decl = parms; decl;)
539518334Speter    {
539618334Speter      tree next = TREE_CHAIN (decl);
539718334Speter
539818334Speter      if (TREE_CODE (decl) != PARM_DECL)
539918334Speter	{
540018334Speter	  TREE_CHAIN (decl) = new_parms;
540118334Speter	  new_parms = decl;
540218334Speter	}
540318334Speter      else if (TREE_ASM_WRITTEN (decl))
540418334Speter	{
540590075Sobrien	  error_with_decl (decl,
540690075Sobrien			   "parameter `%s' has just a forward declaration");
540718334Speter	  TREE_CHAIN (decl) = new_parms;
540818334Speter	  new_parms = decl;
540918334Speter	}
541018334Speter      decl = next;
541118334Speter    }
541218334Speter
541318334Speter  /* Put the parm decls back in the order they were in in the parm list.  */
541418334Speter  for (t = order; t; t = TREE_CHAIN (t))
541518334Speter    {
541618334Speter      if (TREE_CHAIN (t))
541718334Speter	TREE_CHAIN (TREE_VALUE (t)) = TREE_VALUE (TREE_CHAIN (t));
541818334Speter      else
541918334Speter	TREE_CHAIN (TREE_VALUE (t)) = 0;
542018334Speter    }
542118334Speter
542218334Speter  new_parms = chainon (order ? nreverse (TREE_VALUE (order)) : 0,
542318334Speter		       new_parms);
542418334Speter
542518334Speter  /* Store the parmlist in the binding level since the old one
542618334Speter     is no longer a valid list.  (We have changed the chain pointers.)  */
542718334Speter  storedecls (new_parms);
542818334Speter
542918334Speter  for (decl = new_parms; decl; decl = TREE_CHAIN (decl))
543018334Speter    /* There may also be declarations for enumerators if an enumeration
543118334Speter       type is declared among the parms.  Ignore them here.  */
543218334Speter    if (TREE_CODE (decl) == PARM_DECL)
543318334Speter      {
543418334Speter	/* Since there is a prototype,
543518334Speter	   args are passed in their declared types.  */
543618334Speter	tree type = TREE_TYPE (decl);
543718334Speter	DECL_ARG_TYPE (decl) = type;
543890075Sobrien	if (PROMOTE_PROTOTYPES
543990075Sobrien	    && INTEGRAL_TYPE_P (type)
544018334Speter	    && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))
544118334Speter	  DECL_ARG_TYPE (decl) = integer_type_node;
544218334Speter
544390075Sobrien	types = tree_cons (NULL_TREE, TREE_TYPE (decl), types);
544490075Sobrien	if (VOID_TYPE_P (TREE_VALUE (types)) && ! erred
544518334Speter	    && DECL_NAME (decl) == 0)
544618334Speter	  {
544718334Speter	    error ("`void' in parameter list must be the entire list");
544818334Speter	    erred = 1;
544918334Speter	  }
545018334Speter      }
545118334Speter
545218334Speter  if (void_at_end)
545390075Sobrien    return tree_cons (new_parms, tags,
545490075Sobrien		      nreverse (tree_cons (NULL_TREE, void_type_node, types)));
545518334Speter
545690075Sobrien  return tree_cons (new_parms, tags, nreverse (types));
545718334Speter}
545818334Speter
545918334Speter/* At end of parameter list, warn about any struct, union or enum tags
546018334Speter   defined within.  Do so because these types cannot ever become complete.  */
546118334Speter
546218334Spetervoid
546318334Speterparmlist_tags_warning ()
546418334Speter{
546518334Speter  tree elt;
546618334Speter  static int already;
546718334Speter
546818334Speter  for (elt = current_binding_level->tags; elt; elt = TREE_CHAIN (elt))
546918334Speter    {
547018334Speter      enum tree_code code = TREE_CODE (TREE_VALUE (elt));
547118334Speter      /* An anonymous union parm type is meaningful as a GNU extension.
547218334Speter	 So don't warn for that.  */
547350397Sobrien      if (code == UNION_TYPE && TREE_PURPOSE (elt) == 0 && !pedantic)
547418334Speter	continue;
547518334Speter      if (TREE_PURPOSE (elt) != 0)
547690075Sobrien        {
547790075Sobrien          if (code == RECORD_TYPE)
547890075Sobrien            warning ("`struct %s' declared inside parameter list",
547990075Sobrien                     IDENTIFIER_POINTER (TREE_PURPOSE (elt)));
548090075Sobrien          else if (code == UNION_TYPE)
548190075Sobrien            warning ("`union %s' declared inside parameter list",
548290075Sobrien                     IDENTIFIER_POINTER (TREE_PURPOSE (elt)));
548390075Sobrien          else
548490075Sobrien            warning ("`enum %s' declared inside parameter list",
548590075Sobrien                     IDENTIFIER_POINTER (TREE_PURPOSE (elt)));
548690075Sobrien        }
548718334Speter      else
548890075Sobrien	{
548990075Sobrien	  /* For translation these need to be separate warnings */
549090075Sobrien	  if (code == RECORD_TYPE)
549190075Sobrien	    warning ("anonymous struct declared inside parameter list");
549290075Sobrien	  else if (code == UNION_TYPE)
549390075Sobrien	    warning ("anonymous union declared inside parameter list");
549490075Sobrien	  else
549590075Sobrien	    warning ("anonymous enum declared inside parameter list");
549690075Sobrien	}
549718334Speter      if (! already)
549818334Speter	{
549990075Sobrien	  warning ("its scope is only this definition or declaration, which is probably not what you want");
550018334Speter	  already = 1;
550118334Speter	}
550218334Speter    }
550318334Speter}
550418334Speter
550518334Speter/* Get the struct, enum or union (CODE says which) with tag NAME.
550618334Speter   Define the tag as a forward-reference if it is not defined.  */
550718334Speter
550818334Spetertree
550918334Speterxref_tag (code, name)
551018334Speter     enum tree_code code;
551118334Speter     tree name;
551218334Speter{
551318334Speter  /* If a cross reference is requested, look up the type
551418334Speter     already defined for this tag and return it.  */
551518334Speter
551690075Sobrien  tree ref = lookup_tag (code, name, current_binding_level, 0);
551790075Sobrien  /* If this is the right type of tag, return what we found.
551890075Sobrien     (This reference will be shadowed by shadow_tag later if appropriate.)
551990075Sobrien     If this is the wrong type of tag, do not return it.  If it was the
552090075Sobrien     wrong type in the same binding level, we will have had an error
552190075Sobrien     message already; if in a different binding level and declaring
552290075Sobrien     a name, pending_xref_error will give an error message; but if in a
552390075Sobrien     different binding level and not declaring a name, this tag should
552490075Sobrien     shadow the previous declaration of a different type of tag, and
552590075Sobrien     this would not work properly if we return the reference found.
552690075Sobrien     (For example, with "struct foo" in an outer scope, "union foo;"
552790075Sobrien     must shadow that tag with a new one of union type.)  */
552890075Sobrien  if (ref && TREE_CODE (ref) == code)
552918334Speter    return ref;
553018334Speter
553118334Speter  /* If no such tag is yet defined, create a forward-reference node
553218334Speter     and record it as the "definition".
553318334Speter     When a real declaration of this type is found,
553418334Speter     the forward-reference will be altered into a real type.  */
553518334Speter
553618334Speter  ref = make_node (code);
553718334Speter  if (code == ENUMERAL_TYPE)
553818334Speter    {
553918334Speter      /* Give the type a default layout like unsigned int
554018334Speter	 to avoid crashing if it does not get defined.  */
554118334Speter      TYPE_MODE (ref) = TYPE_MODE (unsigned_type_node);
554218334Speter      TYPE_ALIGN (ref) = TYPE_ALIGN (unsigned_type_node);
554390075Sobrien      TYPE_USER_ALIGN (ref) = 0;
554418334Speter      TREE_UNSIGNED (ref) = 1;
554518334Speter      TYPE_PRECISION (ref) = TYPE_PRECISION (unsigned_type_node);
554618334Speter      TYPE_MIN_VALUE (ref) = TYPE_MIN_VALUE (unsigned_type_node);
554718334Speter      TYPE_MAX_VALUE (ref) = TYPE_MAX_VALUE (unsigned_type_node);
554818334Speter    }
554918334Speter
555018334Speter  pushtag (name, ref);
555118334Speter
555218334Speter  return ref;
555318334Speter}
555418334Speter
555518334Speter/* Make sure that the tag NAME is defined *in the current binding level*
555618334Speter   at least as a forward reference.
555790075Sobrien   CODE says which kind of tag NAME ought to be.  */
555818334Speter
555918334Spetertree
556018334Speterstart_struct (code, name)
556118334Speter     enum tree_code code;
556218334Speter     tree name;
556318334Speter{
556418334Speter  /* If there is already a tag defined at this binding level
556518334Speter     (as a forward reference), just return it.  */
556618334Speter
556790075Sobrien  tree ref = 0;
556818334Speter
556918334Speter  if (name != 0)
557018334Speter    ref = lookup_tag (code, name, current_binding_level, 1);
557118334Speter  if (ref && TREE_CODE (ref) == code)
557218334Speter    {
557318334Speter      C_TYPE_BEING_DEFINED (ref) = 1;
557450397Sobrien      TYPE_PACKED (ref) = flag_pack_struct;
557518334Speter      if (TYPE_FIELDS (ref))
557690075Sobrien        {
557790075Sobrien	  if (code == UNION_TYPE)
557890075Sobrien	    error ("redefinition of `union %s'",
557990075Sobrien		   IDENTIFIER_POINTER (name));
558090075Sobrien          else
558190075Sobrien	    error ("redefinition of `struct %s'",
558290075Sobrien		   IDENTIFIER_POINTER (name));
558390075Sobrien	}
558418334Speter
558518334Speter      return ref;
558618334Speter    }
558718334Speter
558818334Speter  /* Otherwise create a forward-reference just so the tag is in scope.  */
558918334Speter
559018334Speter  ref = make_node (code);
559118334Speter  pushtag (name, ref);
559218334Speter  C_TYPE_BEING_DEFINED (ref) = 1;
559350397Sobrien  TYPE_PACKED (ref) = flag_pack_struct;
559418334Speter  return ref;
559518334Speter}
559618334Speter
559718334Speter/* Process the specs, declarator (NULL if omitted) and width (NULL if omitted)
559818334Speter   of a structure component, returning a FIELD_DECL node.
559996263Sobrien   WIDTH is non-NULL for bit fields only, and is an INTEGER_CST node.
560018334Speter
560118334Speter   This is done during the parsing of the struct declaration.
560218334Speter   The FIELD_DECL nodes are chained together and the lot of them
560318334Speter   are ultimately passed to `build_struct' to make the RECORD_TYPE node.  */
560418334Speter
560518334Spetertree
560618334Spetergrokfield (filename, line, declarator, declspecs, width)
560752284Sobrien     const char *filename ATTRIBUTE_UNUSED;
560852284Sobrien     int line ATTRIBUTE_UNUSED;
560918334Speter     tree declarator, declspecs, width;
561018334Speter{
561118334Speter  tree value;
561218334Speter
561390075Sobrien  if (declarator == NULL_TREE && width == NULL_TREE)
561490075Sobrien    {
561590075Sobrien      /* This is an unnamed decl.  We only support unnamed
561690075Sobrien	 structs/unions, so check for other things and refuse them.  */
561790075Sobrien      if (TREE_CODE (TREE_VALUE (declspecs)) != RECORD_TYPE
561890075Sobrien	  && TREE_CODE (TREE_VALUE (declspecs)) != UNION_TYPE)
561990075Sobrien	{
562090075Sobrien	  error ("unnamed fields of type other than struct or union are not allowed");
562190075Sobrien	  return NULL_TREE;
562290075Sobrien	}
562390075Sobrien    }
562418334Speter
562596263Sobrien  value = grokdeclarator (declarator, declspecs, width ? BITFIELD : FIELD, 0);
562618334Speter
562718334Speter  finish_decl (value, NULL_TREE, NULL_TREE);
562896263Sobrien  DECL_INITIAL (value) = width;
562918334Speter
563018334Speter  maybe_objc_check_decl (value);
563118334Speter  return value;
563218334Speter}
563318334Speter
563418334Speter/* Fill in the fields of a RECORD_TYPE or UNION_TYPE node, T.
563518334Speter   FIELDLIST is a chain of FIELD_DECL nodes for the fields.
563690075Sobrien   ATTRIBUTES are attributes to be applied to the structure.  */
563718334Speter
563818334Spetertree
563918334Speterfinish_struct (t, fieldlist, attributes)
564018334Speter     tree t;
564118334Speter     tree fieldlist;
564218334Speter     tree attributes;
564318334Speter{
564490075Sobrien  tree x;
564518334Speter  int toplevel = global_binding_level == current_binding_level;
564690075Sobrien  int saw_named_field;
564718334Speter
564818334Speter  /* If this type was previously laid out as a forward reference,
564918334Speter     make sure we lay it out again.  */
565018334Speter
565118334Speter  TYPE_SIZE (t) = 0;
565218334Speter
565390075Sobrien  decl_attributes (&t, attributes, (int) ATTR_FLAG_TYPE_IN_PLACE);
565418334Speter
565518334Speter  /* Nameless union parm types are useful as GCC extension.  */
565618334Speter  if (! (TREE_CODE (t) == UNION_TYPE && TYPE_NAME (t) == 0) && !pedantic)
565718334Speter    /* Otherwise, warn about any struct or union def. in parmlist.  */
565818334Speter    if (in_parm_level_p ())
565918334Speter      {
566018334Speter	if (pedantic)
566190075Sobrien	  pedwarn ("%s defined inside parms",
566290075Sobrien		   TREE_CODE (t) == UNION_TYPE ? _("union") : _("structure"));
566318334Speter	else if (! flag_traditional)
566490075Sobrien	  warning ("%s defined inside parms",
566590075Sobrien		   TREE_CODE (t) == UNION_TYPE ? _("union") : _("structure"));
566618334Speter      }
566718334Speter
566850397Sobrien  if (pedantic)
566950397Sobrien    {
567050397Sobrien      for (x = fieldlist; x; x = TREE_CHAIN (x))
567150397Sobrien	if (DECL_NAME (x) != 0)
567250397Sobrien	  break;
567318334Speter
567450397Sobrien      if (x == 0)
567590075Sobrien	pedwarn ("%s has no %s",
567690075Sobrien		 TREE_CODE (t) == UNION_TYPE ? _("union") : _("struct"),
567790075Sobrien		 fieldlist ? _("named members") : _("members"));
567850397Sobrien    }
567950397Sobrien
568096263Sobrien  /* Install struct as DECL_CONTEXT of each field decl.
568196263Sobrien     Also process specified field sizes,m which is found in the DECL_INITIAL.
568296263Sobrien     Store 0 there, except for ": 0" fields (so we can find them
568396263Sobrien     and delete them, below).  */
568418334Speter
568590075Sobrien  saw_named_field = 0;
568618334Speter  for (x = fieldlist; x; x = TREE_CHAIN (x))
568718334Speter    {
568818334Speter      DECL_CONTEXT (x) = t;
568918334Speter      DECL_PACKED (x) |= TYPE_PACKED (t);
569018334Speter
569118334Speter      /* If any field is const, the structure type is pseudo-const.  */
569218334Speter      if (TREE_READONLY (x))
569318334Speter	C_TYPE_FIELDS_READONLY (t) = 1;
569418334Speter      else
569518334Speter	{
569618334Speter	  /* A field that is pseudo-const makes the structure likewise.  */
569718334Speter	  tree t1 = TREE_TYPE (x);
569818334Speter	  while (TREE_CODE (t1) == ARRAY_TYPE)
569918334Speter	    t1 = TREE_TYPE (t1);
570018334Speter	  if ((TREE_CODE (t1) == RECORD_TYPE || TREE_CODE (t1) == UNION_TYPE)
570118334Speter	      && C_TYPE_FIELDS_READONLY (t1))
570218334Speter	    C_TYPE_FIELDS_READONLY (t) = 1;
570318334Speter	}
570418334Speter
570518334Speter      /* Any field that is volatile means variables of this type must be
570618334Speter	 treated in some ways as volatile.  */
570718334Speter      if (TREE_THIS_VOLATILE (x))
570818334Speter	C_TYPE_FIELDS_VOLATILE (t) = 1;
570918334Speter
571018334Speter      /* Any field of nominal variable size implies structure is too.  */
571118334Speter      if (C_DECL_VARIABLE_SIZE (x))
571218334Speter	C_TYPE_VARIABLE_SIZE (t) = 1;
571318334Speter
571418334Speter      /* Detect invalid nested redefinition.  */
571518334Speter      if (TREE_TYPE (x) == t)
571618334Speter	error ("nested redefinition of `%s'",
571718334Speter	       IDENTIFIER_POINTER (TYPE_NAME (t)));
571818334Speter
571996263Sobrien      /* Detect invalid bit-field size.  */
572096263Sobrien      if (DECL_INITIAL (x))
572196263Sobrien	STRIP_NOPS (DECL_INITIAL (x));
572296263Sobrien      if (DECL_INITIAL (x))
572318334Speter	{
572496263Sobrien	  if (TREE_CODE (DECL_INITIAL (x)) == INTEGER_CST)
572596263Sobrien	    constant_expression_warning (DECL_INITIAL (x));
572696263Sobrien	  else
572796263Sobrien	    {
572896263Sobrien	      error_with_decl (x,
572996263Sobrien			       "bit-field `%s' width not an integer constant");
573096263Sobrien	      DECL_INITIAL (x) = NULL;
573196263Sobrien	    }
573296263Sobrien	}
573396263Sobrien
573496263Sobrien      /* Detect invalid bit-field type.  */
573596263Sobrien      if (DECL_INITIAL (x)
573696263Sobrien	  && TREE_CODE (TREE_TYPE (x)) != INTEGER_TYPE
573796263Sobrien	  && TREE_CODE (TREE_TYPE (x)) != BOOLEAN_TYPE
573896263Sobrien	  && TREE_CODE (TREE_TYPE (x)) != ENUMERAL_TYPE)
573996263Sobrien	{
574096263Sobrien	  error_with_decl (x, "bit-field `%s' has invalid type");
574196263Sobrien	  DECL_INITIAL (x) = NULL;
574296263Sobrien	}
574396263Sobrien
574496263Sobrien      if (DECL_INITIAL (x) && pedantic
574596263Sobrien	  && TYPE_MAIN_VARIANT (TREE_TYPE (x)) != integer_type_node
574696263Sobrien	  && TYPE_MAIN_VARIANT (TREE_TYPE (x)) != unsigned_type_node
574796263Sobrien	  && TYPE_MAIN_VARIANT (TREE_TYPE (x)) != c_bool_type_node
574896263Sobrien	  /* Accept an enum that's equivalent to int or unsigned int.  */
574996263Sobrien	  && !(TREE_CODE (TREE_TYPE (x)) == ENUMERAL_TYPE
575096263Sobrien	       && (TYPE_PRECISION (TREE_TYPE (x))
575196263Sobrien		   == TYPE_PRECISION (integer_type_node))))
575296263Sobrien	pedwarn_with_decl (x, "bit-field `%s' type invalid in ISO C");
575396263Sobrien
575496263Sobrien      /* Detect and ignore out of range field width and process valid
575596263Sobrien	 field widths.  */
575696263Sobrien      if (DECL_INITIAL (x))
575796263Sobrien	{
575896263Sobrien	  int max_width
575996263Sobrien	    = (TYPE_MAIN_VARIANT (TREE_TYPE (x)) == c_bool_type_node
576096263Sobrien	       ? CHAR_TYPE_SIZE : TYPE_PRECISION (TREE_TYPE (x)));
576196263Sobrien
576296263Sobrien	  if (tree_int_cst_sgn (DECL_INITIAL (x)) < 0)
576396263Sobrien	    error_with_decl (x, "negative width in bit-field `%s'");
576496263Sobrien	  else if (0 < compare_tree_int (DECL_INITIAL (x), max_width))
576596263Sobrien	    pedwarn_with_decl (x, "width of `%s' exceeds its type");
576696263Sobrien	  else if (integer_zerop (DECL_INITIAL (x)) && DECL_NAME (x) != 0)
576796263Sobrien	    error_with_decl (x, "zero width for bit-field `%s'");
576896263Sobrien	  else
576996263Sobrien	    {
577096263Sobrien	      /* The test above has assured us that TREE_INT_CST_HIGH is 0.  */
577196263Sobrien	      unsigned HOST_WIDE_INT width
577296263Sobrien		= tree_low_cst (DECL_INITIAL (x), 1);
577396263Sobrien
577496263Sobrien	      if (TREE_CODE (TREE_TYPE (x)) == ENUMERAL_TYPE
577596263Sobrien		  && (width < min_precision (TYPE_MIN_VALUE (TREE_TYPE (x)),
577696263Sobrien					     TREE_UNSIGNED (TREE_TYPE (x)))
577796263Sobrien		      || (width
577896263Sobrien			  < min_precision (TYPE_MAX_VALUE (TREE_TYPE (x)),
577996263Sobrien					   TREE_UNSIGNED (TREE_TYPE (x))))))
578096263Sobrien		warning_with_decl (x,
578196263Sobrien				   "`%s' is narrower than values of its type");
578296263Sobrien
578396263Sobrien	      DECL_SIZE (x) = bitsize_int (width);
578496263Sobrien	      DECL_BIT_FIELD (x) = 1;
578596263Sobrien	      SET_DECL_C_BIT_FIELD (x);
578696263Sobrien
578796263Sobrien	      if (width == 0
578896263Sobrien		  && ! (* targetm.ms_bitfield_layout_p) (t))
578996263Sobrien		{
579096263Sobrien		  /* field size 0 => force desired amount of alignment.  */
579196263Sobrien#ifdef EMPTY_FIELD_BOUNDARY
579296263Sobrien		  DECL_ALIGN (x) = MAX (DECL_ALIGN (x), EMPTY_FIELD_BOUNDARY);
579396263Sobrien#endif
579496263Sobrien#ifdef PCC_BITFIELD_TYPE_MATTERS
579596263Sobrien		  if (PCC_BITFIELD_TYPE_MATTERS)
579696263Sobrien		    {
579796263Sobrien		      DECL_ALIGN (x) = MAX (DECL_ALIGN (x),
579896263Sobrien					    TYPE_ALIGN (TREE_TYPE (x)));
579996263Sobrien		      DECL_USER_ALIGN (x) |= TYPE_USER_ALIGN (TREE_TYPE (x));
580096263Sobrien		    }
580196263Sobrien#endif
580296263Sobrien		}
580396263Sobrien	    }
580496263Sobrien	}
580596263Sobrien
580696263Sobrien      else if (TREE_TYPE (x) != error_mark_node)
580796263Sobrien	{
580890075Sobrien	  unsigned int min_align = (DECL_PACKED (x) ? BITS_PER_UNIT
580990075Sobrien				    : TYPE_ALIGN (TREE_TYPE (x)));
581018334Speter
581190075Sobrien	  /* Non-bit-fields are aligned for their type, except packed
581290075Sobrien	     fields which require only BITS_PER_UNIT alignment.  */
581390075Sobrien	  DECL_ALIGN (x) = MAX (DECL_ALIGN (x), min_align);
581490075Sobrien	  if (! DECL_PACKED (x))
581590075Sobrien	    DECL_USER_ALIGN (x) |= TYPE_USER_ALIGN (TREE_TYPE (x));
581618334Speter	}
581718334Speter
581896263Sobrien      DECL_INITIAL (x) = 0;
581996263Sobrien
582090075Sobrien      /* Detect flexible array member in an invalid context.  */
582190075Sobrien      if (TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE
582290075Sobrien	  && TYPE_SIZE (TREE_TYPE (x)) == NULL_TREE
582390075Sobrien	  && TYPE_DOMAIN (TREE_TYPE (x)) != NULL_TREE
582490075Sobrien	  && TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (x))) == NULL_TREE)
582518334Speter	{
582690075Sobrien	  if (TREE_CODE (t) == UNION_TYPE)
582790075Sobrien	    error_with_decl (x, "flexible array member in union");
582890075Sobrien	  else if (TREE_CHAIN (x) != NULL_TREE)
582990075Sobrien	    error_with_decl (x, "flexible array member not at end of struct");
583090075Sobrien	  else if (! saw_named_field)
583190075Sobrien	    error_with_decl (x, "flexible array member in otherwise empty struct");
583218334Speter	}
583390075Sobrien      if (DECL_NAME (x))
583490075Sobrien	saw_named_field = 1;
583518334Speter    }
583618334Speter
583718334Speter  /* Delete all duplicate fields from the fieldlist */
583818334Speter  for (x = fieldlist; x && TREE_CHAIN (x);)
583918334Speter    /* Anonymous fields aren't duplicates.  */
584018334Speter    if (DECL_NAME (TREE_CHAIN (x)) == 0)
584118334Speter      x = TREE_CHAIN (x);
584218334Speter    else
584318334Speter      {
584490075Sobrien	tree y = fieldlist;
584590075Sobrien
584618334Speter	while (1)
584718334Speter	  {
584818334Speter	    if (DECL_NAME (y) == DECL_NAME (TREE_CHAIN (x)))
584918334Speter	      break;
585018334Speter	    if (y == x)
585118334Speter	      break;
585218334Speter	    y = TREE_CHAIN (y);
585318334Speter	  }
585418334Speter	if (DECL_NAME (y) == DECL_NAME (TREE_CHAIN (x)))
585518334Speter	  {
585618334Speter	    error_with_decl (TREE_CHAIN (x), "duplicate member `%s'");
585718334Speter	    TREE_CHAIN (x) = TREE_CHAIN (TREE_CHAIN (x));
585818334Speter	  }
585990075Sobrien	else
586090075Sobrien	  x = TREE_CHAIN (x);
586118334Speter      }
586218334Speter
586318334Speter  /* Now we have the nearly final fieldlist.  Record it,
586418334Speter     then lay out the structure or union (including the fields).  */
586518334Speter
586618334Speter  TYPE_FIELDS (t) = fieldlist;
586718334Speter
586818334Speter  layout_type (t);
586918334Speter
587090075Sobrien  /* Delete all zero-width bit-fields from the fieldlist */
587190075Sobrien  {
587290075Sobrien    tree *fieldlistp = &fieldlist;
587390075Sobrien    while (*fieldlistp)
587490075Sobrien      if (TREE_CODE (*fieldlistp) == FIELD_DECL && DECL_INITIAL (*fieldlistp))
587590075Sobrien	*fieldlistp = TREE_CHAIN (*fieldlistp);
587690075Sobrien      else
587790075Sobrien	fieldlistp = &TREE_CHAIN (*fieldlistp);
587890075Sobrien  }
587918334Speter
588090075Sobrien  /* Now we have the truly final field list.
588190075Sobrien     Store it in this type and in the variants.  */
588218334Speter
588318334Speter  TYPE_FIELDS (t) = fieldlist;
588418334Speter
588518334Speter  for (x = TYPE_MAIN_VARIANT (t); x; x = TYPE_NEXT_VARIANT (x))
588618334Speter    {
588718334Speter      TYPE_FIELDS (x) = TYPE_FIELDS (t);
588818334Speter      TYPE_LANG_SPECIFIC (x) = TYPE_LANG_SPECIFIC (t);
588918334Speter      TYPE_ALIGN (x) = TYPE_ALIGN (t);
589090075Sobrien      TYPE_USER_ALIGN (x) = TYPE_USER_ALIGN (t);
589118334Speter    }
589218334Speter
589318334Speter  /* If this was supposed to be a transparent union, but we can't
589418334Speter     make it one, warn and turn off the flag.  */
589518334Speter  if (TREE_CODE (t) == UNION_TYPE
589618334Speter      && TYPE_TRANSPARENT_UNION (t)
589718334Speter      && TYPE_MODE (t) != DECL_MODE (TYPE_FIELDS (t)))
589818334Speter    {
589918334Speter      TYPE_TRANSPARENT_UNION (t) = 0;
590050397Sobrien      warning ("union cannot be made transparent");
590118334Speter    }
590218334Speter
590318334Speter  /* If this structure or union completes the type of any previous
590418334Speter     variable declaration, lay it out and output its rtl.  */
590518334Speter
590618334Speter  if (current_binding_level->n_incomplete != 0)
590718334Speter    {
590818334Speter      tree decl;
590918334Speter      for (decl = current_binding_level->names; decl; decl = TREE_CHAIN (decl))
591018334Speter	{
591190075Sobrien	  if (TYPE_MAIN_VARIANT (TREE_TYPE (decl)) == TYPE_MAIN_VARIANT (t)
591218334Speter	      && TREE_CODE (decl) != TYPE_DECL)
591318334Speter	    {
591418334Speter	      layout_decl (decl, 0);
591518334Speter	      /* This is a no-op in c-lang.c or something real in objc-actions.c.  */
591618334Speter	      maybe_objc_check_decl (decl);
591790075Sobrien	      rest_of_decl_compilation (decl, NULL, toplevel, 0);
591818334Speter	      if (! toplevel)
591918334Speter		expand_decl (decl);
592090075Sobrien	      if (--current_binding_level->n_incomplete == 0)
592190075Sobrien		break;
592218334Speter	    }
592390075Sobrien	  else if (!COMPLETE_TYPE_P (TREE_TYPE (decl))
592418334Speter		   && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
592518334Speter	    {
592618334Speter	      tree element = TREE_TYPE (decl);
592718334Speter	      while (TREE_CODE (element) == ARRAY_TYPE)
592818334Speter		element = TREE_TYPE (element);
592918334Speter	      if (element == t)
593090075Sobrien		{
593190075Sobrien		  layout_array_type (TREE_TYPE (decl));
593290075Sobrien		  if (TREE_CODE (decl) != TYPE_DECL)
593390075Sobrien		    {
593490075Sobrien		      layout_decl (decl, 0);
593590075Sobrien		      maybe_objc_check_decl (decl);
593690075Sobrien		      rest_of_decl_compilation (decl, NULL, toplevel, 0);
593790075Sobrien		      if (! toplevel)
593890075Sobrien			expand_decl (decl);
593990075Sobrien		    }
594090075Sobrien		  if (--current_binding_level->n_incomplete == 0)
594190075Sobrien		    break;
594290075Sobrien		}
594318334Speter	    }
594418334Speter	}
594518334Speter    }
594618334Speter
594718334Speter  /* Finish debugging output for this type.  */
594818334Speter  rest_of_type_compilation (t, toplevel);
594918334Speter
595018334Speter  return t;
595118334Speter}
595218334Speter
595318334Speter/* Lay out the type T, and its element type, and so on.  */
595418334Speter
595518334Speterstatic void
595618334Speterlayout_array_type (t)
595718334Speter     tree t;
595818334Speter{
595918334Speter  if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
596018334Speter    layout_array_type (TREE_TYPE (t));
596118334Speter  layout_type (t);
596218334Speter}
596318334Speter
596418334Speter/* Begin compiling the definition of an enumeration type.
596518334Speter   NAME is its name (or null if anonymous).
596618334Speter   Returns the type object, as yet incomplete.
596718334Speter   Also records info about it so that build_enumerator
596818334Speter   may be used to declare the individual values as they are read.  */
596918334Speter
597018334Spetertree
597118334Speterstart_enum (name)
597218334Speter     tree name;
597318334Speter{
597490075Sobrien  tree enumtype = 0;
597518334Speter
597618334Speter  /* If this is the real definition for a previous forward reference,
597718334Speter     fill in the contents in the same object that used to be the
597818334Speter     forward reference.  */
597918334Speter
598018334Speter  if (name != 0)
598118334Speter    enumtype = lookup_tag (ENUMERAL_TYPE, name, current_binding_level, 1);
598218334Speter
598318334Speter  if (enumtype == 0 || TREE_CODE (enumtype) != ENUMERAL_TYPE)
598418334Speter    {
598518334Speter      enumtype = make_node (ENUMERAL_TYPE);
598618334Speter      pushtag (name, enumtype);
598718334Speter    }
598818334Speter
598918334Speter  C_TYPE_BEING_DEFINED (enumtype) = 1;
599018334Speter
599118334Speter  if (TYPE_VALUES (enumtype) != 0)
599218334Speter    {
599318334Speter      /* This enum is a named one that has been declared already.  */
599418334Speter      error ("redeclaration of `enum %s'", IDENTIFIER_POINTER (name));
599518334Speter
599618334Speter      /* Completely replace its old definition.
599718334Speter	 The old enumerators remain defined, however.  */
599818334Speter      TYPE_VALUES (enumtype) = 0;
599918334Speter    }
600018334Speter
600118334Speter  enum_next_value = integer_zero_node;
600218334Speter  enum_overflow = 0;
600318334Speter
600450397Sobrien  if (flag_short_enums)
600550397Sobrien    TYPE_PACKED (enumtype) = 1;
600650397Sobrien
600718334Speter  return enumtype;
600818334Speter}
600918334Speter
601018334Speter/* After processing and defining all the values of an enumeration type,
601118334Speter   install their decls in the enumeration type and finish it off.
601218334Speter   ENUMTYPE is the type object, VALUES a list of decl-value pairs,
601318334Speter   and ATTRIBUTES are the specified attributes.
601418334Speter   Returns ENUMTYPE.  */
601518334Speter
601618334Spetertree
601718334Speterfinish_enum (enumtype, values, attributes)
601818334Speter     tree enumtype;
601918334Speter     tree values;
602018334Speter     tree attributes;
602118334Speter{
602290075Sobrien  tree pair, tem;
602390075Sobrien  tree minnode = 0, maxnode = 0, enum_value_type;
602490075Sobrien  int precision, unsign;
602590075Sobrien  int toplevel = (global_binding_level == current_binding_level);
602618334Speter
602718334Speter  if (in_parm_level_p ())
602818334Speter    warning ("enum defined inside parms");
602918334Speter
603090075Sobrien  decl_attributes (&enumtype, attributes, (int) ATTR_FLAG_TYPE_IN_PLACE);
603118334Speter
603218334Speter  /* Calculate the maximum value of any enumerator in this type.  */
603318334Speter
603418334Speter  if (values == error_mark_node)
603518334Speter    minnode = maxnode = integer_zero_node;
603618334Speter  else
603790075Sobrien    {
603890075Sobrien      minnode = maxnode = TREE_VALUE (values);
603990075Sobrien      for (pair = TREE_CHAIN (values); pair; pair = TREE_CHAIN (pair))
604090075Sobrien	{
604190075Sobrien	  tree value = TREE_VALUE (pair);
604290075Sobrien	  if (tree_int_cst_lt (maxnode, value))
604390075Sobrien	    maxnode = value;
604490075Sobrien	  if (tree_int_cst_lt (value, minnode))
604590075Sobrien	    minnode = value;
604690075Sobrien	}
604790075Sobrien    }
604818334Speter
604990075Sobrien  /* Construct the final type of this enumeration.  It is the same
605090075Sobrien     as one of the integral types - the narrowest one that fits, except
605190075Sobrien     that normally we only go as narrow as int - and signed iff any of
605290075Sobrien     the values are negative.  */
605390075Sobrien  unsign = (tree_int_cst_sgn (minnode) >= 0);
605490075Sobrien  precision = MAX (min_precision (minnode, unsign),
605590075Sobrien		   min_precision (maxnode, unsign));
605650397Sobrien  if (TYPE_PACKED (enumtype) || precision > TYPE_PRECISION (integer_type_node))
605750397Sobrien    {
605890075Sobrien      tree narrowest = type_for_size (precision, unsign);
605950397Sobrien      if (narrowest == 0)
606050397Sobrien	{
606150397Sobrien	  warning ("enumeration values exceed range of largest integer");
606250397Sobrien	  narrowest = long_long_integer_type_node;
606350397Sobrien	}
606450397Sobrien
606590075Sobrien      precision = TYPE_PRECISION (narrowest);
606650397Sobrien    }
606718334Speter  else
606890075Sobrien    precision = TYPE_PRECISION (integer_type_node);
606918334Speter
607090075Sobrien  if (precision == TYPE_PRECISION (integer_type_node))
607190075Sobrien    enum_value_type = type_for_size (precision, 0);
607290075Sobrien  else
607390075Sobrien    enum_value_type = enumtype;
607490075Sobrien
607590075Sobrien  TYPE_MIN_VALUE (enumtype) = minnode;
607690075Sobrien  TYPE_MAX_VALUE (enumtype) = maxnode;
607790075Sobrien  TYPE_PRECISION (enumtype) = precision;
607890075Sobrien  TREE_UNSIGNED (enumtype) = unsign;
607918334Speter  TYPE_SIZE (enumtype) = 0;
608018334Speter  layout_type (enumtype);
608118334Speter
608218334Speter  if (values != error_mark_node)
608318334Speter    {
608490075Sobrien      /* Change the type of the enumerators to be the enum type.  We
608590075Sobrien	 need to do this irrespective of the size of the enum, for
608690075Sobrien	 proper type checking.  Replace the DECL_INITIALs of the
608790075Sobrien	 enumerators, and the value slots of the list, with copies
608890075Sobrien	 that have the enum type; they cannot be modified in place
608990075Sobrien	 because they may be shared (e.g.  integer_zero_node) Finally,
609090075Sobrien	 change the purpose slots to point to the names of the decls.  */
609118334Speter      for (pair = values; pair; pair = TREE_CHAIN (pair))
609218334Speter	{
609390075Sobrien	  tree enu = TREE_PURPOSE (pair);
609490075Sobrien
609590075Sobrien	  TREE_TYPE (enu) = enumtype;
609690075Sobrien	  DECL_SIZE (enu) = TYPE_SIZE (enumtype);
609790075Sobrien	  DECL_SIZE_UNIT (enu) = TYPE_SIZE_UNIT (enumtype);
609890075Sobrien	  DECL_ALIGN (enu) = TYPE_ALIGN (enumtype);
609990075Sobrien	  DECL_USER_ALIGN (enu) = TYPE_USER_ALIGN (enumtype);
610090075Sobrien	  DECL_MODE (enu) = TYPE_MODE (enumtype);
610190075Sobrien
610290075Sobrien	  /* The ISO C Standard mandates enumerators to have type int,
610390075Sobrien	     even though the underlying type of an enum type is
610490075Sobrien	     unspecified.  Here we convert any enumerators that fit in
610590075Sobrien	     an int to type int, to avoid promotions to unsigned types
610690075Sobrien	     when comparing integers with enumerators that fit in the
610790075Sobrien	     int range.  When -pedantic is given, build_enumerator()
610890075Sobrien	     would have already taken care of those that don't fit.  */
610990075Sobrien	  if (int_fits_type_p (DECL_INITIAL (enu), enum_value_type))
611090075Sobrien	    DECL_INITIAL (enu) = convert (enum_value_type, DECL_INITIAL (enu));
611190075Sobrien	  else
611290075Sobrien	    DECL_INITIAL (enu) = convert (enumtype, DECL_INITIAL (enu));
611390075Sobrien
611490075Sobrien	  TREE_PURPOSE (pair) = DECL_NAME (enu);
611590075Sobrien	  TREE_VALUE (pair) = DECL_INITIAL (enu);
611618334Speter	}
611718334Speter
611818334Speter      TYPE_VALUES (enumtype) = values;
611918334Speter    }
612018334Speter
612118334Speter  /* Fix up all variant types of this enum type.  */
612218334Speter  for (tem = TYPE_MAIN_VARIANT (enumtype); tem; tem = TYPE_NEXT_VARIANT (tem))
612318334Speter    {
612490075Sobrien      if (tem == enumtype)
612590075Sobrien	continue;
612618334Speter      TYPE_VALUES (tem) = TYPE_VALUES (enumtype);
612718334Speter      TYPE_MIN_VALUE (tem) = TYPE_MIN_VALUE (enumtype);
612818334Speter      TYPE_MAX_VALUE (tem) = TYPE_MAX_VALUE (enumtype);
612918334Speter      TYPE_SIZE (tem) = TYPE_SIZE (enumtype);
613050397Sobrien      TYPE_SIZE_UNIT (tem) = TYPE_SIZE_UNIT (enumtype);
613118334Speter      TYPE_MODE (tem) = TYPE_MODE (enumtype);
613218334Speter      TYPE_PRECISION (tem) = TYPE_PRECISION (enumtype);
613318334Speter      TYPE_ALIGN (tem) = TYPE_ALIGN (enumtype);
613490075Sobrien      TYPE_USER_ALIGN (tem) = TYPE_USER_ALIGN (enumtype);
613518334Speter      TREE_UNSIGNED (tem) = TREE_UNSIGNED (enumtype);
613618334Speter    }
613718334Speter
613818334Speter  /* Finish debugging output for this type.  */
613918334Speter  rest_of_type_compilation (enumtype, toplevel);
614018334Speter
614118334Speter  return enumtype;
614218334Speter}
614318334Speter
614418334Speter/* Build and install a CONST_DECL for one value of the
614518334Speter   current enumeration type (one that was begun with start_enum).
614618334Speter   Return a tree-list containing the CONST_DECL and its value.
614718334Speter   Assignment of sequential values by default is handled here.  */
614818334Speter
614918334Spetertree
615018334Speterbuild_enumerator (name, value)
615118334Speter     tree name, value;
615218334Speter{
615390075Sobrien  tree decl, type;
615418334Speter
615518334Speter  /* Validate and default VALUE.  */
615618334Speter
615718334Speter  /* Remove no-op casts from the value.  */
615818334Speter  if (value)
615918334Speter    STRIP_TYPE_NOPS (value);
616018334Speter
616118334Speter  if (value != 0)
616218334Speter    {
616318334Speter      if (TREE_CODE (value) == INTEGER_CST)
616418334Speter	{
616518334Speter	  value = default_conversion (value);
616618334Speter	  constant_expression_warning (value);
616718334Speter	}
616818334Speter      else
616918334Speter	{
617018334Speter	  error ("enumerator value for `%s' not integer constant",
617118334Speter		 IDENTIFIER_POINTER (name));
617218334Speter	  value = 0;
617318334Speter	}
617418334Speter    }
617518334Speter
617618334Speter  /* Default based on previous value.  */
617718334Speter  /* It should no longer be possible to have NON_LVALUE_EXPR
617818334Speter     in the default.  */
617918334Speter  if (value == 0)
618018334Speter    {
618118334Speter      value = enum_next_value;
618218334Speter      if (enum_overflow)
618318334Speter	error ("overflow in enumeration values");
618418334Speter    }
618518334Speter
618618334Speter  if (pedantic && ! int_fits_type_p (value, integer_type_node))
618718334Speter    {
618890075Sobrien      pedwarn ("ISO C restricts enumerator values to range of `int'");
618990075Sobrien      value = convert (integer_type_node, value);
619018334Speter    }
619118334Speter
619218334Speter  /* Set basis for default for next value.  */
619318334Speter  enum_next_value = build_binary_op (PLUS_EXPR, value, integer_one_node, 0);
619418334Speter  enum_overflow = tree_int_cst_lt (enum_next_value, value);
619518334Speter
619618334Speter  /* Now create a declaration for the enum value name.  */
619718334Speter
619818334Speter  type = TREE_TYPE (value);
619918334Speter  type = type_for_size (MAX (TYPE_PRECISION (type),
620018334Speter			     TYPE_PRECISION (integer_type_node)),
620118334Speter			((flag_traditional
620218334Speter			  || TYPE_PRECISION (type) >= TYPE_PRECISION (integer_type_node))
620318334Speter			 && TREE_UNSIGNED (type)));
620418334Speter
620518334Speter  decl = build_decl (CONST_DECL, name, type);
620690075Sobrien  DECL_INITIAL (decl) = convert (type, value);
620718334Speter  pushdecl (decl);
620818334Speter
620990075Sobrien  return tree_cons (decl, value, NULL_TREE);
621018334Speter}
621190075Sobrien
621218334Speter
621318334Speter/* Create the FUNCTION_DECL for a function definition.
621490075Sobrien   DECLSPECS, DECLARATOR and ATTRIBUTES are the parts of
621518334Speter   the declaration; they describe the function's name and the type it returns,
621618334Speter   but twisted together in a fashion that parallels the syntax of C.
621718334Speter
621818334Speter   This function creates a binding context for the function body
621918334Speter   as well as setting up the FUNCTION_DECL in current_function_decl.
622018334Speter
622118334Speter   Returns 1 on success.  If the DECLARATOR is not suitable for a function
622218334Speter   (it defines a datum instead), we return 0, which tells
622390075Sobrien   yyparse to report a parse error.  */
622418334Speter
622518334Speterint
622690075Sobrienstart_function (declspecs, declarator, attributes)
622790075Sobrien     tree declarator, declspecs, attributes;
622818334Speter{
622918334Speter  tree decl1, old_decl;
623018334Speter  tree restype;
623118334Speter  int old_immediate_size_expand = immediate_size_expand;
623218334Speter
623350397Sobrien  current_function_returns_value = 0;  /* Assume, until we see it does.  */
623418334Speter  current_function_returns_null = 0;
623596263Sobrien  current_function_returns_abnormally = 0;
623618334Speter  warn_about_return_type = 0;
623718334Speter  current_extern_inline = 0;
623818334Speter  c_function_varargs = 0;
623918334Speter  named_labels = 0;
624018334Speter  shadowed_labels = 0;
624118334Speter
624218334Speter  /* Don't expand any sizes in the return type of the function.  */
624318334Speter  immediate_size_expand = 0;
624418334Speter
624596263Sobrien  decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, 1);
624618334Speter
624718334Speter  /* If the declarator is not suitable for a function definition,
624818334Speter     cause a syntax error.  */
624918334Speter  if (decl1 == 0)
625050397Sobrien    {
625150397Sobrien      immediate_size_expand = old_immediate_size_expand;
625250397Sobrien      return 0;
625350397Sobrien    }
625418334Speter
625590075Sobrien  decl_attributes (&decl1, attributes, 0);
625618334Speter
625796263Sobrien  /* If #pragma weak was used, mark the decl weak now.  */
625896263Sobrien  if (current_binding_level == global_binding_level)
625996263Sobrien    maybe_apply_pragma_weak (decl1);
626096263Sobrien
626190075Sobrien  if (DECL_DECLARED_INLINE_P (decl1)
626290075Sobrien      && DECL_UNINLINABLE (decl1)
626390075Sobrien      && lookup_attribute ("noinline", DECL_ATTRIBUTES (decl1)))
626490075Sobrien    warning_with_decl (decl1,
626590075Sobrien		       "inline function `%s' given attribute noinline");
626690075Sobrien
626718334Speter  announce_function (decl1);
626818334Speter
626990075Sobrien  if (!COMPLETE_OR_VOID_TYPE_P (TREE_TYPE (TREE_TYPE (decl1))))
627018334Speter    {
627190075Sobrien      error ("return type is an incomplete type");
627218334Speter      /* Make it return void instead.  */
627318334Speter      TREE_TYPE (decl1)
627418334Speter	= build_function_type (void_type_node,
627518334Speter			       TYPE_ARG_TYPES (TREE_TYPE (decl1)));
627618334Speter    }
627718334Speter
627818334Speter  if (warn_about_return_type)
627990075Sobrien    pedwarn_c99 ("return type defaults to `int'");
628018334Speter
628118334Speter  /* Save the parm names or decls from this function's declarator
628218334Speter     where store_parm_decls will find them.  */
628318334Speter  current_function_parms = last_function_parms;
628418334Speter  current_function_parm_tags = last_function_parm_tags;
628518334Speter
628618334Speter  /* Make the init_value nonzero so pushdecl knows this is not tentative.
628718334Speter     error_mark_node is replaced below (in poplevel) with the BLOCK.  */
628818334Speter  DECL_INITIAL (decl1) = error_mark_node;
628918334Speter
629018334Speter  /* If this definition isn't a prototype and we had a prototype declaration
629118334Speter     before, copy the arg type info from that prototype.
629218334Speter     But not if what we had before was a builtin function.  */
629318334Speter  old_decl = lookup_name_current_level (DECL_NAME (decl1));
629418334Speter  if (old_decl != 0 && TREE_CODE (TREE_TYPE (old_decl)) == FUNCTION_TYPE
629518334Speter      && !DECL_BUILT_IN (old_decl)
629618334Speter      && (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (decl1)))
629718334Speter	  == TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (old_decl))))
629818334Speter      && TYPE_ARG_TYPES (TREE_TYPE (decl1)) == 0)
629918334Speter    {
630018334Speter      TREE_TYPE (decl1) = TREE_TYPE (old_decl);
630118334Speter      current_function_prototype_file = DECL_SOURCE_FILE (old_decl);
630218334Speter      current_function_prototype_line = DECL_SOURCE_LINE (old_decl);
630318334Speter    }
630418334Speter
630518334Speter  /* If there is no explicit declaration, look for any out-of-scope implicit
630618334Speter     declarations.  */
630718334Speter  if (old_decl == 0)
630818334Speter    old_decl = IDENTIFIER_IMPLICIT_DECL (DECL_NAME (decl1));
630918334Speter
631018334Speter  /* Optionally warn of old-fashioned def with no previous prototype.  */
631118334Speter  if (warn_strict_prototypes
631218334Speter      && TYPE_ARG_TYPES (TREE_TYPE (decl1)) == 0
631390075Sobrien      && !(old_decl != 0
631490075Sobrien	   && (TYPE_ARG_TYPES (TREE_TYPE (old_decl)) != 0
631590075Sobrien	       || (DECL_BUILT_IN (old_decl)
631690075Sobrien		   && ! C_DECL_ANTICIPATED (old_decl)))))
631718334Speter    warning ("function declaration isn't a prototype");
631818334Speter  /* Optionally warn of any global def with no previous prototype.  */
631918334Speter  else if (warn_missing_prototypes
632018334Speter	   && TREE_PUBLIC (decl1)
632190075Sobrien	   && !(old_decl != 0
632290075Sobrien		&& (TYPE_ARG_TYPES (TREE_TYPE (old_decl)) != 0
632390075Sobrien		    || (DECL_BUILT_IN (old_decl)
632490075Sobrien			&& ! C_DECL_ANTICIPATED (old_decl))))
632590075Sobrien	   && ! MAIN_NAME_P (DECL_NAME (decl1)))
632618334Speter    warning_with_decl (decl1, "no previous prototype for `%s'");
632718334Speter  /* Optionally warn of any def with no previous prototype
632818334Speter     if the function has already been used.  */
632918334Speter  else if (warn_missing_prototypes
633018334Speter	   && old_decl != 0 && TREE_USED (old_decl)
633118334Speter	   && TYPE_ARG_TYPES (TREE_TYPE (old_decl)) == 0)
633218334Speter    warning_with_decl (decl1,
633390075Sobrien		       "`%s' was used with no prototype before its definition");
633418334Speter  /* Optionally warn of any global def with no previous declaration.  */
633518334Speter  else if (warn_missing_declarations
633618334Speter	   && TREE_PUBLIC (decl1)
633718334Speter	   && old_decl == 0
633890075Sobrien	   && ! MAIN_NAME_P (DECL_NAME (decl1)))
633918334Speter    warning_with_decl (decl1, "no previous declaration for `%s'");
634018334Speter  /* Optionally warn of any def with no previous declaration
634118334Speter     if the function has already been used.  */
634218334Speter  else if (warn_missing_declarations
634318334Speter	   && old_decl != 0 && TREE_USED (old_decl)
634418334Speter	   && old_decl == IDENTIFIER_IMPLICIT_DECL (DECL_NAME (decl1)))
634518334Speter    warning_with_decl (decl1,
634690075Sobrien		       "`%s' was used with no declaration before its definition");
634718334Speter
634818334Speter  /* This is a definition, not a reference.
634918334Speter     So normally clear DECL_EXTERNAL.
635018334Speter     However, `extern inline' acts like a declaration
635118334Speter     except for defining how to inline.  So set DECL_EXTERNAL in that case.  */
635218334Speter  DECL_EXTERNAL (decl1) = current_extern_inline;
635318334Speter
635418334Speter  /* This function exists in static storage.
635518334Speter     (This does not mean `static' in the C sense!)  */
635618334Speter  TREE_STATIC (decl1) = 1;
635718334Speter
635818334Speter  /* A nested function is not global.  */
635918334Speter  if (current_function_decl != 0)
636018334Speter    TREE_PUBLIC (decl1) = 0;
636118334Speter
636290075Sobrien  /* Warn for unlikely, improbable, or stupid declarations of `main'.  */
636390075Sobrien  if (warn_main > 0 && MAIN_NAME_P (DECL_NAME (decl1)))
636450397Sobrien    {
636550397Sobrien      tree args;
636650397Sobrien      int argct = 0;
636750397Sobrien
636850397Sobrien      if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (decl1)))
636990075Sobrien	  != integer_type_node)
637050397Sobrien	pedwarn_with_decl (decl1, "return type of `%s' is not `int'");
637150397Sobrien
637250397Sobrien      for (args = TYPE_ARG_TYPES (TREE_TYPE (decl1)); args;
637350397Sobrien	   args = TREE_CHAIN (args))
637450397Sobrien	{
637550397Sobrien	  tree type = args ? TREE_VALUE (args) : 0;
637650397Sobrien
637750397Sobrien	  if (type == void_type_node)
637850397Sobrien	    break;
637950397Sobrien
638050397Sobrien	  ++argct;
638150397Sobrien	  switch (argct)
638250397Sobrien	    {
638350397Sobrien	    case 1:
638450397Sobrien	      if (TYPE_MAIN_VARIANT (type) != integer_type_node)
638550397Sobrien		pedwarn_with_decl (decl1,
638650397Sobrien				   "first argument of `%s' should be `int'");
638750397Sobrien	      break;
638850397Sobrien
638950397Sobrien	    case 2:
639050397Sobrien	      if (TREE_CODE (type) != POINTER_TYPE
639150397Sobrien		  || TREE_CODE (TREE_TYPE (type)) != POINTER_TYPE
639250397Sobrien		  || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type)))
639350397Sobrien		      != char_type_node))
639450397Sobrien		pedwarn_with_decl (decl1,
639590075Sobrien				   "second argument of `%s' should be `char **'");
639650397Sobrien	      break;
639750397Sobrien
639850397Sobrien	    case 3:
639950397Sobrien	      if (TREE_CODE (type) != POINTER_TYPE
640050397Sobrien		  || TREE_CODE (TREE_TYPE (type)) != POINTER_TYPE
640150397Sobrien		  || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type)))
640250397Sobrien		      != char_type_node))
640350397Sobrien		pedwarn_with_decl (decl1,
640490075Sobrien				   "third argument of `%s' should probably be `char **'");
640550397Sobrien	      break;
640650397Sobrien	    }
640750397Sobrien	}
640850397Sobrien
640950397Sobrien      /* It is intentional that this message does not mention the third
641090075Sobrien	 argument because it's only mentioned in an appendix of the
641190075Sobrien	 standard.  */
641250397Sobrien      if (argct > 0 && (argct < 2 || argct > 3))
641350397Sobrien	pedwarn_with_decl (decl1, "`%s' takes only zero or two arguments");
641450397Sobrien
641550397Sobrien      if (! TREE_PUBLIC (decl1))
641650397Sobrien	pedwarn_with_decl (decl1, "`%s' is normally a non-static function");
641750397Sobrien    }
641850397Sobrien
641918334Speter  /* Record the decl so that the function name is defined.
642018334Speter     If we already have a decl for this name, and it is a FUNCTION_DECL,
642118334Speter     use the old decl.  */
642218334Speter
642318334Speter  current_function_decl = pushdecl (decl1);
642418334Speter
642518334Speter  pushlevel (0);
642618334Speter  declare_parm_level (1);
642718334Speter  current_binding_level->subblocks_tag_transparent = 1;
642818334Speter
642990075Sobrien  make_decl_rtl (current_function_decl, NULL);
643018334Speter
643118334Speter  restype = TREE_TYPE (TREE_TYPE (current_function_decl));
643218334Speter  /* Promote the value to int before returning it.  */
643390075Sobrien  if (c_promoting_integer_type_p (restype))
643418334Speter    {
643518334Speter      /* It retains unsignedness if traditional
643618334Speter	 or if not really getting wider.  */
643718334Speter      if (TREE_UNSIGNED (restype)
643818334Speter	  && (flag_traditional
643918334Speter	      || (TYPE_PRECISION (restype)
644018334Speter		  == TYPE_PRECISION (integer_type_node))))
644118334Speter	restype = unsigned_type_node;
644218334Speter      else
644318334Speter	restype = integer_type_node;
644418334Speter    }
644518334Speter  DECL_RESULT (current_function_decl)
644618334Speter    = build_decl (RESULT_DECL, NULL_TREE, restype);
644718334Speter
644818334Speter  /* If this fcn was already referenced via a block-scope `extern' decl
644918334Speter     (or an implicit decl), propagate certain information about the usage.  */
645018334Speter  if (TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (current_function_decl)))
645118334Speter    TREE_ADDRESSABLE (current_function_decl) = 1;
645218334Speter
645318334Speter  immediate_size_expand = old_immediate_size_expand;
645418334Speter
645590075Sobrien  start_fname_decls ();
645690075Sobrien
645718334Speter  return 1;
645818334Speter}
645918334Speter
646018334Speter/* Record that this function is going to be a varargs function.
646118334Speter   This is called before store_parm_decls, which is too early
646218334Speter   to call mark_varargs directly.  */
646318334Speter
646418334Spetervoid
646518334Speterc_mark_varargs ()
646618334Speter{
646718334Speter  c_function_varargs = 1;
646818334Speter}
646918334Speter
647018334Speter/* Store the parameter declarations into the current function declaration.
647118334Speter   This is called after parsing the parameter declarations, before
647218334Speter   digesting the body of the function.
647318334Speter
647418334Speter   For an old-style definition, modify the function's type
647518334Speter   to specify at least the number of arguments.  */
647618334Speter
647718334Spetervoid
647818334Speterstore_parm_decls ()
647918334Speter{
648090075Sobrien  tree fndecl = current_function_decl;
648190075Sobrien  tree parm;
648218334Speter
648318334Speter  /* This is either a chain of PARM_DECLs (if a prototype was used)
648418334Speter     or a list of IDENTIFIER_NODEs (for an old-fashioned C definition).  */
648518334Speter  tree specparms = current_function_parms;
648618334Speter
648718334Speter  /* This is a list of types declared among parms in a prototype.  */
648818334Speter  tree parmtags = current_function_parm_tags;
648918334Speter
649018334Speter  /* This is a chain of PARM_DECLs from old-style parm declarations.  */
649190075Sobrien  tree parmdecls = getdecls ();
649218334Speter
649318334Speter  /* This is a chain of any other decls that came in among the parm
649418334Speter     declarations.  If a parm is declared with  enum {foo, bar} x;
649518334Speter     then CONST_DECLs for foo and bar are put here.  */
649618334Speter  tree nonparms = 0;
649718334Speter
649890075Sobrien  /* The function containing FNDECL, if any.  */
649990075Sobrien  tree context = decl_function_context (fndecl);
650090075Sobrien
650118334Speter  /* Nonzero if this definition is written with a prototype.  */
650218334Speter  int prototype = 0;
650318334Speter
650490075Sobrien  int saved_warn_shadow = warn_shadow;
650590075Sobrien
650690075Sobrien  /* Don't re-emit shadow warnings.  */
650790075Sobrien  warn_shadow = 0;
650890075Sobrien
650918334Speter  if (specparms != 0 && TREE_CODE (specparms) != TREE_LIST)
651018334Speter    {
651118334Speter      /* This case is when the function was defined with an ANSI prototype.
651218334Speter	 The parms already have decls, so we need not do anything here
651318334Speter	 except record them as in effect
651418334Speter	 and complain if any redundant old-style parm decls were written.  */
651518334Speter
651690075Sobrien      tree next;
651718334Speter      tree others = 0;
651818334Speter
651918334Speter      prototype = 1;
652018334Speter
652118334Speter      if (parmdecls != 0)
652218334Speter	{
652318334Speter	  tree decl, link;
652418334Speter
652518334Speter	  error_with_decl (fndecl,
652618334Speter			   "parm types given both in parmlist and separately");
652718334Speter	  /* Get rid of the erroneous decls; don't keep them on
652818334Speter	     the list of parms, since they might not be PARM_DECLs.  */
652918334Speter	  for (decl = current_binding_level->names;
653018334Speter	       decl; decl = TREE_CHAIN (decl))
653118334Speter	    if (DECL_NAME (decl))
653218334Speter	      IDENTIFIER_LOCAL_VALUE (DECL_NAME (decl)) = 0;
653318334Speter	  for (link = current_binding_level->shadowed;
653418334Speter	       link; link = TREE_CHAIN (link))
653518334Speter	    IDENTIFIER_LOCAL_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link);
653618334Speter	  current_binding_level->names = 0;
653718334Speter	  current_binding_level->shadowed = 0;
653818334Speter	}
653918334Speter
654018334Speter      specparms = nreverse (specparms);
654118334Speter      for (parm = specparms; parm; parm = next)
654218334Speter	{
654318334Speter	  next = TREE_CHAIN (parm);
654418334Speter	  if (TREE_CODE (parm) == PARM_DECL)
654518334Speter	    {
654618334Speter	      if (DECL_NAME (parm) == 0)
654718334Speter		error_with_decl (parm, "parameter name omitted");
654890075Sobrien	      else if (TREE_CODE (TREE_TYPE (parm)) != ERROR_MARK
654990075Sobrien		       && VOID_TYPE_P (TREE_TYPE (parm)))
655018334Speter		{
655118334Speter		  error_with_decl (parm, "parameter `%s' declared void");
655218334Speter		  /* Change the type to error_mark_node so this parameter
655318334Speter		     will be ignored by assign_parms.  */
655418334Speter		  TREE_TYPE (parm) = error_mark_node;
655518334Speter		}
655618334Speter	      pushdecl (parm);
655718334Speter	    }
655818334Speter	  else
655918334Speter	    {
656018334Speter	      /* If we find an enum constant or a type tag,
656118334Speter		 put it aside for the moment.  */
656218334Speter	      TREE_CHAIN (parm) = 0;
656318334Speter	      others = chainon (others, parm);
656418334Speter	    }
656518334Speter	}
656618334Speter
656718334Speter      /* Get the decls in their original chain order
656818334Speter	 and record in the function.  */
656918334Speter      DECL_ARGUMENTS (fndecl) = getdecls ();
657018334Speter
657118334Speter#if 0
657218334Speter      /* If this function takes a variable number of arguments,
657318334Speter	 add a phony parameter to the end of the parm list,
657418334Speter	 to represent the position of the first unnamed argument.  */
657518334Speter      if (TREE_VALUE (tree_last (TYPE_ARG_TYPES (TREE_TYPE (fndecl))))
657618334Speter	  != void_type_node)
657718334Speter	{
657818334Speter	  tree dummy = build_decl (PARM_DECL, NULL_TREE, void_type_node);
657918334Speter	  /* Let's hope the address of the unnamed parm
658018334Speter	     won't depend on its type.  */
658118334Speter	  TREE_TYPE (dummy) = integer_type_node;
658218334Speter	  DECL_ARG_TYPE (dummy) = integer_type_node;
658390075Sobrien	  DECL_ARGUMENTS (fndecl) = chainon (DECL_ARGUMENTS (fndecl), dummy);
658418334Speter	}
658518334Speter#endif
658618334Speter
658718334Speter      /* Now pushdecl the enum constants.  */
658818334Speter      for (parm = others; parm; parm = next)
658918334Speter	{
659018334Speter	  next = TREE_CHAIN (parm);
659118334Speter	  if (DECL_NAME (parm) == 0)
659218334Speter	    ;
659318334Speter	  else if (TYPE_MAIN_VARIANT (TREE_TYPE (parm)) == void_type_node)
659418334Speter	    ;
659518334Speter	  else if (TREE_CODE (parm) != PARM_DECL)
659618334Speter	    pushdecl (parm);
659718334Speter	}
659818334Speter
659918334Speter      storetags (chainon (parmtags, gettags ()));
660018334Speter    }
660118334Speter  else
660218334Speter    {
660318334Speter      /* SPECPARMS is an identifier list--a chain of TREE_LIST nodes
660418334Speter	 each with a parm name as the TREE_VALUE.
660518334Speter
660618334Speter	 PARMDECLS is a chain of declarations for parameters.
660718334Speter	 Warning! It can also contain CONST_DECLs which are not parameters
660818334Speter	 but are names of enumerators of any enum types
660918334Speter	 declared among the parameters.
661018334Speter
661118334Speter	 First match each formal parameter name with its declaration.
661218334Speter	 Associate decls with the names and store the decls
661318334Speter	 into the TREE_PURPOSE slots.  */
661418334Speter
661590075Sobrien      /* We use DECL_WEAK as a flag to show which parameters have been
661690075Sobrien	 seen already since it is not used on PARM_DECL or CONST_DECL.  */
661718334Speter      for (parm = parmdecls; parm; parm = TREE_CHAIN (parm))
661890075Sobrien	DECL_WEAK (parm) = 0;
661918334Speter
662018334Speter      for (parm = specparms; parm; parm = TREE_CHAIN (parm))
662118334Speter	{
662290075Sobrien	  tree tail, found = NULL;
662318334Speter
662418334Speter	  if (TREE_VALUE (parm) == 0)
662518334Speter	    {
662690075Sobrien	      error_with_decl (fndecl,
662790075Sobrien			       "parameter name missing from parameter list");
662818334Speter	      TREE_PURPOSE (parm) = 0;
662918334Speter	      continue;
663018334Speter	    }
663118334Speter
663218334Speter	  /* See if any of the parmdecls specifies this parm by name.
663318334Speter	     Ignore any enumerator decls.  */
663418334Speter	  for (tail = parmdecls; tail; tail = TREE_CHAIN (tail))
663518334Speter	    if (DECL_NAME (tail) == TREE_VALUE (parm)
663618334Speter		&& TREE_CODE (tail) == PARM_DECL)
663718334Speter	      {
663818334Speter		found = tail;
663918334Speter		break;
664018334Speter	      }
664118334Speter
664218334Speter	  /* If declaration already marked, we have a duplicate name.
664390075Sobrien	     Complain, and don't use this decl twice.  */
664490075Sobrien	  if (found && DECL_WEAK (found))
664518334Speter	    {
664618334Speter	      error_with_decl (found, "multiple parameters named `%s'");
664718334Speter	      found = 0;
664818334Speter	    }
664918334Speter
665018334Speter	  /* If the declaration says "void", complain and ignore it.  */
665190075Sobrien	  if (found && VOID_TYPE_P (TREE_TYPE (found)))
665218334Speter	    {
665318334Speter	      error_with_decl (found, "parameter `%s' declared void");
665418334Speter	      TREE_TYPE (found) = integer_type_node;
665518334Speter	      DECL_ARG_TYPE (found) = integer_type_node;
665618334Speter	      layout_decl (found, 0);
665718334Speter	    }
665818334Speter
665918334Speter	  /* Traditionally, a parm declared float is actually a double.  */
666018334Speter	  if (found && flag_traditional
666118334Speter	      && TYPE_MAIN_VARIANT (TREE_TYPE (found)) == float_type_node)
666218334Speter	    {
666318334Speter	      TREE_TYPE (found) = double_type_node;
666418334Speter	      DECL_ARG_TYPE (found) = double_type_node;
666518334Speter	      layout_decl (found, 0);
666618334Speter	    }
666718334Speter
666818334Speter	  /* If no declaration found, default to int.  */
666918334Speter	  if (!found)
667018334Speter	    {
667118334Speter	      found = build_decl (PARM_DECL, TREE_VALUE (parm),
667218334Speter				  integer_type_node);
667318334Speter	      DECL_ARG_TYPE (found) = TREE_TYPE (found);
667418334Speter	      DECL_SOURCE_LINE (found) = DECL_SOURCE_LINE (fndecl);
667518334Speter	      DECL_SOURCE_FILE (found) = DECL_SOURCE_FILE (fndecl);
667690075Sobrien	      if (flag_isoc99)
667790075Sobrien		pedwarn_with_decl (found, "type of `%s' defaults to `int'");
667890075Sobrien	      else if (extra_warnings)
667918334Speter		warning_with_decl (found, "type of `%s' defaults to `int'");
668018334Speter	      pushdecl (found);
668118334Speter	    }
668218334Speter
668318334Speter	  TREE_PURPOSE (parm) = found;
668418334Speter
668590075Sobrien	  /* Mark this decl as "already found".  */
668690075Sobrien	  DECL_WEAK (found) = 1;
668718334Speter	}
668818334Speter
668918334Speter      /* Put anything which is on the parmdecls chain and which is
669018334Speter	 not a PARM_DECL onto the list NONPARMS.  (The types of
669118334Speter	 non-parm things which might appear on the list include
669218334Speter	 enumerators and NULL-named TYPE_DECL nodes.) Complain about
669318334Speter	 any actual PARM_DECLs not matched with any names.  */
669418334Speter
669518334Speter      nonparms = 0;
669690075Sobrien      for (parm = parmdecls; parm;)
669718334Speter	{
669818334Speter	  tree next = TREE_CHAIN (parm);
669918334Speter	  TREE_CHAIN (parm) = 0;
670018334Speter
670118334Speter	  if (TREE_CODE (parm) != PARM_DECL)
670218334Speter	    nonparms = chainon (nonparms, parm);
670318334Speter	  else
670418334Speter	    {
670518334Speter	      /* Complain about args with incomplete types.  */
670690075Sobrien	      if (!COMPLETE_TYPE_P (TREE_TYPE (parm)))
670790075Sobrien		{
670890075Sobrien		  error_with_decl (parm, "parameter `%s' has incomplete type");
670990075Sobrien		  TREE_TYPE (parm) = error_mark_node;
671090075Sobrien		}
671118334Speter
671290075Sobrien	      if (! DECL_WEAK (parm))
671390075Sobrien		{
671490075Sobrien		  error_with_decl (parm,
671590075Sobrien				   "declaration for parameter `%s' but no such parameter");
671618334Speter	          /* Pretend the parameter was not missing.
671718334Speter		     This gets us to a standard state and minimizes
671818334Speter		     further error messages.  */
671990075Sobrien		  specparms
672018334Speter		    = chainon (specparms,
672118334Speter			       tree_cons (parm, NULL_TREE, NULL_TREE));
672218334Speter		}
672318334Speter	    }
672418334Speter
672518334Speter	  parm = next;
672618334Speter	}
672718334Speter
672890075Sobrien      /* Chain the declarations together in the order of the list of
672990075Sobrien         names.  Store that chain in the function decl, replacing the
673090075Sobrien         list of names.  */
673118334Speter      parm = specparms;
673218334Speter      DECL_ARGUMENTS (fndecl) = 0;
673318334Speter      {
673490075Sobrien	tree last;
673518334Speter	for (last = 0; parm; parm = TREE_CHAIN (parm))
673618334Speter	  if (TREE_PURPOSE (parm))
673718334Speter	    {
673818334Speter	      if (last == 0)
673918334Speter		DECL_ARGUMENTS (fndecl) = TREE_PURPOSE (parm);
674018334Speter	      else
674118334Speter		TREE_CHAIN (last) = TREE_PURPOSE (parm);
674218334Speter	      last = TREE_PURPOSE (parm);
674318334Speter	      TREE_CHAIN (last) = 0;
674418334Speter	    }
674518334Speter      }
674618334Speter
674718334Speter      /* If there was a previous prototype,
674818334Speter	 set the DECL_ARG_TYPE of each argument according to
674918334Speter	 the type previously specified, and report any mismatches.  */
675018334Speter
675118334Speter      if (TYPE_ARG_TYPES (TREE_TYPE (fndecl)))
675218334Speter	{
675390075Sobrien	  tree type;
675418334Speter	  for (parm = DECL_ARGUMENTS (fndecl),
675518334Speter	       type = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
675618334Speter	       parm || (type && (TYPE_MAIN_VARIANT (TREE_VALUE (type))
675718334Speter				 != void_type_node));
675818334Speter	       parm = TREE_CHAIN (parm), type = TREE_CHAIN (type))
675918334Speter	    {
676018334Speter	      if (parm == 0 || type == 0
676118334Speter		  || TYPE_MAIN_VARIANT (TREE_VALUE (type)) == void_type_node)
676218334Speter		{
676318334Speter		  error ("number of arguments doesn't match prototype");
676418334Speter		  error_with_file_and_line (current_function_prototype_file,
676518334Speter					    current_function_prototype_line,
676618334Speter					    "prototype declaration");
676718334Speter		  break;
676818334Speter		}
676990075Sobrien	      /* Type for passing arg must be consistent with that
677090075Sobrien		 declared for the arg.  ISO C says we take the unqualified
677190075Sobrien		 type for parameters declared with qualified type.  */
677290075Sobrien	      if (! comptypes (TYPE_MAIN_VARIANT (DECL_ARG_TYPE (parm)),
677390075Sobrien			       TYPE_MAIN_VARIANT (TREE_VALUE (type))))
677418334Speter		{
677518334Speter		  if (TYPE_MAIN_VARIANT (TREE_TYPE (parm))
677618334Speter		      == TYPE_MAIN_VARIANT (TREE_VALUE (type)))
677718334Speter		    {
677818334Speter		      /* Adjust argument to match prototype.  E.g. a previous
677918334Speter			 `int foo(float);' prototype causes
678018334Speter			 `int foo(x) float x; {...}' to be treated like
678118334Speter			 `int foo(float x) {...}'.  This is particularly
678218334Speter			 useful for argument types like uid_t.  */
678318334Speter		      DECL_ARG_TYPE (parm) = TREE_TYPE (parm);
678490075Sobrien
678590075Sobrien		      if (PROMOTE_PROTOTYPES
678690075Sobrien			  && INTEGRAL_TYPE_P (TREE_TYPE (parm))
678718334Speter			  && TYPE_PRECISION (TREE_TYPE (parm))
678818334Speter			  < TYPE_PRECISION (integer_type_node))
678918334Speter			DECL_ARG_TYPE (parm) = integer_type_node;
679090075Sobrien
679118334Speter		      if (pedantic)
679218334Speter			{
679318334Speter			  pedwarn ("promoted argument `%s' doesn't match prototype",
679418334Speter				   IDENTIFIER_POINTER (DECL_NAME (parm)));
679518334Speter			  warning_with_file_and_line
679618334Speter			    (current_function_prototype_file,
679718334Speter			     current_function_prototype_line,
679818334Speter			     "prototype declaration");
679918334Speter			}
680018334Speter		    }
680118334Speter		  /* If -traditional, allow `int' argument to match
680218334Speter		     `unsigned' prototype.  */
680318334Speter		  else if (! (flag_traditional
680418334Speter			      && TYPE_MAIN_VARIANT (TREE_TYPE (parm)) == integer_type_node
680518334Speter			      && TYPE_MAIN_VARIANT (TREE_VALUE (type)) == unsigned_type_node))
680618334Speter		    {
680718334Speter		      error ("argument `%s' doesn't match prototype",
680818334Speter			     IDENTIFIER_POINTER (DECL_NAME (parm)));
680918334Speter		      error_with_file_and_line (current_function_prototype_file,
681018334Speter						current_function_prototype_line,
681118334Speter						"prototype declaration");
681218334Speter		    }
681318334Speter		}
681418334Speter	    }
681518334Speter	  TYPE_ACTUAL_ARG_TYPES (TREE_TYPE (fndecl)) = 0;
681618334Speter	}
681718334Speter
681818334Speter      /* Otherwise, create a prototype that would match.  */
681918334Speter
682018334Speter      else
682118334Speter	{
682218334Speter	  tree actual = 0, last = 0, type;
682318334Speter
682418334Speter	  for (parm = DECL_ARGUMENTS (fndecl); parm; parm = TREE_CHAIN (parm))
682518334Speter	    {
682690075Sobrien	      type = tree_cons (NULL_TREE, DECL_ARG_TYPE (parm), NULL_TREE);
682718334Speter	      if (last)
682818334Speter		TREE_CHAIN (last) = type;
682918334Speter	      else
683018334Speter		actual = type;
683118334Speter	      last = type;
683218334Speter	    }
683390075Sobrien	  type = tree_cons (NULL_TREE, void_type_node, NULL_TREE);
683418334Speter	  if (last)
683518334Speter	    TREE_CHAIN (last) = type;
683618334Speter	  else
683718334Speter	    actual = type;
683818334Speter
683918334Speter	  /* We are going to assign a new value for the TYPE_ACTUAL_ARG_TYPES
684018334Speter	     of the type of this function, but we need to avoid having this
684118334Speter	     affect the types of other similarly-typed functions, so we must
684218334Speter	     first force the generation of an identical (but separate) type
684318334Speter	     node for the relevant function type.  The new node we create
684418334Speter	     will be a variant of the main variant of the original function
684518334Speter	     type.  */
684618334Speter
684718334Speter	  TREE_TYPE (fndecl) = build_type_copy (TREE_TYPE (fndecl));
684818334Speter
684918334Speter	  TYPE_ACTUAL_ARG_TYPES (TREE_TYPE (fndecl)) = actual;
685018334Speter	}
685118334Speter
685218334Speter      /* Now store the final chain of decls for the arguments
685318334Speter	 as the decl-chain of the current lexical scope.
685418334Speter	 Put the enumerators in as well, at the front so that
685518334Speter	 DECL_ARGUMENTS is not modified.  */
685618334Speter
685718334Speter      storedecls (chainon (nonparms, DECL_ARGUMENTS (fndecl)));
685818334Speter    }
685918334Speter
686018334Speter  /* Make sure the binding level for the top of the function body
686118334Speter     gets a BLOCK if there are any in the function.
686218334Speter     Otherwise, the dbx output is wrong.  */
686318334Speter
686418334Speter  keep_next_if_subblocks = 1;
686518334Speter
686618334Speter  /* ??? This might be an improvement,
686718334Speter     but needs to be thought about some more.  */
686818334Speter#if 0
686918334Speter  keep_next_level_flag = 1;
687018334Speter#endif
687118334Speter
687218334Speter  /* Write a record describing this function definition to the prototypes
687318334Speter     file (if requested).  */
687418334Speter
687518334Speter  gen_aux_info_record (fndecl, 1, 0, prototype);
687618334Speter
687718334Speter  /* Initialize the RTL code for the function.  */
687818334Speter  init_function_start (fndecl, input_filename, lineno);
687918334Speter
688090075Sobrien  /* Begin the statement tree for this function.  */
688190075Sobrien  begin_stmt_tree (&DECL_SAVED_TREE (current_function_decl));
688218334Speter
688390075Sobrien  /* If this is a nested function, save away the sizes of any
688490075Sobrien     variable-size types so that we can expand them when generating
688590075Sobrien     RTL.  */
688690075Sobrien  if (context)
688718334Speter    {
688890075Sobrien      tree t;
688918334Speter
689090075Sobrien      DECL_LANG_SPECIFIC (fndecl)->pending_sizes
689190075Sobrien	= nreverse (get_pending_sizes ());
689290075Sobrien      for (t = DECL_LANG_SPECIFIC (fndecl)->pending_sizes;
689390075Sobrien	   t;
689490075Sobrien	   t = TREE_CHAIN (t))
689590075Sobrien	SAVE_EXPR_CONTEXT (TREE_VALUE (t)) = context;
689618334Speter    }
689718334Speter
689890075Sobrien  /* This function is being processed in whole-function mode.  */
689990075Sobrien  cfun->x_whole_function_mode_p = 1;
690018334Speter
690190075Sobrien  /* Even though we're inside a function body, we still don't want to
690290075Sobrien     call expand_expr to calculate the size of a variable-sized array.
690390075Sobrien     We haven't necessarily assigned RTL to all variables yet, so it's
690490075Sobrien     not safe to try to expand expressions involving them.  */
690590075Sobrien  immediate_size_expand = 0;
690690075Sobrien  cfun->x_dont_save_pending_sizes_p = 1;
690718334Speter
690890075Sobrien  warn_shadow = saved_warn_shadow;
690918334Speter}
691018334Speter
691118334Speter/* Finish up a function declaration and compile that function
691218334Speter   all the way to assembler language output.  The free the storage
691318334Speter   for the function definition.
691418334Speter
691518334Speter   This is called after parsing the body of the function definition.
691618334Speter
691796263Sobrien   NESTED is nonzero if the function being finished is nested in another.
691896263Sobrien   CAN_DEFER_P is nonzero if the function may be deferred.  */
691918334Speter
692018334Spetervoid
692196263Sobrienfinish_function (nested, can_defer_p)
692218334Speter     int nested;
692396263Sobrien     int can_defer_p;
692418334Speter{
692590075Sobrien  tree fndecl = current_function_decl;
692618334Speter
692796263Sobrien#if 0
692896263Sobrien  /* This caused &foo to be of type ptr-to-const-function which then
692996263Sobrien     got a warning when stored in a ptr-to-function variable.  */
693096263Sobrien  TREE_READONLY (fndecl) = 1;
693196263Sobrien#endif
693218334Speter
693318334Speter  poplevel (1, 0, 1);
693418334Speter  BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
693518334Speter
693618334Speter  /* Must mark the RESULT_DECL as being in this function.  */
693718334Speter
693818334Speter  DECL_CONTEXT (DECL_RESULT (fndecl)) = fndecl;
693918334Speter
694018334Speter  /* Obey `register' declarations if `setjmp' is called in this fn.  */
694118334Speter  if (flag_traditional && current_function_calls_setjmp)
694218334Speter    {
694318334Speter      setjmp_protect (DECL_INITIAL (fndecl));
694418334Speter      setjmp_protect_args ();
694518334Speter    }
694618334Speter
694790075Sobrien  if (MAIN_NAME_P (DECL_NAME (fndecl)) && flag_hosted)
694818334Speter    {
694918334Speter      if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (fndecl)))
695018334Speter	  != integer_type_node)
695150397Sobrien	{
695252284Sobrien	  /* If warn_main is 1 (-Wmain) or 2 (-Wall), we have already warned.
695390075Sobrien	     If warn_main is -1 (-Wno-main) we don't want to be warned.  */
695450397Sobrien	  if (! warn_main)
695550397Sobrien	    pedwarn_with_decl (fndecl, "return type of `%s' is not `int'");
695650397Sobrien	}
695718334Speter      else
695818334Speter	{
695950397Sobrien#ifdef DEFAULT_MAIN_RETURN
696018334Speter	  /* Make it so that `main' always returns success by default.  */
696118334Speter	  DEFAULT_MAIN_RETURN;
696290075Sobrien#else
696390075Sobrien	  if (flag_isoc99)
696490075Sobrien	    c_expand_return (integer_zero_node);
696550397Sobrien#endif
696618334Speter	}
696718334Speter    }
696890075Sobrien
696990075Sobrien  finish_fname_decls ();
697018334Speter
697190075Sobrien  /* Tie off the statement tree for this function.  */
697290075Sobrien  finish_stmt_tree (&DECL_SAVED_TREE (fndecl));
697396263Sobrien
697496263Sobrien  /* Complain if there's just no return statement.  */
697596263Sobrien  if (warn_return_type
697696263Sobrien      && TREE_CODE (TREE_TYPE (TREE_TYPE (fndecl))) != VOID_TYPE
697796263Sobrien      && !current_function_returns_value && !current_function_returns_null
697896263Sobrien      /* Don't complain if we abort.  */
697996263Sobrien      && !current_function_returns_abnormally
698096263Sobrien      /* Don't warn for main().  */
698196263Sobrien      && !MAIN_NAME_P (DECL_NAME (fndecl))
698296263Sobrien      /* Or if they didn't actually specify a return type.  */
698396263Sobrien      && !C_FUNCTION_IMPLICIT_INT (fndecl)
698496263Sobrien      /* Normally, with -Wreturn-type, flow will complain.  Unless we're an
698596263Sobrien	 inline function, as we might never be compiled separately.  */
698696263Sobrien      && DECL_INLINE (fndecl))
698796263Sobrien    warning ("no return statement in function returning non-void");
698896263Sobrien
698990075Sobrien  /* Clear out memory we no longer need.  */
699090075Sobrien  free_after_parsing (cfun);
699190075Sobrien  /* Since we never call rest_of_compilation, we never clear
699290075Sobrien     CFUN.  Do so explicitly.  */
699390075Sobrien  free_after_compilation (cfun);
699490075Sobrien  cfun = NULL;
699590075Sobrien
699690075Sobrien  if (! nested)
699790075Sobrien    {
699890075Sobrien      /* Generate RTL for the body of this function.  */
699996263Sobrien      c_expand_body (fndecl, nested, can_defer_p);
700096263Sobrien
700190075Sobrien      /* Let the error reporting routines know that we're outside a
700290075Sobrien	 function.  For a nested function, this value is used in
700390075Sobrien	 pop_c_function_context and then reset via pop_function_context.  */
700490075Sobrien      current_function_decl = NULL;
700590075Sobrien    }
700690075Sobrien}
700790075Sobrien
700890075Sobrien/* Generate the RTL for a deferred function FNDECL.  */
700990075Sobrien
701090075Sobrienvoid
701190075Sobrienc_expand_deferred_function (fndecl)
701290075Sobrien     tree fndecl;
701390075Sobrien{
701490075Sobrien  /* DECL_INLINE or DECL_RESULT might got cleared after the inline
701590075Sobrien     function was deferred, e.g. in duplicate_decls.  */
701690075Sobrien  if (DECL_INLINE (fndecl) && DECL_RESULT (fndecl))
701790075Sobrien    {
701890075Sobrien      c_expand_body (fndecl, 0, 0);
701990075Sobrien      current_function_decl = NULL;
702090075Sobrien    }
702190075Sobrien}
702290075Sobrien
702390075Sobrien/* Generate the RTL for the body of FNDECL.  If NESTED_P is non-zero,
702490075Sobrien   then we are already in the process of generating RTL for another
702590075Sobrien   function.  If can_defer_p is zero, we won't attempt to defer the
702690075Sobrien   generation of RTL.  */
702790075Sobrien
702890075Sobrienstatic void
702990075Sobrienc_expand_body (fndecl, nested_p, can_defer_p)
703090075Sobrien     tree fndecl;
703190075Sobrien     int nested_p, can_defer_p;
703290075Sobrien{
703390075Sobrien  int uninlinable = 1;
703490075Sobrien
703590075Sobrien  /* There's no reason to do any of the work here if we're only doing
703690075Sobrien     semantic analysis; this code just generates RTL.  */
703790075Sobrien  if (flag_syntax_only)
703890075Sobrien    return;
703990075Sobrien
704090075Sobrien  if (flag_inline_trees)
704190075Sobrien    {
704290075Sobrien      /* First, cache whether the current function is inlinable.  Some
704390075Sobrien         predicates depend on cfun and current_function_decl to
704490075Sobrien         function completely.  */
704590075Sobrien      timevar_push (TV_INTEGRATION);
704690075Sobrien      uninlinable = ! tree_inlinable_function_p (fndecl);
704790075Sobrien
704890075Sobrien      if (! uninlinable && can_defer_p
704990075Sobrien	  /* Save function tree for inlining.  Should return 0 if the
705090075Sobrien             language does not support function deferring or the
705190075Sobrien             function could not be deferred.  */
705290075Sobrien	  && defer_fn (fndecl))
705390075Sobrien	{
705490075Sobrien	  /* Let the back-end know that this function exists.  */
705590075Sobrien	  (*debug_hooks->deferred_inline_function) (fndecl);
705690075Sobrien          timevar_pop (TV_INTEGRATION);
705790075Sobrien	  return;
705890075Sobrien	}
705990075Sobrien
706090075Sobrien      /* Then, inline any functions called in it.  */
706190075Sobrien      optimize_inline_calls (fndecl);
706290075Sobrien      timevar_pop (TV_INTEGRATION);
706390075Sobrien    }
706490075Sobrien
706590075Sobrien  timevar_push (TV_EXPAND);
706690075Sobrien
706790075Sobrien  if (nested_p)
706890075Sobrien    {
706990075Sobrien      /* Make sure that we will evaluate variable-sized types involved
707090075Sobrien	 in our function's type.  */
707190075Sobrien      expand_pending_sizes (DECL_LANG_SPECIFIC (fndecl)->pending_sizes);
707290075Sobrien      /* Squirrel away our current state.  */
707390075Sobrien      push_function_context ();
707490075Sobrien    }
707590075Sobrien
707690075Sobrien  /* Initialize the RTL code for the function.  */
707790075Sobrien  current_function_decl = fndecl;
707890075Sobrien  input_filename = DECL_SOURCE_FILE (fndecl);
707990075Sobrien  init_function_start (fndecl, input_filename, DECL_SOURCE_LINE (fndecl));
708090075Sobrien
708190075Sobrien  /* This function is being processed in whole-function mode.  */
708290075Sobrien  cfun->x_whole_function_mode_p = 1;
708390075Sobrien
708490075Sobrien  /* Even though we're inside a function body, we still don't want to
708590075Sobrien     call expand_expr to calculate the size of a variable-sized array.
708690075Sobrien     We haven't necessarily assigned RTL to all variables yet, so it's
708790075Sobrien     not safe to try to expand expressions involving them.  */
708890075Sobrien  immediate_size_expand = 0;
708990075Sobrien  cfun->x_dont_save_pending_sizes_p = 1;
709090075Sobrien
709190075Sobrien  /* If this is a varargs function, inform function.c.  */
709290075Sobrien  if (c_function_varargs)
709390075Sobrien    mark_varargs ();
709490075Sobrien
709590075Sobrien  /* Set up parameters and prepare for return, for the function.  */
709690075Sobrien  expand_function_start (fndecl, 0);
709790075Sobrien
709890075Sobrien  /* If this function is `main', emit a call to `__main'
709990075Sobrien     to run global initializers, etc.  */
710090075Sobrien  if (DECL_NAME (fndecl)
710190075Sobrien      && MAIN_NAME_P (DECL_NAME (fndecl))
710290075Sobrien      && DECL_CONTEXT (fndecl) == NULL_TREE)
710390075Sobrien    expand_main_function ();
710490075Sobrien
710590075Sobrien  /* Generate the RTL for this function.  */
710690075Sobrien  expand_stmt (DECL_SAVED_TREE (fndecl));
710790075Sobrien  if (uninlinable)
710890075Sobrien    {
710990075Sobrien      /* Allow the body of the function to be garbage collected.  */
711090075Sobrien      DECL_SAVED_TREE (fndecl) = NULL_TREE;
711190075Sobrien    }
711290075Sobrien
711390075Sobrien  /* We hard-wired immediate_size_expand to zero above.
711490075Sobrien     expand_function_end will decrement this variable.  So, we set the
711590075Sobrien     variable to one here, so that after the decrement it will remain
711690075Sobrien     zero.  */
711790075Sobrien  immediate_size_expand = 1;
711890075Sobrien
711990075Sobrien  /* Allow language dialects to perform special processing.  */
712090075Sobrien  if (lang_expand_function_end)
712190075Sobrien    (*lang_expand_function_end) ();
712290075Sobrien
712318334Speter  /* Generate rtl for function exit.  */
712418334Speter  expand_function_end (input_filename, lineno, 0);
712518334Speter
712690075Sobrien  /* If this is a nested function, protect the local variables in the stack
712790075Sobrien     above us from being collected while we're compiling this function.  */
712890075Sobrien  if (nested_p)
712990075Sobrien    ggc_push_context ();
713018334Speter
713118334Speter  /* Run the optimizers and output the assembler code for this function.  */
713218334Speter  rest_of_compilation (fndecl);
713318334Speter
713490075Sobrien  /* Undo the GC context switch.  */
713590075Sobrien  if (nested_p)
713690075Sobrien    ggc_pop_context ();
713718334Speter
713818334Speter  /* With just -W, complain only if function returns both with
713918334Speter     and without a value.  */
714090075Sobrien  if (extra_warnings
714190075Sobrien      && current_function_returns_value
714290075Sobrien      && current_function_returns_null)
714318334Speter    warning ("this function may return with or without a value");
714418334Speter
714518334Speter  /* If requested, warn about function definitions where the function will
714618334Speter     return a value (usually of some struct or union type) which itself will
714718334Speter     take up a lot of stack space.  */
714818334Speter
714918334Speter  if (warn_larger_than && !DECL_EXTERNAL (fndecl) && TREE_TYPE (fndecl))
715018334Speter    {
715190075Sobrien      tree ret_type = TREE_TYPE (TREE_TYPE (fndecl));
715218334Speter
715390075Sobrien      if (ret_type && TYPE_SIZE_UNIT (ret_type)
715490075Sobrien	  && TREE_CODE (TYPE_SIZE_UNIT (ret_type)) == INTEGER_CST
715590075Sobrien	  && 0 < compare_tree_int (TYPE_SIZE_UNIT (ret_type),
715690075Sobrien				   larger_than_size))
715718334Speter	{
715890075Sobrien	  unsigned int size_as_int
715990075Sobrien	    = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (ret_type));
716018334Speter
716190075Sobrien	  if (compare_tree_int (TYPE_SIZE_UNIT (ret_type), size_as_int) == 0)
716290075Sobrien	    warning_with_decl (fndecl,
716390075Sobrien			       "size of return value of `%s' is %u bytes",
716490075Sobrien			       size_as_int);
716590075Sobrien	  else
716690075Sobrien	    warning_with_decl (fndecl,
716790075Sobrien			       "size of return value of `%s' is larger than %d bytes",
716890075Sobrien			       larger_than_size);
716918334Speter	}
717018334Speter    }
717118334Speter
717290075Sobrien  if (DECL_SAVED_INSNS (fndecl) == 0 && ! nested_p
717390075Sobrien      && ! flag_inline_trees)
717418334Speter    {
717590075Sobrien      /* Stop pointing to the local nodes about to be freed.
717690075Sobrien	 But DECL_INITIAL must remain nonzero so we know this
717790075Sobrien	 was an actual function definition.
717890075Sobrien	 For a nested function, this is done in pop_c_function_context.
717990075Sobrien	 If rest_of_compilation set this to 0, leave it 0.  */
718018334Speter      if (DECL_INITIAL (fndecl) != 0)
718118334Speter	DECL_INITIAL (fndecl) = error_mark_node;
718290075Sobrien
718318334Speter      DECL_ARGUMENTS (fndecl) = 0;
718418334Speter    }
718518334Speter
718618334Speter  if (DECL_STATIC_CONSTRUCTOR (fndecl))
718718334Speter    {
718890075Sobrien      if (targetm.have_ctors_dtors)
718990075Sobrien	(* targetm.asm_out.constructor) (XEXP (DECL_RTL (fndecl), 0),
719090075Sobrien				         DEFAULT_INIT_PRIORITY);
719118334Speter      else
719290075Sobrien	static_ctors = tree_cons (NULL_TREE, fndecl, static_ctors);
719318334Speter    }
719490075Sobrien
719518334Speter  if (DECL_STATIC_DESTRUCTOR (fndecl))
719618334Speter    {
719790075Sobrien      if (targetm.have_ctors_dtors)
719890075Sobrien	(* targetm.asm_out.destructor) (XEXP (DECL_RTL (fndecl), 0),
719990075Sobrien				        DEFAULT_INIT_PRIORITY);
720018334Speter      else
720190075Sobrien	static_dtors = tree_cons (NULL_TREE, fndecl, static_dtors);
720218334Speter    }
720318334Speter
720490075Sobrien  if (nested_p)
720590075Sobrien    /* Return to the enclosing function.  */
720690075Sobrien    pop_function_context ();
720790075Sobrien  timevar_pop (TV_EXPAND);
720890075Sobrien}
720990075Sobrien
721090075Sobrien/* Check the declarations given in a for-loop for satisfying the C99
721190075Sobrien   constraints.  */
721290075Sobrienvoid
721390075Sobriencheck_for_loop_decls ()
721490075Sobrien{
721590075Sobrien  tree t;
721690075Sobrien
721790075Sobrien  if (!flag_isoc99)
721818334Speter    {
721990075Sobrien      /* If we get here, declarations have been used in a for loop without
722090075Sobrien	 the C99 for loop scope.  This doesn't make much sense, so don't
722190075Sobrien	 allow it.  */
722290075Sobrien      error ("`for' loop initial declaration used outside C99 mode");
722390075Sobrien      return;
722418334Speter    }
722590075Sobrien  /* C99 subclause 6.8.5 paragraph 3:
722690075Sobrien
722790075Sobrien       [#3]  The  declaration  part  of  a for statement shall only
722890075Sobrien       declare identifiers for objects having storage class auto or
722990075Sobrien       register.
723090075Sobrien
723190075Sobrien     It isn't clear whether, in this sentence, "identifiers" binds to
723290075Sobrien     "shall only declare" or to "objects" - that is, whether all identifiers
723390075Sobrien     declared must be identifiers for objects, or whether the restriction
723490075Sobrien     only applies to those that are.  (A question on this in comp.std.c
723590075Sobrien     in November 2000 received no answer.)  We implement the strictest
723690075Sobrien     interpretation, to avoid creating an extension which later causes
723790075Sobrien     problems.  */
723890075Sobrien
723990075Sobrien  for (t = gettags (); t; t = TREE_CHAIN (t))
724090075Sobrien    {
724190075Sobrien      if (TREE_PURPOSE (t) != 0)
724290075Sobrien        {
724390075Sobrien          enum tree_code code = TREE_CODE (TREE_VALUE (t));
724490075Sobrien
724590075Sobrien          if (code == RECORD_TYPE)
724690075Sobrien            error ("`struct %s' declared in `for' loop initial declaration",
724790075Sobrien                   IDENTIFIER_POINTER (TREE_PURPOSE (t)));
724890075Sobrien          else if (code == UNION_TYPE)
724990075Sobrien            error ("`union %s' declared in `for' loop initial declaration",
725090075Sobrien                   IDENTIFIER_POINTER (TREE_PURPOSE (t)));
725190075Sobrien          else
725290075Sobrien            error ("`enum %s' declared in `for' loop initial declaration",
725390075Sobrien                   IDENTIFIER_POINTER (TREE_PURPOSE (t)));
725490075Sobrien        }
725590075Sobrien    }
725690075Sobrien
725790075Sobrien  for (t = getdecls (); t; t = TREE_CHAIN (t))
725890075Sobrien    {
725990075Sobrien      if (TREE_CODE (t) != VAR_DECL && DECL_NAME (t))
726090075Sobrien	error_with_decl (t, "declaration of non-variable `%s' in `for' loop initial declaration");
726190075Sobrien      else if (TREE_STATIC (t))
726290075Sobrien	error_with_decl (t, "declaration of static variable `%s' in `for' loop initial declaration");
726390075Sobrien      else if (DECL_EXTERNAL (t))
726490075Sobrien	error_with_decl (t, "declaration of `extern' variable `%s' in `for' loop initial declaration");
726590075Sobrien    }
726618334Speter}
726718334Speter
726818334Speter/* Save and restore the variables in this file and elsewhere
726918334Speter   that keep track of the progress of compilation of the current function.
727018334Speter   Used for nested functions.  */
727118334Speter
727290075Sobrienstruct c_language_function
727318334Speter{
727490075Sobrien  struct language_function base;
727518334Speter  tree named_labels;
727618334Speter  tree shadowed_labels;
727718334Speter  int returns_value;
727818334Speter  int returns_null;
727996263Sobrien  int returns_abnormally;
728018334Speter  int warn_about_return_type;
728118334Speter  int extern_inline;
728218334Speter  struct binding_level *binding_level;
728318334Speter};
728418334Speter
728518334Speter/* Save and reinitialize the variables
728618334Speter   used during compilation of a C function.  */
728718334Speter
728818334Spetervoid
728990075Sobrienpush_c_function_context (f)
729090075Sobrien     struct function *f;
729118334Speter{
729290075Sobrien  struct c_language_function *p;
729390075Sobrien  p = ((struct c_language_function *)
729490075Sobrien       xmalloc (sizeof (struct c_language_function)));
729590075Sobrien  f->language = (struct language_function *) p;
729618334Speter
729790075Sobrien  p->base.x_stmt_tree = c_stmt_tree;
729890075Sobrien  p->base.x_scope_stmt_stack = c_scope_stmt_stack;
729918334Speter  p->named_labels = named_labels;
730018334Speter  p->shadowed_labels = shadowed_labels;
730118334Speter  p->returns_value = current_function_returns_value;
730218334Speter  p->returns_null = current_function_returns_null;
730396263Sobrien  p->returns_abnormally = current_function_returns_abnormally;
730418334Speter  p->warn_about_return_type = warn_about_return_type;
730518334Speter  p->extern_inline = current_extern_inline;
730618334Speter  p->binding_level = current_binding_level;
730718334Speter}
730818334Speter
730918334Speter/* Restore the variables used during compilation of a C function.  */
731018334Speter
731118334Spetervoid
731290075Sobrienpop_c_function_context (f)
731390075Sobrien     struct function *f;
731418334Speter{
731590075Sobrien  struct c_language_function *p
731690075Sobrien    = (struct c_language_function *) f->language;
731718334Speter  tree link;
731818334Speter
731918334Speter  /* Bring back all the labels that were shadowed.  */
732018334Speter  for (link = shadowed_labels; link; link = TREE_CHAIN (link))
732118334Speter    if (DECL_NAME (TREE_VALUE (link)) != 0)
732218334Speter      IDENTIFIER_LABEL_VALUE (DECL_NAME (TREE_VALUE (link)))
732318334Speter	= TREE_VALUE (link);
732418334Speter
732590075Sobrien  if (DECL_SAVED_INSNS (current_function_decl) == 0
732690075Sobrien      && DECL_SAVED_TREE (current_function_decl) == NULL_TREE)
732718334Speter    {
732818334Speter      /* Stop pointing to the local nodes about to be freed.  */
732918334Speter      /* But DECL_INITIAL must remain nonzero so we know this
733018334Speter	 was an actual function definition.  */
733118334Speter      DECL_INITIAL (current_function_decl) = error_mark_node;
733218334Speter      DECL_ARGUMENTS (current_function_decl) = 0;
733318334Speter    }
733418334Speter
733590075Sobrien  c_stmt_tree = p->base.x_stmt_tree;
733690075Sobrien  c_scope_stmt_stack = p->base.x_scope_stmt_stack;
733718334Speter  named_labels = p->named_labels;
733818334Speter  shadowed_labels = p->shadowed_labels;
733918334Speter  current_function_returns_value = p->returns_value;
734018334Speter  current_function_returns_null = p->returns_null;
734196263Sobrien  current_function_returns_abnormally = p->returns_abnormally;
734218334Speter  warn_about_return_type = p->warn_about_return_type;
734318334Speter  current_extern_inline = p->extern_inline;
734418334Speter  current_binding_level = p->binding_level;
734518334Speter
734618334Speter  free (p);
734790075Sobrien  f->language = 0;
734818334Speter}
734918334Speter
735090075Sobrien/* Mark the language specific parts of F for GC.  */
735118334Speter
735218334Spetervoid
735390075Sobrienmark_c_function_context (f)
735490075Sobrien     struct function *f;
735590075Sobrien{
735690075Sobrien  struct c_language_function *p
735790075Sobrien    = (struct c_language_function *) f->language;
735890075Sobrien
735990075Sobrien  if (p == 0)
736090075Sobrien    return;
736190075Sobrien
736290075Sobrien  mark_c_language_function (&p->base);
736390075Sobrien  ggc_mark_tree (p->shadowed_labels);
736490075Sobrien  ggc_mark_tree (p->named_labels);
736590075Sobrien  mark_binding_level (&p->binding_level);
736690075Sobrien}
736790075Sobrien
736890075Sobrien/* Copy the DECL_LANG_SPECIFIC data associated with NODE.  */
736990075Sobrien
737090075Sobrienvoid
737190075Sobriencopy_lang_decl (decl)
737290075Sobrien     tree decl;
737390075Sobrien{
737490075Sobrien  struct lang_decl *ld;
737590075Sobrien
737690075Sobrien  if (!DECL_LANG_SPECIFIC (decl))
737790075Sobrien    return;
737890075Sobrien
737990075Sobrien  ld = (struct lang_decl *) ggc_alloc (sizeof (struct lang_decl));
738090075Sobrien  memcpy ((char *) ld, (char *) DECL_LANG_SPECIFIC (decl),
738190075Sobrien	  sizeof (struct lang_decl));
738290075Sobrien  DECL_LANG_SPECIFIC (decl) = ld;
738390075Sobrien}
738490075Sobrien
738590075Sobrien/* Mark the language specific bits in T for GC.  */
738690075Sobrien
738790075Sobrienvoid
738890075Sobrienlang_mark_tree (t)
738990075Sobrien     tree t;
739090075Sobrien{
739190075Sobrien  if (TREE_CODE (t) == IDENTIFIER_NODE)
739290075Sobrien    {
739390075Sobrien      struct lang_identifier *i = (struct lang_identifier *) t;
739490075Sobrien      ggc_mark_tree (i->global_value);
739590075Sobrien      ggc_mark_tree (i->local_value);
739690075Sobrien      ggc_mark_tree (i->label_value);
739790075Sobrien      ggc_mark_tree (i->implicit_decl);
739890075Sobrien      ggc_mark_tree (i->error_locus);
739990075Sobrien      ggc_mark_tree (i->limbo_value);
740090075Sobrien    }
740190075Sobrien  else if (TYPE_P (t) && TYPE_LANG_SPECIFIC (t))
740290075Sobrien    ggc_mark (TYPE_LANG_SPECIFIC (t));
740390075Sobrien  else if (DECL_P (t) && DECL_LANG_SPECIFIC (t))
740490075Sobrien    {
740590075Sobrien      ggc_mark (DECL_LANG_SPECIFIC (t));
740690075Sobrien      c_mark_lang_decl (&DECL_LANG_SPECIFIC (t)->base);
740790075Sobrien      ggc_mark_tree (DECL_LANG_SPECIFIC (t)->pending_sizes);
740890075Sobrien    }
740990075Sobrien}
741090075Sobrien
741190075Sobrien/* The functions below are required for functionality of doing
741290075Sobrien   function at once processing in the C front end. Currently these
741390075Sobrien   functions are not called from anywhere in the C front end, but as
741490075Sobrien   these changes continue, that will change.  */
741590075Sobrien
741690075Sobrien/* Returns non-zero if the current statement is a full expression,
741790075Sobrien   i.e. temporaries created during that statement should be destroyed
741890075Sobrien   at the end of the statement.  */
741990075Sobrien
742090075Sobrienint
742190075Sobrienstmts_are_full_exprs_p ()
742290075Sobrien{
742390075Sobrien  return 0;
742490075Sobrien}
742590075Sobrien
742690075Sobrien/* Returns the stmt_tree (if any) to which statements are currently
742790075Sobrien   being added.  If there is no active statement-tree, NULL is
742890075Sobrien   returned.  */
742990075Sobrien
743090075Sobrienstmt_tree
743190075Sobriencurrent_stmt_tree ()
743290075Sobrien{
743390075Sobrien  return &c_stmt_tree;
743490075Sobrien}
743590075Sobrien
743690075Sobrien/* Returns the stack of SCOPE_STMTs for the current function.  */
743790075Sobrien
743890075Sobrientree *
743990075Sobriencurrent_scope_stmt_stack ()
744090075Sobrien{
744190075Sobrien  return &c_scope_stmt_stack;
744290075Sobrien}
744390075Sobrien
744490075Sobrien/* Nonzero if TYPE is an anonymous union or struct type.  Always 0 in
744590075Sobrien   C.  */
744690075Sobrien
744790075Sobrienint
744890075Sobrienanon_aggr_type_p (node)
744950397Sobrien     tree node ATTRIBUTE_UNUSED;
745018334Speter{
745190075Sobrien  return 0;
745218334Speter}
745390075Sobrien
745490075Sobrien/* Dummy function in place of callback used by C++.  */
745590075Sobrien
745690075Sobrienvoid
745790075Sobrienextract_interface_info ()
745890075Sobrien{
745990075Sobrien}
746090075Sobrien
746190075Sobrien/* Return a new COMPOUND_STMT, after adding it to the current
746290075Sobrien   statement tree.  */
746390075Sobrien
746490075Sobrientree
746590075Sobrienc_begin_compound_stmt ()
746690075Sobrien{
746790075Sobrien  tree stmt;
746890075Sobrien
746990075Sobrien  /* Create the COMPOUND_STMT.  */
747090075Sobrien  stmt = add_stmt (build_stmt (COMPOUND_STMT, NULL_TREE));
747190075Sobrien
747290075Sobrien  return stmt;
747390075Sobrien}
747490075Sobrien
747590075Sobrien/* Expand T (a DECL_STMT) if it declares an entity not handled by the
747690075Sobrien   common code.  */
747790075Sobrien
747890075Sobrienvoid
747990075Sobrienc_expand_decl_stmt (t)
748090075Sobrien     tree t;
748190075Sobrien{
748290075Sobrien  tree decl = DECL_STMT_DECL (t);
748390075Sobrien
748490075Sobrien  /* Expand nested functions.  */
748590075Sobrien  if (TREE_CODE (decl) == FUNCTION_DECL
748690075Sobrien      && DECL_CONTEXT (decl) == current_function_decl
748790075Sobrien      && DECL_SAVED_TREE (decl))
748890075Sobrien    c_expand_body (decl, /*nested_p=*/1, /*can_defer_p=*/0);
748990075Sobrien}
749090075Sobrien
749190075Sobrien/* Return the IDENTIFIER_GLOBAL_VALUE of T, for use in common code, since
749290075Sobrien   the definition of IDENTIFIER_GLOBAL_VALUE is different for C and C++.  */
749390075Sobrien
749490075Sobrientree
749590075Sobrienidentifier_global_value	(t)
749690075Sobrien     tree t;
749790075Sobrien{
749890075Sobrien  return IDENTIFIER_GLOBAL_VALUE (t);
749990075Sobrien}
750090075Sobrien
750190075Sobrien/* Record a builtin type for C.  If NAME is non-NULL, it is the name used;
750290075Sobrien   otherwise the name is found in ridpointers from RID_INDEX.  */
750390075Sobrien
750490075Sobrienvoid
750590075Sobrienrecord_builtin_type (rid_index, name, type)
750690075Sobrien     enum rid rid_index;
750790075Sobrien     const char *name;
750890075Sobrien     tree type;
750990075Sobrien{
751090075Sobrien  tree id;
751190075Sobrien  if (name == 0)
751290075Sobrien    id = ridpointers[(int) rid_index];
751390075Sobrien  else
751490075Sobrien    id = get_identifier (name);
751590075Sobrien  pushdecl (build_decl (TYPE_DECL, id, type));
751690075Sobrien}
751790075Sobrien
751890075Sobrien/* Build the void_list_node (void_type_node having been created).  */
751990075Sobrientree
752090075Sobrienbuild_void_list_node ()
752190075Sobrien{
752290075Sobrien  tree t = build_tree_list (NULL_TREE, void_type_node);
752390075Sobrien  return t;
752490075Sobrien}
7525