diff options
Diffstat (limited to 'gcc/cp/decl.c')
-rw-r--r-- | gcc/cp/decl.c | 1526 |
1 files changed, 736 insertions, 790 deletions
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 4534a7622b9..892affacc82 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -68,7 +68,7 @@ static cxx_saved_binding *store_bindings (tree, cxx_saved_binding *); static tree lookup_tag_reverse (tree, tree); static void push_local_name (tree); static void warn_extern_redeclared_static (tree, tree); -static tree grok_reference_init (tree, tree, tree); +static tree grok_reference_init (tree, tree, tree, tree *); static tree grokfndecl (tree, tree, tree, tree, int, enum overload_flags, tree, tree, int, int, int, int, int, int, tree); @@ -92,7 +92,6 @@ static void check_for_uninitialized_const_var (tree); static hashval_t typename_hash (const void *); static int typename_compare (const void *, const void *); static void push_binding (tree, tree, struct cp_binding_level*); -static int add_binding (tree, tree); static void pop_binding (tree, tree); static tree local_variable_p_walkfn (tree *, int *, void *); static tree select_decl (cxx_binding *, int); @@ -118,7 +117,7 @@ static void pop_labels (tree); static void maybe_deduce_size_from_array_init (tree, tree); static void layout_var_decl (tree); static void maybe_commonize_var (tree); -static tree check_initializer (tree, tree, int); +static tree check_initializer (tree, tree, int, tree *); static void make_rtl_for_nonlocal_decl (tree, tree, const char *); static void save_function_data (tree); static void check_function_type (tree, tree); @@ -371,51 +370,31 @@ struct cp_binding_level GTY(()) TREE_LIST; the TREE_VALUE is the actual declaration. */ tree dead_vars_from_for; - /* 1 for the level that holds the parameters of a function. - 2 for the level that holds a class declaration. */ - unsigned parm_flag : 2; + /* Binding depth at which this level began. */ + int binding_depth; + + /* The kind of scope that this object represents. However, a + SK_TEMPLATE_SPEC scope is represented with KIND set to + SK_TEMPALTE_PARMS and EXPLICIT_SPEC_P set to true. */ + enum scope_kind kind : 4; + + /* True if this scope is an SK_TEMPLATE_SPEC scope. This field is + only valid if KIND == SK_TEMPLATE_PARMS. */ + bool explicit_spec_p : 1; /* 1 means make a BLOCK for this level regardless of all else. 2 for temporary binding contours created by the compiler. */ unsigned keep : 2; - /* Nonzero if this level "doesn't exist" for tags. */ - unsigned tag_transparent : 1; - /* Nonzero if this level can safely have additional cleanup-needing variables added to it. */ unsigned more_cleanups_ok : 1; unsigned have_cleanups : 1; - /* Nonzero if this scope is for storing the decls for template - parameters and generic decls; these decls will be discarded and - replaced with a TEMPLATE_DECL. */ - unsigned template_parms_p : 1; - - /* Nonzero if this scope corresponds to the `<>' in a - `template <>' clause. Whenever this flag is set, - TEMPLATE_PARMS_P will be set as well. */ - unsigned template_spec_p : 1; - - /* This is set for a namespace binding level. */ - unsigned namespace_p : 1; - - /* True if this level is that of a for-statement where we need to - worry about ambiguous (ARM or ISO) scope rules. */ - unsigned is_for_scope : 1; - - /* True if this level corresponds to a TRY block. Currently this - information is only available while building the tree structure. */ - unsigned is_try_scope : 1; - - /* True if this level corresponds to a CATCH block. Currently this - information is only available while building the tree structure. */ - unsigned is_catch_scope : 1; - - /* Three bits left for this word. */ + /* Nonzero if this level "doesn't exist" for tags. */ + unsigned tag_transparent : 1; - /* Binding depth at which this level began. */ - unsigned binding_depth; + /* 20 bits left to fill a 32-bit word. */ }; #define NULL_BINDING_LEVEL ((struct cp_binding_level *) NULL) @@ -469,28 +448,21 @@ static tree pushdecl_with_scope (tree, struct cp_binding_level *); static const char * cxx_scope_descriptor (cxx_scope *scope) { - const char *desc; - - if (scope->namespace_p) - desc = "namespace-scope"; - else if (scope->parm_flag == 1) - desc = "function-prototype-scope"; - else if (scope->parm_flag == 2) - desc = "class-scope"; - else if (scope->is_for_scope) - desc = "for-scope"; - else if (scope->is_try_scope) - desc = "try-scope"; - else if (scope->is_catch_scope) - desc = "catch-scope"; - else if (scope->template_spec_p) - desc = "template-explicit-spec-scope"; - else if (scope->template_parms_p) - desc = "template-prototype-scope"; - else - desc = "block-scope"; + /* The order of this table must match the "scope_kind" + enumerators. */ + static const char* scope_kind_names[] = { + "block-scope", + "try-scope", + "catch-scope", + "for-scope", + "function-parameter-scope", + "class-scope", + "namespace-scope", + "template-parameter-scope", + "template-explicit-spec-scope" + }; - return desc; + return scope_kind_names[scope->kind]; } /* Output a debugging information about SCOPE when performning @@ -556,9 +528,9 @@ find_class_binding_level (void) { struct cp_binding_level *level = current_binding_level; - while (level && level->parm_flag != 2) + while (level && level->kind != sk_class) level = level->level_chain; - if (level && level->parm_flag == 2) + if (level && level->kind == sk_class) class_binding_level = level; else class_binding_level = 0; @@ -587,7 +559,7 @@ pop_binding_level (void) register struct cp_binding_level *level = current_binding_level; current_binding_level = current_binding_level->level_chain; level->level_chain = free_binding_level; - if (level->parm_flag == 2) + if (level->kind == sk_class) level->type_decls = NULL; else binding_table_free (level->type_decls); @@ -660,7 +632,7 @@ innermost_nonclass_level (void) struct cp_binding_level *b; b = current_binding_level; - while (b->parm_flag == 2) + while (b->kind == sk_class) b = b->level_chain; return b; @@ -677,7 +649,7 @@ toplevel_bindings_p (void) { struct cp_binding_level *b = innermost_nonclass_level (); - return b->namespace_p || b->template_parms_p; + return b->kind == sk_namespace || b->kind == sk_template_parms; } /* Nonzero if this is a namespace scope, or if we are defining a class @@ -689,7 +661,7 @@ namespace_bindings_p (void) { struct cp_binding_level *b = innermost_nonclass_level (); - return b->namespace_p; + return b->kind == sk_namespace; } /* If KEEP is nonzero, make a BLOCK node for the next binding level, @@ -714,13 +686,21 @@ kept_level_p (void) && !current_binding_level->tag_transparent)); } +/* Returns the kind of the innermost scope. */ + +scope_kind +innermost_scope_kind (void) +{ + return current_binding_level->kind; +} + /* Returns nonzero if this scope was created to store template parameters. */ int template_parm_scope_p (void) { - return current_binding_level->template_parms_p; + return innermost_scope_kind () == sk_template_parms; } /* Returns the kind of template specialization we are currently @@ -736,7 +716,9 @@ current_tmpl_spec_kind (int n_class_scopes) struct cp_binding_level *b; /* Scan through the template parameter scopes. */ - for (b = current_binding_level; b->template_parms_p; b = b->level_chain) + for (b = current_binding_level; + b->kind == sk_template_parms; + b = b->level_chain) { /* If we see a specialization scope inside a parameter scope, then something is wrong. That corresponds to a declaration @@ -747,7 +729,7 @@ current_tmpl_spec_kind (int n_class_scopes) which is always invalid since [temp.expl.spec] forbids the specialization of a class member template if the enclosing class templates are not explicitly specialized as well. */ - if (b->template_spec_p) + if (b->explicit_spec_p) { if (n_template_parm_scopes == 0) innermost_specialization_p = 1; @@ -824,9 +806,6 @@ set_class_shadows (tree shadows) void pushlevel (int tag_transparent) { - if (cfun && !doing_semantic_analysis_p ()) - return; - push_binding_level (make_cxx_scope (tag_transparent, keep_next_level_flag)); keep_next_level_flag = 0; } @@ -855,35 +834,12 @@ void begin_scope (scope_kind sk) { pushlevel (0); - - switch (sk) + if (sk == sk_template_spec) { - case sk_block: - break; - - case sk_try: - current_binding_level->is_try_scope = 1; - break; - - case sk_catch: - current_binding_level->is_catch_scope = 1; - break; - - case sk_for: - current_binding_level->is_for_scope = 1; - break; - - case sk_template_spec: - current_binding_level->template_spec_p = 1; - /* Fall through. */ - - case sk_template_parms: - current_binding_level->template_parms_p = 1; - break; - - default: - abort (); + current_binding_level->explicit_spec_p = true; + sk = sk_template_parms; } + current_binding_level->kind = sk; } /* Exit the current scope. */ @@ -912,85 +868,6 @@ push_binding (tree id, tree decl, cxx_scope* level) IDENTIFIER_BINDING (id) = binding; } -/* ID is already bound in the current scope. But, DECL is an - additional binding for ID in the same scope. This is the `struct - stat' hack whereby a non-typedef class-name or enum-name can be - bound at the same level as some other kind of entity. It's the - responsibility of the caller to check that inserting this name is - valid here. Returns nonzero if the new binding was successful. */ -static int -add_binding (tree id, tree decl) -{ - cxx_binding *binding = IDENTIFIER_BINDING (id); - int ok = 1; - - timevar_push (TV_NAME_LOOKUP); - if (TREE_CODE (decl) == TYPE_DECL && DECL_ARTIFICIAL (decl)) - /* The new name is the type name. */ - BINDING_TYPE (binding) = decl; - else if (!BINDING_VALUE (binding)) - /* This situation arises when push_class_level_binding moves an - inherited type-binding out of the way to make room for a new - value binding. */ - BINDING_VALUE (binding) = decl; - else if (TREE_CODE (BINDING_VALUE (binding)) == TYPE_DECL - && DECL_ARTIFICIAL (BINDING_VALUE (binding))) - { - /* The old binding was a type name. It was placed in - BINDING_VALUE because it was thought, at the point it was - declared, to be the only entity with such a name. Move the - type name into the type slot; it is now hidden by the new - binding. */ - BINDING_TYPE (binding) = BINDING_VALUE (binding); - BINDING_VALUE (binding) = decl; - INHERITED_VALUE_BINDING_P (binding) = 0; - } - else if (TREE_CODE (BINDING_VALUE (binding)) == TYPE_DECL - && TREE_CODE (decl) == TYPE_DECL - && DECL_NAME (decl) == DECL_NAME (BINDING_VALUE (binding)) - && (same_type_p (TREE_TYPE (decl), - TREE_TYPE (BINDING_VALUE (binding))) - /* If either type involves template parameters, we must - wait until instantiation. */ - || uses_template_parms (TREE_TYPE (decl)) - || uses_template_parms (TREE_TYPE (BINDING_VALUE (binding))))) - /* We have two typedef-names, both naming the same type to have - the same name. This is OK because of: - - [dcl.typedef] - - In a given scope, a typedef specifier can be used to redefine - the name of any type declared in that scope to refer to the - type to which it already refers. */ - ok = 0; - /* There can be two block-scope declarations of the same variable, - so long as they are `extern' declarations. However, there cannot - be two declarations of the same static data member: - - [class.mem] - - A member shall not be declared twice in the - member-specification. */ - else if (TREE_CODE (decl) == VAR_DECL - && TREE_CODE (BINDING_VALUE (binding)) == VAR_DECL - && DECL_EXTERNAL (decl) - && DECL_EXTERNAL (BINDING_VALUE (binding)) - && !DECL_CLASS_SCOPE_P (decl)) - { - duplicate_decls (decl, BINDING_VALUE (binding)); - ok = 0; - } - else - { - error ("declaration of `%#D'", decl); - cp_error_at ("conflicts with previous declaration `%#D'", - BINDING_VALUE (binding)); - ok = 0; - } - - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, ok); -} - /* Add DECL to the list of things declared in B. */ static void @@ -1017,7 +894,7 @@ add_decl_to_level (tree decl, b->names_size++; /* If appropriate, add decl to separate list of statics */ - if (b->namespace_p) + if (b->kind == sk_namespace) if ((TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl)) || (TREE_CODE (decl) == FUNCTION_DECL && (!TREE_PUBLIC (decl) || DECL_DECLARED_INLINE_P (decl)))) @@ -1037,14 +914,12 @@ push_local_binding (tree id, tree decl, int flags) /* Skip over any local classes. This makes sense if we call push_local_binding with a friend decl of a local class. */ - b = current_binding_level; - while (b->parm_flag == 2) - b = b->level_chain; + b = innermost_nonclass_level (); if (lookup_name_current_level (id)) { /* Supplement the existing binding. */ - if (!add_binding (id, decl)) + if (!supplement_binding (IDENTIFIER_BINDING (id), decl)) /* It didn't work. Something else must be bound at this level. Do not add DECL to the list of things to pop later. */ @@ -1083,7 +958,7 @@ push_class_binding (tree id, tree decl) if (binding && BINDING_SCOPE (binding) == class_binding_level) /* Supplement the existing binding. */ - result = add_binding (id, decl); + result = supplement_binding (IDENTIFIER_BINDING (id), decl); else /* Create a new binding. */ push_binding (id, decl, class_binding_level); @@ -1171,7 +1046,7 @@ pop_binding (tree id, tree decl) static void pop_label (tree label, tree old_value) { - if (!processing_template_decl && doing_semantic_analysis_p ()) + if (!processing_template_decl) { if (DECL_INITIAL (label) == NULL_TREE) { @@ -1243,11 +1118,8 @@ poplevel (int keep, int reverse, int functionbody) int leaving_for_scope; timevar_push (TV_NAME_LOOKUP); - if (cfun && !doing_semantic_analysis_p ()) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE); - my_friendly_assert (current_binding_level->parm_flag != 2, - 19990916); + my_friendly_assert (current_binding_level->kind != sk_class, 19990916); real_functionbody = (current_binding_level->keep == 2 ? ((functionbody = 0), tmp) : functionbody); @@ -1278,9 +1150,9 @@ poplevel (int keep, int reverse, int functionbody) if (labels->binding_level == current_binding_level) { tree decl; - if (current_binding_level->is_try_scope) + if (current_binding_level->kind == sk_try) labels->in_try_scope = 1; - if (current_binding_level->is_catch_scope) + if (current_binding_level->kind == sk_catch) labels->in_catch_scope = 1; for (decl = labels->names_in_scope; decl; decl = TREE_CHAIN (decl)) @@ -1362,7 +1234,7 @@ poplevel (int keep, int reverse, int functionbody) ended. We only use the new rules if flag_new_for_scope is nonzero. */ leaving_for_scope - = current_binding_level->is_for_scope && flag_new_for_scope == 1; + = current_binding_level->kind == sk_for && flag_new_for_scope == 1; /* Remove declarations for all the DECLs in this level. */ for (link = decls; link; link = TREE_CHAIN (link)) @@ -1579,7 +1451,6 @@ set_block (tree block ATTRIBUTE_UNUSED ) { /* The RTL expansion machinery requires us to provide this callback, but it is not applicable in function-at-a-time mode. */ - my_friendly_assert (cfun && !doing_semantic_analysis_p (), 20000911); } /* Do a pushlevel for class declarations. */ @@ -1590,10 +1461,8 @@ pushlevel_class (void) if (ENABLE_SCOPE_CHECKING) is_class_level = 1; - push_binding_level (make_cxx_scope (false, 0)); - + begin_scope (sk_class); class_binding_level = current_binding_level; - class_binding_level->parm_flag = 2; class_binding_level->this_entity = current_class_type; } @@ -1626,7 +1495,7 @@ poplevel_class (void) /* Find the next enclosing class, and recreate IDENTIFIER_CLASS_VALUEs appropriate for that class. */ b = level->level_chain; - while (b && b->parm_flag != 2) + while (b && b->kind != sk_class) b = b->level_chain; if (b) @@ -2017,9 +1886,8 @@ initial_push_namespace_scope (tree ns) tree name = DECL_NAME (ns); cxx_scope *scope; - pushlevel (0); + begin_scope (sk_namespace); scope = current_binding_level; - scope->namespace_p = true; scope->type_decls = binding_table_new (name == std_identifier ? NAMESPACE_STD_HT_SIZE : (name == global_scope_name @@ -2220,7 +2088,7 @@ maybe_push_to_top_level (int pseudo) int need_pop; timevar_push (TV_NAME_LOOKUP); - s = (struct saved_scope *) ggc_alloc_cleared (sizeof (struct saved_scope)); + s = ggc_alloc_cleared (sizeof (struct saved_scope)); b = scope_chain ? current_binding_level : 0; @@ -2247,13 +2115,13 @@ maybe_push_to_top_level (int pseudo) inserted into namespace level, finish_file wouldn't find them when doing pending instantiations. Therefore, don't stop at namespace level, but continue until :: . */ - if (global_scope_p (b) || (pseudo && b->template_parms_p)) + if (global_scope_p (b) || (pseudo && b->kind == sk_template_parms)) break; old_bindings = store_bindings (b->names, old_bindings); /* We also need to check class_shadowed to save class-level type bindings, since pushclass doesn't fill in b->names. */ - if (b->parm_flag == 2) + if (b->kind == sk_class) old_bindings = store_bindings (b->class_shadowed, old_bindings); /* Unwind type-value slots back to top level. */ @@ -2313,37 +2181,39 @@ pop_from_top_level (void) timevar_pop (TV_NAME_LOOKUP); } -/* Push a definition of struct, union or enum tag "name". - into binding_level "b". "type" should be the type node, - We assume that the tag "name" is not already defined. - - Note that the definition may really be just a forward reference. - In that case, the TYPE_SIZE will be a NULL_TREE. - - C++ gratuitously puts all these tags in the name space. */ - -/* When setting the IDENTIFIER_TYPE_VALUE field of an identifier ID, - record the shadowed value for this binding contour. TYPE is - the type that ID maps to. */ +/* Push a definition of struct, union or enum tag named ID. into + binding_level B. DECL is a TYPE_DECL for the type. We assume that + the tag ID is not already defined. */ static void set_identifier_type_value_with_scope (tree id, - tree type, + tree decl, struct cp_binding_level* b) { - if (!b->namespace_p) + tree type; + + if (b->kind != sk_namespace) { /* Shadow the marker, not the real thing, so that the marker gets restored later. */ tree old_type_value = REAL_IDENTIFIER_TYPE_VALUE (id); b->type_shadowed = tree_cons (id, old_type_value, b->type_shadowed); + type = decl ? TREE_TYPE (decl) : NULL_TREE; } else { cxx_binding *binding = - binding_for_name (NAMESPACE_LEVEL (current_namespace), id); - BINDING_TYPE (binding) = type; + binding_for_name (NAMESPACE_LEVEL (current_namespace), id); + if (decl) + { + if (BINDING_VALUE (binding)) + supplement_binding (binding, decl); + else + BINDING_VALUE (binding) = decl; + } + else + abort (); /* Store marker instead of real type. */ type = global_type_node; } @@ -2353,9 +2223,9 @@ set_identifier_type_value_with_scope (tree id, /* As set_identifier_type_value_with_scope, but using current_binding_level. */ void -set_identifier_type_value (tree id, tree type) +set_identifier_type_value (tree id, tree decl) { - set_identifier_type_value_with_scope (id, type, current_binding_level); + set_identifier_type_value_with_scope (id, decl, current_binding_level); } /* Return the type associated with id. */ @@ -2389,7 +2259,7 @@ pop_everything (void) verbatim ("XXX entering pop_everything ()\n"); while (!toplevel_bindings_p ()) { - if (current_binding_level->parm_flag == 2) + if (current_binding_level->kind == sk_class) pop_nested_class (); else poplevel (0, 0, 0); @@ -2445,8 +2315,8 @@ maybe_process_template_type_declaration (tree type, friend case, push_template_decl will already have put the friend into global scope, if appropriate. */ if (TREE_CODE (type) != ENUMERAL_TYPE - && !globalize && b->template_parms_p - && b->level_chain->parm_flag == 2) + && !globalize && b->kind == sk_template_parms + && b->level_chain->kind == sk_class) { finish_member_declaration (CLASSTYPE_TI_TEMPLATE (type)); /* Put this UDT in the table of UDTs for the class, since @@ -2542,7 +2412,7 @@ pushtag (tree name, tree type, int globalize) timevar_push (TV_NAME_LOOKUP); b = current_binding_level; while (b->tag_transparent - || (b->parm_flag == 2 + || (b->kind == sk_class && (globalize /* We may be defining a new type in the initializer of a static member variable. We allow this when @@ -2579,8 +2449,9 @@ pushtag (tree name, tree type, int globalize) if (!context) context = current_namespace; - if ((b->template_parms_p && b->level_chain->parm_flag == 2) - || b->parm_flag == 2) + if (b->kind == sk_class + || (b->kind == sk_template_parms + && b->level_chain->kind == sk_class)) in_class = 1; if (current_lang_name == lang_name_java) @@ -2589,12 +2460,12 @@ pushtag (tree name, tree type, int globalize) d = create_implicit_typedef (name, type); DECL_CONTEXT (d) = FROB_CONTEXT (context); if (! in_class) - set_identifier_type_value_with_scope (name, type, b); + set_identifier_type_value_with_scope (name, d, b); d = maybe_process_template_type_declaration (type, globalize, b); - if (b->parm_flag == 2) + if (b->kind == sk_class) { if (!PROCESSING_REAL_TEMPLATE_DECL_P ()) /* Put this TYPE_DECL on the TYPE_FIELDS list for the @@ -2624,14 +2495,12 @@ pushtag (tree name, tree type, int globalize) && !processing_template_decl) VARRAY_PUSH_TREE (local_classes, type); } - if (b->parm_flag == 2) + if (b->kind == sk_class + && !COMPLETE_TYPE_P (current_class_type)) { - if (!COMPLETE_TYPE_P (current_class_type)) - { - maybe_add_class_template_decl_list (current_class_type, - type, /*friend_p=*/0); - CLASSTYPE_NESTED_UTDS (current_class_type) = b->type_decls; - } + maybe_add_class_template_decl_list (current_class_type, + type, /*friend_p=*/0); + CLASSTYPE_NESTED_UTDS (current_class_type) = b->type_decls; } } @@ -2761,16 +2630,17 @@ decls_match (tree newdecl, tree olddecl) } else if (TREE_CODE (newdecl) == TEMPLATE_DECL) { - if (!comp_template_parms (DECL_TEMPLATE_PARMS (newdecl), - DECL_TEMPLATE_PARMS (olddecl))) - return 0; - if (TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) != TREE_CODE (DECL_TEMPLATE_RESULT (olddecl))) return 0; + if (!comp_template_parms (DECL_TEMPLATE_PARMS (newdecl), + DECL_TEMPLATE_PARMS (olddecl))) + return 0; + if (TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) == TYPE_DECL) - types_match = 1; + types_match = same_type_p (TREE_TYPE (DECL_TEMPLATE_RESULT (olddecl)), + TREE_TYPE (DECL_TEMPLATE_RESULT (newdecl))); else types_match = decls_match (DECL_TEMPLATE_RESULT (olddecl), DECL_TEMPLATE_RESULT (newdecl)); @@ -2813,7 +2683,8 @@ warn_extern_redeclared_static (tree newdecl, tree olddecl) if (TREE_CODE (newdecl) == TYPE_DECL || TREE_CODE (newdecl) == TEMPLATE_DECL - || TREE_CODE (newdecl) == CONST_DECL) + || TREE_CODE (newdecl) == CONST_DECL + || TREE_CODE (newdecl) == NAMESPACE_DECL) return; /* Don't get confused by static member functions; that's a different @@ -2884,19 +2755,18 @@ duplicate_decls (tree newdecl, tree olddecl) && DECL_UNINLINABLE (olddecl) && lookup_attribute ("noinline", DECL_ATTRIBUTES (olddecl))) { - warning ("%Hfunction '%D' redeclared as inline", - &DECL_SOURCE_LOCATION (newdecl), newdecl); - warning ("%Hprevious declaration of '%D' with attribute noinline", - &DECL_SOURCE_LOCATION (olddecl), olddecl); + warning ("%Jfunction '%D' redeclared as inline", newdecl, newdecl); + warning ("%Jprevious declaration of '%D' with attribute noinline", + olddecl, olddecl); } else if (DECL_DECLARED_INLINE_P (olddecl) && DECL_UNINLINABLE (newdecl) && lookup_attribute ("noinline", DECL_ATTRIBUTES (newdecl))) { - warning ("%Hfunction '%D' redeclared with attribute noinline", - &DECL_SOURCE_LOCATION (newdecl), newdecl); - warning ("%Hprevious declaration of '%D' was inline", - &DECL_SOURCE_LOCATION (olddecl), olddecl); + warning ("%Jfunction '%D' redeclared with attribute noinline", + newdecl, newdecl); + warning ("%Jprevious declaration of '%D' was inline", + olddecl, olddecl); } } @@ -2941,9 +2811,9 @@ duplicate_decls (tree newdecl, tree olddecl) 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)))) + && DECL_EXTERN_C_P (olddecl)) + || compparms (TYPE_ARG_TYPES (TREE_TYPE (newdecl)), + TYPE_ARG_TYPES (TREE_TYPE (olddecl)))) { /* A near match; override the builtin. */ @@ -2970,6 +2840,10 @@ duplicate_decls (tree newdecl, tree olddecl) else if (DECL_ANTICIPATED (olddecl)) TREE_TYPE (olddecl) = TREE_TYPE (newdecl); + /* Whether or not the builtin can throw exceptions has no + bearing on this declarator. */ + TREE_NOTHROW (olddecl) = 0; + if (DECL_THIS_STATIC (newdecl) && !DECL_THIS_STATIC (olddecl)) { /* If a builtin function is redeclared as `static', merge @@ -3077,8 +2951,10 @@ duplicate_decls (tree newdecl, tree olddecl) else if (current_class_type == NULL_TREE || IDENTIFIER_ERROR_LOCUS (DECL_ASSEMBLER_NAME (newdecl)) != current_class_type) { - error ("conflicting types for `%#D'", newdecl); - cp_error_at ("previous declaration as `%#D'", olddecl); + error ("conflicting declaration '%#D'", newdecl); + cp_error_at ("'%D' has a previous declaration as `%#D'", + olddecl, olddecl); + return false; } } else if (TREE_CODE (newdecl) == FUNCTION_DECL @@ -3132,8 +3008,7 @@ duplicate_decls (tree newdecl, tree olddecl) { /* Prototype decl follows defn w/o prototype. */ cp_warning_at ("prototype for `%#D'", newdecl); - warning ("%Hfollows non-prototype definition here", - &DECL_SOURCE_LOCATION (olddecl)); + warning ("%Jfollows non-prototype definition here", olddecl); } else if (TREE_CODE (olddecl) == FUNCTION_DECL && DECL_LANGUAGE (newdecl) != DECL_LANGUAGE (olddecl)) @@ -3188,10 +3063,8 @@ duplicate_decls (tree newdecl, tree olddecl) && ! DECL_DECLARED_INLINE_P (olddecl) && TREE_ADDRESSABLE (olddecl) && warn_inline) { - warning ("`%#D' was used before it was declared inline", - newdecl); - warning ("%Hprevious non-inline declaration here", - &DECL_SOURCE_LOCATION (olddecl)); + warning ("`%#D' was used before it was declared inline", newdecl); + warning ("%Jprevious non-inline declaration here", olddecl); } } } @@ -3306,6 +3179,8 @@ duplicate_decls (tree newdecl, tree olddecl) { DECL_THIS_EXTERN (newdecl) |= DECL_THIS_EXTERN (olddecl); DECL_INITIALIZED_P (newdecl) |= DECL_INITIALIZED_P (olddecl); + DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (newdecl) + |= DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (olddecl); } /* Do this after calling `merge_types' so that default @@ -3558,36 +3433,30 @@ duplicate_decls (tree newdecl, tree olddecl) function_size - sizeof (struct tree_common)); if (DECL_TEMPLATE_INSTANTIATION (newdecl)) - { - /* If newdecl is a template instantiation, it is possible that - the following sequence of events has occurred: + /* If newdecl is a template instantiation, it is possible that + the following sequence of events has occurred: - o A friend function was declared in a class template. The - class template was instantiated. + o A friend function was declared in a class template. The + class template was instantiated. - o The instantiation of the friend declaration was - recorded on the instantiation list, and is newdecl. + o The instantiation of the friend declaration was + recorded on the instantiation list, and is newdecl. - o Later, however, instantiate_class_template called pushdecl - on the newdecl to perform name injection. But, pushdecl in - turn called duplicate_decls when it discovered that another - declaration of a global function with the same name already - existed. + o Later, however, instantiate_class_template called pushdecl + on the newdecl to perform name injection. But, pushdecl in + turn called duplicate_decls when it discovered that another + declaration of a global function with the same name already + existed. - o Here, in duplicate_decls, we decided to clobber newdecl. + o Here, in duplicate_decls, we decided to clobber newdecl. - If we're going to do that, we'd better make sure that - olddecl, and not newdecl, is on the list of - instantiations so that if we try to do the instantiation - again we won't get the clobbered declaration. */ - - tree tmpl = DECL_TI_TEMPLATE (newdecl); - tree decls = DECL_TEMPLATE_SPECIALIZATIONS (tmpl); - - for (; decls; decls = TREE_CHAIN (decls)) - if (TREE_VALUE (decls) == newdecl) - TREE_VALUE (decls) = olddecl; - } + If we're going to do that, we'd better make sure that + olddecl, and not newdecl, is on the list of + instantiations so that if we try to do the instantiation + again we won't get the clobbered declaration. */ + reregister_specialization (newdecl, + DECL_TI_TEMPLATE (newdecl), + olddecl); } else { @@ -3633,10 +3502,6 @@ pushdecl (tree x) int need_new_binding; timevar_push (TV_NAME_LOOKUP); - /* We shouldn't be calling pushdecl when we're generating RTL for a - function that we already did semantic analysis on previously. */ - my_friendly_assert (!cfun || doing_semantic_analysis_p (), - 19990913); need_new_binding = 1; @@ -3858,9 +3723,7 @@ pushdecl (tree x) if (type != error_mark_node && TYPE_NAME (type) && TYPE_IDENTIFIER (type)) - set_identifier_type_value_with_scope (DECL_NAME (x), type, - current_binding_level); - + set_identifier_type_value (DECL_NAME (x), x); } /* Multiple external decls of the same identifier ought to match. @@ -3950,15 +3813,13 @@ pushdecl (tree x) /* If this is a TYPE_DECL, push it into the type value slot. */ if (TREE_CODE (x) == TYPE_DECL) - set_identifier_type_value_with_scope (name, TREE_TYPE (x), - current_binding_level); + set_identifier_type_value (name, x); /* Clear out any TYPE_DECL shadowed by a namespace so that we won't think this is a type. The C struct hack doesn't go through namespaces. */ if (TREE_CODE (x) == NAMESPACE_DECL) - set_identifier_type_value_with_scope (name, NULL_TREE, - current_binding_level); + set_identifier_type_value (name, NULL_TREE); if (oldlocal) { @@ -4021,10 +3882,10 @@ pushdecl (tree x) b = b->level_chain; /* ARM $8.3 */ - if (b->parm_flag == 1) + if (b->kind == sk_function_parms) { error ("declaration of `%#D' shadows a parameter", - name); + name); err = true; } } @@ -4085,7 +3946,7 @@ pushdecl_with_scope (tree x, struct cp_binding_level* level) timevar_push (TV_NAME_LOOKUP); current_function_decl = NULL_TREE; - if (level->parm_flag == 2) + if (level->kind == sk_class) { b = class_binding_level; class_binding_level = level; @@ -4139,7 +4000,7 @@ pushdecl_namespace_level (tree x) { /* @@ This shouldn't be needed. My test case "zstring.cc" trips up here if this is changed to an assertion. --KR */ - SET_IDENTIFIER_TYPE_VALUE (name, newval); + SET_IDENTIFIER_TYPE_VALUE (name, x); } else { @@ -4202,7 +4063,7 @@ pushdecl_class_level (tree x) { is_valid = push_class_level_binding (name, x); if (TREE_CODE (x) == TYPE_DECL) - set_identifier_type_value (name, TREE_TYPE (x)); + set_identifier_type_value (name, x); } else if (ANON_AGGR_TYPE_P (TREE_TYPE (x))) { @@ -4213,10 +4074,11 @@ pushdecl_class_level (tree x) for (f = TYPE_FIELDS (TREE_TYPE (x)); f; f = TREE_CHAIN (f)) { - push_srcloc (DECL_SOURCE_FILE (f), DECL_SOURCE_LINE (f)); + location_t save_location = input_location; + input_location = DECL_SOURCE_LOCATION (f); if (!pushdecl_class_level (f)) is_valid = false; - pop_srcloc (); + input_location = save_location; } } timevar_pop (TV_NAME_LOOKUP); @@ -4276,47 +4138,56 @@ push_class_level_binding (tree name, tree x) class, then we will need to restore IDENTIFIER_CLASS_VALUE when we leave this class. Record the shadowed declaration here. */ binding = IDENTIFIER_BINDING (name); - if (binding - && ((TREE_CODE (x) == OVERLOAD - && BINDING_VALUE (binding) - && is_overloaded_fn (BINDING_VALUE (binding))) - || INHERITED_VALUE_BINDING_P (binding))) + if (binding && BINDING_VALUE (binding)) { - tree shadow; - tree old_decl; + tree bval = BINDING_VALUE (binding); + tree old_decl = NULL_TREE; - /* If the old binding was from a base class, and was for a tag - name, slide it over to make room for the new binding. The - old binding is still visible if explicitly qualified with a - class-key. */ - if (INHERITED_VALUE_BINDING_P (binding) - && BINDING_VALUE (binding) - && TREE_CODE (BINDING_VALUE (binding)) == TYPE_DECL - && DECL_ARTIFICIAL (BINDING_VALUE (binding)) - && !(TREE_CODE (x) == TYPE_DECL && DECL_ARTIFICIAL (x))) - { - old_decl = BINDING_TYPE (binding); - BINDING_TYPE (binding) = BINDING_VALUE (binding); - BINDING_VALUE (binding) = NULL_TREE; - INHERITED_VALUE_BINDING_P (binding) = 0; + if (INHERITED_VALUE_BINDING_P (binding)) + { + /* If the old binding was from a base class, and was for a + tag name, slide it over to make room for the new binding. + The old binding is still visible if explicitly qualified + with a class-key. */ + if (TREE_CODE (bval) == TYPE_DECL && DECL_ARTIFICIAL (bval) + && !(TREE_CODE (x) == TYPE_DECL && DECL_ARTIFICIAL (x))) + { + old_decl = BINDING_TYPE (binding); + BINDING_TYPE (binding) = bval; + BINDING_VALUE (binding) = NULL_TREE; + INHERITED_VALUE_BINDING_P (binding) = 0; + } + else + old_decl = bval; + } + else if (TREE_CODE (x) == OVERLOAD && is_overloaded_fn (bval)) + old_decl = bval; + else if (TREE_CODE (x) == USING_DECL && TREE_CODE (bval) == USING_DECL) + POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true); + else if (TREE_CODE (x) == USING_DECL && is_overloaded_fn (bval)) + old_decl = bval; + else if (TREE_CODE (bval) == USING_DECL && is_overloaded_fn (x)) + POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true); + + if (old_decl) + { + tree shadow; + + /* Find the previous binding of name on the class-shadowed + list, and update it. */ + for (shadow = class_binding_level->class_shadowed; + shadow; + shadow = TREE_CHAIN (shadow)) + if (TREE_PURPOSE (shadow) == name + && TREE_TYPE (shadow) == old_decl) + { + BINDING_VALUE (binding) = x; + INHERITED_VALUE_BINDING_P (binding) = 0; + TREE_TYPE (shadow) = x; + IDENTIFIER_CLASS_VALUE (name) = x; + POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true); + } } - else - old_decl = BINDING_VALUE (binding); - - /* Find the previous binding of name on the class-shadowed - list, and update it. */ - for (shadow = class_binding_level->class_shadowed; - shadow; - shadow = TREE_CHAIN (shadow)) - if (TREE_PURPOSE (shadow) == name - && TREE_TYPE (shadow) == old_decl) - { - BINDING_VALUE (binding) = x; - INHERITED_VALUE_BINDING_P (binding) = 0; - TREE_TYPE (shadow) = x; - IDENTIFIER_CLASS_VALUE (name) = x; - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true); - } } /* If we didn't replace an existing binding, put the binding on the @@ -4642,9 +4513,6 @@ make_label_decl (tree id, int local_p) tree decl; decl = build_decl (LABEL_DECL, id, void_type_node); - if (expanding_p) - /* Make sure every label has an rtx. */ - label_rtx (decl); DECL_CONTEXT (decl) = current_function_decl; DECL_MODE (decl) = VOIDmode; @@ -4673,8 +4541,7 @@ use_label (tree decl) || named_label_uses->label_decl != decl) { struct named_label_use_list *new_ent; - new_ent = ((struct named_label_use_list *) - ggc_alloc (sizeof (struct named_label_use_list))); + new_ent = ggc_alloc (sizeof (struct named_label_use_list)); new_ent->label_decl = decl; new_ent->names_in_scope = current_binding_level->names; new_ent->binding_level = current_binding_level; @@ -4711,8 +4578,7 @@ lookup_label (tree id) /* Record this label on the list of labels used in this function. We do this before calling make_label_decl so that we get the IDENTIFIER_LABEL_VALUE before the new label is declared. */ - ent = ((struct named_label_list *) - ggc_alloc_cleared (sizeof (struct named_label_list))); + ent = ggc_alloc_cleared (sizeof (struct named_label_list)); ent->old_value = IDENTIFIER_LABEL_VALUE (id); ent->next = named_labels; named_labels = ent; @@ -4815,7 +4681,7 @@ check_previous_goto_1 (tree decl, if (b == level) break; - if ((b->is_try_scope || b->is_catch_scope) && ! saw_eh) + if ((b->kind == sk_try || b->kind == sk_catch) && ! saw_eh) { if (! identified) { @@ -4828,7 +4694,7 @@ check_previous_goto_1 (tree decl, pedwarn ("%H from here", locus); identified = 1; } - if (b->is_try_scope) + if (b->kind == sk_try) error (" enters try block"); else error (" enters catch block"); @@ -4920,7 +4786,7 @@ check_goto (tree decl) if (u > 1 && DECL_ARTIFICIAL (b)) /* Can't skip init of __exception_info. */ - error ("%H enters catch block", &DECL_SOURCE_LOCATION (b)); + error ("%J enters catch block", b); else if (u > 1) cp_error_at (" skips initialization of `%#D'", b); else @@ -4934,8 +4800,7 @@ check_goto (tree decl) } /* Define a label, specifying the location in the source file. - Return the LABEL_DECL node for the label, if the definition is valid. - Otherwise return 0. */ + Return the LABEL_DECL node for the label. */ tree define_label (location_t location, tree name) @@ -4951,17 +4816,16 @@ define_label (location_t location, tree name) /* After labels, make any new cleanups in the function go into their own new (temporary) binding contour. */ - for (p = current_binding_level; !(p->parm_flag); p = p->level_chain) + for (p = current_binding_level; + p->kind != sk_function_parms; + p = p->level_chain) p->more_cleanups_ok = 0; if (name == get_identifier ("wchar_t")) pedwarn ("label named wchar_t"); if (DECL_INITIAL (decl) != NULL_TREE) - { - error ("duplicate label `%D'", decl); - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE); - } + error ("duplicate label `%D'", decl); else { /* Mark label as having been defined. */ @@ -4974,9 +4838,10 @@ define_label (location_t location, tree name) ent->binding_level = current_binding_level; } check_previous_gotos (decl); - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl); } + timevar_pop (TV_NAME_LOOKUP); + return decl; } struct cp_switch @@ -5007,8 +4872,7 @@ static struct cp_switch *switch_stack; void push_switch (tree switch_stmt) { - struct cp_switch *p - = (struct cp_switch *) xmalloc (sizeof (struct cp_switch)); + struct cp_switch *p = xmalloc (sizeof (struct cp_switch)); p->level = current_binding_level; p->next = switch_stack; p->switch_stmt = switch_stmt; @@ -5069,7 +4933,9 @@ finish_case_label (tree low_value, tree high_value) /* After labels, make any new cleanups in the function go into their own new (temporary) binding contour. */ - for (p = current_binding_level; !(p->parm_flag); p = p->level_chain) + for (p = current_binding_level; + p->kind != sk_function_parms; + p = p->level_chain) p->more_cleanups_ok = 0; return r; @@ -5178,7 +5044,7 @@ lookup_tag (enum tree_code form, tree name, if (type != NULL) POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, type); } - else if (level->namespace_p) + else if (level->kind == sk_namespace) /* Do namespace lookup. */ for (tail = current_namespace; 1; tail = CP_DECL_CONTEXT (tail)) { @@ -5193,9 +5059,9 @@ lookup_tag (enum tree_code form, tree name, if (thislevel_only && !allow_template_parms_p && binding && BINDING_VALUE (binding) && DECL_CLASS_TEMPLATE_P (BINDING_VALUE (binding))) - old = TREE_TYPE (BINDING_VALUE (binding)); + old = BINDING_VALUE (binding); else if (binding) - old = BINDING_TYPE (binding); + old = select_decl (binding, LOOKUP_PREFER_TYPES); else old = NULL_TREE; @@ -5204,6 +5070,7 @@ lookup_tag (enum tree_code form, tree name, /* 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 = TREE_TYPE (old); old = follow_tag_typedef (old); if (!old) POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE); @@ -5238,7 +5105,7 @@ lookup_tag (enum tree_code form, tree name, } if (thislevel_only && ! level->tag_transparent) { - if (level->template_parms_p && allow_template_parms_p) + if (level->kind == sk_template_parms && allow_template_parms_p) { /* We must deal with cases like this: @@ -5493,9 +5360,8 @@ make_typename_type (tree context, tree name, tsubst_flags_t complain) error ("`%D' used without template parameters", name); return error_mark_node; } - if (TREE_CODE (name) != IDENTIFIER_NODE) - abort (); - + my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 20030802); + if (TREE_CODE (context) == NAMESPACE_DECL) { /* We can get here from typename_sub0 in the explicit_template_type @@ -5529,7 +5395,7 @@ make_typename_type (tree context, tree name, tsubst_flags_t complain) TREE_OPERAND (fullname, 1), NULL_TREE, context, /*entering_scope=*/0, - tf_error | tf_warning); + tf_error | tf_warning | tf_user); } else { @@ -5647,12 +5513,11 @@ select_decl (cxx_binding *binding, int flags) POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE); } - /* If we could have a type and - we have nothing or we need a type and have none. */ - if (BINDING_TYPE (binding) - && (!val || ((flags & LOOKUP_PREFER_TYPES) - && TREE_CODE (val) != TYPE_DECL))) - val = TYPE_STUB_DECL (BINDING_TYPE (binding)); + /* If looking for a type, or if there is no non-type binding, select + the value binding. */ + if (BINDING_TYPE (binding) + && (!val || (flags & LOOKUP_PREFER_TYPES))) + val = BINDING_TYPE (binding); /* Don't return non-types if we really prefer types. */ else if (val && LOOKUP_TYPES_ONLY (flags) && TREE_CODE (val) != TYPE_DECL && (TREE_CODE (val) != TEMPLATE_DECL @@ -5703,7 +5568,7 @@ unqualified_namespace_lookup (tree name, int flags, tree* spacesp) /* Add all _DECLs seen through local using-directives. */ for (level = current_binding_level; - !level->namespace_p; + level->kind != sk_namespace; level = level->level_chain) if (!lookup_using_namespace (name, &binding, level->using_directives, scope, flags, spacesp)) @@ -5755,7 +5620,8 @@ qualify_lookup (tree val, int flags) return val; if ((flags & LOOKUP_PREFER_NAMESPACES) && TREE_CODE (val) == NAMESPACE_DECL) return val; - if ((flags & LOOKUP_PREFER_TYPES) && TREE_CODE (val) == TYPE_DECL) + if ((flags & LOOKUP_PREFER_TYPES) + && (TREE_CODE (val) == TYPE_DECL || TREE_CODE (val) == TEMPLATE_DECL)) return val; if (flags & (LOOKUP_PREFER_NAMESPACES | LOOKUP_PREFER_TYPES)) return NULL_TREE; @@ -5767,10 +5633,12 @@ qualify_lookup (tree val, int flags) bindings. Returns a DECL (or OVERLOAD, or BASELINK) representing the - declaration found. */ + declaration found. If no suitable declaration can be found, + ERROR_MARK_NODE is returned. Iif COMPLAIN is true and SCOPE is + neither a class-type nor a namespace a diagnostic is issued. */ tree -lookup_qualified_name (tree scope, tree name, bool is_type_p) +lookup_qualified_name (tree scope, tree name, bool is_type_p, bool complain) { int flags = 0; @@ -5782,15 +5650,19 @@ lookup_qualified_name (tree scope, tree name, bool is_type_p) flags |= LOOKUP_COMPLAIN; if (is_type_p) flags |= LOOKUP_PREFER_TYPES; - if (!qualified_lookup_using_namespace (name, scope, &binding, - flags)) - return NULL_TREE; - return select_decl (&binding, flags); + if (qualified_lookup_using_namespace (name, scope, &binding, + flags)) + return select_decl (&binding, flags); } - else if (is_aggr_type (scope, /*or_else=*/1)) - return lookup_member (scope, name, 0, is_type_p); - else - return error_mark_node; + else if (is_aggr_type (scope, complain)) + { + tree t; + t = lookup_member (scope, name, 0, is_type_p); + if (t) + return t; + } + + return error_mark_node; } /* Check to see whether or not DECL is a variable that would have been @@ -5881,7 +5753,7 @@ lookup_name_real (tree name, int prefer_type, int nonclass, struct cp_binding_level *level; for (level = current_binding_level; - level && !level->namespace_p; + level && level->kind != sk_namespace; level = level->level_chain) { tree class_type; @@ -5889,7 +5761,7 @@ lookup_name_real (tree name, int prefer_type, int nonclass, /* A conversion operator can only be declared in a class scope. */ - if (level->parm_flag != 2) + if (level->kind != sk_class) continue; /* Lookup the conversion operator in the class. */ @@ -5979,11 +5851,9 @@ lookup_name_current_level (tree name) tree t = NULL_TREE; timevar_push (TV_NAME_LOOKUP); - b = current_binding_level; - while (b->parm_flag == 2) - b = b->level_chain; + b = innermost_nonclass_level (); - if (b->namespace_p) + if (b->kind == sk_namespace) { t = IDENTIFIER_NAMESPACE_VALUE (name); @@ -6017,7 +5887,8 @@ lookup_type_current_level (tree name) register tree t = NULL_TREE; timevar_push (TV_NAME_LOOKUP); - my_friendly_assert (! current_binding_level->namespace_p, 980716); + my_friendly_assert (current_binding_level->kind != sk_namespace, + 980716); if (REAL_IDENTIFIER_TYPE_VALUE (name) != NULL_TREE && REAL_IDENTIFIER_TYPE_VALUE (name) != global_type_node) @@ -6039,10 +5910,23 @@ lookup_type_current_level (tree name) } + +/* A chain of TYPE_DECLs for the builtin types. */ + +static GTY(()) tree builtin_type_decls; + +/* Return a chain of TYPE_DECLs for the builtin types. */ + +tree +cxx_builtin_type_decls () +{ + return builtin_type_decls; +} + /* Push the declarations of builtin types into the namespace. - RID_INDEX is the index of the builtin type - in the array RID_POINTERS. NAME is the name used when looking - up the builtin type. TYPE is the _TYPE node for the builtin type. */ + RID_INDEX is the index of the builtin type in the array + RID_POINTERS. NAME is the name used when looking up the builtin + type. TYPE is the _TYPE node for the builtin type. */ void record_builtin_type (enum rid rid_index, @@ -6057,26 +5941,34 @@ record_builtin_type (enum rid rid_index, if (name) tname = get_identifier (name); + /* The calls to SET_IDENTIFIER_GLOBAL_VALUE below should be + eliminated. Built-in types should not be looked up name; their + names are keywords that the parser can recognize. However, there + is code in c-common.c that uses identifier_global_value to look + up built-in types by name. */ if (tname) { - tdecl = pushdecl (build_decl (TYPE_DECL, tname, type)); - set_identifier_type_value (tname, NULL_TREE); - if ((int) rid_index < (int) RID_MAX) - /* Built-in types live in the global namespace. */ - SET_IDENTIFIER_GLOBAL_VALUE (tname, tdecl); + tdecl = build_decl (TYPE_DECL, tname, type); + DECL_ARTIFICIAL (tdecl) = 1; + SET_IDENTIFIER_GLOBAL_VALUE (tname, tdecl); } - if (rname != NULL_TREE) + if (rname) { - if (tname != NULL_TREE) + if (!tdecl) { - set_identifier_type_value (rname, NULL_TREE); - SET_IDENTIFIER_GLOBAL_VALUE (rname, tdecl); - } - else - { - tdecl = pushdecl (build_decl (TYPE_DECL, rname, type)); - set_identifier_type_value (rname, NULL_TREE); + tdecl = build_decl (TYPE_DECL, rname, type); + DECL_ARTIFICIAL (tdecl) = 1; } + SET_IDENTIFIER_GLOBAL_VALUE (rname, tdecl); + } + + if (!TYPE_NAME (type)) + TYPE_NAME (type) = tdecl; + + if (tdecl) + { + TREE_CHAIN (tdecl) = builtin_type_decls; + builtin_type_decls = tdecl; } } @@ -6213,7 +6105,7 @@ cxx_init_decl_processing (void) current_lang_name = NULL_TREE; /* Adjust various flags based on command-line settings. */ - if (! flag_permissive && ! pedantic) + if (!flag_permissive) flag_pedantic_errors = 1; if (!flag_no_inline) { @@ -6261,16 +6153,10 @@ cxx_init_decl_processing (void) integer_three_node = build_int_2 (3, 0); TREE_TYPE (integer_three_node) = integer_type_node; - boolean_type_node = make_unsigned_type (BOOL_TYPE_SIZE); - TREE_SET_CODE (boolean_type_node, BOOLEAN_TYPE); - TYPE_MAX_VALUE (boolean_type_node) = build_int_2 (1, 0); - TREE_TYPE (TYPE_MAX_VALUE (boolean_type_node)) = boolean_type_node; - TYPE_PRECISION (boolean_type_node) = 1; record_builtin_type (RID_BOOL, "bool", boolean_type_node); - boolean_false_node = build_int_2 (0, 0); - TREE_TYPE (boolean_false_node) = boolean_type_node; - boolean_true_node = build_int_2 (1, 0); - TREE_TYPE (boolean_true_node) = boolean_type_node; + truthvalue_type_node = boolean_type_node; + truthvalue_false_node = boolean_false_node; + truthvalue_true_node = boolean_true_node; empty_except_spec = build_tree_list (NULL_TREE, NULL_TREE); @@ -6335,14 +6221,22 @@ cxx_init_decl_processing (void) current_lang_name = lang_name_cplusplus; { - tree bad_alloc_type_node, newtype, deltype; + tree bad_alloc_id; + tree bad_alloc_type_node; + tree bad_alloc_decl; + tree newtype, deltype; tree ptr_ftype_sizetype; push_namespace (std_identifier); - bad_alloc_type_node - = xref_tag (class_type, get_identifier ("bad_alloc"), - /*attributes=*/NULL_TREE, 1); + bad_alloc_id = get_identifier ("bad_alloc"); + bad_alloc_type_node = make_aggr_type (RECORD_TYPE); + TYPE_CONTEXT (bad_alloc_type_node) = current_namespace; + bad_alloc_decl + = create_implicit_typedef (bad_alloc_id, bad_alloc_type_node); + DECL_CONTEXT (bad_alloc_decl) = current_namespace; + TYPE_STUB_DECL (bad_alloc_type_node) = bad_alloc_decl; pop_namespace (); + ptr_ftype_sizetype = build_function_type (ptr_type_node, tree_cons (NULL_TREE, @@ -6444,7 +6338,7 @@ cp_make_fname_decl (tree id, int type_dep) if (current_function_decl) { struct cp_binding_level *b = current_binding_level; - while (b->level_chain->parm_flag == 0) + while (b->level_chain->kind != sk_function_parms) b = b->level_chain; pushdecl_with_scope (decl, b); } @@ -6642,19 +6536,6 @@ push_throw_library_fn (tree name, tree type) TREE_NOTHROW (fn) = 0; return fn; } - -/* Apply default attributes to a function, if a system function with default - attributes. */ - -void -cxx_insert_default_attributes (tree decl) -{ - if (!DECL_EXTERN_C_FUNCTION_P (decl)) - return; - if (!TREE_PUBLIC (decl)) - return; - c_common_insert_default_attributes (decl); -} /* When we call finish_struct for an anonymous union, we create default copy constructors and such. But, an anonymous union @@ -6692,8 +6573,8 @@ fixup_anonymous_aggr (tree t) /* ISO C++ 9.5.3. Anonymous unions may not have function members. */ if (TYPE_METHODS (t)) - error ("%Han anonymous union cannot have function members", - &DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (t))); + error ("%Jan anonymous union cannot have function members", + TYPE_MAIN_DECL (t)); /* Anonymous aggregates cannot have fields with ctors, dtors or complex assignment operators (because they cannot have these methods themselves). @@ -7026,8 +6907,7 @@ start_decl (tree declarator, && DECL_DECLARED_INLINE_P (decl) && DECL_UNINLINABLE (decl) && lookup_attribute ("noinline", DECL_ATTRIBUTES (decl))) - warning ("%Hinline function '%D' given attribute noinline", - &DECL_SOURCE_LOCATION (decl), decl); + warning ("%Jinline function '%D' given attribute noinline", decl, decl); if (context && COMPLETE_TYPE_P (complete_type (context))) { @@ -7178,14 +7058,18 @@ start_decl_1 (tree decl) DECL_INITIAL (decl) = NULL_TREE; } -/* Handle initialization of references. - These three arguments are from `cp_finish_decl', and have the - same meaning here that they do there. +/* Handle initialization of references. DECL, TYPE, and INIT have the + same meaning as in cp_finish_decl. *CLEANUP must be NULL on entry, + but will be set to a new CLEANUP_STMT if a temporary is created + that must be destroeyd subsequently. + + Returns an initializer expression to use to initialize DECL, or + NULL if the initialization can be performed statically. Quotes on semantics can be found in ARM 8.4.3. */ static tree -grok_reference_init (tree decl, tree type, tree init) +grok_reference_init (tree decl, tree type, tree init, tree *cleanup) { tree tmp; @@ -7205,7 +7089,7 @@ grok_reference_init (tree decl, tree type, tree init) } if (TREE_CODE (init) == TREE_LIST) - init = build_compound_expr (init); + init = build_x_compound_expr_from_list (init, "initializer"); if (TREE_CODE (TREE_TYPE (init)) == REFERENCE_TYPE) init = convert_from_reference (init); @@ -7222,7 +7106,7 @@ grok_reference_init (tree decl, tree type, tree init) DECL_INITIAL for local references (instead assigning to them explicitly); we need to allow the temporary to be initialized first. */ - tmp = initialize_reference (type, init, decl); + tmp = initialize_reference (type, init, decl, cleanup); if (tmp == error_mark_node) return NULL_TREE; @@ -7392,8 +7276,8 @@ maybe_commonize_var (tree decl) TREE_PUBLIC (decl) = 0; DECL_COMMON (decl) = 0; cp_warning_at ("sorry: semantics of inline function static data `%#D' are wrong (you'll wind up with multiple copies)", decl); - warning ("%H you can work around this by removing the initializer", - &DECL_SOURCE_LOCATION (decl)); + warning ("%J you can work around this by removing the initializer", + decl); } } } @@ -7466,13 +7350,7 @@ reshape_init (tree type, tree *initp) old_init_value = (TREE_CODE (*initp) == TREE_LIST ? TREE_VALUE (*initp) : old_init); - /* For some parse errors, OLD_INIT_VALUE may be NULL. */ - if (!old_init_value) - { - my_friendly_assert (TREE_CODE (old_init) == TREE_LIST, 20021202); - TREE_VALUE (old_init) = error_mark_node; - return old_init; - } + my_friendly_assert (old_init_value, 20030723); /* If the initializer is brace-enclosed, pull initializers from the enclosed elements. Advance past the brace-enclosed initializer @@ -7648,13 +7526,14 @@ reshape_init (tree type, tree *initp) } /* Verify INIT (the initializer for DECL), and record the - initialization in DECL_INITIAL, if appropriate. + initialization in DECL_INITIAL, if appropriate. CLEANUP is as for + grok_reference_init. If the return value is non-NULL, it is an expression that must be evaluated dynamically to initialize DECL. */ static tree -check_initializer (tree decl, tree init, int flags) +check_initializer (tree decl, tree init, int flags, tree *cleanup) { tree type = TREE_TYPE (decl); @@ -7704,7 +7583,7 @@ check_initializer (tree decl, tree init, int flags) init = NULL_TREE; } else if (!DECL_EXTERNAL (decl) && TREE_CODE (type) == REFERENCE_TYPE) - init = grok_reference_init (decl, type, init); + init = grok_reference_init (decl, type, init, cleanup); else if (init) { if (TREE_CODE (init) == CONSTRUCTOR && TREE_HAS_CONSTRUCTOR (init)) @@ -7907,7 +7786,7 @@ maybe_inject_for_scope_var (tree decl) return; } - if (current_binding_level->is_for_scope) + if (current_binding_level->kind == sk_for) { struct cp_binding_level *outer = current_binding_level->level_chain; @@ -7930,7 +7809,7 @@ maybe_inject_for_scope_var (tree decl) { BINDING_VALUE (outer_binding) = DECL_SHADOWED_FOR_VAR (BINDING_VALUE (outer_binding)); - current_binding_level->is_for_scope = 0; + current_binding_level->kind = sk_block; } } timevar_pop (TV_NAME_LOOKUP); @@ -8011,8 +7890,9 @@ initialize_local_var (tree decl, tree init) void cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags) { - register tree type; + tree type; tree ttype = NULL_TREE; + tree cleanup; const char *asmspec = NULL; int was_readonly = 0; @@ -8025,6 +7905,9 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags) my_friendly_assert (TREE_CODE (decl) != RESULT_DECL, 20030619); + /* Assume no cleanup is required. */ + cleanup = NULL_TREE; + /* If a name was specified, get the string. */ if (global_scope_p (current_binding_level)) asmspec_tree = maybe_apply_renaming_pragma (decl, asmspec_tree); @@ -8084,8 +7967,7 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags) { if (TREE_TYPE (DECL_NAME (decl)) && TREE_TYPE (decl) != type) warning ("shadowing previous type declaration of `%#D'", decl); - set_identifier_type_value (DECL_NAME (decl), type); - CLASSTYPE_GOT_SEMICOLON (type) = 1; + set_identifier_type_value (DECL_NAME (decl), decl); } /* If we have installed this as the canonical typedef for this @@ -8139,7 +8021,7 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags) is *not* defined. */ && (!DECL_EXTERNAL (decl) || init)) { - init = check_initializer (decl, init, flags); + init = check_initializer (decl, init, flags, &cleanup); /* Thread-local storage cannot be dynamically initialized. */ if (DECL_THREAD_LOCAL (decl) && init) { @@ -8218,8 +8100,7 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags) if (DECL_FUNCTION_SCOPE_P (decl)) { /* This is a local declaration. */ - if (doing_semantic_analysis_p ()) - maybe_inject_for_scope_var (decl); + maybe_inject_for_scope_var (decl); /* Initialize the local variable. */ if (processing_template_decl) { @@ -8255,10 +8136,19 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags) } } + /* If a CLEANUP_STMT was created to destroy a temporary bound to a + reference, insert it in the statement-tree now. */ + if (cleanup) + add_stmt (cleanup); + finish_end: if (was_readonly) TREE_READONLY (decl) = 1; + + /* If this was marked 'used', be sure it will be output. */ + if (lookup_attribute ("used", DECL_ATTRIBUTES (decl))) + mark_referenced (DECL_ASSEMBLER_NAME (decl)); } /* This is here for a midend callback from c-common.c */ @@ -8483,9 +8373,9 @@ register_dtor_fn (tree decl) pop_deferring_access_checks (); /* Create the body of the anonymous function. */ - compound_stmt = begin_compound_stmt (/*has_no_scope=*/0); + compound_stmt = begin_compound_stmt (/*has_no_scope=*/false); finish_expr_stmt (fcall); - finish_compound_stmt (/*has_no_scope=*/0, compound_stmt); + finish_compound_stmt (compound_stmt); end_cleanup_fn (); /* Call atexit with the cleanup function. */ @@ -8512,8 +8402,6 @@ register_dtor_fn (tree decl) static void expand_static_init (tree decl, tree init) { - tree oldstatic; - my_friendly_assert (TREE_CODE (decl) == VAR_DECL, 20021010); my_friendly_assert (TREE_STATIC (decl), 20021010); @@ -8523,14 +8411,7 @@ expand_static_init (tree decl, tree init) && TYPE_HAS_TRIVIAL_DESTRUCTOR (TREE_TYPE (decl))) return; - oldstatic = value_member (decl, static_aggregates); - - if (oldstatic) - { - if (TREE_PURPOSE (oldstatic) && init != NULL_TREE) - error ("multiple initializations given for `%D'", decl); - } - else if (! toplevel_bindings_p ()) + if (! toplevel_bindings_p ()) { /* Emit code to perform this initialization but once. */ tree if_stmt; @@ -8570,7 +8451,7 @@ expand_static_init (tree decl, tree init) /* Begin the conditional initialization. */ if_stmt = begin_if_stmt (); finish_if_stmt_cond (get_guard_cond (guard), if_stmt); - then_clause = begin_compound_stmt (/*has_no_scope=*/0); + then_clause = begin_compound_stmt (/*has_no_scope=*/false); /* Do the initialization itself. */ assignment = init ? init : NULL_TREE; @@ -8585,12 +8466,7 @@ expand_static_init (tree decl, tree init) run until after TEMP is set to 1. */ guard_init = set_guard (guard); if (assignment) - { - assignment = tree_cons (NULL_TREE, assignment, - build_tree_list (NULL_TREE, - guard_init)); - assignment = build_compound_expr (assignment); - } + assignment = build_compound_expr (assignment, guard_init); else assignment = guard_init; finish_expr_stmt (assignment); @@ -8599,7 +8475,7 @@ expand_static_init (tree decl, tree init) variable. */ register_dtor_fn (decl); - finish_compound_stmt (/*has_no_scope=*/0, then_clause); + finish_compound_stmt (then_clause); finish_then_clause (if_stmt); finish_if_stmt (); } @@ -8905,19 +8781,14 @@ grokfndecl (tree ctype, DECL_NOT_REALLY_EXTERN (decl) = 1; } - DID_INLINE_FUNC (decl) = 0; /* If the declaration was declared inline, mark it as such. */ if (inlinep) DECL_DECLARED_INLINE_P (decl) = 1; /* We inline functions that are explicitly declared inline, or, when the user explicitly asks us to, all functions. */ - if (DECL_DECLARED_INLINE_P (decl)) + if (DECL_DECLARED_INLINE_P (decl) + || (flag_inline_trees == 2 && !DECL_INLINE (decl) && funcdef_flag)) DECL_INLINE (decl) = 1; - if (flag_inline_trees == 2 && !DECL_INLINE (decl) && funcdef_flag) - { - DID_INLINE_FUNC (decl) = 1; - DECL_INLINE (decl) = 1; - } DECL_EXTERNAL (decl) = 1; if (quals != NULL_TREE && TREE_CODE (type) == FUNCTION_TYPE) @@ -8928,7 +8799,7 @@ grokfndecl (tree ctype, } if (IDENTIFIER_OPNAME_P (DECL_NAME (decl))) - grok_op_properties (decl, friendp); + grok_op_properties (decl, friendp, /*complain=*/true); if (ctype && decl_function_context (decl)) DECL_NO_STATIC_CHAIN (decl) = 1; @@ -8978,7 +8849,6 @@ grokfndecl (tree ctype, fns = TREE_OPERAND (fns, 1); } my_friendly_assert (TREE_CODE (fns) == IDENTIFIER_NODE - || TREE_CODE (fns) == LOOKUP_EXPR || TREE_CODE (fns) == OVERLOAD, 20001120); DECL_TEMPLATE_INFO (decl) = tree_cons (fns, args, NULL_TREE); @@ -9271,9 +9141,6 @@ build_ptrmemfunc_type (tree type) later. */ TYPE_SET_PTRMEMFUNC_TYPE (type, t); - /* Seems to be wanted. */ - CLASSTYPE_GOT_SEMICOLON (t) = 1; - return t; } @@ -9282,7 +9149,26 @@ build_ptrmemfunc_type (tree type) tree build_ptrmem_type (tree class_type, tree member_type) { - return build_pointer_type (build_offset_type (class_type, member_type)); + if (TREE_CODE (member_type) == METHOD_TYPE) + { + tree arg_types; + + arg_types = TYPE_ARG_TYPES (member_type); + class_type = (cp_build_qualified_type + (class_type, + cp_type_quals (TREE_TYPE (TREE_VALUE (arg_types))))); + member_type + = build_method_type_directly (class_type, + TREE_TYPE (member_type), + TREE_CHAIN (arg_types)); + return build_ptrmemfunc_type (build_pointer_type (member_type)); + } + else + { + my_friendly_assert (TREE_CODE (member_type) != FUNCTION_TYPE, + 20030716); + return build_offset_type (class_type, member_type); + } } /* DECL is a VAR_DECL defined in-class, whose TYPE is also given. @@ -9519,10 +9405,6 @@ create_array_type_for_decl (tree name, tree type, tree size) error_msg = "array of references"; break; - case OFFSET_TYPE: - error_msg = "array of data members"; - break; - case METHOD_TYPE: error_msg = "array of function members"; break; @@ -9800,9 +9682,6 @@ grokdeclarator (tree declarator, { tree fns = TREE_OPERAND (decl, 0); - if (TREE_CODE (fns) == LOOKUP_EXPR) - fns = TREE_OPERAND (fns, 0); - dname = fns; if (TREE_CODE (dname) == COMPONENT_REF) dname = TREE_OPERAND (dname, 1); @@ -9911,16 +9790,19 @@ grokdeclarator (tree declarator, decl = *next; if (ctype) { - if (TREE_CODE (decl) == IDENTIFIER_NODE - && constructor_name_p (decl, ctype)) + tree name = decl; + + if (TREE_CODE (name) == BIT_NOT_EXPR) + name = TREE_OPERAND (name, 0); + + if (!constructor_name_p (decl, ctype)) + ; + else if (decl == name) { sfk = sfk_constructor; ctor_return_type = ctype; } - else if (TREE_CODE (decl) == BIT_NOT_EXPR - && TREE_CODE (TREE_OPERAND (decl, 0)) == IDENTIFIER_NODE - && constructor_name_p (TREE_OPERAND (decl, 0), - ctype)) + else { sfk = sfk_destructor; ctor_return_type = ctype; @@ -10610,15 +10492,7 @@ grokdeclarator (tree declarator, case ARRAY_REF: { - register tree size; - - size = TREE_OPERAND (declarator, 1); - - /* VC++ spells a zero-sized array with []. */ - if (size == NULL_TREE && decl_context == FIELD && ! staticp - && ! RIDBIT_SETP (RID_TYPEDEF, specbits)) - size = integer_zero_node; - + tree size = TREE_OPERAND (declarator, 1); declarator = TREE_OPERAND (declarator, 0); type = create_array_type_for_decl (dname, type, size); @@ -10958,7 +10832,9 @@ grokdeclarator (tree declarator, else if (TREE_CODE (type) == FUNCTION_TYPE) { if (current_class_type == NULL_TREE || friendp) - type = build_cplus_method_type (ctype, TREE_TYPE (type), + type + = build_method_type_directly (ctype, + TREE_TYPE (type), TYPE_ARG_TYPES (type)); else { @@ -11000,8 +10876,9 @@ grokdeclarator (tree declarator, /* In this case, we will deal with it later. */ ; else if (TREE_CODE (type) == FUNCTION_TYPE) - type = build_cplus_method_type (ctype, TREE_TYPE (type), - TYPE_ARG_TYPES (type)); + type = build_method_type_directly (ctype, + TREE_TYPE (type), + TYPE_ARG_TYPES (type)); } } break; @@ -11137,8 +11014,7 @@ grokdeclarator (tree declarator, { decl = build_decl (TYPE_DECL, declarator, type); if (in_namespace || ctype) - error ("%Htypedef name may not be a nested-name-specifier", - &DECL_SOURCE_LOCATION (decl)); + error ("%Jtypedef name may not be a nested-name-specifier", decl); if (!current_function_decl) DECL_CONTEXT (decl) = FROB_CONTEXT (current_namespace); } @@ -11184,8 +11060,8 @@ grokdeclarator (tree declarator, if (ctype == NULL_TREE) { if (TREE_CODE (type) != METHOD_TYPE) - error ("%Hinvalid type qualifier for non-member function type", - &DECL_SOURCE_LOCATION (decl)); + error ("%Jinvalid type qualifier for non-member function type", + decl); else ctype = TYPE_METHOD_BASETYPE (type); } @@ -11277,7 +11153,8 @@ grokdeclarator (tree declarator, { /* A friendly class? */ if (current_class_type) - make_friend_class (current_class_type, TYPE_MAIN_VARIANT (type)); + make_friend_class (current_class_type, TYPE_MAIN_VARIANT (type), + /*complain=*/true); else error ("trying to make class `%T' a friend of global scope", type); @@ -11354,8 +11231,6 @@ grokdeclarator (tree declarator, } else if (TREE_CODE (type) == FUNCTION_TYPE) type = build_pointer_type (type); - else if (TREE_CODE (type) == OFFSET_TYPE) - type = build_pointer_type (type); } { @@ -11370,6 +11245,14 @@ grokdeclarator (tree declarator, } else if (decl_context == FIELD) { + /* The C99 flexible array extension. */ + if (!staticp && TREE_CODE (type) == ARRAY_TYPE + && TYPE_DOMAIN (type) == NULL_TREE) + { + tree itype = compute_array_index_type (dname, integer_zero_node); + type = build_cplus_array_type (TREE_TYPE (type), itype); + } + if (type == error_mark_node) { /* Happens when declaring arrays of sizes which @@ -11430,8 +11313,9 @@ grokdeclarator (tree declarator, } } else if (staticp < 2) - type = build_cplus_method_type (ctype, TREE_TYPE (type), - TYPE_ARG_TYPES (type)); + type = build_method_type_directly (ctype, + TREE_TYPE (type), + TYPE_ARG_TYPES (type)); } /* Tell grokfndecl if it needs to set TREE_PUBLIC on the node. */ @@ -11485,7 +11369,10 @@ grokdeclarator (tree declarator, members of other classes. */ /* All method decls are public, so tell grokfndecl to set TREE_PUBLIC, also. */ - decl = grokfndecl (ctype, type, declarator, declarator, + decl = grokfndecl (ctype, type, + TREE_CODE (declarator) != TEMPLATE_ID_EXPR + ? declarator : dname, + declarator, virtualp, flags, quals, raises, friendp ? -1 : 0, friendp, 1, 0, funcdef_flag, template_count, in_namespace); @@ -11620,7 +11507,8 @@ grokdeclarator (tree declarator, inlinep, friendp, raises != NULL_TREE); } } - else if (TREE_CODE (type) == FUNCTION_TYPE || TREE_CODE (type) == METHOD_TYPE) + else if (TREE_CODE (type) == FUNCTION_TYPE + || TREE_CODE (type) == METHOD_TYPE) { tree original_name; int publicp = 0; @@ -11663,8 +11551,9 @@ grokdeclarator (tree declarator, } } else if (TREE_CODE (type) == FUNCTION_TYPE && staticp < 2) - type = build_cplus_method_type (ctype, TREE_TYPE (type), - TYPE_ARG_TYPES (type)); + type = build_method_type_directly (ctype, + TREE_TYPE (type), + TYPE_ARG_TYPES (type)); /* Record presence of `static'. */ publicp = (ctype != NULL_TREE @@ -11975,19 +11864,13 @@ grokparms (tree first_parm) { /* Top-level qualifiers on the parameters are ignored for function types. */ - type = TYPE_MAIN_VARIANT (type); + type = cp_build_qualified_type (type, 0); if (TREE_CODE (type) == METHOD_TYPE) { error ("parameter `%D' invalidly declared method type", decl); type = build_pointer_type (type); TREE_TYPE (decl) = type; } - else if (TREE_CODE (type) == OFFSET_TYPE) - { - error ("parameter `%D' invalidly declared offset type", decl); - type = build_pointer_type (type); - TREE_TYPE (decl) = type; - } else if (abstract_virtuals_error (decl, type)) any_error = 1; /* Seems like a good idea. */ else if (POINTER_TYPE_P (type)) @@ -12200,10 +12083,12 @@ unary_op_p (enum tree_code code) || code == TYPE_EXPR); } -/* Do a little sanity-checking on how they declared their operator. */ +/* DECL is a declaration for an overloaded operator. Returns true if + the declaration is valid; false otherwise. If COMPLAIN is true, + errors are issued for invalid declarations. */ -void -grok_op_properties (tree decl, int friendp) +bool +grok_op_properties (tree decl, int friendp, bool complain) { tree argtypes = TYPE_ARG_TYPES (TREE_TYPE (decl)); tree argtype; @@ -12211,6 +12096,10 @@ grok_op_properties (tree decl, int friendp) tree name = DECL_NAME (decl); enum tree_code operator_code; int arity; + bool ok; + + /* Assume that the declaration is valid. */ + ok = true; /* Count the number of arguments. */ for (argtype = argtypes, arity = 0; @@ -12252,19 +12141,6 @@ grok_op_properties (tree decl, int friendp) { switch (operator_code) { - case CALL_EXPR: - TYPE_OVERLOADS_CALL_EXPR (current_class_type) = 1; - break; - - case ARRAY_REF: - TYPE_OVERLOADS_ARRAY_REF (current_class_type) = 1; - break; - - case COMPONENT_REF: - case MEMBER_REF: - TYPE_OVERLOADS_ARROW (current_class_type) = 1; - break; - case NEW_EXPR: TYPE_HAS_NEW_OPERATOR (current_class_type) = 1; break; @@ -12317,33 +12193,38 @@ grok_op_properties (tree decl, int friendp) error ("`%D' must be a nonstatic member function", decl); else { - tree p = argtypes; + tree p; if (DECL_STATIC_FUNCTION_P (decl)) error ("`%D' must be either a non-static member function or a non-member function", decl); - if (p) - for (; TREE_CODE (TREE_VALUE (p)) != VOID_TYPE ; p = TREE_CHAIN (p)) - { - tree arg = non_reference (TREE_VALUE (p)); - - /* This lets bad template code slip through. */ - if (IS_AGGR_TYPE (arg) - || TREE_CODE (arg) == ENUMERAL_TYPE - || TREE_CODE (arg) == TEMPLATE_TYPE_PARM - || TREE_CODE (arg) == BOUND_TEMPLATE_TEMPLATE_PARM) - goto foundaggr; - } - error - ("`%D' must have an argument of class or enumerated type", - decl); - foundaggr: - ; + for (p = argtypes; p && p != void_list_node; p = TREE_CHAIN (p)) + { + tree arg = non_reference (TREE_VALUE (p)); + /* IS_AGGR_TYPE, rather than CLASS_TYPE_P, is used + because these checks are performed even on + template functions. */ + if (IS_AGGR_TYPE (arg) || TREE_CODE (arg) == ENUMERAL_TYPE) + break; + } + + if (!p || p == void_list_node) + { + if (!complain) + return false; + + error ("`%D' must have an argument of class or " + "enumerated type", + decl); + ok = false; + } } } + /* There are no restrictions on the arguments to an overloaded + "operator ()". */ if (operator_code == CALL_EXPR) - return; /* No restrictions on args. */ + return ok; if (IDENTIFIER_TYPENAME_P (name) && ! DECL_TEMPLATE_INFO (decl)) { @@ -12526,6 +12407,8 @@ grok_op_properties (tree decl, int friendp) } } + + return ok; } static const char * @@ -12547,57 +12430,110 @@ tag_name (enum tag_types code) } /* Name lookup in an elaborated-type-specifier (after the keyword - indicated by TAG_CODE) has found TYPE. If the + indicated by TAG_CODE) has found the TYPE_DECL DECL. If the elaborated-type-specifier is invalid, issue a diagnostic and return - error_mark_node; otherwise, return TYPE itself. */ + error_mark_node; otherwise, return the *_TYPE to which it referred. + If ALLOW_TEMPLATE_P is true, TYPE may be a class template. */ -static tree +tree check_elaborated_type_specifier (enum tag_types tag_code, - tree type) + tree decl, + bool allow_template_p) { - tree t; + tree type; - t = follow_tag_typedef (type); + /* In the case of: - /* [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) + struct S { struct S *p; }; + + name lookup will find the TYPE_DECL for the implicit "S::S" + typedef. Adjust for that here. */ + if (DECL_SELF_REFERENCE_P (decl)) + decl = TYPE_NAME (TREE_TYPE (decl)); + + type = TREE_TYPE (decl); + + /* [dcl.type.elab] + + If the identifier resolves to a typedef-name or a template + type-parameter, the elaborated-type-specifier is ill-formed. + + In other words, the only legitimate declaration to use in the + elaborated type specifier is the implicit typedef created when + the type is declared. */ + if (!DECL_IMPLICIT_TYPEDEF_P (decl)) { - error ("using typedef-name `%D' after `%s'", - TYPE_NAME (type), tag_name (tag_code)); - t = error_mark_node; + error ("using typedef-name `%D' after `%s'", decl, tag_name (tag_code)); + return IS_AGGR_TYPE (type) ? type : error_mark_node; } - else if (TREE_CODE (type) == TEMPLATE_TYPE_PARM) + + if (TREE_CODE (type) == TEMPLATE_TYPE_PARM) { error ("using template type parameter `%T' after `%s'", type, tag_name (tag_code)); - t = error_mark_node; + return error_mark_node; + } + else if (TREE_CODE (type) != RECORD_TYPE + && TREE_CODE (type) != UNION_TYPE + && tag_code != enum_type) + { + error ("`%T' referred to as `%s'", type, tag_name (tag_code)); + return error_mark_node; } + else if (TREE_CODE (type) != ENUMERAL_TYPE + && tag_code == enum_type) + { + error ("`%T' referred to as enum", type); + return error_mark_node; + } + else if (!allow_template_p + && TREE_CODE (type) == RECORD_TYPE + && CLASSTYPE_IS_TEMPLATE (type)) + { + /* If a class template appears as elaborated type specifier + without a template header such as: - return t; + template <class T> class C {}; + void f(class C); // No template header here + + then the required template argument is missing. */ + + error ("template argument required for `%s %T'", + tag_name (tag_code), + DECL_NAME (CLASSTYPE_TI_TEMPLATE (type))); + return error_mark_node; + } + + return type; } -/* Get the struct, enum or union (CODE says which) with tag NAME. +/* Get the struct, enum or union (TAG_CODE says which) with tag NAME. Define the tag as a forward-reference if it is not defined. - C++: If a class derivation is given, process it here, and report - an error if multiple derivation declarations are not identical. + If a declaration is given, process it here, and report an error if + multiple declarations are not identical. ATTRIBUTE is the attribute + appeared in this declaration. - If this is a definition, come in through xref_tag and only look in + GLOBALIZE is false when this is also a definition. Only look in the current frame for the name (since C++ allows new names in any - scope.) */ + scope.) + + TEMPLATE_HEADER_P is true when this declaration is preceded by + a set of template parameters. */ tree xref_tag (enum tag_types tag_code, tree name, tree attributes, - bool globalize) + bool globalize, bool template_header_p) { enum tree_code code; - register tree ref, t; + register tree t; struct cp_binding_level *b = current_binding_level; tree context = NULL_TREE; timevar_push (TV_NAME_LOOKUP); + + my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 0); + switch (tag_code) { case record_type: @@ -12614,93 +12550,50 @@ xref_tag (enum tag_types tag_code, tree name, tree attributes, abort (); } - /* If a cross reference is requested, look up the type - already defined for this tag and return it. */ - if (TYPE_P (name)) - { - t = name; - name = TYPE_IDENTIFIER (t); - } - else - t = IDENTIFIER_TYPE_VALUE (name); - - /* Warn about 'friend struct Inherited;' doing the wrong thing. */ - if (t && globalize && TREE_CODE (t) == TYPENAME_TYPE) - { - static int explained; - tree shadowed; - - warning ("`%s %T' declares a new type at namespace scope", - tag_name (tag_code), name); - if (!explained++) - warning (" names from dependent base classes are not visible to unqualified name lookup - to refer to the inherited type, say `%s %T::%T'", - tag_name (tag_code), - constructor_name (current_class_type), - TYPE_IDENTIFIER (t)); - - /* We need to remove the class scope binding for the - TYPENAME_TYPE as otherwise poplevel_class gets confused. */ - for (shadowed = b->class_shadowed; - shadowed; - shadowed = TREE_CHAIN (shadowed)) - if (TREE_TYPE (shadowed) == TYPE_NAME (t)) - { - TREE_PURPOSE (shadowed) = NULL_TREE; - break; - } - } - - if (t && TREE_CODE (t) != code && TREE_CODE (t) != TEMPLATE_TYPE_PARM - && TREE_CODE (t) != BOUND_TEMPLATE_TEMPLATE_PARM) - t = NULL_TREE; - if (! globalize) { /* If we know we are defining this tag, only look it up in this scope and don't try to find it as a type. */ - ref = lookup_tag (code, name, b, 1); + t = lookup_tag (code, name, b, 1); } else { - if (t) - { - ref = check_elaborated_type_specifier (tag_code, t); - if (ref == error_mark_node) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); - } - else - ref = lookup_tag (code, name, b, 0); + tree decl = lookup_name (name, 1); + + if (decl && DECL_CLASS_TEMPLATE_P (decl)) + decl = DECL_TEMPLATE_RESULT (decl); - if (! ref) + if (decl && TREE_CODE (decl) == TYPE_DECL) { - /* Try finding it as a type declaration. If that wins, - use it. */ - ref = lookup_name (name, 1); + /* Two cases we need to consider when deciding if a class + template is allowed as an elaborated type specifier: + 1. It is a self reference to its own class. + 2. It comes with a template header. - if (ref != NULL_TREE - && processing_template_decl - && DECL_CLASS_TEMPLATE_P (ref) - && template_class_depth (current_class_type) == 0) - /* Since GLOBALIZE is true, we're declaring a global - template, so we want this type. */ - ref = DECL_TEMPLATE_RESULT (ref); + For example: - if (ref && TREE_CODE (ref) == TYPE_DECL) - { - ref = check_elaborated_type_specifier (tag_code, - TREE_TYPE (ref)); - if (ref == error_mark_node) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); - if (ref && TREE_CODE (ref) != code) - ref = NULL_TREE; - } - else - ref = NULL_TREE; + template <class T> class C { + class C *c1; // DECL_SELF_REFERENCE_P is true + class D; + }; + template <class U> class C; // template_header_p is true + template <class T> class C<T>::D { + class C *c2; // DECL_SELF_REFERENCE_P is true + }; */ + + t = check_elaborated_type_specifier (tag_code, + decl, + template_header_p + | DECL_SELF_REFERENCE_P (decl)); + if (t == error_mark_node) + POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); } + else + t = NULL_TREE; - if (ref && current_class_type + if (t && current_class_type && template_class_depth (current_class_type) - && PROCESSING_REAL_TEMPLATE_DECL_P ()) + && template_header_p) { /* Since GLOBALIZE is nonzero, we are not looking at a definition of this tag. Since, in addition, we are currently @@ -12738,12 +12631,12 @@ xref_tag (enum tag_types tag_code, tree name, tree attributes, accomplish this by making sure that the new type we create to represent this declaration has the right TYPE_CONTEXT. */ - context = TYPE_CONTEXT (ref); - ref = NULL_TREE; + context = TYPE_CONTEXT (t); + t = NULL_TREE; } } - if (! ref) + if (! t) { /* If no such tag is yet defined, create a forward-reference node and record it as the "definition". @@ -12753,44 +12646,41 @@ xref_tag (enum tag_types tag_code, tree name, tree attributes, { error ("use of enum `%#D' without previous declaration", name); - ref = make_node (ENUMERAL_TYPE); + t = make_node (ENUMERAL_TYPE); /* Give the type a default layout like unsigned int to avoid crashing if it does not get defined. */ - TYPE_MODE (ref) = TYPE_MODE (unsigned_type_node); - TYPE_ALIGN (ref) = TYPE_ALIGN (unsigned_type_node); - TYPE_USER_ALIGN (ref) = 0; - TREE_UNSIGNED (ref) = 1; - TYPE_PRECISION (ref) = TYPE_PRECISION (unsigned_type_node); - TYPE_MIN_VALUE (ref) = TYPE_MIN_VALUE (unsigned_type_node); - TYPE_MAX_VALUE (ref) = TYPE_MAX_VALUE (unsigned_type_node); + TYPE_MODE (t) = TYPE_MODE (unsigned_type_node); + TYPE_ALIGN (t) = TYPE_ALIGN (unsigned_type_node); + TYPE_USER_ALIGN (t) = 0; + TREE_UNSIGNED (t) = 1; + TYPE_PRECISION (t) = TYPE_PRECISION (unsigned_type_node); + TYPE_MIN_VALUE (t) = TYPE_MIN_VALUE (unsigned_type_node); + TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (unsigned_type_node); /* Enable us to recognize when a type is created in class context. To do nested classes correctly, this should probably be cleared out when we leave this classes scope. Currently this in only done in `start_enum'. */ - pushtag (name, ref, globalize); + pushtag (name, t, globalize); } else { - struct cp_binding_level *old_b = class_binding_level; - - ref = make_aggr_type (code); - TYPE_CONTEXT (ref) = context; - pushtag (name, ref, globalize); - class_binding_level = old_b; + t = make_aggr_type (code); + TYPE_CONTEXT (t) = context; + pushtag (name, t, globalize); } } else { - if (!globalize && processing_template_decl && IS_AGGR_TYPE (ref)) - redeclare_class_template (ref, current_template_parms); + if (!globalize && processing_template_decl && IS_AGGR_TYPE (t)) + redeclare_class_template (t, current_template_parms); } - TYPE_ATTRIBUTES (ref) = attributes; + TYPE_ATTRIBUTES (t) = attributes; - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, ref); + POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t); } tree @@ -12806,7 +12696,7 @@ xref_tag_from_type (tree old, tree id, int globalize) if (id == NULL_TREE) id = TYPE_IDENTIFIER (old); - return xref_tag (tag_kind, id, /*attributes=*/NULL_TREE, globalize); + return xref_tag (tag_kind, id, /*attributes=*/NULL_TREE, globalize, false); } /* REF is a type (named NAME), for which we have just seen some @@ -12826,6 +12716,9 @@ xref_basetypes (tree ref, tree base_list) int i; enum tag_types tag_code; + if (ref == error_mark_node) + return; + if (TREE_CODE (ref) == UNION_TYPE) { error ("derived union `%T' invalid", ref); @@ -13004,8 +12897,7 @@ start_enum (tree name) if (enumtype != NULL_TREE && TREE_CODE (enumtype) == ENUMERAL_TYPE) { error ("multiple definition of `%#T'", enumtype); - error ("%Hprevious definition here", - &DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (enumtype))); + error ("%Jprevious definition here", TYPE_MAIN_DECL (enumtype)); /* Clear out TYPE_VALUES, and start again. */ TYPE_VALUES (enumtype) = NULL_TREE; } @@ -13025,7 +12917,9 @@ start_enum (tree name) void finish_enum (tree enumtype) { - tree pair; + tree values; + tree decl; + tree value; tree minnode; tree maxnode; tree t; @@ -13033,6 +12927,8 @@ finish_enum (tree enumtype) int lowprec; int highprec; int precision; + integer_type_kind itk; + tree underlying_type = NULL_TREE; /* We built up the VALUES in reverse order. */ TYPE_VALUES (enumtype) = nreverse (TYPE_VALUES (enumtype)); @@ -13043,21 +12939,25 @@ finish_enum (tree enumtype) works. */ if (processing_template_decl) { - for (pair = TYPE_VALUES (enumtype); pair; pair = TREE_CHAIN (pair)) - TREE_TYPE (TREE_VALUE (pair)) = enumtype; + for (values = TYPE_VALUES (enumtype); + values; + values = TREE_CHAIN (values)) + TREE_TYPE (TREE_VALUE (values)) = enumtype; if (at_function_scope_p ()) add_stmt (build_min (TAG_DEFN, enumtype)); return; } + /* Determine the minimum and maximum values of the enumerators. */ if (TYPE_VALUES (enumtype)) { minnode = maxnode = NULL_TREE; - for (pair = TYPE_VALUES (enumtype); pair; pair = TREE_CHAIN (pair)) + for (values = TYPE_VALUES (enumtype); + values; + values = TREE_CHAIN (values)) { - tree decl = TREE_VALUE (pair); - tree value = DECL_INITIAL (decl); + decl = TREE_VALUE (values); /* [dcl.enum]: Following the closing brace of an enum-specifier, each enumerator has the type of its enumeration. Prior to the @@ -13065,6 +12965,8 @@ finish_enum (tree enumtype) initializing value. */ TREE_TYPE (decl) = enumtype; + /* Update the minimum and maximum values, if appropriate. */ + value = DECL_INITIAL (decl); /* Figure out what the minimum and maximum values of the enumerators are. */ if (!minnode) @@ -13083,13 +12985,13 @@ finish_enum (tree enumtype) value = DECL_INITIAL (decl) = copy_node (value); TREE_TYPE (value) = enumtype; } - - /* In addition, transform the TYPE_VALUES list to contain the - values, rather than the CONST_DECLs for them. */ - TREE_VALUE (pair) = value; } } else + /* [dcl.enum] + + If the enumerator-list is empty, the underlying type is as if + the enumeration had a single enumerator with value 0. */ minnode = maxnode = integer_zero_node; /* Compute the number of bits require to represent all values of the @@ -13101,35 +13003,75 @@ finish_enum (tree enumtype) highprec = min_precision (maxnode, unsignedp); precision = MAX (lowprec, highprec); - /* DR 377 - - IF no integral type can represent all the enumerator values, the - enumeration is ill-formed. */ - if (precision > TYPE_PRECISION (long_long_integer_type_node)) + /* Determine the underlying type of the enumeration. + + [dcl.enum] + + The underlying type of an enumeration is an integral type that + can represent all the enumerator values defined in the + enumeration. It is implementation-defined which integral type is + used as the underlying type for an enumeration except that the + underlying type shall not be larger than int unless the value of + an enumerator cannot fit in an int or unsigned int. + + We use "int" or an "unsigned int" as the underlying type, even if + a smaller integral type would work, unless the user has + explicitly requested that we use the smallest possible type. */ + for (itk = (flag_short_enums ? itk_char : itk_int); + itk != itk_none; + itk++) + { + underlying_type = integer_types[itk]; + if (TYPE_PRECISION (underlying_type) >= precision + && TREE_UNSIGNED (underlying_type) == unsignedp) + break; + } + if (itk == itk_none) { + /* DR 377 + + IF no integral type can represent all the enumerator values, the + enumeration is ill-formed. */ error ("no integral type can represent all of the enumerator values " "for `%T'", enumtype); precision = TYPE_PRECISION (long_long_integer_type_node); + underlying_type = integer_types[itk_unsigned_long_long]; } - /* Compute the minium and maximum values for the type, the size of - the type, and so forth. */ - TYPE_PRECISION (enumtype) = precision; - TYPE_SIZE (enumtype) = NULL_TREE; - if (unsignedp) - fixup_unsigned_type (enumtype); - else - fixup_signed_type (enumtype); + /* Compute the minium and maximum values for the type. - /* We use "int" or "unsigned int" as the underlying type, unless all - the values will not fit or the user has requested that we try to - use shorter types where possible. */ - if (precision < TYPE_PRECISION (integer_type_node) - && !flag_short_enums) - { - TYPE_PRECISION (enumtype) = TYPE_PRECISION (integer_type_node); - TYPE_SIZE (enumtype) = NULL_TREE; - layout_type (enumtype); + [dcl.enum] + + For an enumeration where emin is the smallest enumerator and emax + is the largest, the values of the enumeration are the values of the + underlying type in the range bmin to bmax, where bmin and bmax are, + respectively, the smallest and largest values of the smallest bit- + field that can store emin and emax. */ + TYPE_PRECISION (enumtype) = precision; + set_min_and_max_values_for_integral_type (enumtype, precision, unsignedp); + + /* [dcl.enum] + + The value of sizeof() applied to an enumeration type, an object + of an enumeration type, or an enumerator, is the value of sizeof() + applied to the underlying type. */ + TYPE_SIZE (enumtype) = TYPE_SIZE (underlying_type); + TYPE_SIZE_UNIT (enumtype) = TYPE_SIZE_UNIT (underlying_type); + TYPE_MODE (enumtype) = TYPE_MODE (underlying_type); + TYPE_ALIGN (enumtype) = TYPE_ALIGN (underlying_type); + TYPE_USER_ALIGN (enumtype) = TYPE_USER_ALIGN (underlying_type); + TREE_UNSIGNED (enumtype) = TREE_UNSIGNED (underlying_type); + + /* Convert each of the enumerators to the type of the underlying + type of the enumeration. */ + for (values = TYPE_VALUES (enumtype); values; values = TREE_CHAIN (values)) + { + decl = TREE_VALUE (values); + value = perform_implicit_conversion (underlying_type, + DECL_INITIAL (decl)); + TREE_TYPE (value) = enumtype; + DECL_INITIAL (decl) = value; + TREE_VALUE (values) = value; } /* Fix up all variant types of this enum type. */ @@ -13212,6 +13154,8 @@ build_enumerator (tree name, tree value, tree enumtype) /* C++ associates enums with global, function, or class declarations. */ context = current_scope (); + if (!context) + context = current_namespace; /* Build the actual enumeration constant. Note that the enumeration constants have the type of their initializers until the @@ -13243,8 +13187,8 @@ build_enumerator (tree name, tree value, tree enumtype) if (context && context == current_class_type) /* In something like `struct S { enum E { i = 7 }; };' we put `i' - on the TYPE_FIELDS list for `S'. (That's so that you can say - things like `S::i' later.) */ + on the TYPE_FIELDS list for `S'. (That's so that you can say + things like `S::i' later.) */ finish_member_declaration (decl); else pushdecl (decl); @@ -13275,9 +13219,9 @@ check_function_type (tree decl, tree current_function_parms) { tree ctype = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (fntype))); TREE_TYPE (decl) - = build_cplus_method_type (ctype, - void_type_node, - FUNCTION_ARG_CHAIN (decl)); + = build_method_type_directly (ctype, + void_type_node, + FUNCTION_ARG_CHAIN (decl)); } else TREE_TYPE (decl) @@ -13377,20 +13321,6 @@ start_function (tree declspecs, tree declarator, tree attrs, int flags) fntype = TREE_TYPE (decl1); restype = TREE_TYPE (fntype); - if (CLASS_TYPE_P (restype) && !CLASSTYPE_GOT_SEMICOLON (restype)) - { - error ("semicolon missing after declaration of `%#T'", restype); - shadow_tag (build_tree_list (NULL_TREE, restype)); - CLASSTYPE_GOT_SEMICOLON (restype) = 1; - if (TREE_CODE (fntype) == FUNCTION_TYPE) - fntype = build_function_type (integer_type_node, - TYPE_ARG_TYPES (fntype)); - else - fntype = build_cplus_method_type (build_type_variant (TYPE_METHOD_BASETYPE (fntype), TREE_READONLY (decl1), TREE_SIDE_EFFECTS (decl1)), - integer_type_node, - TYPE_ARG_TYPES (fntype)); - TREE_TYPE (decl1) = fntype; - } if (TREE_CODE (fntype) == METHOD_TYPE) ctype = TYPE_METHOD_BASETYPE (fntype); @@ -13409,8 +13339,7 @@ start_function (tree declspecs, tree declarator, tree attrs, int flags) if (DECL_DECLARED_INLINE_P (decl1) && lookup_attribute ("noinline", attrs)) - warning ("%Hinline function '%D' given attribute noinline", - &DECL_SOURCE_LOCATION (decl1), decl1); + warning ("%Jinline function '%D' given attribute noinline", decl1, decl1); if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (decl1)) /* This is a constructor, we must ensure that any default args @@ -13504,7 +13433,7 @@ start_function (tree declspecs, tree declarator, tree attrs, int flags) CFUN set up, and our per-function variables initialized. FIXME factor out the non-RTL stuff. */ bl = current_binding_level; - init_function_start (decl1); + allocate_struct_function (decl1); current_binding_level = bl; /* Even though we're inside a function body, we still don't want to @@ -13653,8 +13582,7 @@ start_function (tree declspecs, tree declarator, tree attrs, int flags) DECL_INTERFACE_KNOWN (decl1) = 1; } - pushlevel (0); - current_binding_level->parm_flag = 1; + begin_scope (sk_function_parms); ++function_depth; @@ -13764,8 +13692,7 @@ save_function_data (tree decl) 19990908); /* Make a copy. */ - f = ((struct language_function *) - ggc_alloc (sizeof (struct language_function))); + f = ggc_alloc (sizeof (struct language_function)); memcpy (f, cp_function_chain, sizeof (struct language_function)); DECL_SAVED_FUNCTION_DATA (decl) = f; @@ -13776,9 +13703,6 @@ save_function_data (tree decl) f->bindings = NULL; f->x_local_names = NULL; - /* When we get back here again, we will be expanding. */ - f->x_expanding_p = 1; - /* If we've already decided that we cannot inline this function, we must remember that fact when we actually go to expand the function. */ @@ -13838,14 +13762,14 @@ begin_destructor_body (void) initialize the vtables.) */ finish_if_stmt_cond (boolean_true_node, if_stmt); - compound_stmt = begin_compound_stmt (/*has_no_scope=*/0); + compound_stmt = begin_compound_stmt (/*has_no_scope=*/false); /* Make all virtual function table pointers in non-virtual base classes point to CURRENT_CLASS_TYPE's virtual function tables. */ initialize_vtbl_ptrs (current_class_ptr); - finish_compound_stmt (/*has_no_scope=*/0, compound_stmt); + finish_compound_stmt (compound_stmt); finish_then_clause (if_stmt); finish_if_stmt (); @@ -13912,7 +13836,7 @@ begin_function_body (void) operation of dwarfout.c. */ keep_next_level (1); - stmt = begin_compound_stmt (0); + stmt = begin_compound_stmt (/*has_no_scope=*/false); COMPOUND_STMT_BODY_BLOCK (stmt) = 1; if (processing_template_decl) @@ -13938,7 +13862,7 @@ void finish_function_body (tree compstmt) { /* Close the block. */ - finish_compound_stmt (0, compstmt); + finish_compound_stmt (compstmt); if (processing_template_decl) /* Do nothing now. */; @@ -14030,7 +13954,7 @@ finish_function (int flags) /* If the current binding level isn't the outermost binding level for this function, either there is a bug, or we have experienced syntax errors and the statement tree is malformed. */ - if (current_binding_level->parm_flag != 1) + if (current_binding_level->kind != sk_function_parms) { /* Make sure we have already experienced errors. */ if (errorcount == 0) @@ -14040,9 +13964,9 @@ finish_function (int flags) levels. */ DECL_SAVED_TREE (fndecl) = build_stmt (COMPOUND_STMT, NULL_TREE); - while (current_binding_level->parm_flag != 1) + while (current_binding_level->kind != sk_function_parms) { - if (current_binding_level->parm_flag == 2) + if (current_binding_level->kind == sk_class) pop_nested_class (); else poplevel (0, 0, 0); @@ -14050,6 +13974,10 @@ finish_function (int flags) } poplevel (1, 0, 1); + /* Statements should always be full-expressions at the outermost set + of curly braces for a function. */ + my_friendly_assert (stmts_are_full_exprs_p (), 19990831); + /* Set up the named return value optimization, if we can. Here, we eliminate the copy from the nrv into the RESULT_DECL and any cleanup for the nrv. genrtl_start_function and declare_return_variable @@ -14062,7 +13990,7 @@ finish_function (int flags) if (r != error_mark_node /* This is only worth doing for fns that return in memory--and simpler, since we don't have to worry about promoted modes. */ - && aggregate_value_p (TREE_TYPE (TREE_TYPE (fndecl))) + && aggregate_value_p (TREE_TYPE (TREE_TYPE (fndecl)), fndecl) /* Only allow this for variables declared in the outer scope of the function so we know that their lifetime always ends with a return; see g++.dg/opt/nrv6.C. We could be more flexible if @@ -14120,13 +14048,11 @@ finish_function (int flags) inline function, as we might never be compiled separately. */ && (DECL_INLINE (fndecl) || processing_template_decl)) warning ("no return statement in function returning non-void"); - - /* Clear out memory we no longer need. */ - free_after_parsing (cfun); - /* Since we never call rest_of_compilation, we never clear - CFUN. Do so explicitly. */ - free_after_compilation (cfun); + + /* We're leaving the context of this function, so zap cfun. It's still in + DECL_SAVED_INSNS, and we'll restore it in tree_rest_of_compilation. */ cfun = NULL; + current_function_decl = NULL; /* If this is an in-class inline definition, we may have to pop the bindings for the template parameters that we added in @@ -14209,14 +14135,16 @@ start_method (tree declspecs, tree declarator, tree attrlist) check_template_shadow (fndecl); DECL_DECLARED_INLINE_P (fndecl) = 1; - - DID_INLINE_FUNC (fndecl) = 0; if (flag_default_inline) DECL_INLINE (fndecl) = 1; /* We process method specializations in finish_struct_1. */ if (processing_template_decl && !DECL_TEMPLATE_SPECIALIZATION (fndecl)) - fndecl = push_template_decl (fndecl); + { + fndecl = push_template_decl (fndecl); + if (fndecl == error_mark_node) + return fndecl; + } if (! DECL_FRIEND_P (fndecl)) { @@ -14231,8 +14159,7 @@ start_method (tree declspecs, tree declarator, tree attrlist) cp_finish_decl (fndecl, NULL_TREE, NULL_TREE, 0); /* Make a place for the parms */ - pushlevel (0); - current_binding_level->parm_flag = 1; + begin_scope (sk_function_parms); DECL_IN_AGGR_P (fndecl) = 1; return fndecl; @@ -14382,8 +14309,7 @@ cxx_maybe_build_cleanup (tree decl) if (TYPE_USES_VIRTUAL_BASECLASSES (type) && ! TYPE_HAS_DESTRUCTOR (type)) - rval = build_compound_expr (tree_cons (NULL_TREE, rval, - build_tree_list (NULL_TREE, build_vbase_delete (type, decl)))); + rval = build_compound_expr (rval, build_vbase_delete (type, decl)); return rval; } @@ -14434,17 +14360,37 @@ void cxx_push_function_context (struct function * f) { struct language_function *p - = ((struct language_function *) - ggc_alloc_cleared (sizeof (struct language_function))); + = ggc_alloc_cleared (sizeof (struct language_function)); f->language = p; - /* It takes an explicit call to expand_body to generate RTL for a - function. */ - expanding_p = 0; - /* Whenever we start a new function, we destroy temporaries in the usual way. */ current_stmt_tree ()->stmts_are_full_exprs_p = 1; + + if (f->decl) + { + tree fn = f->decl; + + current_function_is_thunk = DECL_THUNK_P (fn); + + if (DECL_SAVED_FUNCTION_DATA (fn)) + { + /* If we already parsed this function, and we're just expanding it + now, restore saved state. */ + *cp_function_chain = *DECL_SAVED_FUNCTION_DATA (fn); + + /* If we decided that we didn't want to inline this function, + make sure the back-end knows that. */ + if (!current_function_cannot_inline) + current_function_cannot_inline = cp_function_chain->cannot_inline; + + /* We don't need the saved data anymore. Unless this is an inline + function; we need the named return value info for + cp_copy_res_decl_for_inlining. */ + if (! DECL_INLINE (fn)) + DECL_SAVED_FUNCTION_DATA (fn) = NULL; + } + } } /* Free the language-specific parts of F, now that we've finished |