diff options
Diffstat (limited to 'gcc/cp/decl.c')
-rw-r--r-- | gcc/cp/decl.c | 627 |
1 files changed, 368 insertions, 259 deletions
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 4d912cdf897..06b081c2831 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -46,15 +46,11 @@ Boston, MA 02111-1307, USA. */ #include "tm_p.h" #include "target.h" #include "c-common.h" +#include "c-pragma.h" #include "diagnostic.h" extern const struct attribute_spec *lang_attribute_table; -#ifndef BOOL_TYPE_SIZE -/* `bool' has size and alignment `1', on all platforms. */ -#define BOOL_TYPE_SIZE CHAR_TYPE_SIZE -#endif - static tree grokparms PARAMS ((tree)); static const char *redeclaration_error_message PARAMS ((tree, tree)); @@ -81,11 +77,14 @@ static tree grokfndecl PARAMS ((tree, tree, tree, tree, int, enum overload_flags, tree, tree, int, int, int, int, int, int, tree)); static tree grokvardecl PARAMS ((tree, tree, RID_BIT_TYPE *, int, int, tree)); +static tree follow_tag_typedef PARAMS ((tree)); static tree lookup_tag PARAMS ((enum tree_code, tree, struct binding_level *, int)); static void set_identifier_type_value_with_scope PARAMS ((tree, tree, struct binding_level *)); static void record_unknown_type PARAMS ((tree, const char *)); +static tree builtin_function_1 PARAMS ((const char *, tree, tree, int, + enum built_in_class, const char *)); static tree build_library_fn_1 PARAMS ((tree, enum tree_code, tree)); static int member_function_or_else PARAMS ((tree, tree, enum overload_flags)); static void bad_specifiers PARAMS ((tree, const char *, int, int, int, int, @@ -395,10 +394,6 @@ struct binding_level /* The binding level which this one is contained in (inherits from). */ struct binding_level *level_chain; - /* List of decls in `names' that have incomplete - structure or union types. */ - tree incomplete; - /* List of VAR_DECLS saved from a previous for statement. These would be dead in ISO-conforming code, but might be referenced in ARM-era code. These are stored in a @@ -481,6 +476,12 @@ static struct binding_level *global_binding_level; static int keep_next_level_flag; +/* A TREE_LIST of VAR_DECLs. The TREE_PURPOSE is a RECORD_TYPE or + UNION_TYPE; the TREE_VALUE is a VAR_DECL with that type. At the + time the VAR_DECL was declared, the type was incomplete. */ + +static tree incomplete_vars; + #if defined(DEBUG_CP_BINDING_LEVELS) static int binding_depth = 0; static int is_class_level = 0; @@ -1954,7 +1955,6 @@ mark_binding_level (arg) ggc_mark_tree (lvl->shadowed_labels); ggc_mark_tree (lvl->blocks); ggc_mark_tree (lvl->this_class); - ggc_mark_tree (lvl->incomplete); ggc_mark_tree (lvl->dead_vars_from_for); } } @@ -1970,7 +1970,7 @@ mark_named_label_lists (labs, uses) for (; l; l = l->next) { ggc_mark (l); - mark_binding_level (l->binding_level); + mark_binding_level (&l->binding_level); ggc_mark_tree (l->old_value); ggc_mark_tree (l->label_decl); ggc_mark_tree (l->bad_decls); @@ -1992,8 +1992,6 @@ print_binding_level (lvl) int i = 0, len; fprintf (stderr, " blocks="); fprintf (stderr, HOST_PTR_PRINTF, lvl->blocks); - fprintf (stderr, " n_incomplete=%d parm_flag=%d keep=%d", - list_length (lvl->incomplete), lvl->parm_flag, lvl->keep); if (lvl->tag_transparent) fprintf (stderr, " tag-transparent"); if (lvl->more_cleanups_ok) @@ -2394,7 +2392,6 @@ mark_saved_scope (arg) ggc_mark_tree (t->x_previous_class_type); ggc_mark_tree (t->x_previous_class_values); ggc_mark_tree (t->x_saved_tree); - ggc_mark_tree (t->incomplete); ggc_mark_tree (t->lookups); mark_stmt_tree (&t->x_stmt_tree); @@ -2500,6 +2497,7 @@ maybe_push_to_top_level (pseudo) s->bindings = b; s->need_pop_function_context = need_pop; s->function_decl = current_function_decl; + s->last_parms = last_function_parms; scope_chain = s; current_function_decl = NULL_TREE; @@ -2541,6 +2539,7 @@ pop_from_top_level () if (s->need_pop_function_context) pop_function_context_from (NULL_TREE); current_function_decl = s->function_decl; + last_function_parms = s->last_parms; free (s); } @@ -3142,6 +3141,10 @@ duplicate_decls (newdecl, olddecl) { if (TREE_CODE (newdecl) != FUNCTION_DECL) { + /* Avoid warnings redeclaring anticipated built-ins. */ + if (DECL_ANTICIPATED (olddecl)) + return 0; + /* If you declare a built-in or predefined function name as static, the old definition is overridden, but optionally warn this was a bad choice of name. */ @@ -3169,7 +3172,10 @@ duplicate_decls (newdecl, olddecl) } else if (!types_match) { - if ((DECL_EXTERN_C_P (newdecl) + /* Avoid warnings redeclaring anticipated built-ins. */ + if (DECL_ANTICIPATED (olddecl)) + ; /* Do nothing yet. */ + else if ((DECL_EXTERN_C_P (newdecl) && DECL_EXTERN_C_P (olddecl)) || compparms (TYPE_ARG_TYPES (TREE_TYPE (newdecl)), TYPE_ARG_TYPES (TREE_TYPE (olddecl)))) @@ -3190,6 +3196,9 @@ duplicate_decls (newdecl, olddecl) else /* Discard the old built-in function. */ return 0; + + /* Replace the old RTL to avoid problems with inlining. */ + SET_DECL_RTL (olddecl, DECL_RTL (newdecl)); } if (DECL_THIS_STATIC (newdecl) && !DECL_THIS_STATIC (olddecl)) @@ -3204,9 +3213,6 @@ duplicate_decls (newdecl, olddecl) will be banished. */ SET_DECL_LANGUAGE (olddecl, DECL_LANGUAGE (newdecl)); SET_DECL_RTL (olddecl, DECL_RTL (newdecl)); - COPY_DECL_ASSEMBLER_NAME (olddecl, newdecl); - SET_IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (newdecl), - newdecl); } } else if (TREE_CODE (olddecl) != TREE_CODE (newdecl)) @@ -3416,6 +3422,18 @@ duplicate_decls (newdecl, olddecl) } } + /* Do not merge an implicit typedef with an explicit one. In: + + class A; + ... + typedef class A A __attribute__ ((foo)); + + the attribute should apply only to the typedef. */ + if (TREE_CODE (olddecl) == TYPE_DECL + && (DECL_IMPLICIT_TYPEDEF_P (olddecl) + || DECL_IMPLICIT_TYPEDEF_P (newdecl))) + return 0; + /* If new decl is `static' and an `extern' was seen previously, warn about it. */ warn_extern_redeclared_static (newdecl, olddecl); @@ -3482,7 +3500,6 @@ duplicate_decls (newdecl, olddecl) except for any that we copy here from the old type. */ DECL_ATTRIBUTES (newdecl) = (*targetm.merge_decl_attributes) (olddecl, newdecl); - decl_attributes (&newdecl, DECL_ATTRIBUTES (newdecl), 0); if (TREE_CODE (newdecl) == TEMPLATE_DECL) { @@ -3514,16 +3531,16 @@ duplicate_decls (newdecl, olddecl) tree newtype; /* Merge the data types specified in the two decls. */ - newtype = common_type (TREE_TYPE (newdecl), TREE_TYPE (olddecl)); + newtype = merge_types (TREE_TYPE (newdecl), TREE_TYPE (olddecl)); - /* If common_type produces a non-typedef type, just use the old type. */ + /* If merge_types produces a non-typedef type, just use the old type. */ if (TREE_CODE (newdecl) == TYPE_DECL && newtype == DECL_ORIGINAL_TYPE (newdecl)) newtype = oldtype; if (TREE_CODE (newdecl) == VAR_DECL) DECL_THIS_EXTERN (newdecl) |= DECL_THIS_EXTERN (olddecl); - /* Do this after calling `common_type' so that default + /* Do this after calling `merge_types' so that default parameters don't confuse us. */ else if (TREE_CODE (newdecl) == FUNCTION_DECL && (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (newdecl)) @@ -3587,15 +3604,23 @@ duplicate_decls (newdecl, olddecl) if (DECL_SECTION_NAME (newdecl) == NULL_TREE) DECL_SECTION_NAME (newdecl) = DECL_SECTION_NAME (olddecl); - /* Keep the old rtl since we can safely use it. */ - COPY_DECL_RTL (olddecl, newdecl); - if (TREE_CODE (newdecl) == FUNCTION_DECL) { DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (newdecl) |= DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (olddecl); DECL_NO_LIMIT_STACK (newdecl) |= DECL_NO_LIMIT_STACK (olddecl); + /* Keep the old RTL. */ + COPY_DECL_RTL (olddecl, newdecl); + } + else if (TREE_CODE (newdecl) == VAR_DECL + && (DECL_SIZE (olddecl) || !DECL_SIZE (newdecl))) + { + /* Keep the old RTL. We cannot keep the old RTL if the old + declaration was for an incomplete object and the new + declaration is not since many attributes of the RTL will + change. */ + COPY_DECL_RTL (olddecl, newdecl); } } /* If cannot merge, then use the new type and qualifiers, @@ -3614,7 +3639,8 @@ duplicate_decls (newdecl, olddecl) } /* Merge the storage class information. */ - DECL_WEAK (newdecl) |= DECL_WEAK (olddecl); + merge_weak (newdecl, olddecl); + DECL_ONE_ONLY (newdecl) |= DECL_ONE_ONLY (olddecl); DECL_DEFER_OUTPUT (newdecl) |= DECL_DEFER_OUTPUT (olddecl); TREE_PUBLIC (newdecl) = TREE_PUBLIC (olddecl); @@ -4230,22 +4256,8 @@ pushdecl (x) if (TREE_CODE (x) == FUNCTION_DECL) check_default_args (x); - /* Keep count of variables in this level with incomplete type. */ - if (TREE_CODE (x) == VAR_DECL - && TREE_TYPE (x) != error_mark_node - && ((!COMPLETE_TYPE_P (TREE_TYPE (x)) - && PROMOTES_TO_AGGR_TYPE (TREE_TYPE (x), ARRAY_TYPE)) - /* RTTI TD entries are created while defining the type_info. */ - || (TYPE_LANG_SPECIFIC (TREE_TYPE (x)) - && TYPE_BEING_DEFINED (TREE_TYPE (x))))) - { - if (namespace_bindings_p ()) - namespace_scope_incomplete - = tree_cons (NULL_TREE, x, namespace_scope_incomplete); - else - current_binding_level->incomplete - = tree_cons (NULL_TREE, x, current_binding_level->incomplete); - } + if (TREE_CODE (x) == VAR_DECL) + maybe_register_incomplete_var (x); } if (need_new_binding) @@ -5289,6 +5301,47 @@ storetags (tags) current_binding_level->tags = tags; } +/* Return the type that should be used when TYPE's name is preceded + by a tag such as 'struct' or 'union', or null if the name cannot + be used in this way. + + For example, when processing the third line of: + + struct A; + typedef struct A A; + struct A; + + lookup of A will find the typedef. Given A's typedef, this function + will return the type associated with "struct A". For the tag to be + anything other than TYPE, TYPE must be a typedef whose original type + has the same name and context as TYPE itself. + + It is not valid for a typedef of an anonymous type to be used with + an explicit tag: + + typedef struct { ... } B; + struct B; + + Return null for this case. */ + +static tree +follow_tag_typedef (type) + tree type; +{ + tree original; + + original = original_type (type); + if (! TYPE_NAME (original)) + return NULL_TREE; + if (TYPE_IDENTIFIER (original) == TYPE_IDENTIFIER (type) + && (CP_DECL_CONTEXT (TYPE_NAME (original)) + == CP_DECL_CONTEXT (TYPE_NAME (type))) + && !(CLASS_TYPE_P (original) && TYPE_WAS_ANONYMOUS (original))) + return original; + else + return NULL_TREE; +} + /* Given NAME, an IDENTIFIER_NODE, return the structure (or union or enum) definition for that name. Searches binding levels from BINDING_LEVEL up to the global level. @@ -5340,18 +5393,23 @@ lookup_tag (form, name, binding_level, thislevel_only) else old = BINDING_TYPE (old); - /* If it has an original type, it is a typedef, and we - should not return it. */ - if (old && DECL_ORIGINAL_TYPE (TYPE_NAME (old))) - old = NULL_TREE; - if (old && TREE_CODE (old) != form - && !(form != ENUMERAL_TYPE && TREE_CODE (old) == TEMPLATE_DECL)) + if (old) { - error ("`%#D' redeclared as %C", old, form); - return NULL_TREE; + /* We've found something at this binding level. If it is + a typedef, extract the tag it refers to. Lookup fails + if the typedef doesn't refer to a taggable type. */ + old = follow_tag_typedef (old); + if (!old) + return NULL_TREE; + if (TREE_CODE (old) != form + && (form == ENUMERAL_TYPE + || TREE_CODE (old) == ENUMERAL_TYPE)) + { + error ("`%#D' redeclared as %C", old, form); + return NULL_TREE; + } + return old; } - if (old) - return old; if (thislevel_only || tail == global_namespace) return NULL_TREE; } @@ -5361,14 +5419,12 @@ lookup_tag (form, name, binding_level, thislevel_only) if (TREE_PURPOSE (tail) == name) { enum tree_code code = TREE_CODE (TREE_VALUE (tail)); - /* Should tighten this up; it'll probably permit - UNION_TYPE and a struct template, for example. */ + if (code != form - && !(form != ENUMERAL_TYPE && code == TEMPLATE_DECL)) + && (form == ENUMERAL_TYPE || code == ENUMERAL_TYPE)) { /* Definition isn't the kind we were looking for. */ - error ("`%#D' redeclared as %C", TREE_VALUE (tail), - form); + error ("`%#D' redeclared as %C", TREE_VALUE (tail), form); return NULL_TREE; } return TREE_VALUE (tail); @@ -5506,7 +5562,12 @@ lookup_namespace_name (namespace, name) /* If we have a single function from a using decl, pull it out. */ if (TREE_CODE (val) == OVERLOAD && ! really_overloaded_fn (val)) val = OVL_FUNCTION (val); - return val; + + /* Ignore built-in functions that haven't been prototyped yet. */ + if (!val || !DECL_P(val) + || !DECL_LANG_SPECIFIC(val) + || !DECL_ANTICIPATED (val)) + return val; } error ("`%D' undeclared in namespace `%D'", name, namespace); @@ -5698,8 +5759,25 @@ make_typename_type (context, name, complain) t = lookup_field (context, name, 0, 1); if (t) { + if (TREE_CODE (t) != TYPE_DECL) + { + if (complain & tf_error) + error ("no type named `%#T' in `%#T'", name, context); + return error_mark_node; + } if (DECL_ARTIFICIAL (t) || !(complain & tf_keep_type_decl)) t = TREE_TYPE (t); + if (IMPLICIT_TYPENAME_P (t)) + { + /* Lookup found an implicit typename that we had + injected into the current scope. Doing things + properly would have located the exact same type, + so there is no error here. We must remove the + implicitness so that we do not warn about it. */ + t = copy_node (t); + TREE_TYPE (t) = NULL_TREE; + } + return t; } } @@ -5785,14 +5863,6 @@ select_decl (binding, flags) tree val; val = BINDING_VALUE (binding); - /* When we implicitly declare some builtin entity, we mark it - DECL_ANTICIPATED, so that we know to ignore it until it is - really declared. */ - if (val && DECL_P (val) - && DECL_LANG_SPECIFIC (val) - && DECL_ANTICIPATED (val)) - return NULL_TREE; - if (LOOKUP_NAMESPACES_ONLY (flags)) { /* We are not interested in types. */ @@ -5842,9 +5912,21 @@ unqualified_namespace_lookup (name, flags, spacesp) *spacesp = tree_cons (scope, NULL_TREE, *spacesp); val = binding_for_name (name, scope); - /* Initialize binding for this context. */ - BINDING_VALUE (b) = BINDING_VALUE (val); - BINDING_TYPE (b) = BINDING_TYPE (val); + /* Ignore anticipated built-in functions. */ + if (val && BINDING_VALUE (val) + && DECL_P (BINDING_VALUE (val)) + && DECL_LANG_SPECIFIC (BINDING_VALUE (val)) + && DECL_ANTICIPATED (BINDING_VALUE (val))) + { + BINDING_VALUE (b) = NULL_TREE; + BINDING_TYPE (b) = NULL_TREE; + } + else + { + /* Initialize binding for this context. */ + BINDING_VALUE (b) = BINDING_VALUE (val); + BINDING_TYPE (b) = BINDING_TYPE (val); + } /* Add all _DECLs seen through local using-directives. */ for (level = current_binding_level; @@ -6024,7 +6106,13 @@ lookup_name_real (name, prefer_type, nonclass, namespaces_only) if (got_scope && got_scope != type && val && TREE_CODE (val) == TYPE_DECL && TREE_CODE (TREE_TYPE (val)) == TYPENAME_TYPE) - TYPE_CONTEXT (TREE_TYPE (val)) = got_scope; + { + val = TREE_TYPE (val); + val = build_typename_type (got_scope, name, + TYPENAME_TYPE_FULLNAME (val), + TREE_TYPE (val)); + val = TYPE_STUB_DECL (val); + } } } else @@ -6434,11 +6522,11 @@ cxx_init_decl_processing () flag_inline_functions = 0; } - /* In C++, we never create builtin functions whose name does not - begin with `__'. Users should be using headers to get prototypes - in C++. It would be nice if we could warn when `-fbuiltin' is - used explicitly, but we do not have that information. */ - flag_no_builtin = 1; + /* Force minimum function alignment if using the least significant + bit of function pointers to store the virtual bit. */ + if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_pfn + && force_align_functions_log < 1) + force_align_functions_log = 1; /* Initially, C. */ current_lang_name = lang_name_c; @@ -6637,6 +6725,7 @@ cxx_init_decl_processing () ggc_add_tree_root (¤t_lang_name, 1); ggc_add_tree_root (&static_aggregates, 1); ggc_add_tree_root (&free_bindings, 1); + ggc_add_tree_root (&incomplete_vars, 1); } /* Generate an initializer for a function naming variable from @@ -6704,10 +6793,9 @@ cp_make_fname_decl (id, type_dep) return decl; } -/* Entry point for the benefit of c_common_nodes_and_builtins. - - Make a definition for a builtin function named NAME and whose data type - is TYPE. TYPE should be a function type with argument types. +/* Make a definition for a builtin function named NAME in the current + namespace, whose data type is TYPE and whose context is CONTEXT. + TYPE should be a function type with argument types. CLASS and CODE tell later passes how to compile calls to this function. See tree.h for possible values. @@ -6715,10 +6803,11 @@ cp_make_fname_decl (id, type_dep) If LIBNAME is nonzero, use that for DECL_ASSEMBLER_NAME, the name to be called if we can't opencode the function. */ -tree -builtin_function (name, type, code, class, libname) +static tree +builtin_function_1 (name, type, context, code, class, libname) const char *name; tree type; + tree context; int code; enum built_in_class class; const char *libname; @@ -6726,23 +6815,13 @@ builtin_function (name, type, code, class, libname) tree decl = build_library_fn_1 (get_identifier (name), ERROR_MARK, type); DECL_BUILT_IN_CLASS (decl) = class; DECL_FUNCTION_CODE (decl) = code; + DECL_CONTEXT (decl) = context; /* The return builtins leave the current function. */ if (code == BUILT_IN_RETURN || code == BUILT_IN_EH_RETURN) TREE_THIS_VOLATILE (decl) = 1; - my_friendly_assert (DECL_CONTEXT (decl) == NULL_TREE, 392); - - /* All builtins that don't begin with an `_' should go in the `std' - namespace. */ - if (name[0] != '_') - { - push_namespace (std_identifier); - DECL_CONTEXT (decl) = std_node; - } pushdecl (decl); - if (name[0] != '_') - pop_namespace (); /* Since `pushdecl' relies on DECL_ASSEMBLER_NAME instead of DECL_NAME, we cannot change DECL_ASSEMBLER_NAME until we have installed this @@ -6762,6 +6841,39 @@ builtin_function (name, type, code, class, libname) return decl; } +/* Entry point for the benefit of c_common_nodes_and_builtins. + + Make a defintion for a builtin function named NAME and whose data type + is TYPE. TYPE should be a function type with argument types. This + function places the anticipated declaration in the global namespace + and additionally in the std namespace if appropriate. + + CLASS and CODE tell later passes how to compile calls to this function. + See tree.h for possible values. + + If LIBNAME is nonzero, use that for DECL_ASSEMBLER_NAME, + the name to be called if we can't opencode the function. */ + +tree +builtin_function (name, type, code, class, libname) + const char *name; + tree type; + int code; + enum built_in_class class; + const char *libname; +{ + /* All builtins that don't begin with an '_' should additionally + go in the 'std' namespace. */ + if (name[0] != '_') + { + push_namespace (std_identifier); + builtin_function_1 (name, type, std_node, code, class, libname); + pop_namespace (); + } + + return builtin_function_1 (name, type, NULL_TREE, code, class, libname); +} + /* Generate a FUNCTION_DECL with the typical flags for a runtime library function. Not called directly. */ @@ -7221,14 +7333,8 @@ start_decl (declarator, declspecs, initialized, attributes, prefix_attributes) switch (TREE_CODE (decl)) { case TYPE_DECL: - /* typedef foo = bar means give foo the same type as bar. - We haven't parsed bar yet, so `cp_finish_decl' will fix that up. - Any other case of an initialization in a TYPE_DECL is an error. */ - if (pedantic || list_length (declspecs) > 1) - { - error ("typedef `%D' is initialized", decl); - initialized = 0; - } + error ("typedef `%D' is initialized (use __typeof__ instead)", decl); + initialized = 0; break; case FUNCTION_DECL: @@ -7259,6 +7365,10 @@ start_decl (declarator, declspecs, initialized, attributes, prefix_attributes) /* Set attributes here so if duplicate decl, will have proper attributes. */ cplus_decl_attributes (&decl, attributes, 0); + /* If #pragma weak was used, mark the decl weak now. */ + if (current_binding_level == global_binding_level) + maybe_apply_pragma_weak (decl); + if (TREE_CODE (decl) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (decl) && DECL_UNINLINABLE (decl) @@ -7391,7 +7501,7 @@ start_decl_1 (decl) if ((! processing_template_decl || ! uses_template_parms (type)) && !COMPLETE_TYPE_P (complete_type (type))) { - error ("aggregate `%#D' has incomplete type and cannot be initialized", + error ("aggregate `%#D' has incomplete type and cannot be defined", decl); /* Change the type so that assemble_variable will give DECL an rtl we can live with: (mem (const_int 0)). */ @@ -7506,7 +7616,13 @@ obscure_complex_init (decl, init) NULL_TREE); else #endif - DECL_INITIAL (decl) = error_mark_node; + { + if (zero_init_p (TREE_TYPE (decl))) + DECL_INITIAL (decl) = error_mark_node; + /* Otherwise, force_store_init_value will have already stored a + zero-init initializer in DECL_INITIAL, that should be + retained. */ + } return init; } @@ -7752,8 +7868,16 @@ check_initializer (decl, init) if (init) init = obscure_complex_init (decl, init); } + else if (!DECL_EXTERNAL (decl) && !zero_init_p (type)) + { + force_store_init_value (decl, build_forced_zero_init (type)); + + if (init) + goto process_init; + } else if (init) { + process_init: if (TYPE_HAS_CONSTRUCTOR (type) || TYPE_NEEDS_CONSTRUCTING (type)) { if (TREE_CODE (type) == ARRAY_TYPE) @@ -7869,8 +7993,9 @@ make_rtl_for_nonlocal_decl (decl, init, asmspec) && toplev && !TREE_PUBLIC (decl)) { - /* Fool with the linkage according to #pragma interface. */ - if (!interface_unknown) + /* Fool with the linkage of static consts according to #pragma + interface. */ + if (!interface_unknown && !TREE_PUBLIC (decl)) { TREE_PUBLIC (decl) = 1; DECL_EXTERNAL (decl) = interface_only; @@ -7878,6 +8003,9 @@ make_rtl_for_nonlocal_decl (decl, init, asmspec) defer_p = 1; } + /* Likewise for template instantiations. */ + else if (DECL_COMDAT (decl)) + defer_p = 1; /* If we're deferring the variable, we only need to make RTL if there's an ASMSPEC. Otherwise, we'll lazily create it later when @@ -7903,6 +8031,12 @@ maybe_inject_for_scope_var (decl) { if (!DECL_NAME (decl)) return; + + /* Declarations of __FUNCTION__ and its ilk appear magically when + the variable is first used. If that happens to be inside a + for-loop, we don't want to do anything special. */ + if (DECL_PRETTY_FUNCTION_P (decl)) + return; if (current_binding_level->is_for_scope) { @@ -8030,8 +8164,7 @@ destroy_local_var (decl) cleanup = maybe_build_cleanup (decl); /* Record the cleanup required for this declaration. */ - if (DECL_SIZE (decl) && TREE_TYPE (decl) != error_mark_node - && cleanup) + if (DECL_SIZE (decl) && cleanup) finish_decl_cleanup (decl, cleanup); } @@ -8065,8 +8198,10 @@ cp_finish_decl (decl, init, asmspec_tree, flags) } /* If a name was specified, get the string. */ + if (current_binding_level == global_binding_level) + asmspec_tree = maybe_apply_renaming_pragma (decl, asmspec_tree); if (asmspec_tree) - asmspec = TREE_STRING_POINTER (asmspec_tree); + asmspec = TREE_STRING_POINTER (asmspec_tree); if (init && TREE_CODE (init) == NAMESPACE_DECL) { @@ -8117,12 +8252,6 @@ cp_finish_decl (decl, init, asmspec_tree, flags) /* Take care of TYPE_DECLs up front. */ if (TREE_CODE (decl) == TYPE_DECL) { - if (init && DECL_INITIAL (decl)) - { - /* typedef foo = bar; store the type of bar as the type of foo. */ - TREE_TYPE (decl) = type = TREE_TYPE (init); - DECL_INITIAL (decl) = init = NULL_TREE; - } if (type != error_mark_node && IS_AGGR_TYPE (type) && DECL_NAME (decl)) { @@ -8391,6 +8520,7 @@ static tree start_cleanup_fn () { static int counter = 0; + int old_interface_only = interface_only; int old_interface_unknown = interface_unknown; char name[32]; tree parmtypes; @@ -8402,6 +8532,7 @@ start_cleanup_fn () /* No need to mangle this. */ push_lang_context (lang_name_c); + interface_only = 0; interface_unknown = 1; /* Build the parameter-types. */ @@ -8443,6 +8574,7 @@ start_cleanup_fn () start_function (/*specs=*/NULL_TREE, fndecl, NULL_TREE, SF_PRE_PARSED); interface_unknown = old_interface_unknown; + interface_only = old_interface_only; pop_lang_context (); @@ -8504,7 +8636,9 @@ register_dtor_fn (decl) cleanup = build_unary_op (ADDR_EXPR, cleanup, 0); if (flag_use_cxa_atexit) { - args = tree_cons (NULL_TREE, get_dso_handle_node (), NULL_TREE); + args = tree_cons (NULL_TREE, + build_unary_op (ADDR_EXPR, get_dso_handle_node (), 0), + NULL_TREE); args = tree_cons (NULL_TREE, null_pointer_node, args); args = tree_cons (NULL_TREE, cleanup, args); } @@ -9937,6 +10071,16 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) next = 0; break; + case TEMPLATE_DECL: + /* Sometimes, we see a template-name used as part of a + decl-specifier like in + std::allocator alloc; + Handle that gracefully. */ + error ("invalid use of template-name '%E' in a declarator", + decl); + return error_mark_node; + break; + default: internal_error ("`%D' as declarator", decl); } @@ -10577,19 +10721,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) type = create_array_type_for_decl (dname, type, size); - /* VLAs never work as fields. */ - if (decl_context == FIELD && !processing_template_decl - && TREE_CODE (type) == ARRAY_TYPE - && TYPE_DOMAIN (type) != NULL_TREE - && !TREE_CONSTANT (TYPE_MAX_VALUE (TYPE_DOMAIN (type)))) - { - error ("size of member `%D' is not constant", dname); - /* Proceed with arbitrary constant size, so that offset - computations don't get confused. */ - type = create_array_type_for_decl (dname, TREE_TYPE (type), - integer_one_node); - } - ctype = NULL_TREE; } break; @@ -10896,8 +11027,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) pop_decl_namespace (); else if (friendp && (TREE_COMPLEXITY (declarator) < 2)) /* Don't fall out into global scope. Hides real bug? --eichin */ ; - else if (! IS_AGGR_TYPE_CODE - (TREE_CODE (TREE_OPERAND (declarator, 0)))) + else if (!TREE_OPERAND (declarator, 0) + || !IS_AGGR_TYPE_CODE + (TREE_CODE (TREE_OPERAND (declarator, 0)))) ; else if (TREE_COMPLEXITY (declarator) == current_class_depth) { @@ -11077,6 +11209,14 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) type = error_mark_node; } + if (decl_context == FIELD + && !processing_template_decl + && variably_modified_type_p (type)) + { + error ("data member may not have variably modified type `%T'", type); + type = error_mark_node; + } + if (explicitp == 1 || (explicitp && friendp)) { /* [dcl.fct.spec] The explicit specifier shall only be used in @@ -11164,6 +11304,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) && TYPE_NAME (type) && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL && TYPE_ANONYMOUS_P (type) + /* Don't do this if there are attributes. */ + && (!attrlist || !*attrlist) && cp_type_quals (type) == TYPE_UNQUALIFIED) { tree oldname = TYPE_NAME (type); @@ -11214,9 +11356,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) bad_specifiers (decl, "type", virtualp, quals != NULL_TREE, inlinep, friendp, raises != NULL_TREE); - if (initialized) - error ("typedef declaration includes an initializer"); - return decl; } @@ -11295,9 +11434,7 @@ friend declaration requires class-key, i.e. `friend %#T'", /* Only try to do this stuff if we didn't already give up. */ if (type != integer_type_node) { - /* DR 209. The friendly class does not need to be accessible - in the scope of the class granting friendship. */ - skip_type_access_control (); + decl_type_access_control (TYPE_NAME (type)); /* A friendly class? */ if (current_class_type) @@ -11559,33 +11696,32 @@ friend declaration requires class-key, i.e. `friend %#T'", if (friendp) { /* Friends are treated specially. */ - tree t = NULL_TREE; - - /* DR 209. The friend does not need to be accessible at this - point. */ - skip_type_access_control (); - if (ctype == current_class_type) warning ("member functions are implicitly friends of their class"); - - if (decl && DECL_NAME (decl)) - { - if (template_class_depth (current_class_type) == 0) - { - decl = check_explicit_specialization - (declarator, decl, - template_count, 2 * (funcdef_flag != 0) + 4); - if (decl == error_mark_node) - return error_mark_node; - } - - t = do_friend (ctype, declarator, decl, - last_function_parms, *attrlist, flags, quals, - funcdef_flag); - } - if (t && funcdef_flag) - return t; - return void_type_node; + else + { + tree t = NULL_TREE; + if (decl && DECL_NAME (decl)) + { + if (template_class_depth (current_class_type) == 0) + { + decl + = check_explicit_specialization + (declarator, decl, + template_count, 2 * (funcdef_flag != 0) + 4); + if (decl == error_mark_node) + return error_mark_node; + } + + t = do_friend (ctype, declarator, decl, + last_function_parms, *attrlist, + flags, quals, funcdef_flag); + } + if (t && funcdef_flag) + return t; + + return void_type_node; + } } /* Structure field. It may not be a function, except for C++ */ @@ -12584,10 +12720,12 @@ grok_op_properties (decl, friendp) /* Effective C++ rule 23. */ if (warn_ecpp && arity == 2 + && !DECL_ASSIGNMENT_OPERATOR_P (decl) && (operator_code == PLUS_EXPR || operator_code == MINUS_EXPR || operator_code == TRUNC_DIV_EXPR - || operator_code == MULT_EXPR) + || operator_code == MULT_EXPR + || operator_code == TRUNC_MOD_EXPR) && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == REFERENCE_TYPE) warning ("`%D' should return by value", decl); @@ -12649,7 +12787,6 @@ xref_tag (code_type_node, name, globalize) enum tree_code code; register tree ref, t; struct binding_level *b = current_binding_level; - int got_type = 0; tree attributes = NULL_TREE; tree context = NULL_TREE; @@ -12686,7 +12823,6 @@ xref_tag (code_type_node, name, globalize) { t = name; name = TYPE_IDENTIFIER (t); - got_type = 1; } else t = IDENTIFIER_TYPE_VALUE (name); @@ -12731,18 +12867,20 @@ xref_tag (code_type_node, name, globalize) { if (t) { + ref = follow_tag_typedef (t); + /* [dcl.type.elab] If the identifier resolves to a typedef-name or a template type-parameter, the elaborated-type-specifier is ill-formed. */ - if (t != TYPE_MAIN_VARIANT (t) - || (CLASS_TYPE_P (t) && TYPE_WAS_ANONYMOUS (t))) - pedwarn ("using typedef-name `%D' after `%s'", - TYPE_NAME (t), tag_name (tag_code)); + if (!ref) + { + pedwarn ("using typedef-name `%D' after `%s'", + TYPE_NAME (t), tag_name (tag_code)); + ref = t; + } else if (TREE_CODE (t) == TEMPLATE_TYPE_PARM) error ("using template type parameter `%T' after `%s'", - t, tag_name (tag_code)); - - ref = t; + t, tag_name (tag_code)); } else ref = lookup_tag (code, name, b, 0); @@ -12863,19 +13001,6 @@ xref_tag (code_type_node, name, globalize) redeclare_class_template (ref, current_template_parms); } - /* Until the type is defined, tentatively accept whatever - structure tag the user hands us. */ - if (!COMPLETE_TYPE_P (ref) - && ref != current_class_type - /* Have to check this, in case we have contradictory tag info. */ - && IS_AGGR_TYPE_CODE (TREE_CODE (ref))) - { - if (tag_code == class_type) - CLASSTYPE_DECLARED_CLASS (ref) = 1; - else if (tag_code == record_type) - CLASSTYPE_DECLARED_CLASS (ref) = 0; - } - TYPE_ATTRIBUTES (ref) = attributes; return ref; @@ -13118,9 +13243,6 @@ start_enum (name) pushtag (name, enumtype, 0); } - if (current_class_type) - TREE_ADDRESSABLE (b->tags) = 1; - return enumtype; } @@ -13495,6 +13617,10 @@ start_function (declspecs, declarator, attrs, flags) cplus_decl_attributes (&decl1, attrs, 0); + /* If #pragma weak was used, mark the decl weak now. */ + if (current_binding_level == global_binding_level) + maybe_apply_pragma_weak (decl1); + fntype = TREE_TYPE (decl1); restype = TREE_TYPE (fntype); @@ -13982,10 +14108,6 @@ begin_destructor_body () finish_compound_stmt (/*has_no_scope=*/0, compound_stmt); finish_then_clause (if_stmt); finish_if_stmt (); - - /* And insert cleanups for our bases and members so that they - will be properly destroyed if we throw. */ - push_base_cleanups (); } /* At the end of every destructor we generate code to delete the object if @@ -13996,6 +14118,13 @@ finish_destructor_body () { tree exprstmt; + /* Any return from a destructor will end up here; that way all base + and member cleanups will be run when the function returns. */ + add_stmt (build_stmt (LABEL_STMT, dtor_label)); + + /* And perform cleanups for our bases and members. */ + perform_base_cleanups (); + /* In a virtual destructor, we must call delete. */ if (DECL_VIRTUAL_P (current_function_decl)) { @@ -14068,14 +14197,7 @@ void finish_function_body (compstmt) tree compstmt; { - if (processing_template_decl) - /* Do nothing now. */; - else if (DECL_DESTRUCTOR_P (current_function_decl)) - /* Any return from a destructor will end up here. Put it before the - cleanups so that an explicit return doesn't duplicate them. */ - add_stmt (build_stmt (LABEL_STMT, dtor_label)); - - /* Close the block; in a destructor, run the member cleanups. */ + /* Close the block. */ finish_compound_stmt (0, compstmt); if (processing_template_decl) @@ -14128,7 +14250,7 @@ finish_function (flags) if (DECL_MAIN_P (current_function_decl)) { /* Make it so that `main' always returns 0 by default. */ -#ifdef VMS_TARGET +#if VMS_TARGET finish_return_stmt (integer_one_node); #else finish_return_stmt (integer_zero_node); @@ -14224,15 +14346,16 @@ finish_function (flags) DECL_UNINLINABLE (fndecl) = 1; /* Complain if there's just no return statement. */ - if (!processing_template_decl + if (warn_return_type + && !processing_template_decl && TREE_CODE (TREE_TYPE (fntype)) != VOID_TYPE && !current_function_returns_value && !current_function_returns_null - && !DECL_NAME (DECL_RESULT (fndecl)) /* Don't complain if we abort or throw. */ && !current_function_returns_abnormally - /* If we have -Wreturn-type, let flow complain. Unless we're an + && !DECL_NAME (DECL_RESULT (fndecl)) + /* Normally, with -Wreturn-type, flow will complain. Unless we're an inline function, as we might never be compiled separately. */ - && (!warn_return_type || DECL_INLINE (fndecl))) + && DECL_INLINE (fndecl)) warning ("no return statement in function returning non-void"); /* Clear out memory we no longer need. */ @@ -14412,72 +14535,58 @@ finish_method (decl) return decl; } -/* Called when a new struct TYPE is defined. - If this structure or union completes the type of any previous - variable declaration, lay it out and output its rtl. */ + +/* VAR is a VAR_DECL. If its type is incomplete, remember VAR so that + we can lay it out later, when and if its type becomes complete. */ void -hack_incomplete_structures (type) - tree type; +maybe_register_incomplete_var (var) + tree var; { - tree *list; - struct binding_level *level; - - if (!type) /* Don't do this for class templates. */ - return; + my_friendly_assert (TREE_CODE (var) == VAR_DECL, 20020406); - if (namespace_bindings_p ()) + /* Keep track of variables with incomplete types. */ + if (!processing_template_decl && TREE_TYPE (var) != error_mark_node + && DECL_EXTERNAL (var)) { - level = 0; - list = &namespace_scope_incomplete; - } - else - { - level = innermost_nonclass_level (); - list = &level->incomplete; + tree inner_type = TREE_TYPE (var); + + while (TREE_CODE (inner_type) == ARRAY_TYPE) + inner_type = TREE_TYPE (inner_type); + inner_type = TYPE_MAIN_VARIANT (inner_type); + + if ((!COMPLETE_TYPE_P (inner_type) && CLASS_TYPE_P (inner_type)) + /* RTTI TD entries are created while defining the type_info. */ + || (TYPE_LANG_SPECIFIC (inner_type) + && TYPE_BEING_DEFINED (inner_type))) + incomplete_vars = tree_cons (inner_type, var, incomplete_vars); } +} - while (1) - { - while (*list) - { - tree decl = TREE_VALUE (*list); - if ((decl && TREE_TYPE (decl) == type) - || (TREE_TYPE (decl) - && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE - && TREE_TYPE (TREE_TYPE (decl)) == type)) - { - int toplevel = toplevel_bindings_p (); - if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE - && TREE_TYPE (TREE_TYPE (decl)) == type) - layout_type (TREE_TYPE (decl)); - layout_decl (decl, 0); - rest_of_decl_compilation (decl, NULL, toplevel, 0); - if (! toplevel) - { - tree cleanup; - expand_decl (decl); - cleanup = maybe_build_cleanup (decl); - expand_decl_init (decl); - if (! expand_decl_cleanup (decl, cleanup)) - error ("parser lost in parsing declaration of `%D'", - decl); - } - *list = TREE_CHAIN (*list); - } - else - list = &TREE_CHAIN (*list); - } +/* Called when a class type (given by TYPE) is defined. If there are + any existing VAR_DECLs whose type hsa been completed by this + declaration, update them now. */ + +void +complete_vars (type) + tree type; +{ + tree *list = &incomplete_vars; - /* Keep looking through artificial binding levels generated - for local variables. */ - if (level && level->keep == 2) + my_friendly_assert (CLASS_TYPE_P (type), 20020406); + while (*list) + { + if (same_type_p (type, TREE_PURPOSE (*list))) { - level = level->level_chain; - list = &level->incomplete; + tree var = TREE_VALUE (*list); + /* Complete the type of the variable. The VAR_DECL itself + will be laid out in expand_expr. */ + complete_type (TREE_TYPE (var)); + /* Remove this entry from the list. */ + *list = TREE_CHAIN (*list); } else - break; + list = &TREE_CHAIN (*list); } } @@ -14518,7 +14627,7 @@ maybe_build_cleanup (decl) return rval; } - return 0; + return NULL_TREE; } /* When a stmt has been parsed, this function is called. */ |