Mercurial > hg > CbC > CbC_gcc
diff gcc/c-decl.c @ 67:f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
author | nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 22 Mar 2011 17:18:12 +0900 |
parents | b7f97abdc517 |
children | 1b10fe6932e1 |
line wrap: on
line diff
--- a/gcc/c-decl.c Tue May 25 18:58:51 2010 +0900 +++ b/gcc/c-decl.c Tue Mar 22 17:18:12 2011 +0900 @@ -34,7 +34,6 @@ #include "intl.h" #include "tree.h" #include "tree-inline.h" -#include "rtl.h" #include "flags.h" #include "function.h" #include "output.h" @@ -46,19 +45,21 @@ #include "debug.h" #include "opts.h" #include "timevar.h" -#include "c-common.h" -#include "c-pragma.h" +#include "c-family/c-common.h" +#include "c-family/c-objc.h" +#include "c-family/c-pragma.h" #include "c-lang.h" #include "langhooks.h" #include "tree-mudflap.h" #include "tree-iterator.h" -#include "diagnostic.h" +#include "diagnostic-core.h" #include "tree-dump.h" #include "cgraph.h" #include "hashtab.h" #include "langhooks-def.h" #include "pointer-set.h" #include "plugin.h" +#include "c-family/c-ada-spec.h" /* In grokdeclarator, distinguish syntactic contexts of declarators. */ enum decl_context @@ -118,12 +119,6 @@ tree c_break_label; tree c_cont_label; -/* Linked list of TRANSLATION_UNIT_DECLS for the translation units - included in this invocation. Note that the current translation - unit is not included in this list. */ - -static GTY(()) tree all_translation_units; - /* A list of decls to be made automatically visible in each file scope. */ static GTY(()) tree visible_builtins; @@ -409,6 +404,13 @@ up searching for labels when popping scopes, particularly since labels are normally only found at function scope. */ BOOL_BITFIELD has_label_bindings : 1; + + /* True if we should issue a warning if a goto statement crosses any + of the bindings. We still need to check the list of bindings to + find the specific ones we need to warn about. This is true if + decl_jump_unsafe would return true for any of the bindings. This + is used to avoid looping over all the bindings unnecessarily. */ + BOOL_BITFIELD has_jump_unsafe_decl : 1; }; /* The scope currently in effect. */ @@ -559,6 +561,31 @@ return t; } +/* Return true if we will want to say something if a goto statement + crosses DECL. */ + +static bool +decl_jump_unsafe (tree decl) +{ + if (decl == error_mark_node || TREE_TYPE (decl) == error_mark_node) + return false; + + /* Always warn about crossing variably modified types. */ + if ((TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == TYPE_DECL) + && variably_modified_type_p (TREE_TYPE (decl), NULL_TREE)) + return true; + + /* Otherwise, only warn if -Wgoto-misses-init and this is an + initialized automatic decl. */ + if (warn_jump_misses_init + && TREE_CODE (decl) == VAR_DECL + && !TREE_STATIC (decl) + && DECL_INITIAL (decl) != NULL_TREE) + return true; + + return false; +} + void c_print_identifier (FILE *file, tree node, int indent) @@ -590,7 +617,7 @@ binding_freelist = b->prev; } else - b = GGC_NEW (struct c_binding); + b = ggc_alloc_c_binding (); b->shadowed = 0; b->decl = decl; @@ -607,6 +634,9 @@ b->prev = scope->bindings; scope->bindings = b; + if (decl_jump_unsafe (decl)) + scope->has_jump_unsafe_decl = 1; + if (!name) return; @@ -704,7 +734,7 @@ record_inline_static (location_t loc, tree func, tree decl, enum c_inline_static_type type) { - struct c_inline_static *csi = GGC_NEW (struct c_inline_static); + struct c_inline_static *csi = ggc_alloc_c_inline_static (); csi->location = loc; csi->function = func; csi->static_decl = decl; @@ -763,31 +793,6 @@ p->left_stmt_expr = false; } -/* Return true if we will want to say something if a goto statement - crosses DECL. */ - -static bool -decl_jump_unsafe (tree decl) -{ - if (decl == error_mark_node || TREE_TYPE (decl) == error_mark_node) - return false; - - /* Always warn about crossing variably modified types. */ - if ((TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == TYPE_DECL) - && variably_modified_type_p (TREE_TYPE (decl), NULL_TREE)) - return true; - - /* Otherwise, only warn if -Wgoto-misses-init and this is an - initialized automatic decl. */ - if (warn_jump_misses_init - && TREE_CODE (decl) == VAR_DECL - && !TREE_STATIC (decl) - && DECL_INITIAL (decl) != NULL_TREE) - return true; - - return false; -} - /* Update spot bindings P as we pop out of SCOPE. Return true if we should push decls for a label. */ @@ -928,7 +933,7 @@ scope_freelist = scope->outer; } else - scope = GGC_CNEW (struct c_scope); + scope = ggc_alloc_cleared_c_scope (); /* The FLOAT_CONST_DECIMAL64 pragma applies to nested scopes. */ if (current_scope) @@ -974,6 +979,7 @@ { struct c_label_vars *label_vars; struct c_binding *b1; + bool hjud; unsigned int ix; struct c_goto_bindings *g; @@ -982,26 +988,32 @@ label_vars = b->u.label; b1 = label_vars->label_bindings.bindings_in_scope; + if (label_vars->label_bindings.scope == NULL) + hjud = false; + else + hjud = label_vars->label_bindings.scope->has_jump_unsafe_decl; if (update_spot_bindings (scope, &label_vars->label_bindings)) { /* This label is defined in this scope. */ - for (; b1 != NULL; b1 = b1->prev) + if (hjud) { - /* A goto from later in the function to this - label will never see the initialization of - B1, if any. Save it to issue a warning if - needed. */ - if (decl_jump_unsafe (b1->decl)) - VEC_safe_push (tree, gc, label_vars->decls_in_scope, - b1->decl); + for (; b1 != NULL; b1 = b1->prev) + { + /* A goto from later in the function to this + label will never see the initialization + of B1, if any. Save it to issue a + warning if needed. */ + if (decl_jump_unsafe (b1->decl)) + VEC_safe_push (tree, gc, + label_vars->decls_in_scope, + b1->decl); + } } } /* Update the bindings of any goto statements associated with this label. */ - for (ix = 0; - VEC_iterate (c_goto_bindings_p, label_vars->gotos, ix, g); - ++ix) + FOR_EACH_VEC_ELT (c_goto_bindings_p, label_vars->gotos, ix, g) update_spot_bindings (scope, &g->goto_bindings); } } @@ -1074,10 +1086,7 @@ context = current_function_decl; else if (scope == file_scope) { - tree file_decl = build_decl (UNKNOWN_LOCATION, - TRANSLATION_UNIT_DECL, 0, 0); - TREE_CHAIN (file_decl) = all_translation_units; - all_translation_units = file_decl; + tree file_decl = build_translation_unit_decl (NULL_TREE); context = file_decl; } else @@ -1100,7 +1109,7 @@ warn_for_unused_label (p); /* Labels go in BLOCK_VARS. */ - TREE_CHAIN (p) = BLOCK_VARS (block); + DECL_CHAIN (p) = BLOCK_VARS (block); BLOCK_VARS (block) = p; gcc_assert (I_LABEL_BINDING (b->id) == b); I_LABEL_BINDING (b->id) = b->shadowed; @@ -1188,7 +1197,7 @@ binding in the home scope. */ if (!b->nested) { - TREE_CHAIN (p) = BLOCK_VARS (block); + DECL_CHAIN (p) = BLOCK_VARS (block); BLOCK_VARS (block) = p; } else if (VAR_OR_FUNCTION_DECL_P (p)) @@ -1211,18 +1220,17 @@ } if (b->locus != UNKNOWN_LOCATION) DECL_SOURCE_LOCATION (extp) = b->locus; - TREE_CHAIN (extp) = BLOCK_VARS (block); + DECL_CHAIN (extp) = BLOCK_VARS (block); BLOCK_VARS (block) = extp; } - /* If this is the file scope, and we are processing more - than one translation unit in this compilation, set - DECL_CONTEXT of each decl to the TRANSLATION_UNIT_DECL. - This makes same_translation_unit_p work, and causes - static declarations to be given disambiguating suffixes. */ - if (scope == file_scope && num_in_fnames > 1) + /* If this is the file scope set DECL_CONTEXT of each decl to + the TRANSLATION_UNIT_DECL. This makes same_translation_unit_p + work. */ + if (scope == file_scope) { DECL_CONTEXT (p) = context; - if (TREE_CODE (p) == TYPE_DECL) + if (TREE_CODE (p) == TYPE_DECL + && TREE_TYPE (p) != error_mark_node) set_type_context (TREE_TYPE (p), context); } @@ -1293,7 +1301,7 @@ start_fname_decls (); - for (decl = visible_builtins; decl; decl = TREE_CHAIN (decl)) + for (decl = visible_builtins; decl; decl = DECL_CHAIN (decl)) bind (DECL_NAME (decl), decl, file_scope, /*invisible=*/false, /*nested=*/true, DECL_SOURCE_LOCATION (decl)); } @@ -1352,9 +1360,7 @@ continue; label_vars = b->u.label; ++label_vars->label_bindings.stmt_exprs; - for (ix = 0; - VEC_iterate (c_goto_bindings_p, label_vars->gotos, ix, g); - ++ix) + FOR_EACH_VEC_ELT (c_goto_bindings_p, label_vars->gotos, ix, g) ++g->goto_bindings.stmt_exprs; } } @@ -1392,9 +1398,7 @@ label_vars->label_bindings.left_stmt_expr = true; label_vars->label_bindings.stmt_exprs = 0; } - for (ix = 0; - VEC_iterate (c_goto_bindings_p, label_vars->gotos, ix, g); - ++ix) + FOR_EACH_VEC_ELT (c_goto_bindings_p, label_vars->gotos, ix, g) { --g->goto_bindings.stmt_exprs; if (g->goto_bindings.stmt_exprs < 0) @@ -1516,9 +1520,8 @@ if (TREE_CODE (olddecl) != FUNCTION_DECL || !comptypes (TREE_TYPE (oldtype), TREE_TYPE (newtype)) - || !((TYPE_ARG_TYPES (oldtype) == 0 && DECL_INITIAL (olddecl) == 0) - || - (TYPE_ARG_TYPES (newtype) == 0 && DECL_INITIAL (newdecl) == 0))) + || !((!prototype_p (oldtype) && DECL_INITIAL (olddecl) == 0) + || (!prototype_p (newtype) && DECL_INITIAL (newdecl) == 0))) return; t = TYPE_ARG_TYPES (oldtype); @@ -1786,18 +1789,48 @@ /* Redeclaration of a type is a constraint violation (6.7.2.3p1), but silently ignore the redeclaration if either is in a system - header. (Conflicting redeclarations were handled above.) */ + header. (Conflicting redeclarations were handled above.) This + is allowed for C1X if the types are the same, not just + compatible. */ if (TREE_CODE (newdecl) == TYPE_DECL) { + bool types_different = false; + int comptypes_result; + + comptypes_result + = comptypes_check_different_types (oldtype, newtype, &types_different); + + if (comptypes_result != 1 || types_different) + { + error ("redefinition of typedef %q+D with different type", newdecl); + locate_old_decl (olddecl); + return false; + } + if (DECL_IN_SYSTEM_HEADER (newdecl) || DECL_IN_SYSTEM_HEADER (olddecl) || TREE_NO_WARNING (newdecl) || TREE_NO_WARNING (olddecl)) return true; /* Allow OLDDECL to continue in use. */ - error ("redefinition of typedef %q+D", newdecl); - locate_old_decl (olddecl); - return false; + if (pedantic && !flag_isoc1x) + { + pedwarn (input_location, OPT_pedantic, + "redefinition of typedef %q+D", newdecl); + locate_old_decl (olddecl); + } + else if (variably_modified_type_p (newtype, NULL)) + { + /* Whether there is a constraint violation for the types not + being the same cannot be determined at compile time; a + warning that there may be one at runtime is considered + appropriate (WG14 reflector message 11743, 8 May 2009). */ + warning (0, "redefinition of typedef %q+D may be a constraint " + "violation at runtime", newdecl); + locate_old_decl (olddecl); + } + + return true; } /* Function declarations can either be 'static' or 'extern' (no @@ -1818,7 +1851,7 @@ && !C_DECL_DECLARED_BUILTIN (olddecl) && (!TREE_PUBLIC (newdecl) || (DECL_INITIAL (newdecl) - && !TYPE_ARG_TYPES (TREE_TYPE (newdecl))))) + && !prototype_p (TREE_TYPE (newdecl))))) { warning (OPT_Wshadow, "declaration of %q+D shadows " "a built-in function", newdecl); @@ -1855,7 +1888,7 @@ /* If we have a prototype after an old-style function definition, the argument types must be checked specially. */ else if (DECL_INITIAL (olddecl) - && !TYPE_ARG_TYPES (oldtype) && TYPE_ARG_TYPES (newtype) + && !prototype_p (oldtype) && prototype_p (newtype) && TYPE_ACTUAL_ARG_TYPES (oldtype) && !validate_proto_after_old_defn (newdecl, newtype, oldtype)) { @@ -2124,9 +2157,9 @@ bool new_is_definition = (TREE_CODE (newdecl) == FUNCTION_DECL && DECL_INITIAL (newdecl) != 0); bool new_is_prototype = (TREE_CODE (newdecl) == FUNCTION_DECL - && TYPE_ARG_TYPES (TREE_TYPE (newdecl)) != 0); + && prototype_p (TREE_TYPE (newdecl))); bool old_is_prototype = (TREE_CODE (olddecl) == FUNCTION_DECL - && TYPE_ARG_TYPES (TREE_TYPE (olddecl)) != 0); + && prototype_p (TREE_TYPE (olddecl))); bool extern_changed = false; /* For real parm decl following a forward decl, rechain the old decl @@ -2370,7 +2403,7 @@ DECL_STRUCT_FUNCTION (newdecl) = DECL_STRUCT_FUNCTION (olddecl); DECL_SAVED_TREE (newdecl) = DECL_SAVED_TREE (olddecl); DECL_ARGUMENTS (newdecl) = copy_list (DECL_ARGUMENTS (olddecl)); - for (t = DECL_ARGUMENTS (newdecl); t ; t = TREE_CHAIN (t)) + for (t = DECL_ARGUMENTS (newdecl); t ; t = DECL_CHAIN (t)) DECL_CONTEXT (t) = newdecl; /* See if we've got a function to instantiate from. */ @@ -2947,7 +2980,8 @@ } else { - error_at (loc, "%qE undeclared (first use in this function)", id); + if (!objc_diagnose_private_ivar (id)) + error_at (loc, "%qE undeclared (first use in this function)", id); if (!already) { inform (loc, "each undeclared identifier is reported only" @@ -2977,7 +3011,7 @@ DECL_CONTEXT (label) = current_function_decl; DECL_MODE (label) = VOIDmode; - label_vars = GGC_NEW (struct c_label_vars); + label_vars = ggc_alloc_c_label_vars (); label_vars->shadowed = NULL; set_spot_bindings (&label_vars->label_bindings, defining); label_vars->decls_in_scope = make_tree_vector (); @@ -2998,7 +3032,7 @@ tree label; struct c_label_vars *label_vars; - if (current_function_decl == 0) + if (current_function_scope == 0) { error ("label %qE referenced outside of any function", name); return 0; @@ -3075,7 +3109,7 @@ { struct c_goto_bindings *g; - g = GGC_NEW (struct c_goto_bindings); + g = ggc_alloc_c_goto_bindings (); g->loc = loc; set_spot_bindings (&g->goto_bindings, true); VEC_safe_push (c_goto_bindings_p, gc, label_vars->gotos, g); @@ -3090,7 +3124,7 @@ ... goto lab; Issue a warning or error. */ - for (ix = 0; VEC_iterate (tree, label_vars->decls_in_scope, ix, decl); ++ix) + FOR_EACH_VEC_ELT (tree, label_vars->decls_in_scope, ix, decl) warn_about_goto (loc, label, decl); if (label_vars->label_bindings.left_stmt_expr) @@ -3142,9 +3176,7 @@ unsigned int ix; struct c_goto_bindings *g; - for (ix = 0; - VEC_iterate (c_goto_bindings_p, label_vars->gotos, ix, g); - ++ix) + FOR_EACH_VEC_ELT (c_goto_bindings_p, label_vars->gotos, ix, g) { struct c_binding *b; struct c_scope *scope; @@ -3152,12 +3184,15 @@ /* We have a goto to this label. The goto is going forward. In g->scope, the goto is going to skip any binding which was defined after g->bindings_in_scope. */ - for (b = g->goto_bindings.scope->bindings; - b != g->goto_bindings.bindings_in_scope; - b = b->prev) - { - if (decl_jump_unsafe (b->decl)) - warn_about_goto (g->loc, label, b->decl); + if (g->goto_bindings.scope->has_jump_unsafe_decl) + { + for (b = g->goto_bindings.scope->bindings; + b != g->goto_bindings.bindings_in_scope; + b = b->prev) + { + if (decl_jump_unsafe (b->decl)) + warn_about_goto (g->loc, label, b->decl); + } } /* We also need to warn about decls defined in any scopes @@ -3167,14 +3202,17 @@ scope = scope->outer) { gcc_assert (scope != NULL); - if (scope == label_vars->label_bindings.scope) - b = label_vars->label_bindings.bindings_in_scope; - else - b = scope->bindings; - for (; b != NULL; b = b->prev) + if (scope->has_jump_unsafe_decl) { - if (decl_jump_unsafe (b->decl)) - warn_about_goto (g->loc, label, b->decl); + if (scope == label_vars->label_bindings.scope) + b = label_vars->label_bindings.bindings_in_scope; + else + b = scope->bindings; + for (; b != NULL; b = b->prev) + { + if (decl_jump_unsafe (b->decl)) + warn_about_goto (g->loc, label, b->decl); + } } } @@ -3290,6 +3328,10 @@ struct c_binding *b; gcc_assert (scope != NULL); + + if (!scope->has_jump_unsafe_decl) + continue; + for (b = scope->bindings; b != NULL; b = b->prev) { if (decl_jump_unsafe (b->decl)) @@ -3506,7 +3548,7 @@ the __FUNCTION__ is believed to appear in K&R style function parameter declarator. In that case we still don't have function_scope. */ - && (!errorcount || current_function_scope)) + && (!seen_error () || current_function_scope)) { DECL_CONTEXT (decl) = current_function_decl; bind (id, decl, current_function_scope, @@ -3525,7 +3567,7 @@ tree id = DECL_NAME (decl); const char *name = IDENTIFIER_POINTER (id); - C_DECL_BUILTIN_PROTOTYPE (decl) = (TYPE_ARG_TYPES (type) != 0); + C_DECL_BUILTIN_PROTOTYPE (decl) = prototype_p (type); /* Should never be called on a symbol with a preexisting meaning. */ gcc_assert (!I_SYMBOL_BINDING (id)); @@ -3537,7 +3579,7 @@ needing to be explicitly declared. See push_file_scope. */ if (name[0] == '_' && (name[1] == '_' || ISUPPER (name[1]))) { - TREE_CHAIN (decl) = visible_builtins; + DECL_CHAIN (decl) = visible_builtins; visible_builtins = decl; } @@ -3551,7 +3593,7 @@ tree id = DECL_NAME (decl); const char *name = IDENTIFIER_POINTER (id); - C_DECL_BUILTIN_PROTOTYPE (decl) = (TYPE_ARG_TYPES (type) != 0); + C_DECL_BUILTIN_PROTOTYPE (decl) = prototype_p (type); /* Should never be called on a symbol with a preexisting meaning. */ gcc_assert (!I_SYMBOL_BINDING (id)); @@ -3563,7 +3605,7 @@ needing to be explicitly declared. See push_file_scope. */ if (name[0] == '_' && (name[1] == '_' || ISUPPER (name[1]))) { - TREE_CHAIN (decl) = visible_builtins; + DECL_CHAIN (decl) = visible_builtins; visible_builtins = decl; } @@ -3621,7 +3663,8 @@ warned = 1; } } - else if (!declspecs->tag_defined_p + else if (declspecs->typespec_kind != ctsk_tagdef + && declspecs->typespec_kind != ctsk_tagfirstref && declspecs->storage_class != csc_none) { if (warned != 1) @@ -3631,7 +3674,8 @@ warned = 1; pending_xref_error (); } - else if (!declspecs->tag_defined_p + else if (declspecs->typespec_kind != ctsk_tagdef + && declspecs->typespec_kind != ctsk_tagfirstref && (declspecs->const_p || declspecs->volatile_p || declspecs->restrict_p @@ -3985,7 +4029,7 @@ prototypes file (if requested). */ if (TREE_CODE (decl) == FUNCTION_DECL) - gen_aux_info_record (decl, 0, 0, TYPE_ARG_TYPES (TREE_TYPE (decl)) != 0); + gen_aux_info_record (decl, 0, 0, prototype_p (TREE_TYPE (decl))); /* ANSI specifies that a tentative definition which is not merged with a non-tentative definition behaves exactly like a definition with an @@ -4031,7 +4075,7 @@ if (ce->kind == cdk_function) { tree args = ce->u.arg_info->parms; - for (; args; args = TREE_CHAIN (args)) + for (; args; args = DECL_CHAIN (args)) { tree type = TREE_TYPE (args); if (type && INTEGRAL_TYPE_P (type) @@ -4060,6 +4104,11 @@ record_inline_static (input_location, current_function_decl, decl, csi_modifiable); + if (c_dialect_objc () + && (TREE_CODE (decl) == VAR_DECL + || TREE_CODE (decl) == FUNCTION_DECL)) + objc_check_global_decl (decl); + /* Add this decl to the current scope. TEM may equal DECL or it may be a previous decl of the same name. */ tem = pushdecl (decl); @@ -4073,6 +4122,35 @@ return tem; } +/* Subroutine of finish_decl. TYPE is the type of an uninitialized object + DECL or the non-array element type if DECL is an uninitialized array. + If that type has a const member, diagnose this. */ + +static void +diagnose_uninitialized_cst_member (tree decl, tree type) +{ + tree field; + for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) + { + tree field_type; + if (TREE_CODE (field) != FIELD_DECL) + continue; + field_type = strip_array_types (TREE_TYPE (field)); + + if (TYPE_QUALS (field_type) & TYPE_QUAL_CONST) + { + warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wc___compat, + "uninitialized const member in %qT is invalid in C++", + strip_array_types (TREE_TYPE (decl))); + inform (DECL_SOURCE_LOCATION (field), "%qD should be initialized", field); + } + + if (TREE_CODE (field_type) == RECORD_TYPE + || TREE_CODE (field_type) == UNION_TYPE) + diagnose_uninitialized_cst_member (decl, field_type); + } +} + /* Finish processing of a declaration; install its initial value. If ORIGTYPE is not NULL_TREE, it is the original type of INIT. @@ -4390,11 +4468,18 @@ if (warn_cxx_compat && TREE_CODE (decl) == VAR_DECL - && TREE_READONLY (decl) && !DECL_EXTERNAL (decl) && DECL_INITIAL (decl) == NULL_TREE) - warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wc___compat, - "uninitialized const %qD is invalid in C++", decl); + { + type = strip_array_types (type); + if (TREE_READONLY (decl)) + warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wc___compat, + "uninitialized const %qD is invalid in C++", decl); + else if ((TREE_CODE (type) == RECORD_TYPE + || TREE_CODE (type) == UNION_TYPE) + && C_TYPE_FIELDS_READONLY (type)) + diagnose_uninitialized_cst_member (decl, type); + } } /* Given a parsed parameter declaration, decode it into a PARM_DECL. */ @@ -4526,7 +4611,9 @@ void check_compound_literal_type (location_t loc, struct c_type_name *type_name) { - if (warn_cxx_compat && type_name->specs->tag_defined_p) + if (warn_cxx_compat + && (type_name->specs->typespec_kind == ctsk_tagdef + || type_name->specs->typespec_kind == ctsk_tagfirstref)) warning_at (loc, OPT_Wc___compat, "defining a type in a compound literal is invalid in C++"); } @@ -4544,8 +4631,8 @@ x = TYPE_FIELDS (type); if (x == NULL_TREE) return false; - while (TREE_CHAIN (x) != NULL_TREE) - x = TREE_CHAIN (x); + while (DECL_CHAIN (x) != NULL_TREE) + x = DECL_CHAIN (x); if (TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE && TYPE_SIZE (TREE_TYPE (x)) == NULL_TREE && TYPE_DOMAIN (TREE_TYPE (x)) != NULL_TREE @@ -4553,7 +4640,7 @@ return true; return false; case UNION_TYPE: - for (x = TYPE_FIELDS (type); x != NULL_TREE; x = TREE_CHAIN (x)) + for (x = TYPE_FIELDS (type); x != NULL_TREE; x = DECL_CHAIN (x)) { if (flexible_array_type_p (TREE_TYPE (x))) return true; @@ -4806,6 +4893,8 @@ tree expr_dummy; bool expr_const_operands_dummy; + if (TREE_CODE (type) == ERROR_MARK) + return error_mark_node; if (expr == NULL) expr = &expr_dummy; if (expr_const_operands == NULL) @@ -5400,6 +5489,7 @@ if (size && integer_zerop (size)) { gcc_assert (itype); + type = build_distinct_type_copy (TYPE_MAIN_VARIANT (type)); TYPE_SIZE (type) = bitsize_zero_node; TYPE_SIZE_UNIT (type) = size_zero_node; SET_TYPE_STRUCTURAL_EQUALITY (type); @@ -5408,6 +5498,7 @@ { gcc_assert (itype); /* The type is complete. C99 6.7.5.2p4 */ + type = build_distinct_type_copy (TYPE_MAIN_VARIANT (type)); TYPE_SIZE (type) = bitsize_zero_node; TYPE_SIZE_UNIT (type) = size_zero_node; SET_TYPE_STRUCTURAL_EQUALITY (type); @@ -5511,12 +5602,11 @@ the formal parameter list of this FUNCTION_TYPE to point to the FUNCTION_TYPE node itself. */ { - tree link; - - for (link = arg_info->tags; - link; - link = TREE_CHAIN (link)) - TYPE_CONTEXT (TREE_VALUE (link)) = type; + c_arg_tag *tag; + unsigned ix; + + FOR_EACH_VEC_ELT_REVERSE (c_arg_tag, arg_info->tags, ix, tag) + TYPE_CONTEXT (tag->type) = type; } break; } @@ -5871,12 +5961,6 @@ pedwarn (loc, OPT_pedantic, "ISO C forbids qualified function types"); - /* GNU C interprets a volatile-qualified function type to indicate - that the function does not return. */ - if ((type_quals & TYPE_QUAL_VOLATILE) - && !VOID_TYPE_P (TREE_TYPE (TREE_TYPE (decl)))) - warning_at (loc, 0, "%<noreturn%> function returns non-void value"); - /* Every function declaration is an external reference (DECL_EXTERNAL) except for those which are not at file scope and are explicitly declared "auto". This is @@ -6078,9 +6162,13 @@ else if (arg_types && TREE_CODE (TREE_VALUE (arg_types)) == IDENTIFIER_NODE) { if (!funcdef_flag) - pedwarn (input_location, 0, "parameter names (without types) in function declaration"); - - arg_info->parms = arg_info->types; + { + pedwarn (input_location, 0, "parameter names (without types) in function declaration"); + arg_info->parms = NULL_TREE; + } + else + arg_info->parms = arg_info->types; + arg_info->types = 0; return 0; } @@ -6101,7 +6189,7 @@ for (parm = arg_info->parms, typelt = arg_types, parmno = 1; parm; - parm = TREE_CHAIN (parm), typelt = TREE_CHAIN (typelt), parmno++) + parm = DECL_CHAIN (parm), typelt = TREE_CHAIN (typelt), parmno++) { type = TREE_VALUE (typelt); if (type == error_mark_node) @@ -6153,6 +6241,22 @@ } } +/* Allocate and initialize a c_arg_info structure from the parser's + obstack. */ + +struct c_arg_info * +build_arg_info (void) +{ + struct c_arg_info *ret = XOBNEW (&parser_obstack, struct c_arg_info); + ret->parms = NULL_TREE; + ret->tags = NULL; + ret->types = NULL_TREE; + ret->others = NULL_TREE; + ret->pending_sizes = NULL; + ret->had_vla_unspec = 0; + return ret; +} + /* Take apart the current scope and return a c_arg_info structure with info on a parameter list just parsed. @@ -6165,21 +6269,16 @@ get_parm_info (bool ellipsis) { struct c_binding *b = current_scope->bindings; - struct c_arg_info *arg_info = XOBNEW (&parser_obstack, - struct c_arg_info); + struct c_arg_info *arg_info = build_arg_info (); + tree parms = 0; - tree tags = 0; + VEC(c_arg_tag,gc) *tags = NULL; tree types = 0; tree others = 0; static bool explained_incomplete_types = false; bool gave_void_only_once_err = false; - arg_info->parms = 0; - arg_info->tags = 0; - arg_info->types = 0; - arg_info->others = 0; - arg_info->pending_sizes = 0; arg_info->had_vla_unspec = current_scope->had_vla_unspec; /* The bindings in this scope must not get put into a block. @@ -6222,6 +6321,7 @@ { tree decl = b->decl; tree type = TREE_TYPE (decl); + c_arg_tag *tag; const char *keyword; switch (TREE_CODE (decl)) @@ -6248,7 +6348,7 @@ else { /* Valid parameter, add it to the list. */ - TREE_CHAIN (decl) = parms; + DECL_CHAIN (decl) = parms; parms = decl; /* Since there is a prototype, args are passed in their @@ -6295,7 +6395,9 @@ } } - tags = tree_cons (b->id, decl, tags); + tag = VEC_safe_push (c_arg_tag, gc, tags, NULL); + tag->id = b->id; + tag->type = decl; break; case CONST_DECL: @@ -6312,7 +6414,7 @@ gcc_assert (TREE_CODE (decl) == FUNCTION_DECL ? b->nested : !b->nested); - TREE_CHAIN (decl) = others; + DECL_CHAIN (decl) = others; others = decl; /* fall through */ @@ -6552,15 +6654,15 @@ is the anonymous union extension. Similarly for struct. If this is something of the form "struct foo;", then - If MS extensions are enabled, this is handled as an - anonymous struct. + If MS or Plan 9 extensions are enabled, this is handled as + an anonymous struct. Otherwise this is a forward declaration of a structure tag. If this is something of the form "foo;" and foo is a TYPE_DECL, then If foo names a structure or union without a tag, then this is an anonymous struct (this is permitted by C1X). - If MS extensions are enabled and foo names a structure, then - again this is an anonymous struct. + If MS or Plan 9 extensions are enabled and foo names a + structure, then again this is an anonymous struct. Otherwise this is an error. Oh what a horrid tangled web we weave. I wonder if MS consciously @@ -6574,7 +6676,7 @@ if (type_ok) { - if (flag_ms_extensions) + if (flag_ms_extensions || flag_plan9_extensions) ok = true; else if (TYPE_NAME (TYPE_MAIN_VARIANT (type)) == NULL) ok = true; @@ -6626,6 +6728,50 @@ return value; } +/* Subroutine of detect_field_duplicates: return whether X and Y, + which are both fields in the same struct, have duplicate field + names. */ + +static bool +is_duplicate_field (tree x, tree y) +{ + if (DECL_NAME (x) != NULL_TREE && DECL_NAME (x) == DECL_NAME (y)) + return true; + + /* When using -fplan9-extensions, an anonymous field whose name is a + typedef can duplicate a field name. */ + if (flag_plan9_extensions + && (DECL_NAME (x) == NULL_TREE || DECL_NAME (y) == NULL_TREE)) + { + tree xt, xn, yt, yn; + + xt = TREE_TYPE (x); + if (DECL_NAME (x) != NULL_TREE) + xn = DECL_NAME (x); + else if ((TREE_CODE (xt) == RECORD_TYPE || TREE_CODE (xt) == UNION_TYPE) + && TYPE_NAME (xt) != NULL_TREE + && TREE_CODE (TYPE_NAME (xt)) == TYPE_DECL) + xn = DECL_NAME (TYPE_NAME (xt)); + else + xn = NULL_TREE; + + yt = TREE_TYPE (y); + if (DECL_NAME (y) != NULL_TREE) + yn = DECL_NAME (y); + else if ((TREE_CODE (yt) == RECORD_TYPE || TREE_CODE (yt) == UNION_TYPE) + && TYPE_NAME (yt) != NULL_TREE + && TREE_CODE (TYPE_NAME (yt)) == TYPE_DECL) + yn = DECL_NAME (TYPE_NAME (yt)); + else + yn = NULL_TREE; + + if (xn != NULL_TREE && xn == yn) + return true; + } + + return false; +} + /* Subroutine of detect_field_duplicates: add the fields of FIELDLIST to HTAB, giving errors for any duplicates. */ @@ -6635,7 +6781,7 @@ tree x, y; void **slot; - for (x = fieldlist; x ; x = TREE_CHAIN (x)) + for (x = fieldlist; x ; x = DECL_CHAIN (x)) if ((y = DECL_NAME (x)) != 0) { slot = htab_find_slot (htab, y, INSERT); @@ -6648,7 +6794,22 @@ } else if (TREE_CODE (TREE_TYPE (x)) == RECORD_TYPE || TREE_CODE (TREE_TYPE (x)) == UNION_TYPE) - detect_field_duplicates_hash (TYPE_FIELDS (TREE_TYPE (x)), htab); + { + detect_field_duplicates_hash (TYPE_FIELDS (TREE_TYPE (x)), htab); + + /* When using -fplan9-extensions, an anonymous field whose + name is a typedef can duplicate a field name. */ + if (flag_plan9_extensions + && TYPE_NAME (TREE_TYPE (x)) != NULL_TREE + && TREE_CODE (TYPE_NAME (TREE_TYPE (x))) == TYPE_DECL) + { + tree xn = DECL_NAME (TYPE_NAME (TREE_TYPE (x))); + slot = htab_find_slot (htab, xn, INSERT); + if (*slot) + error ("duplicate member %q+D", TYPE_NAME (TREE_TYPE (x))); + *slot = xn; + } + } } /* Generate an error for any duplicate field names in FIELDLIST. Munge @@ -6660,20 +6821,29 @@ tree x, y; int timeout = 10; + /* If the struct is the list of instance variables of an Objective-C + class, then we need to add all the instance variables of + superclasses before checking for duplicates (since you can't have + an instance variable in a subclass with the same name as an + instance variable in a superclass). objc_get_interface_ivars() + leaves fieldlist unchanged if we are not in this case, so in that + case nothing changes compared to C. + */ + if (c_dialect_objc ()) + fieldlist = objc_get_interface_ivars (fieldlist); + /* First, see if there are more than "a few" fields. This is trivially true if there are zero or one fields. */ - if (!fieldlist) + if (!fieldlist || !DECL_CHAIN (fieldlist)) return; - x = TREE_CHAIN (fieldlist); - if (!x) - return; + x = fieldlist; do { timeout--; if (DECL_NAME (x) == NULL_TREE && (TREE_CODE (TREE_TYPE (x)) == RECORD_TYPE || TREE_CODE (TREE_TYPE (x)) == UNION_TYPE)) timeout = 0; - x = TREE_CHAIN (x); + x = DECL_CHAIN (x); } while (timeout > 0 && x); /* If there were "few" fields and no anonymous structures or unions, @@ -6681,11 +6851,19 @@ the nested traversal thing. */ if (timeout > 0) { - for (x = TREE_CHAIN (fieldlist); x ; x = TREE_CHAIN (x)) - if (DECL_NAME (x)) + for (x = DECL_CHAIN (fieldlist); x; x = DECL_CHAIN (x)) + /* When using -fplan9-extensions, we can have duplicates + between typedef names and fields. */ + if (DECL_NAME (x) + || (flag_plan9_extensions + && DECL_NAME (x) == NULL_TREE + && (TREE_CODE (TREE_TYPE (x)) == RECORD_TYPE + || TREE_CODE (TREE_TYPE (x)) == UNION_TYPE) + && TYPE_NAME (TREE_TYPE (x)) != NULL_TREE + && TREE_CODE (TYPE_NAME (TREE_TYPE (x))) == TYPE_DECL)) { for (y = fieldlist; y != x; y = TREE_CHAIN (y)) - if (DECL_NAME (y) == DECL_NAME (x)) + if (is_duplicate_field (y, x)) { error ("duplicate member %q+D", x); DECL_NAME (x) = NULL_TREE; @@ -6715,7 +6893,7 @@ because the flag is used to issue visibility warnings, and we only want to issue those warnings if the type is referenced outside of the struct declaration. */ - for (ix = 0; VEC_iterate (tree, struct_parse_info->struct_types, ix, x); ++ix) + FOR_EACH_VEC_ELT (tree, struct_parse_info->struct_types, ix, x) C_TYPE_DEFINED_IN_STRUCT (x) = 1; /* The TYPEDEFS_SEEN field of STRUCT_PARSE_INFO is a list of @@ -6731,14 +6909,13 @@ a pointer_set because identifiers are interned. */ struct pointer_set_t *tset = pointer_set_create (); - for (ix = 0; - VEC_iterate (tree, struct_parse_info->typedefs_seen, ix, x); - ++ix) + FOR_EACH_VEC_ELT (tree, struct_parse_info->typedefs_seen, ix, x) pointer_set_insert (tset, DECL_NAME (x)); - for (x = fieldlist; x != NULL_TREE; x = TREE_CHAIN (x)) - { - if (pointer_set_contains (tset, DECL_NAME (x))) + for (x = fieldlist; x != NULL_TREE; x = DECL_CHAIN (x)) + { + if (DECL_NAME (x) != NULL_TREE + && pointer_set_contains (tset, DECL_NAME (x))) { warning_at (DECL_SOURCE_LOCATION (x), OPT_Wc___compat, ("using %qD as both field and typedef name is " @@ -6754,9 +6931,7 @@ /* For each field which has a binding and which was not defined in an enclosing struct, clear the in_struct field. */ - for (ix = 0; - VEC_iterate (c_binding_ptr, struct_parse_info->fields, ix, b); - ++ix) + FOR_EACH_VEC_ELT (c_binding_ptr, struct_parse_info->fields, ix, b) b->in_struct = 0; } @@ -6785,7 +6960,7 @@ if (pedantic) { - for (x = fieldlist; x; x = TREE_CHAIN (x)) + for (x = fieldlist; x; x = DECL_CHAIN (x)) { if (DECL_NAME (x) != 0) break; @@ -6822,7 +6997,7 @@ until now.) */ saw_named_field = 0; - for (x = fieldlist; x; x = TREE_CHAIN (x)) + for (x = fieldlist; x; x = DECL_CHAIN (x)) { if (TREE_TYPE (x) == error_mark_node) continue; @@ -6835,9 +7010,7 @@ else { /* A field that is pseudo-const makes the structure likewise. */ - tree t1 = TREE_TYPE (x); - while (TREE_CODE (t1) == ARRAY_TYPE) - t1 = TREE_TYPE (t1); + tree t1 = strip_array_types (TREE_TYPE (x)); if ((TREE_CODE (t1) == RECORD_TYPE || TREE_CODE (t1) == UNION_TYPE) && C_TYPE_FIELDS_READONLY (t1)) C_TYPE_FIELDS_READONLY (t) = 1; @@ -6877,7 +7050,7 @@ "flexible array member in union"); TREE_TYPE (x) = error_mark_node; } - else if (TREE_CHAIN (x) != NULL_TREE) + else if (DECL_CHAIN (x) != NULL_TREE) { error_at (DECL_SOURCE_LOCATION (x), "flexible array member not at end of struct"); @@ -6930,7 +7103,7 @@ DECL_INITIAL (*fieldlistp) = 0; } else - fieldlistp = &TREE_CHAIN (*fieldlistp); + fieldlistp = &DECL_CHAIN (*fieldlistp); } /* Now we have the truly final field list. @@ -6944,7 +7117,7 @@ { int len = 0; - for (x = fieldlist; x; x = TREE_CHAIN (x)) + for (x = fieldlist; x; x = DECL_CHAIN (x)) { if (len > 15 || DECL_NAME (x) == NULL) break; @@ -6963,14 +7136,14 @@ ensure that this lives as long as the rest of the struct decl. All decls in an inline function need to be saved. */ - space = GGC_CNEW (struct lang_type); - space2 = GGC_NEWVAR (struct sorted_fields_type, - sizeof (struct sorted_fields_type) + len * sizeof (tree)); + space = ggc_alloc_cleared_lang_type (sizeof (struct lang_type)); + space2 = ggc_alloc_sorted_fields_type + (sizeof (struct sorted_fields_type) + len * sizeof (tree)); len = 0; space->s = space2; field_array = &space2->elts[0]; - for (x = fieldlist; x; x = TREE_CHAIN (x)) + for (x = fieldlist; x; x = DECL_CHAIN (x)) { field_array[len++] = x; @@ -7246,7 +7419,7 @@ /* Record the min/max values so that we can warn about bit-field enumerations that are too small for the values. */ - lt = GGC_CNEW (struct lang_type); + lt = ggc_alloc_cleared_lang_type (sizeof (struct lang_type)); lt->enum_min = minnode; lt->enum_max = maxnode; TYPE_LANG_SPECIFIC (enumtype) = lt; @@ -7284,12 +7457,13 @@ /* Build and install a CONST_DECL for one value of the current enumeration type (one that was begun with start_enum). - LOC is the location of the enumerator. + DECL_LOC is the location of the enumerator. + LOC is the location of the '=' operator if any, DECL_LOC otherwise. Return a tree-list containing the CONST_DECL and its value. Assignment of sequential values by default is handled here. */ tree -build_enumerator (location_t loc, +build_enumerator (location_t decl_loc, location_t loc, struct c_enum_contents *the_enum, tree name, tree value) { tree decl, type; @@ -7363,9 +7537,8 @@ /* Set basis for default for next value. */ the_enum->enum_next_value - = build_binary_op - (EXPR_HAS_LOCATION (value) ? EXPR_LOCATION (value) : input_location, - PLUS_EXPR, value, integer_one_node, 0); + = build_binary_op (EXPR_LOC_OR_HERE (value), + PLUS_EXPR, value, integer_one_node, 0); the_enum->enum_overflow = tree_int_cst_lt (the_enum->enum_next_value, value); /* Now create a declaration for the enum value name. */ @@ -7377,7 +7550,7 @@ >= TYPE_PRECISION (integer_type_node) && TYPE_UNSIGNED (type))); - decl = build_decl (loc, CONST_DECL, name, type); + decl = build_decl (decl_loc, CONST_DECL, name, type); DECL_INITIAL (decl) = convert (type, value); pushdecl (decl); @@ -7478,7 +7651,7 @@ current_function_prototype_locus = UNKNOWN_LOCATION; current_function_prototype_built_in = false; current_function_prototype_arg_types = NULL_TREE; - if (TYPE_ARG_TYPES (TREE_TYPE (decl1)) == 0) + if (!prototype_p (TREE_TYPE (decl1))) { if (old_decl != 0 && TREE_CODE (TREE_TYPE (old_decl)) == FUNCTION_TYPE && comptypes (TREE_TYPE (TREE_TYPE (decl1)), @@ -7527,7 +7700,7 @@ /* Optionally warn of old-fashioned def with no previous prototype. */ if (warn_strict_prototypes && old_decl != error_mark_node - && TYPE_ARG_TYPES (TREE_TYPE (decl1)) == 0 + && !prototype_p (TREE_TYPE (decl1)) && C_DECL_ISNT_PROTOTYPE (old_decl)) warning_at (loc, OPT_Wstrict_prototypes, "function declaration isn%'t a prototype"); @@ -7545,7 +7718,7 @@ && old_decl != 0 && old_decl != error_mark_node && TREE_USED (old_decl) - && TYPE_ARG_TYPES (TREE_TYPE (old_decl)) == 0) + && !prototype_p (TREE_TYPE (old_decl))) warning_at (loc, OPT_Wmissing_prototypes, "%qD was used with no prototype before its definition", decl1); /* Optionally warn of any global def with no previous declaration. */ @@ -7620,6 +7793,8 @@ store_parm_decls_newstyle (tree fndecl, const struct c_arg_info *arg_info) { tree decl; + c_arg_tag *tag; + unsigned ix; if (current_scope->bindings) { @@ -7642,7 +7817,7 @@ /* Now make all the parameter declarations visible in the function body. We can bypass most of the grunt work of pushdecl. */ - for (decl = arg_info->parms; decl; decl = TREE_CHAIN (decl)) + for (decl = arg_info->parms; decl; decl = DECL_CHAIN (decl)) { DECL_CONTEXT (decl) = current_function_decl; if (DECL_NAME (decl)) @@ -7661,7 +7836,7 @@ DECL_ARGUMENTS (fndecl) = arg_info->parms; /* Now make all the ancillary declarations visible, likewise. */ - for (decl = arg_info->others; decl; decl = TREE_CHAIN (decl)) + for (decl = arg_info->others; decl; decl = DECL_CHAIN (decl)) { DECL_CONTEXT (decl) = current_function_decl; if (DECL_NAME (decl)) @@ -7672,9 +7847,9 @@ } /* And all the tag declarations. */ - for (decl = arg_info->tags; decl; decl = TREE_CHAIN (decl)) - if (TREE_PURPOSE (decl)) - bind (TREE_PURPOSE (decl), TREE_VALUE (decl), current_scope, + FOR_EACH_VEC_ELT_REVERSE (c_arg_tag, arg_info->tags, ix, tag) + if (tag->id) + bind (tag->id, tag->type, current_scope, /*invisible=*/false, /*nested=*/false, UNKNOWN_LOCATION); } @@ -7709,6 +7884,9 @@ if (b && B_IN_CURRENT_SCOPE (b)) { decl = b->decl; + /* Skip erroneous parameters. */ + if (decl == error_mark_node) + continue; /* If we got something other than a PARM_DECL it is an error. */ if (TREE_CODE (decl) != PARM_DECL) error_at (DECL_SOURCE_LOCATION (decl), @@ -7813,10 +7991,10 @@ for (parm = TREE_CHAIN (parm); parm; parm = TREE_CHAIN (parm)) if (TREE_PURPOSE (parm)) { - TREE_CHAIN (last) = TREE_PURPOSE (parm); + DECL_CHAIN (last) = TREE_PURPOSE (parm); last = TREE_PURPOSE (parm); } - TREE_CHAIN (last) = 0; + DECL_CHAIN (last) = 0; } pointer_set_destroy (seen_args); @@ -7832,7 +8010,7 @@ type = current_function_prototype_arg_types; parm || (type && TREE_VALUE (type) != error_mark_node && (TYPE_MAIN_VARIANT (TREE_VALUE (type)) != void_type_node)); - parm = TREE_CHAIN (parm), type = TREE_CHAIN (type)) + parm = DECL_CHAIN (parm), type = TREE_CHAIN (type)) { if (parm == 0 || type == 0 || TYPE_MAIN_VARIANT (TREE_VALUE (type)) == void_type_node) @@ -7923,7 +8101,7 @@ { tree actual = 0, last = 0, type; - for (parm = DECL_ARGUMENTS (fndecl); parm; parm = TREE_CHAIN (parm)) + for (parm = DECL_ARGUMENTS (fndecl); parm; parm = DECL_CHAIN (parm)) { type = tree_cons (NULL_TREE, DECL_ARG_TYPE (parm), NULL_TREE); if (last) @@ -8017,7 +8195,7 @@ tree t; int i; - for (i = 0; VEC_iterate (tree, pending_sizes, i, t); i++) + FOR_EACH_VEC_ELT (tree, pending_sizes, i, t) add_stmt (t); } @@ -8030,7 +8208,7 @@ /* Finish up a function declaration and compile that function - all the way to assembler language output. The free the storage + all the way to assembler language output. Then free the storage for the function definition. This is called after parsing the body of the function definition. */ @@ -8039,12 +8217,15 @@ finish_function (void) { tree fndecl = current_function_decl; + + if (c_dialect_objc ()) + objc_finish_function (); if (TREE_CODE (fndecl) == FUNCTION_DECL && targetm.calls.promote_prototypes (TREE_TYPE (fndecl))) { tree args = DECL_ARGUMENTS (fndecl); - for (; args; args = TREE_CHAIN (args)) + for (; args; args = DECL_CHAIN (args)) { tree type = TREE_TYPE (args); if (INTEGRAL_TYPE_P (type) @@ -8107,7 +8288,7 @@ for (decl = DECL_ARGUMENTS (fndecl); decl; - decl = TREE_CHAIN (decl)) + decl = DECL_CHAIN (decl)) if (TREE_USED (decl) && TREE_CODE (decl) == PARM_DECL && !DECL_READ_P (decl) @@ -8173,16 +8354,23 @@ /* Check the declarations given in a for-loop for satisfying the C99 constraints. If exactly one such decl is found, return it. LOC is - the location of the opening parenthesis of the for loop. */ + the location of the opening parenthesis of the for loop. The last + parameter allows you to control the "for loop initial declarations + are only allowed in C99 mode". Normally, you should pass + flag_isoc99 as that parameter. But in some cases (Objective-C + foreach loop, for example) we want to run the checks in this + function even if not in C99 mode, so we allow the caller to turn + off the error about not being in C99 mode. +*/ tree -check_for_loop_decls (location_t loc) +check_for_loop_decls (location_t loc, bool turn_off_iso_c99_error) { struct c_binding *b; tree one_decl = NULL_TREE; int n_decls = 0; - if (!flag_isoc99) + if (!turn_off_iso_c99_error) { static bool hint = true; /* If we get here, declarations have been used in a for loop without @@ -8269,7 +8457,7 @@ c_push_function_context (void) { struct language_function *p; - p = GGC_NEW (struct language_function); + p = ggc_alloc_language_function (); cfun->language = p; p->base.x_stmt_tree = c_stmt_tree; @@ -8468,10 +8656,9 @@ ret->storage_class = csc_none; ret->expr_const_operands = true; ret->declspecs_seen_p = false; - ret->type_seen_p = false; + ret->typespec_kind = ctsk_none; ret->non_sc_seen_p = false; ret->typedef_p = false; - ret->tag_defined_p = false; ret->explicit_signed_p = false; ret->deprecated_p = false; ret->default_int_p = false; @@ -8555,7 +8742,7 @@ tree type = spec.spec; specs->non_sc_seen_p = true; specs->declspecs_seen_p = true; - specs->type_seen_p = true; + specs->typespec_kind = spec.kind; if (TREE_DEPRECATED (type)) specs->deprecated_p = true; @@ -8604,6 +8791,10 @@ error_at (loc, ("both %<long%> and %<void%> in " "declaration specifiers")); + else if (specs->typespec_word == cts_int128) + error_at (loc, + ("both %<long%> and %<__int128%> in " + "declaration specifiers")); else if (specs->typespec_word == cts_bool) error_at (loc, ("both %<long%> and %<_Bool%> in " @@ -8641,6 +8832,10 @@ error_at (loc, ("both %<short%> and %<void%> in " "declaration specifiers")); + else if (specs->typespec_word == cts_int128) + error_at (loc, + ("both %<short%> and %<__int128%> in " + "declaration specifiers")); else if (specs->typespec_word == cts_bool) error_at (loc, ("both %<short%> and %<_Bool%> in " @@ -8790,7 +8985,13 @@ dupe = specs->saturating_p; pedwarn (loc, OPT_pedantic, "ISO C does not support saturating types"); - if (specs->typespec_word == cts_void) + if (specs->typespec_word == cts_int128) + { + error_at (loc, + ("both %<_Sat%> and %<__int128%> in " + "declaration specifiers")); + } + else if (specs->typespec_word == cts_void) error_at (loc, ("both %<_Sat%> and %<void%> in " "declaration specifiers")); @@ -8845,7 +9046,7 @@ else { /* "void", "_Bool", "char", "int", "float", "double", "_Decimal32", - "_Decimal64", "_Decimal128", "_Fract" or "_Accum". */ + "__int128", "_Decimal64", "_Decimal128", "_Fract" or "_Accum". */ if (specs->typespec_word != cts_none) { error_at (loc, @@ -8854,6 +9055,31 @@ } switch (i) { + case RID_INT128: + if (int128_integer_type_node == NULL_TREE) + { + error_at (loc, "%<__int128%> is not supported for this target"); + return specs; + } + if (!in_system_header) + pedwarn (loc, OPT_pedantic, + "ISO C does not support %<__int128%> type"); + + if (specs->long_p) + error_at (loc, + ("both %<__int128%> and %<long%> in " + "declaration specifiers")); + else if (specs->saturating_p) + error_at (loc, + ("both %<_Sat%> and %<__int128%> in " + "declaration specifiers")); + else if (specs->short_p) + error_at (loc, + ("both %<__int128%> and %<short%> in " + "declaration specifiers")); + else + specs->typespec_word = cts_int128; + return specs; case RID_VOID: if (specs->long_p) error_at (loc, @@ -9117,11 +9343,9 @@ else specs->type = TREE_TYPE (t); } - else if (TREE_CODE (type) != ERROR_MARK) - { - if (spec.kind == ctsk_tagdef || spec.kind == ctsk_tagfirstref) - specs->tag_defined_p = true; - if (spec.kind == ctsk_typeof) + else + { + if (TREE_CODE (type) != ERROR_MARK && spec.kind == ctsk_typeof) { specs->typedef_p = true; if (spec.expr) @@ -9251,6 +9475,10 @@ gcc_assert (!specs->long_p && !specs->long_long_p && !specs->short_p && !specs->signed_p && !specs->unsigned_p && !specs->complex_p); + + /* Set a dummy type. */ + if (TREE_CODE (specs->type) == ERROR_MARK) + specs->type = integer_type_node; return specs; } @@ -9326,6 +9554,19 @@ specs->type = build_complex_type (specs->type); } break; + case cts_int128: + gcc_assert (!specs->long_p && !specs->short_p && !specs->long_long_p); + gcc_assert (!(specs->signed_p && specs->unsigned_p)); + specs->type = (specs->unsigned_p + ? int128_unsigned_type_node + : int128_integer_type_node); + if (specs->complex_p) + { + pedwarn (input_location, OPT_pedantic, + "ISO C does not support complex integer types"); + specs->type = build_complex_type (specs->type); + } + break; case cts_int: gcc_assert (!(specs->long_p && specs->short_p)); gcc_assert (!(specs->signed_p && specs->unsigned_p)); @@ -9491,7 +9732,7 @@ bool reconsider; /* Process the decls in the order they were written. */ - for (decl = globals; decl; decl = TREE_CHAIN (decl)) + for (decl = globals; decl; decl = DECL_CHAIN (decl)) { /* Check for used but undefined static functions using the C standard's definition of "used", and set TREE_NO_WARNING so @@ -9512,12 +9753,12 @@ do { reconsider = false; - for (decl = globals; decl; decl = TREE_CHAIN (decl)) + for (decl = globals; decl; decl = DECL_CHAIN (decl)) reconsider |= wrapup_global_declaration_2 (decl); } while (reconsider); - for (decl = globals; decl; decl = TREE_CHAIN (decl)) + for (decl = globals; decl; decl = DECL_CHAIN (decl)) check_global_declaration_1 (decl); } @@ -9529,10 +9770,49 @@ { tree decl; - for (decl = globals; decl ; decl = TREE_CHAIN (decl)) + for (decl = globals; decl ; decl = DECL_CHAIN (decl)) debug_hooks->global_decl (decl); } +/* Callback to collect a source_ref from a DECL. */ + +static void +collect_source_ref_cb (tree decl) +{ + if (!DECL_IS_BUILTIN (decl)) + collect_source_ref (LOCATION_FILE (decl_sloc (decl, false))); +} + +/* Collect all references relevant to SOURCE_FILE. */ + +static void +collect_all_refs (const char *source_file) +{ + tree t; + unsigned i; + + FOR_EACH_VEC_ELT (tree, all_translation_units, i, t) + collect_ada_nodes (BLOCK_VARS (DECL_INITIAL (t)), source_file); +} + +/* Iterate over all global declarations and call CALLBACK. */ + +static void +for_each_global_decl (void (*callback) (tree decl)) +{ + tree t; + tree decls; + tree decl; + unsigned i; + + FOR_EACH_VEC_ELT (tree, all_translation_units, i, t) + { + decls = DECL_INITIAL (t); + for (decl = BLOCK_VARS (decls); decl; decl = TREE_CHAIN (decl)) + callback (decl); + } +} + /* Preserve the external declarations scope across a garbage collect. */ static GTY(()) tree ext_block; @@ -9540,21 +9820,35 @@ c_write_global_declarations (void) { tree t; + unsigned i; /* We don't want to do this if generating a PCH. */ if (pch_file) return; - /* Don't waste time on further processing if -fsyntax-only. - Continue for warning and errors issued during lowering though. */ - if (flag_syntax_only) - return; + /* Do the Objective-C stuff. This is where all the Objective-C + module stuff gets generated (symtab, class/protocol/selector + lists etc). */ + if (c_dialect_objc ()) + objc_write_global_declarations (); /* Close the external scope. */ ext_block = pop_scope (); external_scope = 0; gcc_assert (!current_scope); + /* Handle -fdump-ada-spec[-slim]. */ + if (dump_enabled_p (TDI_ada)) + { + /* Build a table of files to generate specs for */ + if (get_dump_file_info (TDI_ada)->flags & TDF_SLIM) + collect_source_ref (main_input_filename); + else + for_each_global_decl (collect_source_ref_cb); + + dump_ada_specs (collect_all_refs, NULL); + } + if (ext_block) { tree tmp = BLOCK_VARS (ext_block); @@ -9569,7 +9863,7 @@ /* Process all file scopes in this compilation, and the external_scope, through wrapup_global_declarations and check_global_declarations. */ - for (t = all_translation_units; t; t = TREE_CHAIN (t)) + FOR_EACH_VEC_ELT (tree, all_translation_units, i, t) c_write_global_declarations_1 (BLOCK_VARS (DECL_INITIAL (t))); c_write_global_declarations_1 (BLOCK_VARS (ext_block)); @@ -9579,10 +9873,10 @@ /* After cgraph has had a chance to emit everything that's going to be emitted, output debug information for globals. */ - if (errorcount == 0 && sorrycount == 0) + if (!seen_error ()) { timevar_push (TV_SYMOUT); - for (t = all_translation_units; t; t = TREE_CHAIN (t)) + FOR_EACH_VEC_ELT (tree, all_translation_units, i, t) c_write_global_declarations_2 (BLOCK_VARS (DECL_INITIAL (t))); c_write_global_declarations_2 (BLOCK_VARS (ext_block)); timevar_pop (TV_SYMOUT); @@ -9591,4 +9885,23 @@ ext_block = NULL; } +/* Register reserved keyword WORD as qualifier for address space AS. */ + +void +c_register_addr_space (const char *word, addr_space_t as) +{ + int rid = RID_FIRST_ADDR_SPACE + as; + tree id; + + /* Address space qualifiers are only supported + in C with GNU extensions enabled. */ + if (c_dialect_objc () || flag_no_asm) + return; + + id = get_identifier (word); + C_SET_RID_CODE (id, rid); + C_IS_RESERVED_WORD (id) = 1; + ridpointers [rid] = id; +} + #include "gt-c-decl.h"