X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fc-decl.c;h=e60ab9de785fcdcb5e71df085f8231296d60fc97;hb=d2b79698ed71bf318fcf9aafa8a4dd0d903bf317;hp=940d4b18393c7298208f13e55661c1e0353dbd14;hpb=a4e59c310c504ec95d282ad7bc023e836e4cc0ec;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/c-decl.c b/gcc/c-decl.c index 940d4b18393..e60ab9de785 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -1,6 +1,6 @@ /* Process declarations and variables for C compiler. - Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000 - Free Software Foundation, Inc. + Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, + 2001 Free Software Foundation, Inc. This file is part of GNU CC. @@ -38,14 +38,9 @@ Boston, MA 02111-1307, USA. */ #include "c-tree.h" #include "c-lex.h" #include "toplev.h" -#include "defaults.h" #include "ggc.h" #include "tm_p.h" - -#if USE_CPPLIB #include "cpplib.h" -extern cpp_reader parse_in; -#endif /* In grokdeclarator, distinguish syntactic contexts of declarators. */ enum decl_context @@ -56,31 +51,7 @@ enum decl_context BITFIELD, /* Likewise but with specified width */ TYPENAME}; /* Typename (inside cast or sizeof) */ -/* We let tm.h override the types used here, to handle trivial differences - such as the choice of unsigned int or long unsigned int for size_t. - When machines start needing nontrivial differences in the size type, - it would be best to do something here to figure out automatically - from other information what type to use. */ - -#ifndef SIZE_TYPE -#define SIZE_TYPE "long unsigned int" -#endif - -#ifndef PTRDIFF_TYPE -#define PTRDIFF_TYPE "long int" -#endif - -#ifndef WCHAR_TYPE -#define WCHAR_TYPE "int" -#endif - -#ifndef WINT_TYPE -#define WINT_TYPE "unsigned int" -#endif -/* Do GC. */ -int ggc_p = 1; - /* Nonzero if we have seen an invalid cross reference to a struct, union, or enum, but not yet printed the message. */ @@ -133,11 +104,6 @@ static struct stmt_tree_s c_stmt_tree; static tree c_scope_stmt_stack; -/* Nonzero if __FUNCTION__ and its ilk have been declared in this - function. */ - -static int c_function_name_declared_p; - /* A list (chain of TREE_LIST nodes) of all LABEL_DECLs in the function that have names. Here so we can clear out their names' definitions at the end of the function. */ @@ -308,7 +274,7 @@ static tree grokdeclarator PARAMS ((tree, tree, enum decl_context, int)); static tree grokparms PARAMS ((tree, int)); static void layout_array_type PARAMS ((tree)); -static tree c_make_fname_decl PARAMS ((tree, const char *, int)); +static tree c_make_fname_decl PARAMS ((tree, int)); static void c_expand_body PARAMS ((tree, int)); /* C-specific option variables. */ @@ -318,32 +284,15 @@ static void c_expand_body PARAMS ((tree, int)); int flag_cond_mismatch; -/* Nonzero means give `double' the same size as `float'. */ - -int flag_short_double; - -/* Nonzero means give `wchar_t' the same size as `short'. */ - -int flag_short_wchar; - /* Nonzero means don't recognize the keyword `asm'. */ int flag_no_asm; -/* Nonzero means don't recognize any builtin functions. */ - -int flag_no_builtin; - -/* Nonzero means don't recognize the non-ANSI builtin functions. - -ansi sets this. */ - -int flag_no_nonansi_builtin; - /* Nonzero means do some things the same way PCC does. */ int flag_traditional; -/* Nonzero means enable C89 Amendment 1 features, other than digraphs. */ +/* Nonzero means enable C89 Amendment 1 features. */ int flag_isoc94 = 0; @@ -351,10 +300,6 @@ int flag_isoc94 = 0; int flag_isoc99 = 0; -/* Nonzero means accept digraphs. */ - -int flag_digraphs = 1; - /* Nonzero means that we have builtin functions, and main is an int */ int flag_hosted = 1; @@ -403,9 +348,9 @@ int warn_cast_qual; int warn_bad_function_cast; -/* Warn about functions which might be candidates for attribute noreturn. */ +/* Warn about functions which might be candidates for format attributes. */ -int warn_missing_noreturn; +int warn_missing_format_attribute; /* Warn about traditional constructs whose meanings changed in ANSI C. */ @@ -444,10 +389,6 @@ int warn_redundant_decls = 0; int warn_nested_externs = 0; -/* Warn about *printf or *scanf format/argument anomalies. */ - -int warn_format; - /* Warn about a subscript that has type char. */ int warn_char_subscripts = 0; @@ -507,19 +448,13 @@ c_decode_option (argc, argv) { int strings_processed; char *p = argv[0]; -#if USE_CPPLIB - strings_processed = cpp_handle_option (&parse_in, argc, argv); -#else - strings_processed = 0; -#endif /* ! USE_CPPLIB */ - if (!strcmp (p, "-lang-objc")) - c_language = clk_objective_c; - else if (!strcmp (p, "-ftraditional") || !strcmp (p, "-traditional")) + strings_processed = cpp_handle_option (parse_in, argc, argv); + + if (!strcmp (p, "-ftraditional") || !strcmp (p, "-traditional")) { flag_traditional = 1; flag_writable_strings = 1; - flag_digraphs = 0; } else if (!strcmp (p, "-fallow-single-precision")) flag_allow_single_precision = 1; @@ -540,7 +475,6 @@ c_decode_option (argc, argv) { flag_traditional = 0; flag_writable_strings = 0; - flag_digraphs = 1; } else if (!strncmp (p, "-std=", 5)) { @@ -560,9 +494,8 @@ c_decode_option (argc, argv) || !strcmp (argstart, "c89")) { iso_1990: - flag_digraphs = 0; flag_isoc94 = 0; - iso_1990_digraphs: + iso_1994: flag_traditional = 0; flag_writable_strings = 0; flag_no_asm = 1; @@ -572,9 +505,8 @@ c_decode_option (argc, argv) } else if (!strcmp (argstart, "iso9899:199409")) { - flag_digraphs = 1; flag_isoc94 = 1; - goto iso_1990_digraphs; + goto iso_1994; } else if (!strcmp (argstart, "iso9899:199x") || !strcmp (argstart, "iso9899:1999") @@ -587,7 +519,6 @@ c_decode_option (argc, argv) flag_no_nonansi_builtin = 1; flag_noniso_default_format_attributes = 0; flag_isoc99 = 1; - flag_digraphs = 1; flag_isoc94 = 1; } else if (!strcmp (argstart, "gnu89")) @@ -598,7 +529,6 @@ c_decode_option (argc, argv) flag_no_nonansi_builtin = 0; flag_noniso_default_format_attributes = 1; flag_isoc99 = 0; - flag_digraphs = 1; flag_isoc94 = 0; } else if (!strcmp (argstart, "gnu9x") || !strcmp (argstart, "gnu99")) @@ -609,7 +539,6 @@ c_decode_option (argc, argv) flag_no_nonansi_builtin = 0; flag_noniso_default_format_attributes = 1; flag_isoc99 = 1; - flag_digraphs = 1; flag_isoc94 = 1; } else @@ -663,6 +592,8 @@ c_decode_option (argc, argv) flag_no_builtin = 0; else if (!strcmp (p, "-fno-builtin")) flag_no_builtin = 1; + else if (dump_switch_p (p)) + ; else if (!strcmp (p, "-ansi")) goto iso_1990; else if (!strcmp (p, "-Werror-implicit-function-declaration")) @@ -699,10 +630,12 @@ c_decode_option (argc, argv) warn_bad_function_cast = 1; else if (!strcmp (p, "-Wno-bad-function-cast")) warn_bad_function_cast = 0; - else if (!strcmp (p, "-Wmissing-noreturn")) - warn_missing_noreturn = 1; else if (!strcmp (p, "-Wno-missing-noreturn")) warn_missing_noreturn = 0; + else if (!strcmp (p, "-Wmissing-format-attribute")) + warn_missing_format_attribute = 1; + else if (!strcmp (p, "-Wno-missing-format-attribute")) + warn_missing_format_attribute = 0; else if (!strcmp (p, "-Wpointer-arith")) warn_pointer_arith = 1; else if (!strcmp (p, "-Wno-pointer-arith")) @@ -732,11 +665,27 @@ c_decode_option (argc, argv) else if (!strcmp (p, "-Wno-traditional")) warn_traditional = 0; else if (!strncmp (p, "-Wformat=", 9)) - warn_format = atol (p + 9); + set_Wformat (atoi (p + 9)); else if (!strcmp (p, "-Wformat")) - warn_format = 1; + set_Wformat (1); else if (!strcmp (p, "-Wno-format")) - warn_format = 0; + set_Wformat (0); + else if (!strcmp (p, "-Wformat-y2k")) + warn_format_y2k = 1; + else if (!strcmp (p, "-Wno-format-y2k")) + warn_format_y2k = 0; + else if (!strcmp (p, "-Wformat-extra-args")) + warn_format_extra_args = 1; + else if (!strcmp (p, "-Wno-format-extra-args")) + warn_format_extra_args = 0; + else if (!strcmp (p, "-Wformat-nonliteral")) + warn_format_nonliteral = 1; + else if (!strcmp (p, "-Wno-format-nonliteral")) + warn_format_nonliteral = 0; + else if (!strcmp (p, "-Wformat-security")) + warn_format_security = 1; + else if (!strcmp (p, "-Wno-format-security")) + warn_format_security = 0; else if (!strcmp (p, "-Wchar-subscripts")) warn_char_subscripts = 1; else if (!strcmp (p, "-Wno-char-subscripts")) @@ -753,6 +702,10 @@ c_decode_option (argc, argv) warn_return_type = 1; else if (!strcmp (p, "-Wno-return-type")) warn_return_type = 0; + else if (!strcmp (p, "-Wsequence-point")) + warn_sequence_point = 1; + else if (!strcmp (p, "-Wno-sequence-point")) + warn_sequence_point = 0; else if (!strcmp (p, "-Wcomment")) ; /* cpp handles this one. */ else if (!strcmp (p, "-Wno-comment")) @@ -811,9 +764,10 @@ c_decode_option (argc, argv) warn_return_type = 1; set_Wunused (1); warn_switch = 1; - warn_format = 1; + set_Wformat (1); warn_char_subscripts = 1; warn_parentheses = 1; + warn_sequence_point = 1; warn_missing_braces = 1; /* We set this to 2 here, but 1 in -Wmain, so -ffreestanding can turn it off only if it's not explicit. */ @@ -1294,6 +1248,10 @@ set_block (block) register tree block; { current_binding_level->this_block = block; + current_binding_level->names = chainon (current_binding_level->names, + BLOCK_VARS (block)); + current_binding_level->blocks = chainon (current_binding_level->blocks, + BLOCK_SUBBLOCKS (block)); } void @@ -1544,7 +1502,7 @@ duplicate_decls (newdecl, olddecl, different_binding_level) oldtype = trytype; } /* Accept harmless mismatch in first argument type also. - This is for ffs. */ + This is for the ffs and fprintf builtins. */ if (TYPE_ARG_TYPES (TREE_TYPE (newdecl)) != 0 && TYPE_ARG_TYPES (oldtype) != 0 && TREE_VALUE (TYPE_ARG_TYPES (newtype)) != 0 @@ -1833,11 +1791,17 @@ duplicate_decls (newdecl, olddecl, different_binding_level) if (TREE_CODE (newdecl) != FUNCTION_DECL || !DECL_BUILT_IN (olddecl)) { if (different_binding_level) - TREE_TYPE (newdecl) - = build_type_attribute_variant - (newtype, - merge_attributes (TYPE_ATTRIBUTES (newtype), - TYPE_ATTRIBUTES (oldtype))); + { + if (TYPE_ARG_TYPES (oldtype) != 0 + && TYPE_ARG_TYPES (newtype) == 0) + TREE_TYPE (newdecl) = common_type (newtype, oldtype); + else + TREE_TYPE (newdecl) + = build_type_attribute_variant + (newtype, + merge_attributes (TYPE_ATTRIBUTES (newtype), + TYPE_ATTRIBUTES (oldtype))); + } else TREE_TYPE (newdecl) = TREE_TYPE (olddecl) @@ -1869,7 +1833,7 @@ duplicate_decls (newdecl, olddecl, different_binding_level) } /* Keep the old rtl since we can safely use it. */ - DECL_RTL (newdecl) = DECL_RTL (olddecl); + COPY_DECL_RTL (olddecl, newdecl); /* Merge the type qualifiers. */ if (TREE_CODE (olddecl) == FUNCTION_DECL @@ -1926,7 +1890,7 @@ duplicate_decls (newdecl, olddecl, different_binding_level) /* Copy the assembler name. Currently, it can only be defined in the prototype. */ - DECL_ASSEMBLER_NAME (newdecl) = DECL_ASSEMBLER_NAME (olddecl); + COPY_DECL_ASSEMBLER_NAME (olddecl, newdecl); if (TREE_CODE (newdecl) == FUNCTION_DECL) { @@ -1989,12 +1953,27 @@ duplicate_decls (newdecl, olddecl, different_binding_level) if (TREE_CODE (newdecl) == FUNCTION_DECL) { - /* If either decl says `inline', this fn is inline, - unless its definition was passed already. */ - if (DECL_INLINE (newdecl) && DECL_INITIAL (olddecl) == 0) - DECL_INLINE (olddecl) = 1; + /* If we're redefining a function previously defined as extern + inline, make sure we emit debug info for the inline before we + throw it away, in case it was inlined into a function that hasn't + been written out yet. */ + if (new_is_definition && DECL_INITIAL (olddecl) && TREE_USED (olddecl)) + { + note_outlining_of_inline_function (olddecl); - DECL_INLINE (newdecl) = DECL_INLINE (olddecl); + /* The new defn must not be inline. */ + DECL_INLINE (newdecl) = 0; + DECL_UNINLINABLE (newdecl) = 1; + } + else + { + /* If either decl says `inline', this fn is inline, + unless its definition was passed already. */ + if (DECL_INLINE (newdecl) && DECL_INITIAL (olddecl) == 0) + DECL_INLINE (olddecl) = 1; + + DECL_INLINE (newdecl) = DECL_INLINE (olddecl); + } if (DECL_BUILT_IN (olddecl)) { @@ -2018,7 +1997,7 @@ duplicate_decls (newdecl, olddecl, different_binding_level) } /* Also preserve various other info from the definition. */ else if (! new_is_definition) - DECL_FRAME_SIZE (newdecl) = DECL_FRAME_SIZE (olddecl); + DECL_NUM_STMTS (newdecl) = DECL_NUM_STMTS (olddecl); if (! new_is_definition) { DECL_RESULT (newdecl) = DECL_RESULT (olddecl); @@ -2041,9 +2020,9 @@ duplicate_decls (newdecl, olddecl, different_binding_level) { register unsigned olddecl_uid = DECL_UID (olddecl); - bcopy ((char *) newdecl + sizeof (struct tree_common), - (char *) olddecl + sizeof (struct tree_common), - sizeof (struct tree_decl) - sizeof (struct tree_common)); + memcpy ((char *) olddecl + sizeof (struct tree_common), + (char *) newdecl + sizeof (struct tree_common), + sizeof (struct tree_decl) - sizeof (struct tree_common)); DECL_UID (olddecl) = olddecl_uid; } @@ -2381,7 +2360,7 @@ pushdecl (x) DECL_INITIAL (x) = (current_function_decl == oldglobal ? 0 : DECL_INITIAL (oldglobal)); DECL_SAVED_INSNS (x) = DECL_SAVED_INSNS (oldglobal); - DECL_FRAME_SIZE (x) = DECL_FRAME_SIZE (oldglobal); + DECL_NUM_STMTS (x) = DECL_NUM_STMTS (oldglobal); DECL_ARGUMENTS (x) = DECL_ARGUMENTS (oldglobal); DECL_RESULT (x) = DECL_RESULT (oldglobal); TREE_ASM_WRITTEN (x) = TREE_ASM_WRITTEN (oldglobal); @@ -2561,7 +2540,7 @@ implicitly_declare (functionid) /* This is a no-op in c-lang.c or something real in objc-actions.c. */ maybe_objc_check_decl (decl); - rest_of_decl_compilation (decl, NULL_PTR, 0, 0); + rest_of_decl_compilation (decl, NULL, 0, 0); if (implicit_warning) implicit_decl_warning (functionid); @@ -2843,6 +2822,7 @@ lookup_tag (code, name, binding_level, thislevel_only) int thislevel_only; { register struct binding_level *level; + int thislevel = 1; for (level = binding_level; level; level = level->level_chain) { @@ -2857,12 +2837,22 @@ lookup_tag (code, name, binding_level, thislevel_only) pending_invalid_xref = name; pending_invalid_xref_file = input_filename; pending_invalid_xref_line = lineno; + /* If in the same binding level as a declaration as a tag + of a different type, this must not be allowed to + shadow that tag, so give the error immediately. + (For example, "struct foo; union foo;" is invalid.) */ + if (thislevel) + pending_xref_error (); } return TREE_VALUE (tail); } } - if (thislevel_only && ! level->tag_transparent) - return NULL_TREE; + if (! level->tag_transparent) + { + if (thislevel_only) + return NULL_TREE; + thislevel = 0; + } } return NULL_TREE; } @@ -2973,9 +2963,6 @@ init_decl_processing () { register tree endlink; tree ptr_ftype_void, ptr_ftype_ptr; - int wchar_type_size; - tree array_domain_type; - tree t; current_function_decl = NULL; named_labels = NULL; @@ -2988,136 +2975,24 @@ init_decl_processing () build_common_tree_nodes (flag_signed_char); - /* Define `int' and `char' first so that dbx will output them first. */ - pushdecl (build_decl (TYPE_DECL, ridpointers[(int) RID_INT], - integer_type_node)); - pushdecl (build_decl (TYPE_DECL, get_identifier ("char"), - char_type_node)); - pushdecl (build_decl (TYPE_DECL, get_identifier ("long int"), - long_integer_type_node)); - pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned int"), - unsigned_type_node)); - pushdecl (build_decl (TYPE_DECL, get_identifier ("long unsigned int"), - long_unsigned_type_node)); - pushdecl (build_decl (TYPE_DECL, get_identifier ("long long int"), - long_long_integer_type_node)); - pushdecl (build_decl (TYPE_DECL, get_identifier ("long long unsigned int"), - long_long_unsigned_type_node)); - pushdecl (build_decl (TYPE_DECL, get_identifier ("short int"), - short_integer_type_node)); - pushdecl (build_decl (TYPE_DECL, get_identifier ("short unsigned int"), - short_unsigned_type_node)); - pushdecl (build_decl (TYPE_DECL, get_identifier ("signed char"), - signed_char_type_node)); - pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned char"), - unsigned_char_type_node)); - pushdecl (build_decl (TYPE_DECL, NULL_TREE, intQI_type_node)); - pushdecl (build_decl (TYPE_DECL, NULL_TREE, intHI_type_node)); - pushdecl (build_decl (TYPE_DECL, NULL_TREE, intSI_type_node)); - pushdecl (build_decl (TYPE_DECL, NULL_TREE, intDI_type_node)); -#if HOST_BITS_PER_WIDE_INT >= 64 - pushdecl (build_decl (TYPE_DECL, NULL_TREE, intTI_type_node)); -#endif - pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intQI_type_node)); - pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intHI_type_node)); - pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intSI_type_node)); - pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intDI_type_node)); -#if HOST_BITS_PER_WIDE_INT >= 64 - pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intTI_type_node)); -#endif - - /* `unsigned long' is the standard type for sizeof. - Traditionally, use a signed type. - Note that stddef.h uses `unsigned long', - and this must agree, even if long and int are the same size. */ - t = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (SIZE_TYPE))); - signed_size_type_node = signed_type (t); - if (flag_traditional && TREE_UNSIGNED (t)) - t = signed_type (t); - - c_size_type_node = t; - set_sizetype (t); - - /* Create the widest literal types. */ - widest_integer_literal_type_node - = make_signed_type (HOST_BITS_PER_WIDE_INT * 2); - widest_unsigned_literal_type_node - = make_unsigned_type (HOST_BITS_PER_WIDE_INT * 2); - pushdecl (build_decl (TYPE_DECL, NULL_TREE, - widest_integer_literal_type_node)); - pushdecl (build_decl (TYPE_DECL, NULL_TREE, - widest_unsigned_literal_type_node)); - - build_common_tree_nodes_2 (flag_short_double); - - pushdecl (build_decl (TYPE_DECL, ridpointers[(int) RID_FLOAT], - float_type_node)); - pushdecl (build_decl (TYPE_DECL, ridpointers[(int) RID_DOUBLE], - double_type_node)); - pushdecl (build_decl (TYPE_DECL, get_identifier ("long double"), - long_double_type_node)); - pushdecl (build_decl (TYPE_DECL, get_identifier ("complex int"), - complex_integer_type_node)); - pushdecl (build_decl (TYPE_DECL, get_identifier ("complex float"), - complex_float_type_node)); - pushdecl (build_decl (TYPE_DECL, get_identifier ("complex double"), - complex_double_type_node)); - pushdecl (build_decl (TYPE_DECL, get_identifier ("complex long double"), - complex_long_double_type_node)); - pushdecl (build_decl (TYPE_DECL, - ridpointers[(int) RID_VOID], void_type_node)); - -#ifdef MD_INIT_BUILTINS - MD_INIT_BUILTINS; -#endif - - wchar_type_node = get_identifier (flag_short_wchar - ? "short unsigned int" - : WCHAR_TYPE); - wchar_type_node = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (wchar_type_node)); - wchar_type_size = TYPE_PRECISION (wchar_type_node); - signed_wchar_type_node = signed_type (wchar_type_node); - unsigned_wchar_type_node = unsigned_type (wchar_type_node); - - wint_type_node = - TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (WINT_TYPE))); + c_common_nodes_and_builtins (); boolean_type_node = integer_type_node; boolean_true_node = integer_one_node; boolean_false_node = integer_zero_node; - string_type_node = build_pointer_type (char_type_node); - const_string_type_node - = build_pointer_type (build_type_variant (char_type_node, 1, 0)); - - /* Make a type to be the domain of a few array types - whose domains don't really matter. - 200 is small enough that it always fits in size_t - and large enough that it can hold most function names for the - initializations of __FUNCTION__ and __PRETTY_FUNCTION__. */ - array_domain_type = build_index_type (build_int_2 (200, 0)); - - /* make a type for arrays of characters. - With luck nothing will ever really depend on the length of this - array type. */ - char_array_type_node = build_array_type (char_type_node, array_domain_type); - - /* Likewise for arrays of ints. */ - int_array_type_node - = build_array_type (integer_type_node, array_domain_type); - - /* This is for wide string constants. */ - wchar_array_type_node - = build_array_type (wchar_type_node, array_domain_type); - - void_list_node = tree_cons (NULL_TREE, void_type_node, NULL_TREE); - - default_function_type = build_function_type (integer_type_node, NULL_TREE); - ptrdiff_type_node - = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (PTRDIFF_TYPE))); - unsigned_ptrdiff_type_node = unsigned_type (ptrdiff_type_node); - - c_common_nodes_and_builtins (0, flag_no_builtin, flag_no_nonansi_builtin); + /* With GCC, C99's _Bool is always of size 1. */ + c_bool_type_node = make_unsigned_type (CHAR_TYPE_SIZE); + TREE_SET_CODE (c_bool_type_node, BOOLEAN_TYPE); + TYPE_MAX_VALUE (c_bool_type_node) = build_int_2 (1, 0); + TREE_TYPE (TYPE_MAX_VALUE (c_bool_type_node)) = c_bool_type_node; + TYPE_PRECISION (c_bool_type_node) = 1; + pushdecl (build_decl (TYPE_DECL, get_identifier ("_Bool"), + c_bool_type_node)); + c_bool_false_node = build_int_2 (0, 0); + TREE_TYPE (c_bool_false_node) = c_bool_type_node; + c_bool_true_node = build_int_2 (1, 0); + TREE_TYPE (c_bool_true_node) = c_bool_type_node; endlink = void_list_node; ptr_ftype_void = build_function_type (ptr_type_node, endlink); @@ -3174,48 +3049,10 @@ init_decl_processing () g77_ulongint_type_node)); } - builtin_function ("__builtin_aggregate_incoming_address", - build_function_type (ptr_type_node, NULL_TREE), - BUILT_IN_AGGREGATE_INCOMING_ADDRESS, - BUILT_IN_NORMAL, NULL_PTR); - - /* Hooks for the DWARF 2 __throw routine. */ - builtin_function ("__builtin_unwind_init", - build_function_type (void_type_node, endlink), - BUILT_IN_UNWIND_INIT, BUILT_IN_NORMAL, NULL_PTR); - builtin_function ("__builtin_dwarf_cfa", ptr_ftype_void, - BUILT_IN_DWARF_CFA, BUILT_IN_NORMAL, NULL_PTR); - builtin_function ("__builtin_dwarf_fp_regnum", - build_function_type (unsigned_type_node, endlink), - BUILT_IN_DWARF_FP_REGNUM, BUILT_IN_NORMAL, NULL_PTR); - builtin_function ("__builtin_init_dwarf_reg_size_table", void_ftype_ptr, - BUILT_IN_INIT_DWARF_REG_SIZES, BUILT_IN_NORMAL, NULL_PTR); - builtin_function ("__builtin_frob_return_addr", ptr_ftype_ptr, - BUILT_IN_FROB_RETURN_ADDR, BUILT_IN_NORMAL, NULL_PTR); - builtin_function ("__builtin_extract_return_addr", ptr_ftype_ptr, - BUILT_IN_EXTRACT_RETURN_ADDR, BUILT_IN_NORMAL, NULL_PTR); - builtin_function - ("__builtin_eh_return", - build_function_type (void_type_node, - tree_cons (NULL_TREE, ptr_type_node, - tree_cons (NULL_TREE, - type_for_mode (ptr_mode, 0), - tree_cons (NULL_TREE, - ptr_type_node, - endlink)))), - BUILT_IN_EH_RETURN, BUILT_IN_NORMAL, NULL_PTR); - pedantic_lvalues = pedantic; - /* Create the global bindings for __FUNCTION__, __PRETTY_FUNCTION__, - and __func__. */ - function_id_node = get_identifier ("__FUNCTION__"); - pretty_function_id_node = get_identifier ("__PRETTY_FUNCTION__"); - func_id_node = get_identifier ("__func__"); make_fname_decl = c_make_fname_decl; - declare_function_name (); - - start_identifier_warnings (); + start_fname_decls (); /* Prepare to check format strings against argument lists. */ init_function_format_info (); @@ -3246,30 +3083,33 @@ init_decl_processing () are string merging candidates, which is wrong for C99's __func__. FIXME. */ static tree -c_make_fname_decl (id, name, type_dep) +c_make_fname_decl (id, type_dep) tree id; - const char *name; - int type_dep ATTRIBUTE_UNUSED; + int type_dep; { + const char *name = fname_as_string (type_dep); tree decl, type, init; size_t length = strlen (name); type = build_array_type (build_qualified_type (char_type_node, TYPE_QUAL_CONST), - build_index_type (build_int_2 (length, 0))); + build_index_type (size_int (length))); decl = build_decl (VAR_DECL, id, type); + /* We don't push the decl, so have to set its context here. */ + DECL_CONTEXT (decl) = current_function_decl; + TREE_STATIC (decl) = 1; TREE_READONLY (decl) = 1; - TREE_ASM_WRITTEN (decl) = 1; - DECL_SOURCE_LINE (decl) = 0; DECL_ARTIFICIAL (decl) = 1; - DECL_IN_SYSTEM_HEADER (decl) = 1; - DECL_IGNORED_P (decl) = 1; + init = build_string (length + 1, name); TREE_TYPE (init) = type; DECL_INITIAL (decl) = init; - finish_decl (pushdecl (decl), init, NULL_TREE); + + TREE_USED (decl) = 1; + + finish_decl (decl, init, NULL_TREE); return decl; } @@ -3299,8 +3139,8 @@ builtin_function (name, type, function_code, class, library_name) if (flag_traditional && name[0] != '_') DECL_BUILT_IN_NONANSI (decl) = 1; if (library_name) - DECL_ASSEMBLER_NAME (decl) = get_identifier (library_name); - make_decl_rtl (decl, NULL_PTR, 1); + SET_DECL_ASSEMBLER_NAME (decl, get_identifier (library_name)); + make_decl_rtl (decl, NULL); pushdecl (decl); DECL_BUILT_IN_CLASS (decl) = class; DECL_FUNCTION_CODE (decl) = function_code; @@ -3399,6 +3239,60 @@ shadow_tag_warned (declspecs, warned) } } +/* Construct an array declarator. EXPR is the expression inside [], or + NULL_TREE. QUALS are the type qualifiers inside the [] (to be applied + to the pointer to which a parameter array is converted). STATIC_P is + non-zero if "static" is inside the [], zero otherwise. VLA_UNSPEC_P + is non-zero is the array is [*], a VLA of unspecified length which is + nevertheless a complete type (not currently implemented by GCC), + zero otherwise. The declarator is constructed as an ARRAY_REF + (to be decoded by grokdeclarator), whose operand 0 is what's on the + left of the [] (filled by in set_array_declarator_type) and operand 1 + is the expression inside; whose TREE_TYPE is the type qualifiers and + which has TREE_STATIC set if "static" is used. */ + +tree +build_array_declarator (expr, quals, static_p, vla_unspec_p) + tree expr; + tree quals; + int static_p; + int vla_unspec_p; +{ + tree decl; + decl = build_nt (ARRAY_REF, NULL_TREE, expr); + TREE_TYPE (decl) = quals; + TREE_STATIC (decl) = (static_p ? 1 : 0); + if (pedantic && !flag_isoc99) + { + if (static_p || quals != NULL_TREE) + pedwarn ("ISO C89 does not support `static' or type qualifiers in parameter array declarators"); + if (vla_unspec_p) + pedwarn ("ISO C89 does not support `[*]' array declarators"); + } + if (vla_unspec_p) + warning ("GCC does not yet properly implement `[*]' array declarators"); + return decl; +} + +/* Set the type of an array declarator. DECL is the declarator, as + constructed by build_array_declarator; TYPE is what appears on the left + of the [] and goes in operand 0. ABSTRACT_P is non-zero if it is an + abstract declarator, zero otherwise; this is used to reject static and + type qualifiers in abstract declarators, where they are not in the + C99 grammar. */ + +tree +set_array_declarator_type (decl, type, abstract_p) + tree decl; + tree type; + int abstract_p; +{ + TREE_OPERAND (decl, 0) = type; + if (abstract_p && (TREE_TYPE (decl) != NULL_TREE || TREE_STATIC (decl))) + error ("static or type qualifiers in abstract declarator"); + return decl; +} + /* Decode a "typename", such as "int **", returning a ..._TYPE node. */ tree @@ -3488,7 +3382,12 @@ start_decl (declarator, declspecs, initialized, attributes, prefix_attributes) default: /* Don't allow initializations for incomplete types except for arrays which might be completed by the initialization. */ - if (COMPLETE_TYPE_P (TREE_TYPE (decl))) + + /* This can happen if the array size is an undefined macro. We already + gave a warning, so we don't need another one. */ + if (TREE_TYPE (decl) == error_mark_node) + initialized = 0; + else if (COMPLETE_TYPE_P (TREE_TYPE (decl))) { /* A complete type is ok if size is fixed. */ @@ -3563,10 +3462,11 @@ start_decl (declarator, declspecs, initialized, attributes, prefix_attributes) /* But not if this is a duplicate decl and we preserved the rtl from the previous one (which may or may not happen). */ - && DECL_RTL (tem) == 0 + && !DECL_RTL_SET_P (tem) && !DECL_CONTEXT (tem)) { - if (COMPLETE_TYPE_P (TREE_TYPE (tem))) + if (TREE_TYPE (tem) != error_mark_node + && COMPLETE_TYPE_P (TREE_TYPE (tem))) expand_decl (tem); else if (TREE_CODE (TREE_TYPE (tem)) == ARRAY_TYPE && DECL_INITIAL (tem) != 0) @@ -3588,16 +3488,16 @@ finish_decl (decl, init, asmspec_tree) { register tree type = TREE_TYPE (decl); int was_incomplete = (DECL_SIZE (decl) == 0); - char *asmspec = 0; + const char *asmspec = 0; /* If a name was specified, get the string. */ if (asmspec_tree) asmspec = TREE_STRING_POINTER (asmspec_tree); /* If `start_decl' didn't like having an initialization, ignore it now. */ - if (init != 0 && DECL_INITIAL (decl) == 0) init = 0; + /* Don't crash if parm is initialized. */ if (TREE_CODE (decl) == PARM_DECL) init = 0; @@ -3615,7 +3515,6 @@ finish_decl (decl, init, asmspec_tree) } /* Deduce size of array from initialization, if not already known */ - if (TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type) == 0 && TREE_CODE (decl) != TYPE_DECL) @@ -3661,10 +3560,13 @@ finish_decl (decl, init, asmspec_tree) if (TREE_CODE (decl) == VAR_DECL) { - if (DECL_SIZE (decl) == 0 && COMPLETE_TYPE_P (TREE_TYPE (decl))) + if (DECL_SIZE (decl) == 0 && TREE_TYPE (decl) != error_mark_node + && COMPLETE_TYPE_P (TREE_TYPE (decl))) layout_decl (decl, 0); if (DECL_SIZE (decl) == 0 + /* Don't give an error if we already gave one earlier. */ + && TREE_TYPE (decl) != error_mark_node && (TREE_STATIC (decl) ? /* A static variable with an incomplete type @@ -3702,8 +3604,8 @@ finish_decl (decl, init, asmspec_tree) if (TREE_CODE (decl) == FUNCTION_DECL && asmspec) { DECL_BUILT_IN_CLASS (decl) = NOT_BUILT_IN; - DECL_RTL (decl) = 0; - DECL_ASSEMBLER_NAME (decl) = get_identifier (asmspec); + SET_DECL_RTL (decl, NULL_RTX); + SET_DECL_ASSEMBLER_NAME (decl, get_identifier (asmspec)); } /* Output the assembler code and/or RTL code for variables and functions, @@ -3716,13 +3618,43 @@ finish_decl (decl, init, asmspec_tree) maybe_objc_check_decl (decl); if (!DECL_CONTEXT (decl)) - rest_of_decl_compilation (decl, asmspec, - (DECL_CONTEXT (decl) == 0 - || TREE_ASM_WRITTEN (decl)), 0); + { + if (DECL_INITIAL (decl) == NULL_TREE + || DECL_INITIAL (decl) == error_mark_node) + /* Don't output anything + when a tentative file-scope definition is seen. + But at end of compilation, do output code for them. */ + DECL_DEFER_OUTPUT (decl) = 1; + rest_of_decl_compilation (decl, asmspec, + (DECL_CONTEXT (decl) == 0 + || TREE_ASM_WRITTEN (decl)), 0); + } else { + /* This is a local variable. If there is an ASMSPEC, the + user has requested that we handle it specially. */ if (asmspec) - DECL_ASSEMBLER_NAME (decl) = get_identifier (asmspec); + { + /* In conjunction with an ASMSPEC, the `register' + keyword indicates that we should place the variable + in a particular register. */ + if (DECL_REGISTER (decl)) + DECL_C_HARD_REGISTER (decl) = 1; + + /* If this is not a static variable, issue a warning. + It doesn't make any sense to give an ASMSPEC for an + ordinary, non-register local variable. Historically, + GCC has accepted -- but ignored -- the ASMSPEC in + this case. */ + if (TREE_CODE (decl) == VAR_DECL + && !DECL_REGISTER (decl) + && !TREE_STATIC (decl)) + warning_with_decl (decl, + "ignoring asm-specifier for non-static local variable `%s'"); + else + SET_DECL_ASSEMBLER_NAME (decl, get_identifier (asmspec)); + } + add_decl_stmt (decl); } @@ -3746,7 +3678,7 @@ finish_decl (decl, init, asmspec_tree) { /* This is a no-op in c-lang.c or something real in objc-actions.c. */ maybe_objc_check_decl (decl); - rest_of_decl_compilation (decl, NULL_PTR, DECL_CONTEXT (decl) == 0, 0); + rest_of_decl_compilation (decl, NULL, DECL_CONTEXT (decl) == 0, 0); } /* At the end of a declaration, throw away any variable type sizes @@ -3944,6 +3876,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized) int bitfield = 0; int size_varies = 0; tree decl_machine_attr = NULL_TREE; + tree array_ptr_quals = NULL_TREE; + int array_parm_static = 0; if (decl_context == BITFIELD) bitfield = 1, decl_context = FIELD; @@ -4022,9 +3956,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized) if (TREE_CODE (id) == IDENTIFIER_NODE && C_IS_RESERVED_WORD (id)) { enum rid i = C_RID_CODE (id); - if (i <= RID_LAST_MODIFIER) + if ((int) i <= (int) RID_LAST_MODIFIER) { - if (i == RID_LONG && specbits & (1<names; decl; decl = TREE_CHAIN (decl)) { - if (TREE_TYPE (decl) == t + if (TYPE_MAIN_VARIANT (TREE_TYPE (decl)) == TYPE_MAIN_VARIANT (t) && TREE_CODE (decl) != TYPE_DECL) { layout_decl (decl, 0); /* This is a no-op in c-lang.c or something real in objc-actions.c. */ maybe_objc_check_decl (decl); - rest_of_decl_compilation (decl, NULL_PTR, toplevel, 0); + rest_of_decl_compilation (decl, NULL, toplevel, 0); if (! toplevel) expand_decl (decl); --current_binding_level->n_incomplete; @@ -5665,13 +5722,19 @@ finish_enum (enumtype, values, attributes) unsign = (tree_int_cst_sgn (minnode) >= 0); precision = MAX (min_precision (minnode, unsign), min_precision (maxnode, unsign)); - if (!TYPE_PACKED (enumtype)) - precision = MAX (precision, TYPE_PRECISION (integer_type_node)); - if (type_for_size (precision, unsign) == 0) + if (TYPE_PACKED (enumtype) || precision > TYPE_PRECISION (integer_type_node)) { - warning ("enumeration values exceed range of largest integer"); - precision = TYPE_PRECISION (long_long_integer_type_node); + tree narrowest = type_for_size (precision, unsign); + if (narrowest == 0) + { + warning ("enumeration values exceed range of largest integer"); + narrowest = long_long_integer_type_node; + } + + precision = TYPE_PRECISION (narrowest); } + else + precision = TYPE_PRECISION (integer_type_node); if (precision == TYPE_PRECISION (integer_type_node)) enum_value_type = type_for_size (precision, 0); @@ -5905,12 +5968,18 @@ start_function (declspecs, declarator, prefix_attributes, attributes) /* Optionally warn of old-fashioned def with no previous prototype. */ if (warn_strict_prototypes && TYPE_ARG_TYPES (TREE_TYPE (decl1)) == 0 - && !(old_decl != 0 && TYPE_ARG_TYPES (TREE_TYPE (old_decl)) != 0)) + && !(old_decl != 0 + && (TYPE_ARG_TYPES (TREE_TYPE (old_decl)) != 0 + || (DECL_BUILT_IN (old_decl) + && ! C_DECL_ANTICIPATED (old_decl))))) warning ("function declaration isn't a prototype"); /* Optionally warn of any global def with no previous prototype. */ else if (warn_missing_prototypes && TREE_PUBLIC (decl1) - && !(old_decl != 0 && TYPE_ARG_TYPES (TREE_TYPE (old_decl)) != 0) + && !(old_decl != 0 + && (TYPE_ARG_TYPES (TREE_TYPE (old_decl)) != 0 + || (DECL_BUILT_IN (old_decl) + && ! C_DECL_ANTICIPATED (old_decl)))) && ! MAIN_NAME_P (DECL_NAME (decl1))) warning_with_decl (decl1, "no previous prototype for `%s'"); /* Optionally warn of any def with no previous prototype @@ -6000,14 +6069,11 @@ start_function (declspecs, declarator, prefix_attributes, attributes) } /* It is intentional that this message does not mention the third - argument, which is warned for only pedantically, because it's - blessed by mention in an appendix of the standard. */ + argument because it's only mentioned in an appendix of the + standard. */ if (argct > 0 && (argct < 2 || argct > 3)) pedwarn_with_decl (decl1, "`%s' takes only zero or two arguments"); - if (argct == 3 && pedantic) - pedwarn_with_decl (decl1, "third argument of `%s' is deprecated"); - if (! TREE_PUBLIC (decl1)) pedwarn_with_decl (decl1, "`%s' is normally a non-static function"); } @@ -6022,11 +6088,11 @@ start_function (declspecs, declarator, prefix_attributes, attributes) declare_parm_level (1); current_binding_level->subblocks_tag_transparent = 1; - make_function_rtl (current_function_decl); + make_decl_rtl (current_function_decl, NULL); restype = TREE_TYPE (TREE_TYPE (current_function_decl)); /* Promote the value to int before returning it. */ - if (C_PROMOTING_INTEGER_TYPE_P (restype)) + if (c_promoting_integer_type_p (restype)) { /* It retains unsignedness if traditional or if not really getting wider. */ @@ -6048,6 +6114,8 @@ start_function (declspecs, declarator, prefix_attributes, attributes) immediate_size_expand = old_immediate_size_expand; + start_fname_decls (); + return 1; } @@ -6092,6 +6160,9 @@ store_parm_decls () /* Nonzero if this definition is written with a prototype. */ int prototype = 0; + /* The function containing FNDECL, if any. */ + tree context = decl_function_context (fndecl); + if (specparms != 0 && TREE_CODE (specparms) != TREE_LIST) { /* This case is when the function was defined with an ANSI prototype. @@ -6367,8 +6438,7 @@ store_parm_decls () DECL_ARG_TYPE (parm) = TREE_TYPE (parm); if (PROMOTE_PROTOTYPES - && (TREE_CODE (TREE_TYPE (parm)) == INTEGER_TYPE - || TREE_CODE (TREE_TYPE (parm)) == ENUMERAL_TYPE) + && INTEGRAL_TYPE_P (TREE_TYPE (parm)) && TYPE_PRECISION (TREE_TYPE (parm)) < TYPE_PRECISION (integer_type_node)) DECL_ARG_TYPE (parm) = integer_type_node; @@ -6460,14 +6530,28 @@ store_parm_decls () gen_aux_info_record (fndecl, 1, 0, prototype); /* Initialize the RTL code for the function. */ - init_function_start (fndecl, input_filename, lineno); /* Begin the statement tree for this function. */ - DECL_LANG_SPECIFIC (current_function_decl) - =((struct lang_decl *) ggc_alloc (sizeof (struct lang_decl))); + DECL_LANG_SPECIFIC (current_function_decl) + =((struct lang_decl *) ggc_alloc_cleared (sizeof (struct lang_decl))); begin_stmt_tree (&DECL_SAVED_TREE (current_function_decl)); + /* If this is a nested function, save away the sizes of any + variable-size types so that we can expand them when generating + RTL. */ + if (context) + { + tree t; + + DECL_LANG_SPECIFIC (fndecl)->pending_sizes + = nreverse (get_pending_sizes ()); + for (t = DECL_LANG_SPECIFIC (fndecl)->pending_sizes; + t; + t = TREE_CHAIN (t)) + SAVE_EXPR_CONTEXT (TREE_VALUE (t)) = context; + } + /* This function is being processed in whole-function mode. */ cfun->x_whole_function_mode_p = 1; @@ -6675,6 +6759,8 @@ finish_function (nested) #endif } } + + finish_fname_decls (); /* Tie off the statement tree for this function. */ finish_stmt_tree (&DECL_SAVED_TREE (fndecl)); @@ -6710,13 +6796,18 @@ c_expand_body (fndecl, nested_p) if (flag_syntax_only) return; - /* Squirrel away our current state. */ if (nested_p) - push_function_context (); + { + /* Make sure that we will evaluate variable-sized types involved + in our function's type. */ + expand_pending_sizes (DECL_LANG_SPECIFIC (fndecl)->pending_sizes); + /* Squirrel away our current state. */ + push_function_context (); + } /* Initialize the RTL code for the function. */ current_function_decl = fndecl; - init_function_start (fndecl, input_filename, lineno); + init_function_start (fndecl, input_filename, DECL_SOURCE_LINE (fndecl)); /* This function is being processed in whole-function mode. */ cfun->x_whole_function_mode_p = 1; @@ -6747,7 +6838,7 @@ c_expand_body (fndecl, nested_p) /* Allow the body of the function to be garbage collected. */ DECL_SAVED_TREE (fndecl) = NULL_TREE; - /* We hard-wired immediate_size_expand to zero in start_function. + /* We hard-wired immediate_size_expand to zero above. expand_function_end will decrement this variable. So, we set the variable to one here, so that after the decrement it will remain zero. */ @@ -6760,9 +6851,6 @@ c_expand_body (fndecl, nested_p) /* Generate rtl for function exit. */ expand_function_end (input_filename, lineno, 0); - /* So we can tell if jump_optimize sets it to 1. */ - can_reach_end = 0; - /* If this is a nested function, protect the local variables in the stack above us from being collected while we're compiling this function. */ if (nested_p) @@ -6775,25 +6863,11 @@ c_expand_body (fndecl, nested_p) if (nested_p) ggc_pop_context (); - current_function_returns_null |= can_reach_end; - - if (warn_missing_noreturn - && !TREE_THIS_VOLATILE (fndecl) - && !current_function_returns_null - && !current_function_returns_value) - warning ("function might be possible candidate for attribute `noreturn'"); - - if (TREE_THIS_VOLATILE (fndecl) && current_function_returns_null) - warning ("`noreturn' function does return"); - else if (warn_return_type && can_reach_end - && !VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fndecl)))) - /* If this function returns non-void and control can drop through, - complain. */ - warning ("control reaches end of non-void function"); /* With just -W, complain only if function returns both with and without a value. */ - else if (extra_warnings - && current_function_returns_value && current_function_returns_null) + if (extra_warnings + && current_function_returns_value + && current_function_returns_null) warning ("this function may return with or without a value"); /* If requested, warn about function definitions where the function will @@ -6804,7 +6878,8 @@ c_expand_body (fndecl, nested_p) { tree ret_type = TREE_TYPE (TREE_TYPE (fndecl)); - if (ret_type && TREE_CODE (TYPE_SIZE_UNIT (ret_type)) == INTEGER_CST + if (ret_type && TYPE_SIZE_UNIT (ret_type) + && TREE_CODE (TYPE_SIZE_UNIT (ret_type)) == INTEGER_CST && 0 < compare_tree_int (TYPE_SIZE_UNIT (ret_type), larger_than_size)) { @@ -6868,7 +6943,56 @@ c_expand_body (fndecl, nested_p) pop_function_context (); } } - + +} + +/* Check the declarations given in a for-loop for satisfying the C99 + constraints. */ +void +check_for_loop_decls () +{ + tree t; + + if (!flag_isoc99) + { + /* If we get here, declarations have been used in a for loop without + the C99 for loop scope. This doesn't make much sense, so don't + allow it. */ + error ("`for' loop initial declaration used outside C99 mode"); + return; + } + /* C99 subclause 6.8.5 paragraph 3: + + [#3] The declaration part of a for statement shall only + declare identifiers for objects having storage class auto or + register. + + It isn't clear whether, in this sentence, "identifiers" binds to + "shall only declare" or to "objects" - that is, whether all identifiers + declared must be identifiers for objects, or whether the restriction + only applies to those that are. (A question on this in comp.std.c + in November 2000 received no answer.) We implement the strictest + interpretation, to avoid creating an extension which later causes + problems. */ + + for (t = gettags (); t; t = TREE_CHAIN (t)) + { + if (TREE_PURPOSE (t) != 0) + error ("`%s %s' declared in `for' loop initial declaration", + (TREE_CODE (TREE_VALUE (t)) == RECORD_TYPE ? "struct" + : TREE_CODE (TREE_VALUE (t)) == UNION_TYPE ? "union" + : "enum"), + IDENTIFIER_POINTER (TREE_PURPOSE (t))); + } + for (t = getdecls (); t; t = TREE_CHAIN (t)) + { + if (TREE_CODE (t) != VAR_DECL && DECL_NAME (t)) + error_with_decl (t, "declaration of non-variable `%s' in `for' loop initial declaration"); + else if (TREE_STATIC (t)) + error_with_decl (t, "declaration of static variable `%s' in `for' loop initial declaration"); + else if (DECL_EXTERNAL (t)) + error_with_decl (t, "declaration of `extern' variable `%s' in `for' loop initial declaration"); + } } /* Save and restore the variables in this file and elsewhere @@ -6895,13 +7019,12 @@ push_c_function_context (f) struct function *f; { struct c_language_function *p; - p = ((struct c_language_function *) + p = ((struct c_language_function *) xmalloc (sizeof (struct c_language_function))); f->language = (struct language_function *) p; p->base.x_stmt_tree = c_stmt_tree; p->base.x_scope_stmt_stack = c_scope_stmt_stack; - p->base.x_function_name_declared_p = c_function_name_declared_p; p->named_labels = named_labels; p->shadowed_labels = shadowed_labels; p->returns_value = current_function_returns_value; @@ -6917,7 +7040,7 @@ void pop_c_function_context (f) struct function *f; { - struct c_language_function *p + struct c_language_function *p = (struct c_language_function *) f->language; tree link; @@ -6939,7 +7062,6 @@ pop_c_function_context (f) c_stmt_tree = p->base.x_stmt_tree; c_scope_stmt_stack = p->base.x_scope_stmt_stack; - c_function_name_declared_p = p->base.x_function_name_declared_p; named_labels = p->named_labels; shadowed_labels = p->shadowed_labels; current_function_returns_value = p->returns_value; @@ -6958,7 +7080,7 @@ void mark_c_function_context (f) struct function *f; { - struct c_language_function *p + struct c_language_function *p = (struct c_language_function *) f->language; if (p == 0) @@ -6982,8 +7104,8 @@ copy_lang_decl (decl) return; ld = (struct lang_decl *) ggc_alloc (sizeof (struct lang_decl)); - bcopy ((char *)DECL_LANG_SPECIFIC (decl), (char *)ld, - sizeof (struct lang_decl)); + memcpy ((char *) ld, (char *) DECL_LANG_SPECIFIC (decl), + sizeof (struct lang_decl)); DECL_LANG_SPECIFIC (decl) = ld; } @@ -7009,6 +7131,7 @@ lang_mark_tree (t) { ggc_mark (DECL_LANG_SPECIFIC (t)); c_mark_lang_decl (&DECL_LANG_SPECIFIC (t)->base); + ggc_mark_tree (DECL_LANG_SPECIFIC (t)->pending_sizes); } } @@ -7072,14 +7195,7 @@ c_begin_compound_stmt () /* Create the COMPOUND_STMT. */ stmt = add_stmt (build_stmt (COMPOUND_STMT, NULL_TREE)); - /* If we haven't already declared __FUNCTION__ and its ilk then this - is the opening curly brace of the function. Declare them now. */ - if (!c_function_name_declared_p) - { - c_function_name_declared_p = 1; - declare_function_name (); - } - + return stmt; } @@ -7091,10 +7207,45 @@ c_expand_decl_stmt (t) tree t; { tree decl = DECL_STMT_DECL (t); - + /* Expand nested functions. */ if (TREE_CODE (decl) == FUNCTION_DECL && DECL_CONTEXT (decl) == current_function_decl && DECL_SAVED_TREE (decl)) c_expand_body (decl, /*nested_p=*/1); } + +/* Return the IDENTIFIER_GLOBAL_VALUE of T, for use in common code, since + the definition of IDENTIFIER_GLOBAL_VALUE is different for C and C++. */ + +tree +identifier_global_value (t) + tree t; +{ + return IDENTIFIER_GLOBAL_VALUE (t); +} + +/* Record a builtin type for C. If NAME is non-NULL, it is the name used; + otherwise the name is found in ridpointers from RID_INDEX. */ + +void +record_builtin_type (rid_index, name, type) + enum rid rid_index; + const char *name; + tree type; +{ + tree id; + if (name == 0) + id = ridpointers[(int) rid_index]; + else + id = get_identifier (name); + pushdecl (build_decl (TYPE_DECL, id, type)); +} + +/* Build the void_list_node (void_type_node having been created). */ +tree +build_void_list_node () +{ + tree t = build_tree_list (NULL_TREE, void_type_node); + return t; +}