X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fcp%2Fdecl.c;h=7e38ec3dff1f3e5f83fe553ca78a6da29e6a13df;hb=97b5d56a27d8144ba069cca825ba2503f566d6fc;hp=47732cb6bc8112625dc47632106686704faf7b6a;hpb=a1212c35003bd4ab215b2710a357346e6563488d;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 47732cb6bc8..7e38ec3dff1 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -17,8 +17,8 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GCC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ +the Free Software Foundation, 51 Franklin Street, Fifth Floor, +Boston, MA 02110-1301, USA. */ /* Process declarations and symbol lookup for C++ front end. @@ -66,7 +66,7 @@ static tree grokvardecl (tree, tree, const cp_decl_specifier_seq *, static void record_unknown_type (tree, const char *); static tree builtin_function_1 (const char *, tree, tree, enum built_in_function code, - enum built_in_class cl, const char *, + enum built_in_class cl, const char *, tree); static tree build_library_fn_1 (tree, enum tree_code, tree); static int member_function_or_else (tree, tree, enum overload_flags); @@ -114,7 +114,7 @@ static void store_parm_decls (tree); static void initialize_local_var (tree, tree); static void expand_static_init (tree, tree); static tree next_initializable_field (tree); -static tree reshape_init (tree, tree *); +static tree reshape_init (tree, tree); /* Erroneous argument lists can use this *IFF* they do not modify it. */ tree error_mark_list; @@ -128,12 +128,6 @@ tree error_mark_list; tree vtable_entry_type; tree delta_type_node; tree __t_desc_type_node; - tree ti_desc_type_node; - tree bltn_desc_type_node, ptr_desc_type_node; - tree ary_desc_type_node, func_desc_type_node, enum_desc_type_node; - tree class_desc_type_node, si_class_desc_type_node, vmi_class_desc_type_node; - tree ptm_desc_type_node; - tree base_desc_type_node; tree class_type_node; tree unknown_type_node; @@ -306,7 +300,7 @@ current_tmpl_spec_kind (int n_class_scopes) /* We've not seen enough template headers to match all the specialized classes present. For example: - template void R::S::f(int); + template void R::S::f(int); This is invalid; there needs to be one set of template parameters for each class. */ @@ -315,7 +309,7 @@ current_tmpl_spec_kind (int n_class_scopes) /* We're processing a non-template declaration (even though it may be a member of a template class.) For example: - template void S::f(int); + template void S::f(int); The `class T' maches the `S', leaving no template headers corresponding to the `f'. */ @@ -323,14 +317,14 @@ current_tmpl_spec_kind (int n_class_scopes) else if (n_template_parm_scopes > n_class_scopes + 1) /* We've got too many template headers. For example: - template <> template void f (T); + template <> template void f (T); There need to be more enclosing classes. */ return tsk_excessive_parms; else /* This must be a template. It's of the form: - template template void S::f(U); + template template void S::f(U); This is a specialization if the innermost level was a specialization; otherwise it's just a definition of the @@ -358,18 +352,18 @@ pop_label (tree label, tree old_value) { location_t location; - cp_error_at ("label %qD used but not defined", label); + error ("label %q+D used but not defined", label); #ifdef USE_MAPPED_LOCATION location = input_location; /* FIXME want (input_filename, (line)0) */ #else - location.file = input_filename; + location.file = input_filename; location.line = 0; #endif /* Avoid crashing later. */ define_label (location, DECL_NAME (label)); } else if (warn_unused_label && !TREE_USED (label)) - cp_warning_at ("label %qD defined but not used", label); + warning (0, "label %q+D defined but not used", label); } SET_IDENTIFIER_LABEL_VALUE (DECL_NAME (label), old_value); @@ -419,19 +413,17 @@ objc_mark_locals_volatile (void *enclosing_blk) struct cp_binding_level *scope; for (scope = current_binding_level; - scope && scope != enclosing_blk && scope->kind == sk_block; + scope && scope != enclosing_blk; scope = scope->level_chain) { tree decl; for (decl = scope->names; decl; decl = TREE_CHAIN (decl)) - { - if (TREE_CODE (decl) == VAR_DECL) - { - DECL_REGISTER (decl) = 0; - TREE_THIS_VOLATILE (decl) = 1; - } - } + objc_volatilize_decl (decl); + + /* Do not climb up past the current function. */ + if (scope->kind == sk_function_parms) + break; } } @@ -565,13 +557,13 @@ poplevel (int keep, int reverse, int functionbody) && ! TREE_USED (decl) && ! DECL_IN_SYSTEM_HEADER (decl) && DECL_NAME (decl) && ! DECL_ARTIFICIAL (decl)) - warning ("%Junused variable %qD", decl, decl); + warning (0, "unused variable %q+D", decl); /* Remove declarations for all the DECLs in this level. */ for (link = decls; link; link = TREE_CHAIN (link)) { if (leaving_for_scope && TREE_CODE (link) == VAR_DECL - && DECL_NAME (link)) + && DECL_NAME (link)) { tree name = DECL_NAME (link); cxx_binding *ob; @@ -588,8 +580,8 @@ poplevel (int keep, int reverse, int functionbody) if (ob && ob->scope == current_binding_level->level_chain) /* We have something like: - int i; - for (int i; ;); + int i; + for (int i; ;); and we are leaving the `for' scope. There's no reason to keep the binding of the inner `i' in this case. */ @@ -616,7 +608,10 @@ poplevel (int keep, int reverse, int functionbody) /* Keep track of what should have happened when we popped the binding. */ if (ob && ob->value) - DECL_SHADOWED_FOR_VAR (link) = ob->value; + { + SET_DECL_SHADOWED_FOR_VAR (link, ob->value); + DECL_HAS_SHADOWED_FOR_VAR_P (link) = 1; + } /* Add it to the list of dead variables in the next outermost binding to that we can remove these when we @@ -635,14 +630,14 @@ poplevel (int keep, int reverse, int functionbody) else { tree name; - + /* Remove the binding. */ decl = link; if (TREE_CODE (decl) == TREE_LIST) decl = TREE_VALUE (decl); name = decl; - + if (TREE_CODE (name) == OVERLOAD) name = OVL_FUNCTION (name); @@ -786,14 +781,15 @@ int wrapup_globals_for_namespace (tree namespace, void* data) { struct cp_binding_level *level = NAMESPACE_LEVEL (namespace); - varray_type statics = level->static_decls; - tree *vec = &VARRAY_TREE (statics, 0); - int len = VARRAY_ACTIVE_SIZE (statics); + VEC(tree,gc) *statics = level->static_decls; + tree *vec = VEC_address (tree, statics); + int len = VEC_length (tree, statics); int last_time = (data != 0); if (last_time) { check_global_declarations (vec, len); + emit_debug_global_declarations (vec, len); return 0; } @@ -832,15 +828,13 @@ push_local_name (tree decl) tree t, name; timevar_push (TV_NAME_LOOKUP); - if (!local_names) - VARRAY_TREE_INIT (local_names, 8, "local_names"); name = DECL_NAME (decl); - nelts = VARRAY_ACTIVE_SIZE (local_names); + nelts = VEC_length (tree, local_names); for (i = 0; i < nelts; i++) { - t = VARRAY_TREE (local_names, i); + t = VEC_index (tree, local_names, i); if (DECL_NAME (t) == name) { if (!DECL_LANG_SPECIFIC (decl)) @@ -851,13 +845,13 @@ push_local_name (tree decl) else DECL_DISCRIMINATOR (decl) = 1; - VARRAY_TREE (local_names, i) = decl; + VEC_replace (tree, local_names, i, decl); timevar_pop (TV_NAME_LOOKUP); return; } } - VARRAY_PUSH_TREE (local_names, decl); + VEC_safe_push (tree, gc, local_names, decl); timevar_pop (TV_NAME_LOOKUP); } @@ -894,15 +888,15 @@ decls_match (tree newdecl, tree olddecl) return 0; if (TREE_CODE (f1) != TREE_CODE (f2)) - return 0; + return 0; if (same_type_p (TREE_TYPE (f1), TREE_TYPE (f2))) { if (p2 == NULL_TREE && DECL_EXTERN_C_P (olddecl) && (DECL_BUILT_IN (olddecl) #ifndef NO_IMPLICIT_EXTERN_C - || (DECL_IN_SYSTEM_HEADER (newdecl) && !DECL_CLASS_SCOPE_P (newdecl)) - || (DECL_IN_SYSTEM_HEADER (olddecl) && !DECL_CLASS_SCOPE_P (olddecl)) + || (DECL_IN_SYSTEM_HEADER (newdecl) && !DECL_CLASS_SCOPE_P (newdecl)) + || (DECL_IN_SYSTEM_HEADER (olddecl) && !DECL_CLASS_SCOPE_P (olddecl)) #endif )) { @@ -913,11 +907,11 @@ decls_match (tree newdecl, tree olddecl) #ifndef NO_IMPLICIT_EXTERN_C else if (p1 == NULL_TREE && (DECL_EXTERN_C_P (olddecl) - && DECL_IN_SYSTEM_HEADER (olddecl) - && !DECL_CLASS_SCOPE_P (olddecl)) + && DECL_IN_SYSTEM_HEADER (olddecl) + && !DECL_CLASS_SCOPE_P (olddecl)) && (DECL_EXTERN_C_P (newdecl) - && DECL_IN_SYSTEM_HEADER (newdecl) - && !DECL_CLASS_SCOPE_P (newdecl))) + && DECL_IN_SYSTEM_HEADER (newdecl) + && !DECL_CLASS_SCOPE_P (newdecl))) { types_match = self_promoting_args_p (p2); TREE_TYPE (newdecl) = TREE_TYPE (olddecl); @@ -948,6 +942,12 @@ decls_match (tree newdecl, tree olddecl) } else { + /* Need to check scope for variable declaration (VAR_DECL). + For typedef (TYPE_DECL), scope is ignored. */ + if (TREE_CODE (newdecl) == VAR_DECL + && CP_DECL_CONTEXT (newdecl) != CP_DECL_CONTEXT (olddecl)) + return 0; + if (TREE_TYPE (newdecl) == error_mark_node) types_match = TREE_TYPE (olddecl) == error_mark_node; else if (TREE_TYPE (olddecl) == NULL_TREE) @@ -1001,7 +1001,7 @@ warn_extern_redeclared_static (tree newdecl, tree olddecl) name = DECL_ASSEMBLER_NAME (newdecl); pedwarn ("%qD was declared % and later %", newdecl); - cp_pedwarn_at ("previous declaration of %qD", olddecl); + pedwarn ("previous declaration of %q+D", olddecl); } /* If NEWDECL is a redeclaration of OLDDECL, merge the declarations. @@ -1009,13 +1009,15 @@ warn_extern_redeclared_static (tree newdecl, tree olddecl) error_mark_node is returned. Otherwise, OLDDECL is returned. If NEWDECL is not a redeclaration of OLDDECL, NULL_TREE is - returned. */ + returned. + + NEWDECL_IS_FRIEND is true if NEWDECL was declared as a friend. */ tree -duplicate_decls (tree newdecl, tree olddecl) +duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) { unsigned olddecl_uid = DECL_UID (olddecl); - int olddecl_friend = 0, types_match = 0; + int olddecl_friend = 0, types_match = 0, hidden_friend = 0; int new_defines_function = 0; if (newdecl == olddecl) @@ -1049,18 +1051,19 @@ duplicate_decls (tree newdecl, tree olddecl) && DECL_UNINLINABLE (olddecl) && lookup_attribute ("noinline", DECL_ATTRIBUTES (olddecl))) { - warning ("%Jfunction %qD redeclared as inline", newdecl, newdecl); - warning ("%Jprevious declaration of %qD with attribute noinline", - olddecl, olddecl); + warning (OPT_Wattributes, "function %q+D redeclared as inline", + newdecl); + warning (OPT_Wattributes, "previous declaration of %q+D " + "with attribute noinline", olddecl); } else if (DECL_DECLARED_INLINE_P (olddecl) && DECL_UNINLINABLE (newdecl) && lookup_attribute ("noinline", DECL_ATTRIBUTES (newdecl))) { - warning ("%Jfunction %qD redeclared with attribute noinline", - newdecl, newdecl); - warning ("%Jprevious declaration of %qD was inline", - olddecl, olddecl); + warning (OPT_Wattributes, "function %q+D redeclared with " + "attribute noinline", newdecl); + warning (OPT_Wattributes, "previous declaration of %q+D was inline", + olddecl); } } @@ -1068,11 +1071,13 @@ duplicate_decls (tree newdecl, tree olddecl) if (TREE_CODE (olddecl) == FUNCTION_DECL && DECL_ARTIFICIAL (olddecl)) { + gcc_assert (!DECL_HIDDEN_FRIEND_P (olddecl)); if (TREE_CODE (newdecl) != FUNCTION_DECL) { - /* Avoid warnings redeclaring anticipated built-ins. */ - if (DECL_ANTICIPATED (olddecl)) - return NULL_TREE; + /* Avoid warnings redeclaring built-ins which have not been + explicitly declared. */ + if (DECL_ANTICIPATED (olddecl)) + return NULL_TREE; /* If you declare a built-in or predefined function name as static, the old definition is overridden, but optionally warn this was a @@ -1080,29 +1085,30 @@ duplicate_decls (tree newdecl, tree olddecl) if (! TREE_PUBLIC (newdecl)) { if (warn_shadow) - warning ("shadowing %s function %q#D", - DECL_BUILT_IN (olddecl) ? "built-in" : "library", - olddecl); + warning (0, "shadowing %s function %q#D", + DECL_BUILT_IN (olddecl) ? "built-in" : "library", + olddecl); /* Discard the old built-in function. */ return NULL_TREE; } /* If the built-in is not ansi, then programs can override it even globally without an error. */ else if (! DECL_BUILT_IN (olddecl)) - warning ("library function %q#D redeclared as non-function %q#D", - olddecl, newdecl); + warning (0, "library function %q#D redeclared as non-function %q#D", + olddecl, newdecl); else { error ("declaration of %q#D", newdecl); error ("conflicts with built-in declaration %q#D", - olddecl); + olddecl); } return NULL_TREE; } else if (!types_match) { - /* Avoid warnings redeclaring anticipated built-ins. */ - if (DECL_ANTICIPATED (olddecl)) + /* Avoid warnings redeclaring built-ins which have not been + explicitly declared. */ + if (DECL_ANTICIPATED (olddecl)) { /* Deal with fileptr_type_node. FILE type is not known at the time we create the builtins. */ @@ -1130,7 +1136,8 @@ duplicate_decls (tree newdecl, tree olddecl) = TYPE_ARG_TYPES (TREE_TYPE (newdecl)); types_match = decls_match (newdecl, olddecl); if (types_match) - return duplicate_decls (newdecl, olddecl); + return duplicate_decls (newdecl, olddecl, + newdecl_is_friend); TYPE_ARG_TYPES (TREE_TYPE (olddecl)) = oldargs; } } @@ -1146,14 +1153,14 @@ duplicate_decls (tree newdecl, tree olddecl) if (TREE_PUBLIC (newdecl)) { - warning ("new declaration %q#D", newdecl); - warning ("ambiguates built-in declaration %q#D", - olddecl); + warning (0, "new declaration %q#D", newdecl); + warning (0, "ambiguates built-in declaration %q#D", + olddecl); } else if (warn_shadow) - warning ("shadowing %s function %q#D", - DECL_BUILT_IN (olddecl) ? "built-in" : "library", - olddecl); + warning (0, "shadowing %s function %q#D", + DECL_BUILT_IN (olddecl) ? "built-in" : "library", + olddecl); } else /* Discard the old built-in function. */ @@ -1162,8 +1169,9 @@ duplicate_decls (tree newdecl, tree olddecl) /* Replace the old RTL to avoid problems with inlining. */ COPY_DECL_RTL (newdecl, olddecl); } - /* Even if the types match, prefer the new declarations type - for anticipated built-ins, for exception lists, etc... */ + /* Even if the types match, prefer the new declarations type for + built-ins which have not been explicitly declared, for + exception lists, etc... */ else if (DECL_ANTICIPATED (olddecl)) { tree type = TREE_TYPE (newdecl); @@ -1221,7 +1229,7 @@ duplicate_decls (tree newdecl, tree olddecl) error ("%q#D redeclared as different kind of symbol", newdecl); if (TREE_CODE (olddecl) == TREE_LIST) olddecl = TREE_VALUE (olddecl); - cp_error_at ("previous declaration of %q#D", olddecl); + error ("previous declaration of %q+#D", olddecl); return error_mark_node; } @@ -1241,8 +1249,7 @@ duplicate_decls (tree newdecl, tree olddecl) || TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) == TYPE_DECL) { error ("declaration of template %q#D", newdecl); - cp_error_at ("conflicts with previous declaration %q#D", - olddecl); + error ("conflicts with previous declaration %q+#D", olddecl); } else if (TREE_CODE (DECL_TEMPLATE_RESULT (olddecl)) == FUNCTION_DECL && TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) == FUNCTION_DECL @@ -1256,7 +1263,7 @@ duplicate_decls (tree newdecl, tree olddecl) TREE_TYPE (TREE_TYPE (olddecl)))) { error ("new declaration %q#D", newdecl); - cp_error_at ("ambiguates old declaration %q#D", olddecl); + error ("ambiguates old declaration %q+#D", olddecl); } return NULL_TREE; } @@ -1265,14 +1272,14 @@ duplicate_decls (tree newdecl, tree olddecl) if (DECL_EXTERN_C_P (newdecl) && DECL_EXTERN_C_P (olddecl)) { error ("declaration of C function %q#D conflicts with", - newdecl); - cp_error_at ("previous declaration %q#D here", olddecl); + newdecl); + error ("previous declaration %q+#D here", olddecl); } else if (compparms (TYPE_ARG_TYPES (TREE_TYPE (newdecl)), TYPE_ARG_TYPES (TREE_TYPE (olddecl)))) { error ("new declaration %q#D", newdecl); - cp_error_at ("ambiguates old declaration %q#D", olddecl); + error ("ambiguates old declaration %q+#D", olddecl); } else return NULL_TREE; @@ -1280,9 +1287,8 @@ duplicate_decls (tree newdecl, tree olddecl) else { error ("conflicting declaration %q#D", newdecl); - cp_error_at ("%qD has a previous declaration as %q#D", - olddecl, olddecl); - return error_mark_node; + error ("%q+D has a previous declaration as %q#D", olddecl, olddecl); + return error_mark_node; } } else if (TREE_CODE (newdecl) == FUNCTION_DECL @@ -1314,27 +1320,27 @@ duplicate_decls (tree newdecl, tree olddecl) else if (TREE_CODE (newdecl) == NAMESPACE_DECL) { /* In [namespace.alias] we have: - - In a declarative region, a namespace-alias-definition can be + + In a declarative region, a namespace-alias-definition can be used to redefine a namespace-alias declared in that declarative region to refer only to the namespace to which it already refers. - + Therefore, if we encounter a second alias directive for the same alias, we can just ignore the second directive. */ if (DECL_NAMESPACE_ALIAS (newdecl) - && (DECL_NAMESPACE_ALIAS (newdecl) + && (DECL_NAMESPACE_ALIAS (newdecl) == DECL_NAMESPACE_ALIAS (olddecl))) return olddecl; /* [namespace.alias] - A namespace-name or namespace-alias shall not be declared as + A namespace-name or namespace-alias shall not be declared as the name of any other entity in the same declarative region. A namespace-name defined at global scope shall not be declared as the name of any other entity in any global scope of the program. */ error ("declaration of namespace %qD conflicts with", newdecl); - cp_error_at ("previous declaration of namespace %qD here", olddecl); + error ("previous declaration of namespace %q+D here", olddecl); return error_mark_node; } else @@ -1344,10 +1350,9 @@ duplicate_decls (tree newdecl, tree olddecl) { error (errmsg, newdecl); if (DECL_NAME (olddecl) != NULL_TREE) - cp_error_at ((DECL_INITIAL (olddecl) - && namespace_bindings_p ()) - ? "%q#D previously defined here" - : "%q#D previously declared here", olddecl); + error ((DECL_INITIAL (olddecl) && namespace_bindings_p ()) + ? "%q+#D previously defined here" + : "%q+#D previously declared here", olddecl); return error_mark_node; } else if (TREE_CODE (olddecl) == FUNCTION_DECL @@ -1356,8 +1361,8 @@ duplicate_decls (tree newdecl, tree olddecl) && TYPE_ARG_TYPES (TREE_TYPE (newdecl)) != NULL_TREE) { /* Prototype decl follows defn w/o prototype. */ - cp_warning_at ("prototype for %q#D", newdecl); - warning ("%Jfollows non-prototype definition here", olddecl); + warning (0, "prototype for %q+#D", newdecl); + warning (0, "%Jfollows non-prototype definition here", olddecl); } else if (TREE_CODE (olddecl) == FUNCTION_DECL && DECL_LANGUAGE (newdecl) != DECL_LANGUAGE (olddecl)) @@ -1369,10 +1374,10 @@ duplicate_decls (tree newdecl, tree olddecl) SET_DECL_LANGUAGE (newdecl, DECL_LANGUAGE (olddecl)); else { - cp_error_at ("previous declaration of %q#D with %qL linkage", - olddecl, DECL_LANGUAGE (olddecl)); + error ("previous declaration of %q+#D with %qL linkage", + olddecl, DECL_LANGUAGE (olddecl)); error ("conflicts with new declaration with %qL linkage", - DECL_LANGUAGE (newdecl)); + DECL_LANGUAGE (newdecl)); } } @@ -1396,14 +1401,13 @@ duplicate_decls (tree newdecl, tree olddecl) { pedwarn ("default argument given for parameter %d of %q#D", i, newdecl); - cp_pedwarn_at ("after previous specification in %q#D", - olddecl); + pedwarn ("after previous specification in %q+#D", olddecl); } else { error ("default argument given for parameter %d of %q#D", - i, newdecl); - cp_error_at ("after previous specification in %q#D", + i, newdecl); + error ("after previous specification in %q+#D", olddecl); } } @@ -1412,8 +1416,8 @@ duplicate_decls (tree newdecl, tree olddecl) && ! DECL_DECLARED_INLINE_P (olddecl) && TREE_ADDRESSABLE (olddecl) && warn_inline) { - warning ("%q#D was used before it was declared inline", newdecl); - warning ("%Jprevious non-inline declaration here", olddecl); + warning (0, "%q#D was used before it was declared inline", newdecl); + warning (0, "%Jprevious non-inline declaration here", olddecl); } } } @@ -1456,17 +1460,17 @@ duplicate_decls (tree newdecl, tree olddecl) new_defines_function = DECL_INITIAL (newdecl) != NULL_TREE; /* Optionally warn about more than one declaration for the same - name, but don't warn about a function declaration followed by a - definition. */ + name, but don't warn about a function declaration followed by a + definition. */ if (warn_redundant_decls && ! DECL_ARTIFICIAL (olddecl) && !(new_defines_function && DECL_INITIAL (olddecl) == NULL_TREE) /* Don't warn about extern decl followed by definition. */ && !(DECL_EXTERNAL (olddecl) && ! DECL_EXTERNAL (newdecl)) /* Don't warn about friends, let add_friend take care of it. */ - && ! (DECL_FRIEND_P (newdecl) || DECL_FRIEND_P (olddecl))) + && ! (newdecl_is_friend || DECL_FRIEND_P (olddecl))) { - warning ("redundant redeclaration of %qD in same scope", newdecl); - cp_warning_at ("previous declaration of %qD", olddecl); + warning (0, "redundant redeclaration of %qD in same scope", newdecl); + warning (0, "previous declaration of %q+D", olddecl); } } @@ -1538,6 +1542,8 @@ duplicate_decls (tree newdecl, tree olddecl) { DECL_THIS_EXTERN (newdecl) |= DECL_THIS_EXTERN (olddecl); DECL_INITIALIZED_P (newdecl) |= DECL_INITIALIZED_P (olddecl); + DECL_NONTRIVIALLY_INITIALIZED_P (newdecl) + |= DECL_NONTRIVIALLY_INITIALIZED_P (olddecl); DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (newdecl) |= DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (olddecl); } @@ -1557,11 +1563,11 @@ duplicate_decls (tree newdecl, tree olddecl) && ! DECL_IS_BUILTIN (olddecl) && flag_exceptions && !comp_except_specs (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (newdecl)), - TYPE_RAISES_EXCEPTIONS (TREE_TYPE (olddecl)), 1)) + TYPE_RAISES_EXCEPTIONS (TREE_TYPE (olddecl)), 1)) { error ("declaration of %qF throws different exceptions", - newdecl); - cp_error_at ("than previous declaration %qF", olddecl); + newdecl); + error ("than previous declaration %q+F", olddecl); } } TREE_TYPE (newdecl) = TREE_TYPE (olddecl) = newtype; @@ -1608,7 +1614,7 @@ duplicate_decls (tree newdecl, tree olddecl) } /* Merge the section attribute. - We want to issue an error if the sections conflict but that must be + We want to issue an error if the sections conflict but that must be done later in decl_attributes since we are called before attributes are assigned. */ if (DECL_SECTION_NAME (newdecl) == NULL_TREE) @@ -1669,13 +1675,14 @@ duplicate_decls (tree newdecl, tree olddecl) DECL_COMDAT (newdecl) |= DECL_COMDAT (olddecl); DECL_TEMPLATE_INSTANTIATED (newdecl) |= DECL_TEMPLATE_INSTANTIATED (olddecl); - /* If the OLDDECL is an implicit instantiation, then the NEWDECL - must be too. But, it may not yet be marked as such if the - caller has created NEWDECL, but has not yet figured out that - it is a redeclaration. */ - if (DECL_IMPLICIT_INSTANTIATION (olddecl) - && !DECL_USE_TEMPLATE (newdecl)) - SET_DECL_IMPLICIT_INSTANTIATION (newdecl); + + /* If the OLDDECL is an instantiation and/or specialization, + then the NEWDECL must be too. But, it may not yet be marked + as such if the caller has created NEWDECL, but has not yet + figured out that it is a redeclaration. */ + if (!DECL_USE_TEMPLATE (newdecl)) + DECL_USE_TEMPLATE (newdecl) = DECL_USE_TEMPLATE (olddecl); + /* Don't really know how much of the language-specific values we should copy from old to new. */ DECL_IN_AGGR_P (newdecl) = DECL_IN_AGGR_P (olddecl); @@ -1685,8 +1692,11 @@ duplicate_decls (tree newdecl, tree olddecl) DECL_REPO_AVAILABLE_P (newdecl) = DECL_REPO_AVAILABLE_P (olddecl); DECL_TEMPLATE_INFO (newdecl) = DECL_TEMPLATE_INFO (olddecl); DECL_INITIALIZED_IN_CLASS_P (newdecl) - |= DECL_INITIALIZED_IN_CLASS_P (olddecl); + |= DECL_INITIALIZED_IN_CLASS_P (olddecl); olddecl_friend = DECL_FRIEND_P (olddecl); + hidden_friend = (DECL_ANTICIPATED (olddecl) + && DECL_HIDDEN_FRIEND_P (olddecl) + && newdecl_is_friend); /* Only functions have DECL_BEFRIENDING_CLASSES. */ if (TREE_CODE (newdecl) == FUNCTION_DECL @@ -1796,13 +1806,14 @@ duplicate_decls (tree newdecl, tree olddecl) COPY_DECL_ASSEMBLER_NAME (olddecl, newdecl); /* Warn about conflicting visibility specifications. */ - if (DECL_VISIBILITY_SPECIFIED (olddecl) + if (DECL_VISIBILITY_SPECIFIED (olddecl) && DECL_VISIBILITY_SPECIFIED (newdecl) && DECL_VISIBILITY (newdecl) != DECL_VISIBILITY (olddecl)) { - warning ("%J%qD: visibility attribute ignored because it", - newdecl, newdecl); - warning ("%Jconflicts with previous declaration here", olddecl); + warning (OPT_Wattributes, "%q+D: visibility attribute ignored " + "because it", newdecl); + warning (OPT_Wattributes, "%Jconflicts with previous " + "declaration here", olddecl); } /* Choose the declaration which specified visibility. */ if (DECL_VISIBILITY_SPECIFIED (olddecl)) @@ -1810,12 +1821,19 @@ duplicate_decls (tree newdecl, tree olddecl) DECL_VISIBILITY (newdecl) = DECL_VISIBILITY (olddecl); DECL_VISIBILITY_SPECIFIED (newdecl) = 1; } + /* Init priority used to be merged from newdecl to olddecl by the memcpy, + so keep this behavior. */ + if (TREE_CODE (newdecl) == VAR_DECL && DECL_HAS_INIT_PRIORITY_P (newdecl)) + { + SET_DECL_INIT_PRIORITY (olddecl, DECL_INIT_PRIORITY (newdecl)); + DECL_HAS_INIT_PRIORITY_P (olddecl) = 1; + } /* The DECL_LANG_SPECIFIC information in OLDDECL will be replaced with that from NEWDECL below. */ if (DECL_LANG_SPECIFIC (olddecl)) { - gcc_assert (DECL_LANG_SPECIFIC (olddecl) + gcc_assert (DECL_LANG_SPECIFIC (olddecl) != DECL_LANG_SPECIFIC (newdecl)); ggc_free (DECL_LANG_SPECIFIC (olddecl)); } @@ -1824,13 +1842,16 @@ duplicate_decls (tree newdecl, tree olddecl) { int function_size; - function_size = sizeof (struct tree_decl); + function_size = sizeof (struct tree_decl_common); memcpy ((char *) olddecl + sizeof (struct tree_common), (char *) newdecl + sizeof (struct tree_common), function_size - sizeof (struct tree_common)); - if (DECL_TEMPLATE_INSTANTIATION (newdecl)) + memcpy ((char *) olddecl + sizeof (struct tree_decl_common), + (char *) newdecl + sizeof (struct tree_decl_common), + sizeof (struct tree_function_decl) - sizeof (struct tree_decl_common)); + if (DECL_TEMPLATE_INFO (newdecl)) /* If newdecl is a template instantiation, it is possible that the following sequence of events has occurred: @@ -1858,15 +1879,42 @@ duplicate_decls (tree newdecl, tree olddecl) } else { + size_t size = tree_code_size (TREE_CODE (olddecl)); memcpy ((char *) olddecl + sizeof (struct tree_common), (char *) newdecl + sizeof (struct tree_common), - sizeof (struct tree_decl) - sizeof (struct tree_common) - + TREE_CODE_LENGTH (TREE_CODE (newdecl)) * sizeof (char *)); + sizeof (struct tree_decl_common) - sizeof (struct tree_common)); + switch (TREE_CODE (olddecl)) + { + case LABEL_DECL: + case VAR_DECL: + case RESULT_DECL: + case PARM_DECL: + case FIELD_DECL: + case TYPE_DECL: + case CONST_DECL: + { + memcpy ((char *) olddecl + sizeof (struct tree_decl_common), + (char *) newdecl + sizeof (struct tree_decl_common), + size - sizeof (struct tree_decl_common) + + TREE_CODE_LENGTH (TREE_CODE (newdecl)) * sizeof (char *)); + } + break; + default: + memcpy ((char *) olddecl + sizeof (struct tree_decl_common), + (char *) newdecl + sizeof (struct tree_decl_common), + sizeof (struct tree_decl_non_common) - sizeof (struct tree_decl_common) + + TREE_CODE_LENGTH (TREE_CODE (newdecl)) * sizeof (char *)); + break; + } } - DECL_UID (olddecl) = olddecl_uid; if (olddecl_friend) DECL_FRIEND_P (olddecl) = 1; + if (hidden_friend) + { + DECL_ANTICIPATED (olddecl) = 1; + DECL_HIDDEN_FRIEND_P (olddecl) = 1; + } /* NEWDECL contains the merged attribute lists. Update OLDDECL to be the same. */ @@ -1920,11 +1968,12 @@ redeclaration_error_message (tree newdecl, tree olddecl) /* If both functions come from different namespaces, this is not a redeclaration - this is a conflict with a used function. */ if (DECL_NAMESPACE_SCOPE_P (olddecl) - && DECL_CONTEXT (olddecl) != DECL_CONTEXT (newdecl)) + && DECL_CONTEXT (olddecl) != DECL_CONTEXT (newdecl) + && ! decls_match (olddecl, newdecl)) return "%qD conflicts with used function"; /* We'll complain about linkage mismatches in - warn_extern_redeclared_static. */ + warn_extern_redeclared_static. */ /* Defining the same name twice is no good. */ if (DECL_INITIAL (olddecl) != NULL_TREE @@ -2101,16 +2150,15 @@ decl_jump_unsafe (tree decl) if (TREE_CODE (decl) != VAR_DECL || TREE_STATIC (decl)) return 0; - if (DECL_INITIAL (decl) == NULL_TREE - && pod_type_p (TREE_TYPE (decl))) + if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)) + || DECL_NONTRIVIALLY_INITIALIZED_P (decl)) + return 2; + + if (pod_type_p (TREE_TYPE (decl))) return 0; - /* This is really only important if we're crossing an initialization. - The POD stuff is just pedantry; why should it matter if the class + /* The POD stuff is just pedantry; why should it matter if the class contains a field of pointer to member type? */ - if (DECL_INITIAL (decl) - || (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))) - return 2; return 1; } @@ -2121,8 +2169,8 @@ decl_jump_unsafe (tree decl) static void check_previous_goto_1 (tree decl, - struct cp_binding_level* level, - tree names, const location_t *locus) + struct cp_binding_level* level, + tree names, const location_t *locus) { int identified = 0; int saw_eh = 0; @@ -2151,11 +2199,9 @@ check_previous_goto_1 (tree decl, } if (problem > 1) - cp_error_at (" crosses initialization of %q#D", - new_decls); + error (" crosses initialization of %q+#D", new_decls); else - cp_pedwarn_at (" enters scope of non-POD %q#D", - new_decls); + pedwarn (" enters scope of non-POD %q+#D", new_decls); } if (b == level) @@ -2253,7 +2299,7 @@ check_goto (tree decl) if ((lab->in_try_scope || lab->in_catch_scope || lab->bad_decls) && !identified) { - cp_pedwarn_at ("jump to label %qD", decl); + pedwarn ("jump to label %q+D", decl); pedwarn (" from here"); identified = 1; } @@ -2267,9 +2313,9 @@ check_goto (tree decl) /* Can't skip init of __exception_info. */ error ("%J enters catch block", b); else if (u > 1) - cp_error_at (" skips initialization of %q#D", b); + error (" skips initialization of %q+#D", b); else - cp_pedwarn_at (" enters scope of non-POD %q#D", b); + pedwarn (" enters scope of non-POD %q+#D", b); } if (lab->in_try_scope) @@ -2362,9 +2408,17 @@ void pop_switch (void) { struct cp_switch *cs = switch_stack; + location_t switch_location; /* Emit warnings as needed. */ - c_do_switch_warnings (cs->cases, cs->switch_stmt); + if (EXPR_HAS_LOCATION (cs->switch_stmt)) + switch_location = EXPR_LOCATION (cs->switch_stmt); + else + switch_location = input_location; + if (!processing_template_decl) + c_do_switch_warnings (cs->cases, switch_location, + SWITCH_STMT_TYPE (cs->switch_stmt), + SWITCH_STMT_COND (cs->switch_stmt)); splay_tree_delete (cs->cases); switch_stack = switch_stack->next; @@ -2452,7 +2506,7 @@ typename_compare (const void * k1, const void * k2) /* Build a TYPENAME_TYPE. If the type is `typename T::t', CONTEXT is the type of `T', NAME is the IDENTIFIER_NODE for `t'. - + Returns the new TYPENAME_TYPE. */ static GTY ((param_is (union tree_node))) htab_t typename_htab; @@ -2471,7 +2525,7 @@ build_typename_type (tree context, tree name, tree fullname, typename_htab = htab_create_ggc (61, &typename_hash, &typename_compare, NULL); - ti.scope = FROB_CONTEXT (context); + ti.scope = FROB_CONTEXT (context); ti.name = name; ti.template_id = fullname; ti.enum_p = tag_type == enum_type; @@ -2493,7 +2547,7 @@ build_typename_type (tree context, tree name, tree fullname, TYPENAME_TYPE_FULLNAME (t) = ti.template_id; TYPENAME_IS_ENUM_P (t) = ti.enum_p; TYPENAME_IS_CLASS_P (t) = ti.class_p; - + /* Build the corresponding TYPE_DECL. */ d = build_decl (TYPE_DECL, name, t); TYPE_NAME (TREE_TYPE (d)) = d; @@ -2504,7 +2558,7 @@ build_typename_type (tree context, tree name, tree fullname, /* Store it in the hash table. */ *e = t; } - + return t; } @@ -2570,7 +2624,7 @@ make_typename_type (tree context, tree name, enum tag_types tag_type, { if (complain & tf_error) error ("no class template named %q#T in %q#T", - name, context); + name, context); return error_mark_node; } @@ -2581,11 +2635,11 @@ make_typename_type (tree context, tree name, enum tag_types tag_type, TREE_OPERAND (fullname, 1), NULL_TREE, context, /*entering_scope=*/0, - tf_error | tf_warning | tf_user); + tf_error | tf_warning | tf_user); } else { - tree t; + tree t; if (!IS_AGGR_TYPE (context)) { @@ -2628,7 +2682,7 @@ make_typename_type (tree context, tree name, enum tag_types tag_type, } /* Resolve `CONTEXT::template NAME'. Returns a TEMPLATE_DECL if the name - can be resolved or an UNBOUND_CLASS_TEMPLATE, unless an error occurs, + can be resolved or an UNBOUND_CLASS_TEMPLATE, unless an error occurs, in which case error_mark_node is returned. If PARM_LIST is non-NULL, also make sure that the template parameter @@ -2670,7 +2724,7 @@ make_unbound_class_template (tree context, tree name, tree parm_list, if (complain & tf_error) { error ("template parameters do not match template"); - cp_error_at ("%qD declared here", tmpl); + error ("%q+D declared here", tmpl); } return error_mark_node; } @@ -2706,8 +2760,8 @@ make_unbound_class_template (tree context, tree name, tree parm_list, void record_builtin_type (enum rid rid_index, - const char* name, - tree type) + const char* name, + tree type) { tree rname = NULL_TREE, tname = NULL_TREE; tree tdecl = NULL_TREE; @@ -2794,7 +2848,7 @@ record_unknown_type (tree type, const char* name) TYPE_MODE (type) = TYPE_MODE (void_type_node); } -/* An string for which we should create an IDENTIFIER_NODE at +/* A string for which we should create an IDENTIFIER_NODE at startup. */ typedef struct predefined_identifier @@ -2872,7 +2926,7 @@ cxx_init_decl_processing (void) /* Enter the global namespace. */ gcc_assert (global_namespace == NULL_TREE); global_namespace = build_lang_decl (NAMESPACE_DECL, global_scope_name, - void_type_node); + void_type_node); begin_scope (sk_namespace, global_namespace); current_lang_name = NULL_TREE; @@ -3105,7 +3159,7 @@ cp_make_fname_decl (tree id, int type_dep) struct cp_binding_level *b = current_binding_level; while (b->level_chain->kind != sk_function_parms) b = b->level_chain; - pushdecl_with_scope (decl, b); + pushdecl_with_scope (decl, b, /*is_friend=*/false); cp_finish_decl (decl, init, NULL_TREE, LOOKUP_ONLYCONVERTING); } else @@ -3128,12 +3182,12 @@ cp_make_fname_decl (tree id, int type_dep) static tree builtin_function_1 (const char* name, - tree type, - tree context, + tree type, + tree context, enum built_in_function code, - enum built_in_class class, - const char* libname, - tree attrs) + enum built_in_class class, + const char* libname, + tree attrs) { tree decl = build_library_fn_1 (get_identifier (name), ERROR_MARK, type); DECL_BUILT_IN_CLASS (decl) = class; @@ -3148,8 +3202,9 @@ builtin_function_1 (const char* name, if (libname) SET_DECL_ASSEMBLER_NAME (decl, get_identifier (libname)); - /* Warn if a function in the namespace for users - is used without an occasion to consider it declared. */ + /* A function in the user's namespace should have an explicit + declaration before it is used. Mark the built-in function as + anticipated but not actually declared. */ if (name[0] != '_' || name[1] != '_') DECL_ANTICIPATED (decl) = 1; @@ -3180,11 +3235,11 @@ builtin_function_1 (const char* name, tree builtin_function (const char* name, - tree type, - int code, - enum built_in_class cl, - const char* libname, - tree attrs) + tree type, + int code, + enum built_in_class cl, + const char* libname, + tree attrs) { /* All builtins that don't begin with an '_' should additionally go in the 'std' namespace. */ @@ -3209,7 +3264,6 @@ build_library_fn_1 (tree name, enum tree_code operator_code, tree type) DECL_EXTERNAL (fn) = 1; TREE_PUBLIC (fn) = 1; DECL_ARTIFICIAL (fn) = 1; - TREE_NOTHROW (fn) = 1; SET_OVERLOADED_OPERATOR_CODE (fn, operator_code); SET_DECL_LANGUAGE (fn, lang_c); /* Runtime library routines are, by definition, available in an @@ -3226,7 +3280,9 @@ build_library_fn_1 (tree name, enum tree_code operator_code, tree type) tree build_library_fn (tree name, tree type) { - return build_library_fn_1 (name, ERROR_MARK, type); + tree fn = build_library_fn_1 (name, ERROR_MARK, type); + TREE_NOTHROW (fn) = 1; + return fn; } /* Returns the _DECL for a library function with C++ linkage. */ @@ -3358,18 +3414,15 @@ fixup_anonymous_aggr (tree t) type = TREE_TYPE (field); if (CLASS_TYPE_P (type)) { - if (TYPE_NEEDS_CONSTRUCTING (type)) - cp_error_at ("member %q#D with constructor not allowed " - "in anonymous aggregate", - field); + if (TYPE_NEEDS_CONSTRUCTING (type)) + error ("member %q+#D with constructor not allowed " + "in anonymous aggregate", field); if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)) - cp_error_at ("member %q#D with destructor not allowed " - "in anonymous aggregate", - field); + error ("member %q+#D with destructor not allowed " + "in anonymous aggregate", field); if (TYPE_HAS_COMPLEX_ASSIGN_REF (type)) - cp_error_at ("member %q#D with copy assignment operator " - "not allowed in anonymous aggregate", - field); + error ("member %q+#D with copy assignment operator " + "not allowed in anonymous aggregate", field); } } } @@ -3417,26 +3470,26 @@ check_tag_decl (cp_decl_specifier_seq *declspecs) && TYPE_ANONYMOUS_P (declared_type)) { /* 7/3 In a simple-declaration, the optional init-declarator-list - can be omitted only when declaring a class (clause 9) or - enumeration (7.2), that is, when the decl-specifier-seq contains - either a class-specifier, an elaborated-type-specifier with - a class-key (9.1), or an enum-specifier. In these cases and - whenever a class-specifier or enum-specifier is present in the - decl-specifier-seq, the identifiers in these specifiers are among - the names being declared by the declaration (as class-name, - enum-names, or enumerators, depending on the syntax). In such - cases, and except for the declaration of an unnamed bit-field (9.6), - the decl-specifier-seq shall introduce one or more names into the - program, or shall redeclare a name introduced by a previous - declaration. [Example: - enum { }; // ill-formed - typedef class { }; // ill-formed - --end example] */ + can be omitted only when declaring a class (clause 9) or + enumeration (7.2), that is, when the decl-specifier-seq contains + either a class-specifier, an elaborated-type-specifier with + a class-key (9.1), or an enum-specifier. In these cases and + whenever a class-specifier or enum-specifier is present in the + decl-specifier-seq, the identifiers in these specifiers are among + the names being declared by the declaration (as class-name, + enum-names, or enumerators, depending on the syntax). In such + cases, and except for the declaration of an unnamed bit-field (9.6), + the decl-specifier-seq shall introduce one or more names into the + program, or shall redeclare a name introduced by a previous + declaration. [Example: + enum { }; // ill-formed + typedef class { }; // ill-formed + --end example] */ if (saw_typedef) - { - error ("missing type-name in typedef-declaration"); - return NULL_TREE; - } + { + error ("missing type-name in typedef-declaration"); + return NULL_TREE; + } /* Anonymous unions are objects, so they can have specifiers. */; SET_ANON_AGGR_TYPE_P (declared_type); @@ -3495,10 +3548,9 @@ shadow_tag (cp_decl_specifier_seq *declspecs) if (declspecs->attributes) { - cp_warning_at ("attribute ignored in declaration of %q#T", t); - cp_warning_at ("attribute for %q#T must follow the %qs keyword", - t, - class_key_or_enum_as_string (t)); + warning (0, "attribute ignored in declaration of %q+#T", t); + warning (0, "attribute for %q+#T must follow the %qs keyword", + t, class_key_or_enum_as_string (t)); } @@ -3558,9 +3610,9 @@ groktypename (cp_decl_specifier_seq *type_specifiers, tree start_decl (const cp_declarator *declarator, cp_decl_specifier_seq *declspecs, - int initialized, - tree attributes, - tree prefix_attributes, + int initialized, + tree attributes, + tree prefix_attributes, tree *pushed_scope_p) { tree decl; @@ -3568,7 +3620,7 @@ start_decl (const cp_declarator *declarator, tree context; *pushed_scope_p = NULL_TREE; - + /* This should only be done once on the top most decl. */ if (have_extern_spec) { @@ -3588,20 +3640,18 @@ start_decl (const cp_declarator *declarator, deprecated_state = DEPRECATED_NORMAL; - if (decl == NULL_TREE || TREE_CODE (decl) == VOID_TYPE) + if (decl == NULL_TREE || TREE_CODE (decl) == VOID_TYPE + || decl == error_mark_node) return error_mark_node; type = TREE_TYPE (decl); - if (type == error_mark_node) - return error_mark_node; - context = DECL_CONTEXT (decl); if (context) { *pushed_scope_p = push_scope (context); - + /* We are only interested in class contexts, later. */ if (TREE_CODE (context) == NAMESPACE_DECL) context = NULL_TREE; @@ -3631,8 +3681,8 @@ start_decl (const cp_declarator *declarator, { if (! toplevel_bindings_p () && DECL_EXTERNAL (decl)) - warning ("declaration of %q#D has % and is initialized", - decl); + warning (0, "declaration of %q#D has % and is initialized", + decl); DECL_EXTERNAL (decl) = 0; if (toplevel_bindings_p ()) TREE_STATIC (decl) = 1; @@ -3647,14 +3697,13 @@ start_decl (const cp_declarator *declarator, cplus_decl_attributes (&decl, attributes, 0); /* If #pragma weak was used, mark the decl weak now. */ - if (global_scope_p (current_binding_level)) - maybe_apply_pragma_weak (decl); + maybe_apply_pragma_weak (decl); if (TREE_CODE (decl) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (decl) && DECL_UNINLINABLE (decl) && lookup_attribute ("noinline", DECL_ATTRIBUTES (decl))) - warning ("%Jinline function %qD given attribute noinline", decl, decl); + warning (0, "inline function %q+D given attribute noinline", decl); if (context && COMPLETE_TYPE_P (complete_type (context))) { @@ -3669,7 +3718,7 @@ start_decl (const cp_declarator *declarator, { if (!same_type_p (DECL_CONTEXT (field), context)) pedwarn ("ISO C++ does not permit %<%T::%D%> " - "to be defined as %<%T::%D%>", + "to be defined as %<%T::%D%>", DECL_CONTEXT (field), DECL_NAME (decl), context, DECL_NAME (decl)); DECL_CONTEXT (decl) = DECL_CONTEXT (field); @@ -3684,9 +3733,10 @@ start_decl (const cp_declarator *declarator, declaration will have DECL_EXTERNAL set, but will have an initialization. Thus, duplicate_decls won't warn about this situation, and so we check here. */ - if (DECL_INITIAL (decl) && DECL_INITIAL (field)) + if (DECL_INITIAL (decl) + && DECL_INITIALIZED_IN_CLASS_P (field)) error ("duplicate initialization of %qD", decl); - if (duplicate_decls (decl, field)) + if (duplicate_decls (decl, field, /*newdecl_is_friend=*/false)) decl = field; } } @@ -3697,34 +3747,35 @@ start_decl (const cp_declarator *declarator, > template_class_depth (context)) ? current_template_parms : NULL_TREE); - if (field && duplicate_decls (decl, field)) + if (field && duplicate_decls (decl, field, + /*newdecl_is_friend=*/false)) decl = field; } /* cp_finish_decl sets DECL_EXTERNAL if DECL_IN_AGGR_P is set. */ DECL_IN_AGGR_P (decl) = 0; - if ((DECL_LANG_SPECIFIC (decl) && DECL_USE_TEMPLATE (decl)) - || CLASSTYPE_TEMPLATE_INSTANTIATION (context)) - { - /* Do not mark DECL as an explicit specialization if it was - not already marked as an instantiation; a declaration - should never be marked as a specialization unless we know - what template is being specialized. */ - if (DECL_LANG_SPECIFIC (decl) && DECL_USE_TEMPLATE (decl)) - SET_DECL_TEMPLATE_SPECIALIZATION (decl); + /* Do not mark DECL as an explicit specialization if it was not + already marked as an instantiation; a declaration should + never be marked as a specialization unless we know what + template is being specialized. */ + if (DECL_LANG_SPECIFIC (decl) && DECL_USE_TEMPLATE (decl)) + { + SET_DECL_TEMPLATE_SPECIALIZATION (decl); + /* [temp.expl.spec] An explicit specialization of a static data member of a template is a definition if the declaration includes an initializer; otherwise, it is a declaration. We check for processing_specialization so this only applies to the new specialization syntax. */ - if (DECL_INITIAL (decl) == NULL_TREE && processing_specialization) + if (!DECL_INITIAL (decl) + && processing_specialization) DECL_EXTERNAL (decl) = 1; } if (DECL_EXTERNAL (decl) && ! DECL_TEMPLATE_SPECIALIZATION (decl)) pedwarn ("declaration of %q#D outside of class is not definition", - decl); + decl); } /* Enter this declaration into the symbol table. */ @@ -3742,7 +3793,7 @@ start_decl (const cp_declarator *declarator, produce errors about redefs; to do this we force variables into the data segment. */ DECL_COMMON (tem) = ((TREE_CODE (tem) != VAR_DECL - || !DECL_THREAD_LOCAL (tem)) + || !DECL_THREAD_LOCAL_P (tem)) && (flag_conserve_space || ! TREE_PUBLIC (tem))); #endif @@ -3852,7 +3903,7 @@ grok_reference_init (tree decl, tree type, tree init, tree *cleanup) if (TREE_CODE (init) == CONSTRUCTOR) { error ("ISO C++ forbids use of initializer list to " - "initialize reference %qD", decl); + "initialize reference %qD", decl); return NULL_TREE; } @@ -3906,7 +3957,8 @@ maybe_deduce_size_from_array_init (tree decl, tree init) But let's leave it here to ease the eventual merge. */ int do_default = !DECL_EXTERNAL (decl); tree initializer = init ? init : DECL_INITIAL (decl); - int failure = complete_array_type (type, initializer, do_default); + int failure = cp_complete_array_type (&TREE_TYPE (decl), initializer, + do_default); if (failure == 1) error ("initializer fails to determine size of %qD", decl); @@ -3923,11 +3975,11 @@ maybe_deduce_size_from_array_init (tree decl, tree init) DECL_EXTERNAL (decl) = 1; } - if (pedantic && TYPE_DOMAIN (type) != NULL_TREE - && tree_int_cst_lt (TYPE_MAX_VALUE (TYPE_DOMAIN (type)), - integer_zero_node)) + if (failure == 3) error ("zero-size array %qD", decl); + cp_apply_type_quals_to_decl (cp_type_quals (TREE_TYPE (decl)), decl); + layout_decl (decl, 0); } } @@ -3939,9 +3991,6 @@ static void layout_var_decl (tree decl) { tree type = TREE_TYPE (decl); -#if 0 - tree ttype = target_type (type); -#endif /* If we haven't already layed out this declaration, do so now. Note that we must not call complete type for an external object @@ -4040,11 +4089,11 @@ maybe_commonize_var (tree decl) be merged. */ TREE_PUBLIC (decl) = 0; DECL_COMMON (decl) = 0; - cp_warning_at ("sorry: semantics of inline function static " - "data %q#D are wrong (you'll wind up " - "with multiple copies)", decl); - warning ("%J you can work around this by removing " - "the initializer", + warning (0, "sorry: semantics of inline function static " + "data %q+#D are wrong (you'll wind up " + "with multiple copies)", decl); + warning (0, "%J you can work around this by removing " + "the initializer", decl); } } @@ -4073,6 +4122,18 @@ check_for_uninitialized_const_var (tree decl) error ("uninitialized const %qD", decl); } + +/* Structure holding the current initializer being processed by reshape_init. + CUR is a pointer to the current element being processed, END is a pointer + after the last element present in the initializer. */ +typedef struct reshape_iterator_t +{ + constructor_elt *cur; + constructor_elt *end; +} reshape_iter; + +static tree reshape_init_r (tree, reshape_iter *, bool); + /* FIELD is a FIELD_DECL or NULL. In the former case, the value returned is the next FIELD_DECL (possibly FIELD itself) that can be initialized. If there are no more such fields, the return value @@ -4090,137 +4151,210 @@ next_initializable_field (tree field) return field; } -/* Subroutine of reshape_init. Reshape the constructor for an array. INITP - is the pointer to the old constructor list (to the CONSTRUCTOR_ELTS of - the CONSTRUCTOR we are processing), while NEW_INIT is the CONSTRUCTOR we - are building. - ELT_TYPE is the element type of the array. MAX_INDEX is an INTEGER_CST - representing the size of the array minus one (the maximum index), or - NULL_TREE if the array was declared without specifying the size. */ +/* Subroutine of reshape_init_array and reshape_init_vector, which does + the actual work. ELT_TYPE is the element type of the array. MAX_INDEX is an + INTEGER_CST representing the size of the array minus one (the maximum index), + or NULL_TREE if the array was declared without specifying the size. D is + the iterator within the constructor. */ -static bool -reshape_init_array (tree elt_type, tree max_index, - tree *initp, tree new_init) +static tree +reshape_init_array_1 (tree elt_type, tree max_index, reshape_iter *d) { + tree new_init; bool sized_array_p = (max_index != NULL_TREE); - HOST_WIDE_INT max_index_cst = 0; - HOST_WIDE_INT index; + unsigned HOST_WIDE_INT max_index_cst = 0; + unsigned HOST_WIDE_INT index; + + /* The initializer for an array is always a CONSTRUCTOR. */ + new_init = build_constructor (NULL_TREE, NULL); if (sized_array_p) - /* HWI is either 32bit or 64bit, so it must be enough to represent the - array size. */ - max_index_cst = tree_low_cst (max_index, 1); + { + if (host_integerp (max_index, 1)) + max_index_cst = tree_low_cst (max_index, 1); + /* sizetype is sign extended, not zero extended. */ + else + max_index_cst = tree_low_cst (fold_convert (size_type_node, max_index), + 1); + } /* Loop until there are no more initializers. */ for (index = 0; - *initp && (!sized_array_p || index <= max_index_cst); + d->cur != d->end && (!sized_array_p || index <= max_index_cst); ++index) { - tree element_init; - tree designated_index; + tree elt_init; - element_init = reshape_init (elt_type, initp); - if (element_init == error_mark_node) - return false; - TREE_CHAIN (element_init) = CONSTRUCTOR_ELTS (new_init); - CONSTRUCTOR_ELTS (new_init) = element_init; - designated_index = TREE_PURPOSE (element_init); - if (designated_index) - { + if (d->cur->index) + { /* Handle array designated initializers (GNU extension). */ - if (TREE_CODE (designated_index) == IDENTIFIER_NODE) + if (TREE_CODE (d->cur->index) == IDENTIFIER_NODE) { error ("name %qD used in a GNU-style designated " - "initializer for an array", designated_index); - TREE_PURPOSE (element_init) = NULL_TREE; + "initializer for an array", d->cur->index); } else - { - gcc_assert (TREE_CODE (designated_index) == INTEGER_CST); - if (sized_array_p - && tree_int_cst_lt (max_index, designated_index)) - { - error ("Designated initializer %qE larger than array " - "size", designated_index); - TREE_PURPOSE (element_init) = NULL_TREE; - } - else - index = tree_low_cst (designated_index, 1); - } + gcc_unreachable (); } + + elt_init = reshape_init_r (elt_type, d, /*first_initializer_p=*/false); + CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (new_init), NULL_TREE, elt_init); } - return true; + return new_init; } -/* Undo the brace-elision allowed by [dcl.init.aggr] in a - brace-enclosed aggregate initializer. +/* Subroutine of reshape_init_r, processes the initializers for arrays. + Parameters are the same of reshape_init_r. */ - *INITP is one of a list of initializers describing a brace-enclosed - initializer for an entity of the indicated aggregate TYPE. It may - not presently match the shape of the TYPE; for example: +static tree +reshape_init_array (tree type, reshape_iter *d) +{ + tree max_index = NULL_TREE; - struct S { int a; int b; }; - struct S a[] = { 1, 2, 3, 4 }; + gcc_assert (TREE_CODE (type) == ARRAY_TYPE); - Here *INITP will point to TREE_LIST of four elements, rather than a - list of two elements, each itself a list of two elements. This - routine transforms INIT from the former form into the latter. The - revised initializer is returned. */ + if (TYPE_DOMAIN (type)) + max_index = array_type_nelts (type); + + return reshape_init_array_1 (TREE_TYPE (type), max_index, d); +} + +/* Subroutine of reshape_init_r, processes the initializers for vectors. + Parameters are the same of reshape_init_r. */ + +static tree +reshape_init_vector (tree type, reshape_iter *d) +{ + tree max_index = NULL_TREE; + tree rtype; + + gcc_assert (TREE_CODE (type) == VECTOR_TYPE); + + if (TREE_CODE (d->cur->value) == CONSTRUCTOR + && TREE_HAS_CONSTRUCTOR (d->cur->value)) + { + tree value = d->cur->value; + if (!same_type_p (TREE_TYPE (value), type)) + { + error ("invalid type %qT as initializer for a vector of type %qT", + TREE_TYPE (d->cur->value), type); + value = error_mark_node; + } + ++d->cur; + return value; + } + + /* For a vector, the representation type is a struct + containing a single member which is an array of the + appropriate size. */ + rtype = TYPE_DEBUG_REPRESENTATION_TYPE (type); + if (rtype && TYPE_DOMAIN (TREE_TYPE (TYPE_FIELDS (rtype)))) + max_index = array_type_nelts (TREE_TYPE (TYPE_FIELDS (rtype))); + + return reshape_init_array_1 (TREE_TYPE (type), max_index, d); +} + +/* Subroutine of reshape_init_r, processes the initializers for classes + or union. Parameters are the same of reshape_init_r. */ static tree -reshape_init (tree type, tree *initp) +reshape_init_class (tree type, reshape_iter *d, bool first_initializer_p) { - tree inits; - tree old_init; - tree old_init_value; + tree field; tree new_init; - bool brace_enclosed_p; - old_init = *initp; - old_init_value = (TREE_CODE (*initp) == TREE_LIST - ? TREE_VALUE (*initp) : old_init); + gcc_assert (CLASS_TYPE_P (type)); - gcc_assert (old_init_value); + /* The initializer for a class is always a CONSTRUCTOR. */ + new_init = build_constructor (NULL_TREE, NULL); + field = next_initializable_field (TYPE_FIELDS (type)); - /* If the initializer is brace-enclosed, pull initializers from the - enclosed elements. Advance past the brace-enclosed initializer - now. */ - if (TREE_CODE (old_init_value) == CONSTRUCTOR - && BRACE_ENCLOSED_INITIALIZER_P (old_init_value)) + if (!field) { - *initp = TREE_CHAIN (old_init); - TREE_CHAIN (old_init) = NULL_TREE; - inits = CONSTRUCTOR_ELTS (old_init_value); - initp = &inits; - brace_enclosed_p = true; + /* [dcl.init.aggr] + + An initializer for an aggregate member that is an + empty class shall have the form of an empty + initializer-list {}. */ + if (!first_initializer_p) + { + error ("initializer for %qT must be brace-enclosed", type); + return error_mark_node; + } + return new_init; } - else + + /* Loop through the initializable fields, gathering initializers. */ + while (d->cur != d->end) { - inits = NULL_TREE; - brace_enclosed_p = false; + tree field_init; + + /* Handle designated initializers, as an extension. */ + if (d->cur->index) + { + if (pedantic) + pedwarn ("ISO C++ does not allow designated initializers"); + + field = lookup_field_1 (type, d->cur->index, /*want_type=*/false); + + if (!field || TREE_CODE (field) != FIELD_DECL) + error ("%qT has no non-static data member named %qD", type, + d->cur->index); + } + + /* If we processed all the member of the class, we are done. */ + if (!field) + break; + + field_init = reshape_init_r (TREE_TYPE (field), d, + /*first_initializer_p=*/false); + CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (new_init), field, field_init); + + /* [dcl.init.aggr] + + When a union is initialized with a brace-enclosed + initializer, the braces shall only contain an + initializer for the first member of the union. */ + if (TREE_CODE (type) == UNION_TYPE) + break; + + field = next_initializable_field (TREE_CHAIN (field)); } + return new_init; +} + +/* Subroutine of reshape_init, which processes a single initializer (part of + a CONSTRUCTOR). TYPE is the type of the variable being initialized, D is the + iterator within the CONSTRUCTOR which points to the initializer to process. + FIRST_INITIALIZER_P is true if this is the first initializer of the + CONSTRUCTOR node. */ + +static tree +reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p) +{ + tree init = d->cur->value; + /* A non-aggregate type is always initialized with a single initializer. */ if (!CP_AGGREGATE_TYPE_P (type)) - { - *initp = TREE_CHAIN (old_init); - TREE_CHAIN (old_init) = NULL_TREE; - /* It is invalid to initialize a non-aggregate type with a - brace-enclosed initializer. */ - if (brace_enclosed_p) - { - error ("brace-enclosed initializer used to initialize %qT", - type); - if (TREE_CODE (old_init) == TREE_LIST) - TREE_VALUE (old_init) = error_mark_node; - else - old_init = error_mark_node; - } - - return old_init; - } + { + /* It is invalid to initialize a non-aggregate type with a + brace-enclosed initializer. + We need to check for BRACE_ENCLOSED_INITIALIZER_P here because + of g++.old-deja/g++.mike/p7626.C: a pointer-to-member constant is + a CONSTRUCTOR (with a record type). */ + if (TREE_CODE (init) == CONSTRUCTOR + && BRACE_ENCLOSED_INITIALIZER_P (init)) /* p7626.C */ + { + error ("braces around scalar initializer for type %qT", type); + init = error_mark_node; + } + + d->cur++; + return init; + } /* [dcl.init.aggr] @@ -4231,137 +4365,124 @@ reshape_init (tree type, tree *initp) non-empty subaggregate, brace elision is assumed and the initializer is considered for the initialization of the first member of the subaggregate. */ - if (!brace_enclosed_p - && can_convert_arg (type, TREE_TYPE (old_init_value), old_init_value)) + if (TREE_CODE (init) != CONSTRUCTOR + && can_convert_arg (type, TREE_TYPE (init), init, LOOKUP_NORMAL)) { - *initp = TREE_CHAIN (old_init); - TREE_CHAIN (old_init) = NULL_TREE; - return old_init; + d->cur++; + return init; } - if (TREE_CODE (old_init_value) == STRING_CST - && TREE_CODE (type) == ARRAY_TYPE + /* [dcl.init.string] + + A char array (whether plain char, signed char, or unsigned char) + can be initialized by a string-literal (optionally enclosed in + braces); a wchar_t array can be initialized by a wide + string-literal (optionally enclosed in braces). */ + if (TREE_CODE (type) == ARRAY_TYPE && char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type)))) { - /* [dcl.init.string] + tree str_init = init; - A char array (whether plain char, signed char, or unsigned char) - can be initialized by a string-literal (optionally enclosed in - braces); a wchar_t array can be initialized by a wide - string-literal (optionally enclosed in braces). */ - new_init = old_init; - /* Move past the initializer. */ - *initp = TREE_CHAIN (old_init); - TREE_CHAIN (old_init) = NULL_TREE; + /* Strip one level of braces if and only if they enclose a single + element (as allowed by [dcl.init.string]). */ + if (!first_initializer_p + && TREE_CODE (str_init) == CONSTRUCTOR + && VEC_length (constructor_elt, CONSTRUCTOR_ELTS (str_init)) == 1) + { + str_init = VEC_index (constructor_elt, + CONSTRUCTOR_ELTS (str_init), 0)->value; + } + + /* If it's a string literal, then it's the initializer for the array + as a whole. Otherwise, continue with normal initialization for + array types (one value per array element). */ + if (TREE_CODE (str_init) == STRING_CST) + { + d->cur++; + return str_init; + } } - else - { - /* Build a CONSTRUCTOR to hold the contents of the aggregate. */ - new_init = build_constructor (NULL_TREE, NULL_TREE); - if (CLASS_TYPE_P (type)) + /* The following cases are about aggregates. If we are not within a full + initializer already, and there is not a CONSTRUCTOR, it means that there + is a missing set of braces (that is, we are processing the case for + which reshape_init exists). */ + if (!first_initializer_p) + { + if (TREE_CODE (init) == CONSTRUCTOR) { - tree field; - - field = next_initializable_field (TYPE_FIELDS (type)); - - if (!field) + /* For a nested compound literal, there is no need to reshape since + brace elision is not allowed. Even if we decided to allow it, + we should add a call to reshape_init in finish_compound_literal, + before calling digest_init, so changing this code would still + not be necessary. */ + if (!TREE_HAS_CONSTRUCTOR (init)) { - /* [dcl.init.aggr] - - An initializer for an aggregate member that is an - empty class shall have the form of an empty - initializer-list {}. */ - if (!brace_enclosed_p) - { - error ("initializer for %qT must be brace-enclosed", type); - return error_mark_node; - } + ++d->cur; + gcc_assert (BRACE_ENCLOSED_INITIALIZER_P (init)); + return reshape_init (type, init); } else - { - /* Loop through the initializable fields, gathering - initializers. */ - while (*initp) - { - tree field_init; + gcc_assert (!BRACE_ENCLOSED_INITIALIZER_P (init)); + } - /* Handle designated initializers, as an extension. */ - if (TREE_PURPOSE (*initp)) - { - if (pedantic) - pedwarn ("ISO C++ does not allow designated initializers"); - field = lookup_field_1 (type, TREE_PURPOSE (*initp), - /*want_type=*/false); - if (!field || TREE_CODE (field) != FIELD_DECL) - error ("%qT has no non-static data member named %qD", - type, TREE_PURPOSE (*initp)); - } - if (!field) - break; + warning (OPT_Wmissing_braces, "missing braces around initializer for %qT", + type); + } - field_init = reshape_init (TREE_TYPE (field), initp); - if (field_init == error_mark_node) - return error_mark_node; - TREE_CHAIN (field_init) = CONSTRUCTOR_ELTS (new_init); - CONSTRUCTOR_ELTS (new_init) = field_init; - /* [dcl.init.aggr] - - When a union is initialized with a brace-enclosed - initializer, the braces shall only contain an - initializer for the first member of the union. */ - if (TREE_CODE (type) == UNION_TYPE) - break; - field = next_initializable_field (TREE_CHAIN (field)); - } - } - } - else if (TREE_CODE (type) == ARRAY_TYPE - || TREE_CODE (type) == VECTOR_TYPE) - { - /* If the bound of the array is known, take no more initializers - than are allowed. */ - tree max_index = NULL_TREE; - if (TREE_CODE (type) == ARRAY_TYPE) - { - if (TYPE_DOMAIN (type)) - max_index = array_type_nelts (type); - } - else - { - /* For a vector, the representation type is a struct - containing a single member which is an array of the - appropriate size. */ - tree rtype = TYPE_DEBUG_REPRESENTATION_TYPE (type); - if (rtype && TYPE_DOMAIN (TREE_TYPE (TYPE_FIELDS (rtype)))) - max_index = array_type_nelts (TREE_TYPE (TYPE_FIELDS - (rtype))); - } + /* Dispatch to specialized routines. */ + if (CLASS_TYPE_P (type)) + return reshape_init_class (type, d, first_initializer_p); + else if (TREE_CODE (type) == ARRAY_TYPE) + return reshape_init_array (type, d); + else if (TREE_CODE (type) == VECTOR_TYPE) + return reshape_init_vector (type, d); + else + gcc_unreachable(); +} - if (!reshape_init_array (TREE_TYPE (type), max_index, - initp, new_init)) - return error_mark_node; - } - else - gcc_unreachable (); +/* Undo the brace-elision allowed by [dcl.init.aggr] in a + brace-enclosed aggregate initializer. - /* The initializers were placed in reverse order in the - CONSTRUCTOR. */ - CONSTRUCTOR_ELTS (new_init) = nreverse (CONSTRUCTOR_ELTS (new_init)); + INIT is the CONSTRUCTOR containing the list of initializers describing + a brace-enclosed initializer for an entity of the indicated aggregate TYPE. + It may not presently match the shape of the TYPE; for example: - if (TREE_CODE (old_init) == TREE_LIST) - new_init = build_tree_list (TREE_PURPOSE (old_init), new_init); - } + struct S { int a; int b; }; + struct S a[] = { 1, 2, 3, 4 }; - /* If there are more initializers than necessary, issue a - diagnostic. */ - if (*initp) - { - if (brace_enclosed_p) - error ("too many initializers for %qT", type); - else if (warn_missing_braces) - warning ("missing braces around initializer"); - } + Here INIT will hold a VEC of four elements, rather than a + VEC of two elements, each itself a VEC of two elements. This + routine transforms INIT from the former form into the latter. The + revised CONSTRUCTOR node is returned. */ + +static tree +reshape_init (tree type, tree init) +{ + VEC(constructor_elt, gc) *v; + reshape_iter d; + tree new_init; + + gcc_assert (TREE_CODE (init) == CONSTRUCTOR); + gcc_assert (BRACE_ENCLOSED_INITIALIZER_P (init)); + + v = CONSTRUCTOR_ELTS (init); + + /* An empty constructor does not need reshaping, and it is always a valid + initializer. */ + if (VEC_empty (constructor_elt, v)) + return init; + + /* Recurse on this CONSTRUCTOR. */ + d.cur = VEC_index (constructor_elt, v, 0); + d.end = d.cur + VEC_length (constructor_elt, v); + + new_init = reshape_init_r (type, &d, true); + + /* Make sure all the element of the constructor were used. Otherwise, + issue an error about exceeding initializers. */ + if (d.cur != d.end) + error ("too many initializers for %qT", type); return new_init; } @@ -4428,20 +4549,13 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup) init = grok_reference_init (decl, type, init, cleanup); else if (init) { + /* Do not reshape constructors of vectors (they don't need to be + reshaped. */ if (TREE_CODE (init) == CONSTRUCTOR - && BRACE_ENCLOSED_INITIALIZER_P (init)) + && !TREE_HAS_CONSTRUCTOR (init) + && !TREE_TYPE (init)) /* ptrmemfunc */ { - /* [dcl.init] paragraph 13, - If T is a scalar type, then a declaration of the form - T x = { a }; - is equivalent to - T x = a; - - reshape_init will complain about the extra braces, - and doesn't do anything useful in the case where TYPE is - scalar, so just don't call it. */ - if (CP_AGGREGATE_TYPE_P (type)) - init = reshape_init (type, &init); + init = reshape_init (type, init); if ((*targetm.vector_opaque_p) (type)) { @@ -4459,13 +4573,13 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup) { if (TREE_CODE (type) == ARRAY_TYPE) goto initialize_aggr; - else if (TREE_CODE (init) == CONSTRUCTOR - && BRACE_ENCLOSED_INITIALIZER_P (init)) + else if (TREE_CODE (init) == CONSTRUCTOR) { + gcc_assert (BRACE_ENCLOSED_INITIALIZER_P (init)); if (TYPE_NON_AGGREGATE_CLASS (type)) { error ("%qD must be initialized by constructor, " - "not by %<{...}%>", + "not by %<{...}%>", decl); init = error_mark_node; } @@ -4500,7 +4614,7 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup) && DECL_INITIAL (decl) && TREE_CODE (DECL_INITIAL (decl)) == STRING_CST && PAREN_STRING_LITERAL_P (DECL_INITIAL (decl))) - warning ("array %qD initialized by parenthesized string literal %qE", + warning (0, "array %qD initialized by parenthesized string literal %qE", decl, DECL_INITIAL (decl)); init = NULL; } @@ -4537,6 +4651,7 @@ make_rtl_for_nonlocal_decl (tree decl, tree init, const char* asmspec) { int toplev = toplevel_bindings_p (); int defer_p; + const char *filename; /* Set the DECL_ASSEMBLER_NAME for the object. */ if (asmspec) @@ -4546,7 +4661,7 @@ make_rtl_for_nonlocal_decl (tree decl, tree init, const char* asmspec) placed in a particular register. */ if (TREE_CODE (decl) == VAR_DECL && DECL_REGISTER (decl)) { - change_decl_assembler_name (decl, get_identifier (asmspec)); + set_user_assembler_name (decl, asmspec); DECL_HARD_REGISTER (decl) = 1; } else @@ -4586,17 +4701,19 @@ make_rtl_for_nonlocal_decl (tree decl, tree init, const char* asmspec) /* We try to defer namespace-scope static constants so that they are not emitted into the object file unnecessarily. */ + filename = input_filename; if (!DECL_VIRTUAL_P (decl) && TREE_READONLY (decl) && DECL_INITIAL (decl) != NULL_TREE && DECL_INITIAL (decl) != error_mark_node + && filename != NULL && ! EMPTY_CONSTRUCTOR_P (DECL_INITIAL (decl)) && toplev && !TREE_PUBLIC (decl)) { /* Fool with the linkage of static consts according to #pragma interface. */ - struct c_fileinfo *finfo = get_fileinfo (lbasename (input_filename)); + struct c_fileinfo *finfo = get_fileinfo (lbasename (filename)); if (!finfo->interface_unknown && !TREE_PUBLIC (decl)) { TREE_PUBLIC (decl) = 1; @@ -4683,7 +4800,7 @@ initialize_local_var (tree decl, tree init) void initialize_artificial_var (tree decl, tree init) { - DECL_INITIAL (decl) = build_constructor (NULL_TREE, init); + DECL_INITIAL (decl) = build_constructor_from_list (NULL_TREE, init); DECL_INITIALIZED_P (decl) = 1; determine_visibility (decl); layout_var_decl (decl); @@ -4706,7 +4823,6 @@ void cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags) { tree type; - tree ttype = NULL_TREE; tree cleanup; const char *asmspec = NULL; int was_readonly = 0; @@ -4749,9 +4865,6 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags) if (type == error_mark_node) goto finish_end; - if (TYPE_HAS_MUTABLE_P (type)) - TREE_READONLY (decl) = 0; - if (processing_template_decl) { /* Add this declaration to the statement-tree. */ @@ -4764,7 +4877,7 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags) && !DECL_PRETTY_FUNCTION_P (decl) && !dependent_type_p (TREE_TYPE (decl))) maybe_deduce_size_from_array_init (decl, init); - + goto finish_end; } @@ -4778,7 +4891,7 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags) && IS_AGGR_TYPE (type) && DECL_NAME (decl)) { if (TREE_TYPE (DECL_NAME (decl)) && TREE_TYPE (decl) != type) - warning ("shadowing previous type declaration of %q#D", decl); + warning (0, "shadowing previous type declaration of %q#D", decl); set_identifier_type_value (DECL_NAME (decl), decl); } @@ -4794,27 +4907,20 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags) goto finish_end; } - if (TREE_CODE (decl) != FUNCTION_DECL) - ttype = target_type (type); - - - /* Currently, GNU C++ puts constants in text space, making them - impossible to initialize. In the future, one would hope for - an operating system which understood the difference between - initialization and the running of a program. */ - if (! DECL_EXTERNAL (decl) && TREE_READONLY (decl)) + /* A reference will be modified here, as it is initialized. */ + if (! DECL_EXTERNAL (decl) + && TREE_READONLY (decl) + && TREE_CODE (type) == REFERENCE_TYPE) { was_readonly = 1; - if (TYPE_NEEDS_CONSTRUCTING (type) - || TREE_CODE (type) == REFERENCE_TYPE) - TREE_READONLY (decl) = 0; + TREE_READONLY (decl) = 0; } if (TREE_CODE (decl) == VAR_DECL) { /* Only PODs can have thread-local storage. Other types may require various kinds of non-trivial initialization. */ - if (DECL_THREAD_LOCAL (decl) && !pod_type_p (TREE_TYPE (decl))) + if (DECL_THREAD_LOCAL_P (decl) && !pod_type_p (TREE_TYPE (decl))) error ("%qD cannot be thread-local because it has non-POD type %qT", decl, TREE_TYPE (decl)); /* Convert the initializer to the type of DECL, if we have not @@ -4826,14 +4932,36 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags) is *not* defined. */ && (!DECL_EXTERNAL (decl) || init)) { + if (init) + DECL_NONTRIVIALLY_INITIALIZED_P (decl) = 1; init = check_initializer (decl, init, flags, &cleanup); /* Thread-local storage cannot be dynamically initialized. */ - if (DECL_THREAD_LOCAL (decl) && init) + if (DECL_THREAD_LOCAL_P (decl) && init) { error ("%qD is thread-local and so cannot be dynamically " "initialized", decl); init = NULL_TREE; } + + /* Check that the initializer for a static data member was a + constant. Although we check in the parser that the + initializer is an integral constant expression, we do not + simplify division-by-zero at the point at which it + occurs. Therefore, in: + + struct S { static const int i = 7 / 0; }; + + we issue an error at this point. It would + probably be better to forbid division by zero in + integral constant expressions. */ + if (DECL_EXTERNAL (decl) && init) + { + error ("%qD cannot be initialized by a non-constant expression" + " when being declared", decl); + DECL_INITIALIZED_IN_CLASS_P (decl) = 0; + init = NULL_TREE; + } + /* Handle: [dcl.init] @@ -4923,7 +5051,7 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags) else if (!TREE_STATIC (decl)) initialize_local_var (decl, init); } - + /* If a variable is defined, and then a subsequent definition with external linkage is encountered, we will get here twice for the same variable. We want to avoid @@ -4933,8 +5061,8 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags) initializer. It is not legal to redeclare a static data member, so this issue does not arise in that case. */ if (var_definition_p && TREE_STATIC (decl)) - expand_static_init (decl, init); - } + expand_static_init (decl, init); + } } /* If a CLEANUP_STMT was created to destroy a temporary bound to a @@ -5000,6 +5128,7 @@ get_atexit_node (void) tree fn_type; tree fn_ptr_type; const char *name; + bool use_aeabi_atexit; if (atexit_node) return atexit_node; @@ -5013,6 +5142,7 @@ get_atexit_node (void) We build up the argument types and then then function type itself. */ + use_aeabi_atexit = targetm.cxx.use_aeabi_atexit (); /* First, build the pointer-to-function type for the first argument. */ arg_types = tree_cons (NULL_TREE, ptr_type_node, void_list_node); @@ -5020,18 +5150,29 @@ get_atexit_node (void) fn_ptr_type = build_pointer_type (fn_type); /* Then, build the rest of the argument types. */ arg_types = tree_cons (NULL_TREE, ptr_type_node, void_list_node); - arg_types = tree_cons (NULL_TREE, ptr_type_node, arg_types); - arg_types = tree_cons (NULL_TREE, fn_ptr_type, arg_types); + if (use_aeabi_atexit) + { + arg_types = tree_cons (NULL_TREE, fn_ptr_type, arg_types); + arg_types = tree_cons (NULL_TREE, ptr_type_node, arg_types); + } + else + { + arg_types = tree_cons (NULL_TREE, ptr_type_node, arg_types); + arg_types = tree_cons (NULL_TREE, fn_ptr_type, arg_types); + } /* And the final __cxa_atexit type. */ fn_type = build_function_type (integer_type_node, arg_types); fn_ptr_type = build_pointer_type (fn_type); - name = "__cxa_atexit"; + if (use_aeabi_atexit) + name = "__aeabi_atexit"; + else + name = "__cxa_atexit"; } else { /* The declaration for `atexit' is: - int atexit (void (*)()); + int atexit (void (*)()); We build up the argument types and then then function type itself. */ @@ -5186,8 +5327,16 @@ register_dtor_fn (tree decl) args = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, get_dso_handle_node (), 0), NULL_TREE); - args = tree_cons (NULL_TREE, null_pointer_node, args); - args = tree_cons (NULL_TREE, cleanup, args); + if (targetm.cxx.use_aeabi_atexit ()) + { + args = tree_cons (NULL_TREE, cleanup, args); + args = tree_cons (NULL_TREE, null_pointer_node, args); + } + else + { + args = tree_cons (NULL_TREE, null_pointer_node, args); + args = tree_cons (NULL_TREE, cleanup, args); + } } else args = tree_cons (NULL_TREE, cleanup, NULL_TREE); @@ -5222,16 +5371,16 @@ expand_static_init (tree decl, tree init) /* Emit code to perform this initialization but once. This code looks like: - static guard; - if (!guard.first_byte) { + static guard; + if (!guard.first_byte) { if (__cxa_guard_acquire (&guard)) { bool flag = false; try { - // Do initialization. - flag = true; __cxa_guard_release (&guard); - // Register variable for destruction at end of program. + // Do initialization. + flag = true; __cxa_guard_release (&guard); + // Register variable for destruction at end of program. } catch { - if (!flag) __cxa_guard_abort (&guard); + if (!flag) __cxa_guard_abort (&guard); } } @@ -5242,11 +5391,11 @@ expand_static_init (tree decl, tree init) [stmt.dcl] - If the initialization exits by throwing an exception, the + If the initialization exits by throwing an exception, the initialization is not complete, so it will be tried again the next time control enters the declaration. - This process should be thread-safe, too; multiple threads + This process should be thread-safe, too; multiple threads should not be able to initialize the variable more than once. */ @@ -5297,15 +5446,15 @@ expand_static_init (tree decl, tree init) flag = TARGET_EXPR_SLOT (begin); TARGET_EXPR_CLEANUP (begin) - = build (COND_EXPR, void_type_node, flag, - void_zero_node, - build_call (abort_fn, guard_addr_list)); + = build3 (COND_EXPR, void_type_node, flag, + void_zero_node, + build_call (abort_fn, guard_addr_list)); CLEANUP_EH_ONLY (begin) = 1; /* Do the initialization itself. */ init = add_stmt_to_compound (begin, init); init = add_stmt_to_compound - (init, build (MODIFY_EXPR, void_type_node, flag, boolean_true_node)); + (init, build2 (MODIFY_EXPR, void_type_node, flag, boolean_true_node)); init = add_stmt_to_compound (init, build_call (release_fn, guard_addr_list)); } @@ -5339,102 +5488,52 @@ expand_static_init (tree decl, tree init) /* Make TYPE a complete type based on INITIAL_VALUE. Return 0 if successful, 1 if INITIAL_VALUE can't be deciphered, - 2 if there was no information (in which case assume 0 if DO_DEFAULT). */ + 2 if there was no information (in which case assume 0 if DO_DEFAULT), + 3 if the initializer list is empty (in pedantic mode). */ int -complete_array_type (tree type, tree initial_value, int do_default) +cp_complete_array_type (tree *ptype, tree initial_value, bool do_default) { - tree maxindex = NULL_TREE; - int value = 0; + int failure; + tree type, elt_type; if (initial_value) { /* An array of character type can be initialized from a - brace-enclosed string constant. */ - if (char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type))) - && TREE_CODE (initial_value) == CONSTRUCTOR - && CONSTRUCTOR_ELTS (initial_value) - && (TREE_CODE (TREE_VALUE (CONSTRUCTOR_ELTS (initial_value))) - == STRING_CST) - && TREE_CHAIN (CONSTRUCTOR_ELTS (initial_value)) == NULL_TREE) - initial_value = TREE_VALUE (CONSTRUCTOR_ELTS (initial_value)); - - /* Note MAXINDEX is really the maximum index, one less than the - size. */ - if (TREE_CODE (initial_value) == STRING_CST) - { - int eltsize - = int_size_in_bytes (TREE_TYPE (TREE_TYPE (initial_value))); - maxindex = build_int_cst (NULL_TREE, - (TREE_STRING_LENGTH (initial_value) - / eltsize) - 1); - } - else if (TREE_CODE (initial_value) == CONSTRUCTOR) - { - tree elts = CONSTRUCTOR_ELTS (initial_value); + brace-enclosed string constant. - maxindex = ssize_int (-1); - for (; elts; elts = TREE_CHAIN (elts)) - { - if (TREE_PURPOSE (elts)) - maxindex = TREE_PURPOSE (elts); - else - maxindex = size_binop (PLUS_EXPR, maxindex, ssize_int (1)); - } - } - else + FIXME: this code is duplicated from reshape_init. Probably + we should just call reshape_init here? */ + if (char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (*ptype))) + && TREE_CODE (initial_value) == CONSTRUCTOR + && !VEC_empty (constructor_elt, CONSTRUCTOR_ELTS (initial_value))) { - /* Make an error message unless that happened already. */ - if (initial_value != error_mark_node) - value = 1; - else - initial_value = NULL_TREE; + VEC(constructor_elt,gc) *v = CONSTRUCTOR_ELTS (initial_value); + tree value = VEC_index (constructor_elt, v, 0)->value; - /* Prevent further error messages. */ - maxindex = build_int_cst (NULL_TREE, 0); + if (TREE_CODE (value) == STRING_CST + && VEC_length (constructor_elt, v) == 1) + initial_value = value; } } - if (!maxindex) - { - if (do_default) - maxindex = build_int_cst (NULL_TREE, 0); - value = 2; - } + failure = complete_array_type (ptype, initial_value, do_default); - if (maxindex) + /* We can create the array before the element type is complete, which + means that we didn't have these two bits set in the original type + either. In completing the type, we are expected to propagate these + bits. See also complete_type which does the same thing for arrays + of fixed size. */ + type = *ptype; + if (TYPE_DOMAIN (type)) { - tree itype; - tree domain; - tree elt_type; - - domain = build_index_type (maxindex); - TYPE_DOMAIN (type) = domain; - - if (initial_value) - itype = TREE_TYPE (initial_value); - else - itype = NULL; - if (itype && !TYPE_DOMAIN (itype)) - TYPE_DOMAIN (itype) = domain; - /* The type of the main variant should never be used for arrays - of different sizes. It should only ever be completed with the - size of the array. */ - if (! TYPE_DOMAIN (TYPE_MAIN_VARIANT (type))) - TYPE_DOMAIN (TYPE_MAIN_VARIANT (type)) = domain; - elt_type = TREE_TYPE (type); - TYPE_NEEDS_CONSTRUCTING (type) - = TYPE_NEEDS_CONSTRUCTING (TYPE_MAIN_VARIANT (elt_type)); + TYPE_NEEDS_CONSTRUCTING (type) = TYPE_NEEDS_CONSTRUCTING (elt_type); TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type) - = TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TYPE_MAIN_VARIANT (elt_type)); + = TYPE_HAS_NONTRIVIAL_DESTRUCTOR (elt_type); } - /* Lay out the type now that we can get the real answer. */ - - layout_type (type); - - return value; + return failure; } /* Return zero if something is declared to be a member of type @@ -5462,12 +5561,12 @@ member_function_or_else (tree ctype, tree cur_type, enum overload_flags flags) static void bad_specifiers (tree object, - const char* type, - int virtualp, - int quals, - int inlinep, - int friendp, - int raises) + const char* type, + int virtualp, + int quals, + int inlinep, + int friendp, + int raises) { if (virtualp) error ("%qD declared as a % %s", object, type); @@ -5475,16 +5574,51 @@ bad_specifiers (tree object, error ("%qD declared as an % %s", object, type); if (quals) error ("% and % function specifiers on " - "%qD invalid in %s declaration", - object, type); + "%qD invalid in %s declaration", + object, type); if (friendp) - cp_error_at ("%qD declared as a friend", object); + error ("%q+D declared as a friend", object); if (raises && (TREE_CODE (object) == TYPE_DECL || (!TYPE_PTRFN_P (TREE_TYPE (object)) && !TYPE_REFFN_P (TREE_TYPE (object)) && !TYPE_PTRMEMFUNC_P (TREE_TYPE (object))))) - cp_error_at ("%qD declared with an exception specification", object); + error ("%q+D declared with an exception specification", object); +} + +/* DECL is a member function or static data member and is presently + being defined. Check that the definition is taking place in a + valid namespace. */ + +static void +check_class_member_definition_namespace (tree decl) +{ + /* These checks only apply to member functions and static data + members. */ + gcc_assert (TREE_CODE (decl) == FUNCTION_DECL + || TREE_CODE (decl) == VAR_DECL); + /* We check for problems with specializations in pt.c in + check_specialization_namespace, where we can issue better + diagnostics. */ + if (processing_specialization) + return; + /* There are no restrictions on the placement of + explicit instantiations. */ + if (processing_explicit_instantiation) + return; + /* [class.mfct] + + A member function definition that appears outside of the + class definition shall appear in a namespace scope enclosing + the class definition. + + [class.static.data] + + The definition for a static data member shall appear in a + namespace scope enclosing the member's class definition. */ + if (!is_ancestor (current_namespace, DECL_CONTEXT (decl))) + pedwarn ("definition of %qD is not in namespace enclosing %qT", + decl, DECL_CONTEXT (decl)); } /* CTYPE is class type, or null if non-class. @@ -5507,22 +5641,22 @@ bad_specifiers (tree object, static tree grokfndecl (tree ctype, - tree type, - tree declarator, + tree type, + tree declarator, tree parms, - tree orig_declarator, - int virtualp, - enum overload_flags flags, + tree orig_declarator, + int virtualp, + enum overload_flags flags, cp_cv_quals quals, - tree raises, - int check, - int friendp, - int publicp, - int inlinep, + tree raises, + int check, + int friendp, + int publicp, + int inlinep, special_function_kind sfk, - int funcdef_flag, - int template_count, - tree in_namespace, + int funcdef_flag, + int template_count, + tree in_namespace, tree* attrlist) { tree decl; @@ -5565,7 +5699,11 @@ grokfndecl (tree ctype, } if (ctype) - DECL_CONTEXT (decl) = ctype; + { + DECL_CONTEXT (decl) = ctype; + if (funcdef_flag) + check_class_member_definition_namespace (decl); + } if (ctype == NULL_TREE && DECL_MAIN_P (decl)) { @@ -5578,8 +5716,12 @@ grokfndecl (tree ctype, if (!same_type_p (TREE_TYPE (TREE_TYPE (decl)), integer_type_node)) { + tree oldtypeargs = TYPE_ARG_TYPES (TREE_TYPE (decl)); + tree newtype; error ("%<::main%> must return %"); - TREE_TYPE (TREE_TYPE (decl)) = integer_type_node; + newtype = build_function_type (integer_type_node, + oldtypeargs); + TREE_TYPE (decl) = newtype; } inlinep = 0; publicp = 1; @@ -5611,9 +5753,9 @@ grokfndecl (tree ctype, pedwarn ("non-local function %q#D uses anonymous type", decl); if (DECL_ORIGINAL_TYPE (TYPE_NAME (t))) - cp_pedwarn_at ("%q#D does not refer to the unqualified " - "type, so it is not used for linkage", - TYPE_NAME (t)); + pedwarn ("%q+#D does not refer to the unqualified " + "type, so it is not used for linkage", + TYPE_NAME (t)); } } else @@ -5646,7 +5788,7 @@ grokfndecl (tree ctype, } if (IDENTIFIER_OPNAME_P (DECL_NAME (decl))) - grok_op_properties (decl, friendp, /*complain=*/true); + grok_op_properties (decl, /*complain=*/true); if (ctype && decl_function_context (decl)) DECL_NO_STATIC_CHAIN (decl) = 1; @@ -5675,8 +5817,8 @@ grokfndecl (tree ctype, { /* Something like `template friend void f()'. */ error ("invalid use of template-id %qD in declaration " - "of primary template", - orig_declarator); + "of primary template", + orig_declarator); return NULL_TREE; } @@ -5685,17 +5827,17 @@ grokfndecl (tree ctype, the information in the TEMPLATE_ID_EXPR. */ SET_DECL_IMPLICIT_INSTANTIATION (decl); - if (TREE_CODE (fns) == COMPONENT_REF) - { - /* Due to bison parser ickiness, we will have already looked - up an operator_name or PFUNCNAME within the current class - (see template_id in parse.y). If the current class contains - such a name, we'll get a COMPONENT_REF here. Undo that. */ + if (TREE_CODE (fns) == COMPONENT_REF) + { + /* Due to bison parser ickiness, we will have already looked + up an operator_name or PFUNCNAME within the current class + (see template_id in parse.y). If the current class contains + such a name, we'll get a COMPONENT_REF here. Undo that. */ - gcc_assert (TREE_TYPE (TREE_OPERAND (fns, 0)) + gcc_assert (TREE_TYPE (TREE_OPERAND (fns, 0)) == current_class_type); - fns = TREE_OPERAND (fns, 1); - } + fns = TREE_OPERAND (fns, 1); + } gcc_assert (TREE_CODE (fns) == IDENTIFIER_NODE || TREE_CODE (fns) == OVERLOAD); DECL_TEMPLATE_INFO (decl) = tree_cons (fns, args, NULL_TREE); @@ -5703,16 +5845,16 @@ grokfndecl (tree ctype, if (has_default_arg) { error ("default arguments are not allowed in declaration " - "of friend template specialization %qD", - decl); + "of friend template specialization %qD", + decl); return NULL_TREE; } if (inlinep) { error ("% is not allowed in declaration of friend " - "template specialization %qD", - decl); + "template specialization %qD", + decl); return NULL_TREE; } } @@ -5761,7 +5903,7 @@ grokfndecl (tree ctype, (processing_template_decl > template_class_depth (ctype)) ? current_template_parms - : NULL_TREE); + : NULL_TREE); if (old_decl && TREE_CODE (old_decl) == TEMPLATE_DECL) /* Because grokfndecl is always supposed to return a @@ -5791,7 +5933,7 @@ grokfndecl (tree ctype, /* Attempt to merge the declarations. This can fail, in the case of some invalid specialization declarations. */ pushed_scope = push_scope (ctype); - ok = duplicate_decls (decl, old_decl); + ok = duplicate_decls (decl, old_decl, friendp); if (pushed_scope) pop_scope (pushed_scope); if (!ok) @@ -5843,11 +5985,11 @@ set_linkage_for_static_data_member (tree decl) static tree grokvardecl (tree type, - tree name, + tree name, const cp_decl_specifier_seq *declspecs, - int initialized, - int constp, - tree scope) + int initialized, + int constp, + tree scope) { tree decl; tree explicit_scope; @@ -5897,6 +6039,7 @@ grokvardecl (tree type, set_linkage_for_static_data_member (decl); /* This function is only called with out-of-class definitions. */ DECL_EXTERNAL (decl) = 0; + check_class_member_definition_namespace (decl); } /* At top level, either `static' or no s.c. makes a definition (perhaps tentative), and absence of `static' makes it public. */ @@ -5916,7 +6059,7 @@ grokvardecl (tree type, if (declspecs->specs[(int)ds_thread]) { if (targetm.have_tls) - DECL_THREAD_LOCAL (decl) = 1; + DECL_TLS_MODEL (decl) = decl_default_tls_model (decl); else /* A mere warning is sure to result in improper semantics at runtime. Don't bother to allow this to compile. */ @@ -5930,8 +6073,7 @@ grokvardecl (tree type, declare an entity with linkage. Only check this for public decls for now. */ - tree t1 = TREE_TYPE (decl); - tree t = no_linkage_check (t1, /*relaxed_p=*/false); + tree t = no_linkage_check (TREE_TYPE (decl), /*relaxed_p=*/false); if (t) { if (TYPE_ANONYMOUS_P (t)) @@ -5939,31 +6081,26 @@ grokvardecl (tree type, if (DECL_EXTERN_C_P (decl)) /* Allow this; it's pretty common in C. */ ; - else if (same_type_ignoring_top_level_qualifiers_p(t1, t)) - /* This is something like "enum { a = 3 } x;", which is - well formed. The enum doesn't have "a name with no - linkage", because it has no name. See closed CWG issue - 132. - - Note that while this construct is well formed in C++03 - it is likely to become ill formed in C++0x. See open - CWG issue 389 and related issues. */ - ; else { - /* It's a typedef referring to an anonymous type. */ - pedwarn ("non-local variable %q#D uses anonymous type", + /* DRs 132, 319 and 389 seem to indicate types with + no linkage can only be used to declare extern "C" + entities. Since it's not always an error in the + ISO C++ 90 Standard, we only issue a warning. */ + warning (0, "non-local variable %q#D uses anonymous type", decl); if (DECL_ORIGINAL_TYPE (TYPE_NAME (t))) - cp_pedwarn_at ("%q#D does not refer to the unqualified " - "type, so it is not used for linkage", - TYPE_NAME (t)); + warning (0, "%q+#D does not refer to the unqualified " + "type, so it is not used for linkage", + TYPE_NAME (t)); } } else - pedwarn ("non-local variable %q#D uses local type %qT", decl, t); + warning (0, "non-local variable %q#D uses local type %qT", decl, t); } } + else + DECL_INTERFACE_KNOWN (decl) = 1; return decl; } @@ -6077,7 +6214,7 @@ check_static_variable_definition (tree decl, tree type) if (!ARITHMETIC_TYPE_P (type) && TREE_CODE (type) != ENUMERAL_TYPE) { error ("invalid in-class initialization of static data member " - "of non-integral type %qT", + "of non-integral type %qT", type); /* If we just return the declaration, crashes will sometimes occur. We therefore return void_type_node, as if this were a @@ -6087,11 +6224,11 @@ check_static_variable_definition (tree decl, tree type) } else if (!CP_TYPE_CONST_P (type)) error ("ISO C++ forbids in-class initialization of non-const " - "static member %qD", - decl); + "static member %qD", + decl); else if (pedantic && !INTEGRAL_TYPE_P (type)) pedwarn ("ISO C++ forbids initialization of member constant " - "%qD of non-integral type %qT", decl, type); + "%qD of non-integral type %qT", decl, type); return 0; } @@ -6168,7 +6305,7 @@ compute_array_index_type (tree name, tree size) /* `(int) &fn' is not a valid array bound. */ if (name) error ("size of array %qD is not an integral constant-expression", - name); + name); else error ("size of array is not an integral constant-expression"); } @@ -6188,9 +6325,9 @@ compute_array_index_type (tree name, tree size) HOST_WIDE_INT saved_processing_template_decl; /* Compute the index of the largest element in the array. It is - one less than the number of elements in the array. We save - and restore PROCESSING_TEMPLATE_DECL so that computations in - cp_build_binary_op will be appropriately folded. */ + one less than the number of elements in the array. We save + and restore PROCESSING_TEMPLATE_DECL so that computations in + cp_build_binary_op will be appropriately folded. */ saved_processing_template_decl = processing_template_decl; processing_template_decl = 0; itype = cp_build_binary_op (MINUS_EXPR, @@ -6203,8 +6340,8 @@ compute_array_index_type (tree name, tree size) /* A variable sized array. */ itype = variable_size (itype); /* Make sure that there was no overflow when creating to a signed - index type. (For example, on a 32-bit machine, an array with - size 2^32 - 1 is too big.) */ + index type. (For example, on a 32-bit machine, an array with + size 2^32 - 1 is too big.) */ else if (TREE_OVERFLOW (itype)) { error ("overflow in array dimension"); @@ -6296,11 +6433,11 @@ create_array_type_for_decl (tree name, tree type, tree size) { if (name) error ("declaration of %qD as multidimensional array must " - "have bounds for all dimensions except the first", - name); + "have bounds for all dimensions except the first", + name); else error ("multidimensional array must have bounds for all " - "dimensions except the first"); + "dimensions except the first"); return error_mark_node; } @@ -6327,8 +6464,8 @@ create_array_type_for_decl (tree name, tree type, tree size) static tree check_special_function_return_type (special_function_kind sfk, - tree type, - tree optype) + tree type, + tree optype) { switch (sfk) { @@ -6391,7 +6528,7 @@ check_var_type (tree identifier, tree type) error ("variable or field declared void"); type = integer_type_node; } - + return type; } @@ -6437,9 +6574,9 @@ check_var_type (tree identifier, tree type) tree grokdeclarator (const cp_declarator *declarator, const cp_decl_specifier_seq *declspecs, - enum decl_context decl_context, - int initialized, - tree* attrlist) + enum decl_context decl_context, + int initialized, + tree* attrlist) { tree type = NULL_TREE; int longlong = 0; @@ -6566,13 +6703,13 @@ grokdeclarator (const cp_declarator *declarator, error ("declaration of %qD as non-function", decl); return error_mark_node; } - else if (!qualifying_scope + else if (!qualifying_scope && !(current_class_type && at_class_scope_p ())) { error ("declaration of %qD as non-member", decl); return error_mark_node; } - + type = TREE_OPERAND (decl, 0); name = IDENTIFIER_POINTER (constructor_name (type)); } @@ -6793,7 +6930,7 @@ grokdeclarator (const cp_declarator *declarator, else if (pedantic || ! is_main) pedwarn ("ISO C++ forbids declaration of %qs with no type", name); else if (warn_return_type) - warning ("ISO C++ forbids declaration of %qs with no type", name); + warning (0, "ISO C++ forbids declaration of %qs with no type", name); type = integer_type_node; } @@ -6929,12 +7066,26 @@ grokdeclarator (const cp_declarator *declarator, type_quals |= TYPE_QUAL_RESTRICT; if (sfk == sfk_conversion && type_quals != TYPE_UNQUALIFIED) error ("qualifiers are not allowed on declaration of %", - ctor_return_type); + ctor_return_type); + if (TREE_CODE (type) == FUNCTION_TYPE + && type_quals != TYPE_UNQUALIFIED) + { + /* This was an error in C++98 (cv-qualifiers cannot be added to + a function type), but DR 295 makes the code well-formed by + dropping the extra qualifiers. */ + if (pedantic) + { + tree bad_type = build_qualified_type (type, type_quals); + pedwarn ("ignoring %qV qualifiers added to function type %qT", + bad_type, type); + } + type_quals = TYPE_UNQUALIFIED; + } type_quals |= cp_type_quals (type); type = cp_build_qualified_type_real (type, type_quals, ((typedef_decl && !DECL_ARTIFICIAL (typedef_decl) - ? tf_ignore_bad_quals : 0) | tf_error | tf_warning)); + ? tf_ignore_bad_quals : 0) | tf_error | tf_warning)); /* We might have ignored or rejected some of the qualifiers. */ type_quals = cp_type_quals (type); @@ -6988,7 +7139,10 @@ grokdeclarator (const cp_declarator *declarator, /* Warn about storage classes that are invalid for certain kinds of declarations (parameters, typenames, etc.). */ if (declspecs->multiple_storage_classes_p) - error ("multiple storage classes in declaration of %qs", name); + { + error ("multiple storage classes in declaration of %qs", name); + storage_class = sc_none; + } else if (thread_p && ((storage_class && storage_class != sc_extern @@ -7018,30 +7172,7 @@ grokdeclarator (const cp_declarator *declarator, else { if (decl_context == FIELD) - { - tree tmp = NULL_TREE; - int op = 0; - - if (declarator) - { - /* Avoid trying to get an operand off an identifier node. */ - if (declarator->kind != cdk_id) - tmp = declarator->declarator->u.id.unqualified_name; - else - tmp = declarator->u.id.unqualified_name; - op = IDENTIFIER_OPNAME_P (tmp); - if (IDENTIFIER_TYPENAME_P (tmp)) - { - if (is_typename_at_global_scope (tmp)) - name = IDENTIFIER_POINTER (tmp); - else - name = ""; - } - } - error ("storage class specified for %s %qs", - op ? "member operator" : "field", - name); - } + error ("storage class specified for %qs", name); else { if (decl_context == PARM || decl_context == CATCHPARM) @@ -7064,7 +7195,7 @@ grokdeclarator (const cp_declarator *declarator, /* It's common practice (and completely valid) to have a const be initialized and declared extern. */ if (!(type_quals & TYPE_QUAL_CONST)) - warning ("%qs initialized and declared %", name); + warning (0, "%qs initialized and declared %", name); } else error ("%qs has both % and initializer", name); @@ -7119,9 +7250,7 @@ grokdeclarator (const cp_declarator *declarator, /* Determine the type of the entity declared by recurring on the declarator. */ - for (; - declarator && declarator->kind != cdk_id; - declarator = declarator->declarator) + for (; declarator; declarator = declarator->declarator) { const cp_declarator *inner_declarator; tree attrs; @@ -7129,8 +7258,6 @@ grokdeclarator (const cp_declarator *declarator, if (type == error_mark_node) return error_mark_node; - inner_declarator = declarator->declarator; - attrs = declarator->attributes; if (attrs) { @@ -7148,6 +7275,11 @@ grokdeclarator (const cp_declarator *declarator, attr_flags); } + if (declarator->kind == cdk_id) + break; + + inner_declarator = declarator->declarator; + switch (declarator->kind) { case cdk_array: @@ -7164,7 +7296,7 @@ grokdeclarator (const cp_declarator *declarator, Make sure we have a valid type for the function to return. */ /* We now know that the TYPE_QUALS don't apply to the - decl, but to its return type. */ + decl, but to its return type. */ type_quals = TYPE_UNQUALIFIED; /* Warn about some types functions can't return. */ @@ -7226,7 +7358,7 @@ grokdeclarator (const cp_declarator *declarator, return void_type_node; } } - else /* It's a constructor. */ + else /* It's a constructor. */ { if (explicitp == 1) explicitp = 2; @@ -7274,8 +7406,8 @@ grokdeclarator (const cp_declarator *declarator, error ("friend declaration not in class definition"); if (current_function_decl && funcdef_flag) error ("can't define friend function %qs in a local " - "class definition", - name); + "class definition", + name); } arg_types = grokparms (declarator->u.function.parameters, @@ -7292,6 +7424,7 @@ grokdeclarator (const cp_declarator *declarator, } type = build_function_type (type, arg_types); + type = cp_build_qualified_type (type, quals); } break; @@ -7324,7 +7457,15 @@ grokdeclarator (const cp_declarator *declarator, && (TREE_CODE (type) == FUNCTION_TYPE || (quals && TREE_CODE (type) == METHOD_TYPE))) { - tree dummy = build_decl (TYPE_DECL, NULL_TREE, type); + tree dummy; + + /* If the type is a FUNCTION_TYPE, pick up the + qualifiers from that function type. No other + qualifiers may be supplied. */ + if (TREE_CODE (type) == FUNCTION_TYPE) + quals = cp_type_quals (type); + + dummy = build_decl (TYPE_DECL, NULL_TREE, type); grok_method_quals (declarator->u.pointer.class_type, dummy, quals); type = TREE_TYPE (dummy); @@ -7348,6 +7489,9 @@ grokdeclarator (const cp_declarator *declarator, declarator->u.pointer.class_type); type = build_pointer_type (type); } + else if (declarator->u.pointer.class_type == error_mark_node) + /* We will already have complained. */ + type = error_mark_node; else type = build_ptrmem_type (declarator->u.pointer.class_type, type); @@ -7385,8 +7529,13 @@ grokdeclarator (const cp_declarator *declarator, unqualified_id = dname; } - /* If DECLARATOR is non-NULL, we know it is a cdk_id declarator; - otherwise, we would not have exited the loop above. */ + /* If TYPE is a FUNCTION_TYPE, but the function name was explicitly + qualified with a class-name, turn it into a METHOD_TYPE, unless + we know that the function is static. We take advantage of this + opportunity to do other processing that pertains to entities + explicitly declared to be class members. Note that if DECLARATOR + is non-NULL, we know it is a cdk_id declarator; otherwise, we + would not have exited the loop above. */ if (declarator && declarator->u.id.qualifying_scope && TYPE_P (declarator->u.id.qualifying_scope)) @@ -7408,9 +7557,13 @@ grokdeclarator (const cp_declarator *declarator, is correct; there shouldn't be a `template <>' for the definition of `S::f'. */ - if (CLASSTYPE_TEMPLATE_INFO (t) - && (CLASSTYPE_TEMPLATE_INSTANTIATION (t) - || uses_template_parms (CLASSTYPE_TI_ARGS (t))) + if (CLASSTYPE_TEMPLATE_SPECIALIZATION (t) + && !any_dependent_template_arguments_p (CLASSTYPE_TI_ARGS (t))) + /* T is an explicit (not partial) specialization. All + containing classes must therefore also be explicitly + specialized. */ + break; + if ((CLASSTYPE_USE_TEMPLATE (t) || CLASSTYPE_IS_TEMPLATE (t)) && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (t))) template_count += 1; @@ -7419,17 +7572,8 @@ grokdeclarator (const cp_declarator *declarator, } if (ctype == current_class_type) - { - /* class A { - void A::f (); - }; - - Is this ill-formed? */ - - if (pedantic) - pedwarn ("extra qualification %<%T::%> on member %qs ignored", - ctype, name); - } + pedwarn ("extra qualification %<%T::%> on member %qs", + ctype, name); else if (TREE_CODE (type) == FUNCTION_TYPE) { tree sname = declarator->u.id.unqualified_name; @@ -7447,7 +7591,7 @@ grokdeclarator (const cp_declarator *declarator, else { error ("cannot declare member function %<%T::%s%> within %<%T%>", - ctype, name, current_class_type); + ctype, name, current_class_type); return error_mark_node; } } @@ -7473,6 +7617,8 @@ grokdeclarator (const cp_declarator *declarator, } } + /* Now TYPE has the actual type. */ + if (returned_attrs) { if (attrlist) @@ -7481,13 +7627,12 @@ grokdeclarator (const cp_declarator *declarator, attrlist = &returned_attrs; } - /* Now TYPE has the actual type. */ - /* Did array size calculations overflow? */ if (TREE_CODE (type) == ARRAY_TYPE && COMPLETE_TYPE_P (type) - && TREE_OVERFLOW (TYPE_SIZE (type))) + && TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST + && TREE_OVERFLOW (TYPE_SIZE_UNIT (type))) { error ("size of array %qs is too large", name); /* If we proceed with the array type as it is, we'll eventually @@ -7509,7 +7654,7 @@ grokdeclarator (const cp_declarator *declarator, if (explicitp == 1 || (explicitp && friendp)) { /* [dcl.fct.spec] The explicit specifier shall only be used in - declarations of constructors within a class definition. */ + declarations of constructors within a class definition. */ error ("only declarations of constructors can be %"); explicitp = 0; } @@ -7517,21 +7662,21 @@ grokdeclarator (const cp_declarator *declarator, if (storage_class == sc_mutable) { if (decl_context != FIELD || friendp) - { + { error ("non-member %qs cannot be declared %", name); storage_class = sc_none; - } + } else if (decl_context == TYPENAME || declspecs->specs[(int)ds_typedef]) { error ("non-object member %qs cannot be declared %", name); storage_class = sc_none; } else if (TREE_CODE (type) == FUNCTION_TYPE - || TREE_CODE (type) == METHOD_TYPE) - { + || TREE_CODE (type) == METHOD_TYPE) + { error ("function %qs cannot be declared %", name); storage_class = sc_none; - } + } else if (staticp) { error ("static %qs cannot be declared %", name); @@ -7566,7 +7711,7 @@ grokdeclarator (const cp_declarator *declarator, if (!current_function_decl) DECL_CONTEXT (decl) = FROB_CONTEXT (current_namespace); else if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (current_function_decl) - || (DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P + || (DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (current_function_decl))) /* The TYPE_DECL is "abstract" because there will be clones of this constructor/destructor, and there will @@ -7618,11 +7763,12 @@ grokdeclarator (const cp_declarator *declarator, { if (ctype == NULL_TREE) { - if (TREE_CODE (type) != METHOD_TYPE) - error ("%Jinvalid type qualifier for non-member function type", - decl); - else + if (TREE_CODE (type) == METHOD_TYPE) ctype = TYPE_METHOD_BASETYPE (type); + /* Any qualifiers on a function type typedef have + already been dealt with. */ + else if (TREE_CODE (type) == FUNCTION_TYPE) + quals = TYPE_UNQUALIFIED; } if (ctype != NULL_TREE) grok_method_quals (ctype, decl, quals); @@ -7665,6 +7811,23 @@ grokdeclarator (const cp_declarator *declarator, } parms = nreverse (decls); + + if (decl_context != TYPENAME) + { + /* A cv-qualifier-seq shall only be part of the function type + for a non-static member function. [8.3.5/4 dcl.fct] */ + if (cp_type_quals (type) != TYPE_UNQUALIFIED + && (current_class_type == NULL_TREE || staticp) ) + { + error ("qualified function types cannot be used to declare %s functions", + (staticp? "static member" : "free")); + type = TYPE_MAIN_VARIANT (type); + } + + /* The qualifiers on the function type become the qualifiers on + the non-static member function. */ + quals |= cp_type_quals (type); + } } /* If this is a type name (such as, in a cast or sizeof), @@ -7697,11 +7860,11 @@ grokdeclarator (const cp_declarator *declarator, if (TREE_CODE (type) == TEMPLATE_TYPE_PARM) pedwarn ("template parameters cannot be friends"); else if (TREE_CODE (type) == TYPENAME_TYPE) - pedwarn ("friend declaration requires class-key, " + pedwarn ("friend declaration requires class-key, " "i.e. %", TYPE_CONTEXT (type), TYPENAME_TYPE_FULLNAME (type)); else - pedwarn ("friend declaration requires class-key, " + pedwarn ("friend declaration requires class-key, " "i.e. %", type); } @@ -7715,7 +7878,7 @@ grokdeclarator (const cp_declarator *declarator, /*complain=*/true); else error ("trying to make class %qT a friend of global scope", - type); + type); type = void_type_node; } @@ -7725,9 +7888,9 @@ grokdeclarator (const cp_declarator *declarator, if (ctype == NULL_TREE) { if (TREE_CODE (type) != METHOD_TYPE) - error ("invalid qualifiers on non-member function type"); + error ("invalid qualifiers on non-member function type"); else - ctype = TYPE_METHOD_BASETYPE (type); + ctype = TYPE_METHOD_BASETYPE (type); } if (ctype) { @@ -7848,7 +8011,7 @@ grokdeclarator (const cp_declarator *declarator, if (virtualp) { error ("%qD cannot be declared virtual, since it " - "is always static", + "is always static", unqualified_id); virtualp = 0; } @@ -7860,15 +8023,25 @@ grokdeclarator (const cp_declarator *declarator, } /* Check that the name used for a destructor makes sense. */ - if (sfk == sfk_destructor - && !same_type_p (TREE_OPERAND - (id_declarator->u.id.unqualified_name, 0), - ctype)) + if (sfk == sfk_destructor) { - error ("declaration of %qD as member of %qT", - id_declarator->u.id.unqualified_name, - ctype); - return error_mark_node; + if (!ctype) + { + gcc_assert (friendp); + error ("expected qualified name in friend declaration " + "for destructor %qD", + id_declarator->u.id.unqualified_name); + return error_mark_node; + } + + if (!same_type_p (TREE_OPERAND + (id_declarator->u.id.unqualified_name, 0), + ctype)) + { + error ("declaration of %qD as member of %qT", + id_declarator->u.id.unqualified_name, ctype); + return error_mark_node; + } } /* Tell grokfndecl if it needs to set TREE_PUBLIC on the node. */ @@ -7931,8 +8104,8 @@ grokdeclarator (const cp_declarator *declarator, unqualified_id, virtualp, flags, quals, raises, friendp ? -1 : 0, friendp, 1, 0, sfk, - funcdef_flag, template_count, in_namespace, - attrlist); + funcdef_flag, template_count, in_namespace, + attrlist); if (decl == NULL_TREE) return NULL_TREE; } @@ -7953,7 +8126,7 @@ grokdeclarator (const cp_declarator *declarator, && declspecs->type && declspecs->type == type) error (" in instantiation of template %qT", - current_class_type); + current_class_type); type = error_mark_node; decl = NULL_TREE; @@ -7963,7 +8136,7 @@ grokdeclarator (const cp_declarator *declarator, if (friendp) { error ("%qE is neither function nor member function; " - "cannot be declared friend", unqualified_id); + "cannot be declared friend", unqualified_id); friendp = 0; } decl = NULL_TREE; @@ -7973,8 +8146,8 @@ grokdeclarator (const cp_declarator *declarator, { /* Friends are treated specially. */ if (ctype == current_class_type) - warning ("member functions are implicitly friends of their class"); - else if (decl && DECL_NAME (decl)) + warning (0, "member functions are implicitly friends of their class"); + else if (decl && DECL_NAME (decl)) { if (template_class_depth (current_class_type) == 0) { @@ -8089,10 +8262,10 @@ grokdeclarator (const cp_declarator *declarator, { if (storage_class == sc_static) pedwarn ("% specified invalid for function %qs " - "declared out of global scope", name); + "declared out of global scope", name); else pedwarn ("% specifier invalid for function %qs " - "declared out of global scope", name); + "declared out of global scope", name); } if (ctype == NULL_TREE) @@ -8131,7 +8304,7 @@ grokdeclarator (const cp_declarator *declarator, if (TREE_CODE (type) == METHOD_TYPE) { pedwarn ("cannot declare member function %qD to have " - "static linkage", decl); + "static linkage", decl); invalid_static = 1; } else if (current_function_decl) @@ -8166,9 +8339,9 @@ grokdeclarator (const cp_declarator *declarator, DECL_CONTEXT (decl) = ctype; if (staticp == 1) { - pedwarn ("% may not be used when defining " - "(as opposed to declaring) a static data member"); - staticp = 0; + pedwarn ("% may not be used when defining " + "(as opposed to declaring) a static data member"); + staticp = 0; storage_class = sc_none; } if (storage_class == sc_register && TREE_STATIC (decl)) @@ -8178,9 +8351,9 @@ grokdeclarator (const cp_declarator *declarator, } if (storage_class == sc_extern && pedantic) { - pedwarn ("cannot explicitly declare member %q#D to have " - "extern linkage", - decl); + pedwarn ("cannot explicitly declare member %q#D to have " + "extern linkage", + decl); storage_class = sc_none; } } @@ -8200,7 +8373,7 @@ grokdeclarator (const cp_declarator *declarator, when processing a template; we'll do this for the instantiated declaration based on the type of DECL. */ if (!processing_template_decl) - c_apply_type_quals_to_decl (type_quals, decl); + cp_apply_type_quals_to_decl (type_quals, decl); return decl; } @@ -8217,14 +8390,16 @@ require_complete_types_for_parms (tree parms) { if (dependent_type_p (TREE_TYPE (parms))) continue; - if (VOID_TYPE_P (TREE_TYPE (parms))) - /* grokparms will have already issued an error. */ - TREE_TYPE (parms) = error_mark_node; - else if (complete_type_or_else (TREE_TYPE (parms), parms)) + if (!VOID_TYPE_P (TREE_TYPE (parms)) + && complete_type_or_else (TREE_TYPE (parms), parms)) { - layout_decl (parms, 0); + relayout_decl (parms); DECL_ARG_TYPE (parms) = type_passed_as (TREE_TYPE (parms)); } + else + /* grokparms or complete_type_or_else will have already issued + an error. */ + TREE_TYPE (parms) = error_mark_node; } } @@ -8290,13 +8465,6 @@ check_default_argument (tree decl, tree arg) deal with it after the class is complete. */ return arg; - if (processing_template_decl || uses_template_parms (arg)) - /* We don't do anything checking until instantiation-time. Note - that there may be uninstantiated arguments even for an - instantiated function, since default arguments are not - instantiated until they are needed. */ - return arg; - if (TYPE_P (decl)) { decl_type = decl; @@ -8318,14 +8486,14 @@ check_default_argument (tree decl, tree arg) A default argument expression is implicitly converted to the parameter type. */ if (!TREE_TYPE (arg) - || !can_convert_arg (decl_type, TREE_TYPE (arg), arg)) + || !can_convert_arg (decl_type, TREE_TYPE (arg), arg, LOOKUP_NORMAL)) { if (decl) error ("default argument for %q#D has type %qT", - decl, TREE_TYPE (arg)); + decl, TREE_TYPE (arg)); else error ("default argument for parameter of type %qT has type %qT", - decl_type, TREE_TYPE (arg)); + decl_type, TREE_TYPE (arg)); return error_mark_node; } @@ -8375,32 +8543,32 @@ grokparms (cp_parameter_declarator *first_parm, tree *parms) tree decl; if (parm == no_parameters) - break; + break; attrs = parm->decl_specifiers.attributes; parm->decl_specifiers.attributes = NULL_TREE; decl = grokdeclarator (parm->declarator, &parm->decl_specifiers, PARM, init != NULL_TREE, &attrs); if (! decl || TREE_TYPE (decl) == error_mark_node) - continue; + continue; if (attrs) cplus_decl_attributes (&decl, attrs, 0); type = TREE_TYPE (decl); if (VOID_TYPE_P (type)) - { - if (same_type_p (type, void_type_node) - && !DECL_NAME (decl) && !result && !parm->next && !ellipsis) - /* this is a parmlist of `(void)', which is ok. */ - break; - cxx_incomplete_type_error (decl, type); + { + if (same_type_p (type, void_type_node) + && !DECL_NAME (decl) && !result && !parm->next && !ellipsis) + /* this is a parmlist of `(void)', which is ok. */ + break; + cxx_incomplete_type_error (decl, type); /* It's not a good idea to actually create parameters of type `void'; other parts of the compiler assume that a void type terminates the parameter list. */ type = error_mark_node; TREE_TYPE (decl) = error_mark_node; - } + } if (type != error_mark_node) { @@ -8422,26 +8590,26 @@ grokparms (cp_parameter_declarator *first_parm, tree *parms) tree t = TREE_TYPE (type); int ptr = TYPE_PTR_P (type); - while (1) - { - if (TYPE_PTR_P (t)) - ptr = 1; - else if (TREE_CODE (t) != ARRAY_TYPE) - break; - else if (!TYPE_DOMAIN (t)) - break; - t = TREE_TYPE (t); - } + while (1) + { + if (TYPE_PTR_P (t)) + ptr = 1; + else if (TREE_CODE (t) != ARRAY_TYPE) + break; + else if (!TYPE_DOMAIN (t)) + break; + t = TREE_TYPE (t); + } if (TREE_CODE (t) == ARRAY_TYPE) error ("parameter %qD includes %s to array of unknown " - "bound %qT", - decl, ptr ? "pointer" : "reference", t); + "bound %qT", + decl, ptr ? "pointer" : "reference", t); } - if (!any_error && init) - init = check_default_argument (decl, init); - else + if (any_error) init = NULL_TREE; + else if (init && !processing_template_decl) + init = check_default_argument (decl, init); } TREE_CHAIN (decl) = decls; @@ -8485,7 +8653,7 @@ copy_fn_p (tree d) gcc_assert (DECL_FUNCTION_MEMBER_P (d)); - if (DECL_TEMPLATE_INFO (d) + if (DECL_TEMPLATE_INFO (d) && DECL_MEMBER_TEMPLATE_P (DECL_TI_TEMPLATE (d))) /* Instantiations of template member functions are never copy functions. Note that member functions of templated classes are @@ -8536,11 +8704,11 @@ void grok_special_member_properties (tree decl) { /* [class.copy] - A non-template constructor for class X is a copy - constructor if its first parameter is of type X&, const - X&, volatile X& or const volatile X&, and either there - are no other parameters or else all other parameters have - default arguments. */ + A non-template constructor for class X is a copy + constructor if its first parameter is of type X&, const + X&, volatile X& or const volatile X&, and either there + are no other parameters or else all other parameters have + default arguments. */ TYPE_HAS_INIT_REF (DECL_CONTEXT (decl)) = 1; if (ctor > 1) TYPE_HAS_CONST_INIT_REF (DECL_CONTEXT (decl)) = 1; @@ -8552,9 +8720,9 @@ void grok_special_member_properties (tree decl) { /* [class.copy] - A non-template assignment operator for class X is a copy - assignment operator if its parameter is of type X, X&, const - X&, volatile X& or const volatile X&. */ + A non-template assignment operator for class X is a copy + assignment operator if its parameter is of type X, X&, const + X&, volatile X& or const volatile X&. */ int assop = copy_fn_p (decl); @@ -8579,19 +8747,19 @@ grok_ctor_properties (tree ctype, tree decl) { /* [class.copy] - A declaration of a constructor for a class X is ill-formed if - its first parameter is of type (optionally cv-qualified) X - and either there are no other parameters or else all other - parameters have default arguments. - - We *don't* complain about member template instantiations that - have this form, though; they can occur as we try to decide - what constructor to use during overload resolution. Since - overload resolution will never prefer such a constructor to - the non-template copy constructor (which is either explicitly - or implicitly defined), there's no need to worry about their - existence. Theoretically, they should never even be - instantiated, but that's hard to forestall. */ + A declaration of a constructor for a class X is ill-formed if + its first parameter is of type (optionally cv-qualified) X + and either there are no other parameters or else all other + parameters have default arguments. + + We *don't* complain about member template instantiations that + have this form, though; they can occur as we try to decide + what constructor to use during overload resolution. Since + overload resolution will never prefer such a constructor to + the non-template copy constructor (which is either explicitly + or implicitly defined), there's no need to worry about their + existence. Theoretically, they should never even be + instantiated, but that's hard to forestall. */ error ("invalid constructor; you probably meant %<%T (const %T&)%>", ctype, ctype); return 0; @@ -8607,7 +8775,7 @@ ambi_op_p (enum tree_code code) { return (code == INDIRECT_REF || code == ADDR_EXPR - || code == CONVERT_EXPR + || code == UNARY_PLUS_EXPR || code == NEGATE_EXPR || code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR); @@ -8624,12 +8792,11 @@ unary_op_p (enum tree_code code) || code == TYPE_EXPR); } -/* DECL is a declaration for an overloaded operator. Returns true if - the declaration is valid; false otherwise. If COMPLAIN is true, +/* DECL is a declaration for an overloaded operator. If COMPLAIN is true, errors are issued for invalid declarations. */ -bool -grok_op_properties (tree decl, int friendp, bool complain) +void +grok_op_properties (tree decl, bool complain) { tree argtypes = TYPE_ARG_TYPES (TREE_TYPE (decl)); tree argtype; @@ -8637,10 +8804,7 @@ grok_op_properties (tree decl, int friendp, bool complain) tree name = DECL_NAME (decl); enum tree_code operator_code; int arity; - bool ok; - - /* Assume that the declaration is valid. */ - ok = true; + tree class_type; /* Count the number of arguments. */ for (argtype = argtypes, arity = 0; @@ -8648,8 +8812,9 @@ grok_op_properties (tree decl, int friendp, bool complain) argtype = TREE_CHAIN (argtype)) ++arity; - if (current_class_type == NULL_TREE) - friendp = 1; + class_type = DECL_CONTEXT (decl); + if (class_type && !CLASS_TYPE_P (class_type)) + class_type = NULL_TREE; if (DECL_CONV_FN_P (decl)) operator_code = TYPE_EXPR; @@ -8678,30 +8843,28 @@ grok_op_properties (tree decl, int friendp, bool complain) gcc_assert (operator_code != LAST_CPLUS_TREE_CODE); SET_OVERLOADED_OPERATOR_CODE (decl, operator_code); - if (! friendp) - { - switch (operator_code) - { - case NEW_EXPR: - TYPE_HAS_NEW_OPERATOR (current_class_type) = 1; - break; + if (class_type) + switch (operator_code) + { + case NEW_EXPR: + TYPE_HAS_NEW_OPERATOR (class_type) = 1; + break; - case DELETE_EXPR: - TYPE_GETS_DELETE (current_class_type) |= 1; - break; + case DELETE_EXPR: + TYPE_GETS_DELETE (class_type) |= 1; + break; - case VEC_NEW_EXPR: - TYPE_HAS_ARRAY_NEW_OPERATOR (current_class_type) = 1; - break; + case VEC_NEW_EXPR: + TYPE_HAS_ARRAY_NEW_OPERATOR (class_type) = 1; + break; - case VEC_DELETE_EXPR: - TYPE_GETS_DELETE (current_class_type) |= 2; - break; + case VEC_DELETE_EXPR: + TYPE_GETS_DELETE (class_type) |= 2; + break; - default: - break; - } - } + default: + break; + } /* [basic.std.dynamic.allocation]/1: @@ -8738,14 +8901,20 @@ grok_op_properties (tree decl, int friendp, bool complain) || operator_code == COMPONENT_REF || operator_code == ARRAY_REF || operator_code == NOP_EXPR) - error ("%qD must be a nonstatic member function", decl); + { + error ("%qD must be a nonstatic member function", decl); + return; + } else { tree p; if (DECL_STATIC_FUNCTION_P (decl)) - error ("%qD must be either a non-static member " - "function or a non-member function", decl); + { + error ("%qD must be either a non-static member " + "function or a non-member function", decl); + return; + } for (p = argtypes; p && p != void_list_node; p = TREE_CHAIN (p)) { @@ -8760,12 +8929,11 @@ grok_op_properties (tree decl, int friendp, bool complain) if (!p || p == void_list_node) { if (!complain) - return false; + return; error ("%qD must have an argument of class or " "enumerated type", decl); - ok = false; } } } @@ -8773,34 +8941,40 @@ grok_op_properties (tree decl, int friendp, bool complain) /* There are no restrictions on the arguments to an overloaded "operator ()". */ if (operator_code == CALL_EXPR) - return ok; + return; - if (IDENTIFIER_TYPENAME_P (name) && ! DECL_TEMPLATE_INFO (decl)) + /* Warn about conversion operators that will never be used. */ + if (IDENTIFIER_TYPENAME_P (name) + && ! DECL_TEMPLATE_INFO (decl) + && warn_conversion + /* Warn only declaring the function; there is no need to + warn again about out-of-class definitions. */ + && class_type == current_class_type) { tree t = TREE_TYPE (name); - if (! friendp) - { - int ref = (TREE_CODE (t) == REFERENCE_TYPE); - const char *what = 0; + int ref = (TREE_CODE (t) == REFERENCE_TYPE); + const char *what = 0; - if (ref) - t = TYPE_MAIN_VARIANT (TREE_TYPE (t)); + if (ref) + t = TYPE_MAIN_VARIANT (TREE_TYPE (t)); - if (TREE_CODE (t) == VOID_TYPE) - what = "void"; - else if (t == current_class_type) + if (TREE_CODE (t) == VOID_TYPE) + what = "void"; + else if (class_type) + { + if (t == class_type) what = "the same type"; /* Don't force t to be complete here. */ else if (IS_AGGR_TYPE (t) && COMPLETE_TYPE_P (t) - && DERIVED_FROM_P (t, current_class_type)) + && DERIVED_FROM_P (t, class_type)) what = "a base class"; - - if (what && warn_conversion) - warning ("conversion to %s%s will never use a type " - "conversion operator", - ref ? "a reference to " : "", what); } + + if (what) + warning (0, "conversion to %s%s will never use a type " + "conversion operator", + ref ? "a reference to " : "", what); } if (operator_code == COND_EXPR) { @@ -8827,7 +9001,7 @@ grok_op_properties (tree decl, int friendp, bool complain) operator_code = BIT_AND_EXPR; break; - case CONVERT_EXPR: + case UNARY_PLUS_EXPR: operator_code = PLUS_EXPR; break; @@ -8889,13 +9063,13 @@ grok_op_properties (tree decl, int friendp, bool complain) if (TREE_CODE (ret) != REFERENCE_TYPE || !same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (ret)), arg)) - warning ("prefix %qD should return %qT", decl, - build_reference_type (arg)); + warning (0, "prefix %qD should return %qT", decl, + build_reference_type (arg)); } else { if (!same_type_p (TYPE_MAIN_VARIANT (ret), arg)) - warning ("postfix %qD should return %qT", decl, arg); + warning (0, "postfix %qD should return %qT", decl, arg); } } } @@ -8924,8 +9098,8 @@ grok_op_properties (tree decl, int friendp, bool complain) && (operator_code == TRUTH_ANDIF_EXPR || operator_code == TRUTH_ORIF_EXPR || operator_code == COMPOUND_EXPR)) - warning ("user-defined %qD always evaluates both arguments", - decl); + warning (0, "user-defined %qD always evaluates both arguments", + decl); } /* Effective C++ rule 23. */ @@ -8938,27 +9112,26 @@ grok_op_properties (tree decl, int friendp, bool complain) || operator_code == MULT_EXPR || operator_code == TRUNC_MOD_EXPR) && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == REFERENCE_TYPE) - warning ("%qD should return by value", decl); + warning (0, "%qD should return by value", decl); /* [over.oper]/8 */ for (; argtypes && argtypes != void_list_node; - argtypes = TREE_CHAIN (argtypes)) - if (TREE_PURPOSE (argtypes)) - { - TREE_PURPOSE (argtypes) = NULL_TREE; - if (operator_code == POSTINCREMENT_EXPR + argtypes = TREE_CHAIN (argtypes)) + if (TREE_PURPOSE (argtypes)) + { + TREE_PURPOSE (argtypes) = NULL_TREE; + if (operator_code == POSTINCREMENT_EXPR || operator_code == POSTDECREMENT_EXPR) - { - if (pedantic) - pedwarn ("%qD cannot have default arguments", decl); - } - else - error ("%qD cannot have default arguments", decl); - } + { + if (pedantic) + pedwarn ("%qD cannot have default arguments", decl); + } + else + error ("%qD cannot have default arguments", decl); + } } - return ok; } /* Return a string giving the keyword associate with CODE. */ @@ -9027,7 +9200,7 @@ check_elaborated_type_specifier (enum tag_types tag_code, && tag_code != typename_type) { error ("using typedef-name %qD after %qs", decl, tag_name (tag_code)); - cp_error_at ("%qD has a previous declaration here", decl); + error ("%q+D has a previous declaration here", decl); return error_mark_node; } else if (TREE_CODE (type) != RECORD_TYPE @@ -9036,15 +9209,14 @@ check_elaborated_type_specifier (enum tag_types tag_code, && tag_code != typename_type) { error ("%qT referred to as %qs", type, tag_name (tag_code)); - cp_error_at ("%qT has a previous declaration here", type); + error ("%q+T has a previous declaration here", type); return error_mark_node; } else if (TREE_CODE (type) != ENUMERAL_TYPE - && tag_code == enum_type - && tag_code != typename_type) + && tag_code == enum_type) { error ("%qT referred to as enum", type); - cp_error_at ("%qT has a previous declaration here", type); + error ("%q+T has a previous declaration here", type); return error_mark_node; } else if (!allow_template_p @@ -9058,7 +9230,6 @@ check_elaborated_type_specifier (enum tag_types tag_code, 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))); @@ -9080,7 +9251,19 @@ lookup_and_check_tag (enum tag_types tag_code, tree name, tree t; tree decl; if (scope == ts_global) - decl = lookup_name (name, 2); + { + /* First try ordinary name lookup, ignoring hidden class name + injected via friend declaration. */ + decl = lookup_name (name, 2); + /* If that fails, the name will be placed in the smallest + non-class, non-function-prototype scope according to 3.3.1/5. + We may already have a hidden name declared as friend in this + scope. So lookup again but not ignoring hidden name. + If we find one, that name will be made visible rather than + creating a new tag. */ + if (!decl) + decl = lookup_type_scope (name, ts_within_enclosing_non_class); + } else decl = lookup_type_scope (name, scope); @@ -9240,8 +9423,7 @@ xref_tag (enum tag_types tag_code, tree name, { t = make_aggr_type (code); TYPE_CONTEXT (t) = context; - /* pushtag only cares whether SCOPE is zero or not. */ - t = pushtag (name, t, scope != ts_current); + t = pushtag (name, t, scope); } } else @@ -9255,6 +9437,20 @@ xref_tag (enum tag_types tag_code, tree name, error ("redeclaration of %qT as a non-template", t); t = error_mark_node; } + + /* Make injected friend class visible. */ + if (scope != ts_within_enclosing_non_class + && hidden_name_p (TYPE_NAME (t))) + { + DECL_ANTICIPATED (TYPE_NAME (t)) = 0; + DECL_FRIEND_P (TYPE_NAME (t)) = 0; + + if (TYPE_TEMPLATE_INFO (t)) + { + DECL_ANTICIPATED (TYPE_TI_TEMPLATE (t)) = 0; + DECL_FRIEND_P (TYPE_TI_TEMPLATE (t)) = 0; + } + } } POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t); @@ -9340,7 +9536,7 @@ xref_basetypes (tree ref, tree base_list) if (max_bases) { - BINFO_BASE_ACCESSES (binfo) = VEC_alloc (tree, max_bases); + BINFO_BASE_ACCESSES (binfo) = VEC_alloc (tree, gc, max_bases); /* An aggregate cannot have baseclasses. */ CLASSTYPE_NON_AGGREGATE (ref) = 1; @@ -9356,7 +9552,7 @@ xref_basetypes (tree ref, tree base_list) if (max_vbases) { - CLASSTYPE_VBASECLASSES (ref) = VEC_alloc (tree, max_vbases); + CLASSTYPE_VBASECLASSES (ref) = VEC_alloc (tree, gc, max_vbases); if (TYPE_FOR_JAVA (ref)) error ("Java class %qT cannot have virtual bases", ref); @@ -9405,7 +9601,7 @@ xref_basetypes (tree ref, tree base_list) CLASSTYPE_REPEATED_BASE_P (ref) |= CLASSTYPE_REPEATED_BASE_P (basetype); } - + /* We must do this test after we've seen through a typedef type. */ if (TYPE_MARKED_P (basetype)) @@ -9496,7 +9692,7 @@ start_enum (tree name) name = make_anon_name (); enumtype = make_node (ENUMERAL_TYPE); - enumtype = pushtag (name, enumtype, 0); + enumtype = pushtag (name, enumtype, /*tag_scope=*/ts_current); } return enumtype; @@ -9560,6 +9756,8 @@ finish_enum (tree enumtype) /* Update the minimum and maximum values, if appropriate. */ value = DECL_INITIAL (decl); + if (value == error_mark_node) + value = integer_zero_node; /* Figure out what the minimum and maximum values of the enumerators are. */ if (!minnode) @@ -9662,13 +9860,18 @@ finish_enum (tree enumtype) type of the enumeration. */ for (values = TYPE_VALUES (enumtype); values; values = TREE_CHAIN (values)) { + location_t saved_location; + decl = TREE_VALUE (values); + saved_location = input_location; + input_location = DECL_SOURCE_LOCATION (decl); value = perform_implicit_conversion (underlying_type, DECL_INITIAL (decl)); + input_location = saved_location; /* Do not clobber shared ints. */ value = copy_node (value); - + TREE_TYPE (value) = enumtype; DECL_INITIAL (decl) = value; TREE_VALUE (values) = value; @@ -9743,7 +9946,7 @@ build_enumerator (tree name, tree value, tree enumtype) bool overflowed; /* The next value is the previous value plus one. We can - safely assume that the previous value is an INTEGER_CST. + safely assume that the previous value is an INTEGER_CST. add_double doesn't know the type of the target expression, so we must check with int_fits_type_p as well. */ prev_value = DECL_INITIAL (TREE_VALUE (TYPE_VALUES (enumtype))); @@ -9754,7 +9957,10 @@ build_enumerator (tree name, tree value, tree enumtype) overflowed |= !int_fits_type_p (value, TREE_TYPE (prev_value)); if (overflowed) - error ("overflow in enumeration values at %qD", name); + { + error ("overflow in enumeration values at %qD", name); + value = error_mark_node; + } } else value = integer_zero_node; @@ -9825,25 +10031,20 @@ check_function_type (tree decl, tree current_function_parms) return; if (!COMPLETE_OR_VOID_TYPE_P (return_type)) { - error ("return type %q#T is incomplete", TREE_TYPE (fntype)); + tree args = TYPE_ARG_TYPES (fntype); + + error ("return type %q#T is incomplete", return_type); - /* Make it return void instead, but don't change the - type of the DECL_RESULT, in case we have a named return value. */ + /* Make it return void instead. */ if (TREE_CODE (fntype) == METHOD_TYPE) - { - tree ctype = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (fntype))); - TREE_TYPE (decl) - = build_method_type_directly (ctype, - void_type_node, - FUNCTION_ARG_CHAIN (decl)); - } + fntype = build_method_type_directly (TREE_TYPE (TREE_VALUE (args)), + void_type_node, + TREE_CHAIN (args)); else - TREE_TYPE (decl) - = build_function_type (void_type_node, - TYPE_ARG_TYPES (TREE_TYPE (decl))); + fntype = build_function_type (void_type_node, args); TREE_TYPE (decl) = build_exception_variant (fntype, - TYPE_RAISES_EXCEPTIONS (fntype)); + TYPE_RAISES_EXCEPTIONS (TREE_TYPE (decl))); } else abstract_virtuals_error (decl, TREE_TYPE (fntype)); @@ -9876,7 +10077,9 @@ start_preparsed_function (tree decl1, tree attrs, int flags) int doing_friend = 0; struct cp_binding_level *bl; tree current_function_parms; - struct c_fileinfo *finfo = get_fileinfo (lbasename (input_filename)); + struct c_fileinfo *finfo + = get_fileinfo (lbasename (LOCATION_FILE (DECL_SOURCE_LOCATION (decl1)))); + bool honor_interface; /* Sanity check. */ gcc_assert (TREE_CODE (TREE_VALUE (void_list_node)) == VOID_TYPE); @@ -9903,7 +10106,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags) if (DECL_DECLARED_INLINE_P (decl1) && lookup_attribute ("noinline", attrs)) - warning ("%Jinline function %qD given attribute noinline", decl1, decl1); + warning (0, "inline function %q+D given attribute noinline", decl1); if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (decl1)) /* This is a constructor, we must ensure that any default args @@ -9940,7 +10143,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags) if (warn_ecpp && DECL_OVERLOADED_OPERATOR_P (decl1) == NOP_EXPR && TREE_CODE (TREE_TYPE (fntype)) == VOID_TYPE) - warning ("% should return a reference to %<*this%>"); + warning (0, "% should return a reference to %<*this%>"); /* Make the init_value nonzero so pushdecl knows this is not tentative. error_mark_node is replaced below (in poplevel) with the BLOCK. */ @@ -9956,7 +10159,12 @@ start_preparsed_function (tree decl1, tree attrs, int flags) class scope, current_class_type will be NULL_TREE until set above by push_nested_class.) */ if (processing_template_decl) - decl1 = push_template_decl (decl1); + { + /* FIXME: Handle error_mark_node more gracefully. */ + tree newdecl1 = push_template_decl (decl1); + if (newdecl1 != error_mark_node) + decl1 = newdecl1; + } /* We are now in the scope of the function being defined. */ current_function_decl = decl1; @@ -9984,7 +10192,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags) DECL_IGNORED_P (resdecl) = 1; DECL_RESULT (decl1) = resdecl; - c_apply_type_quals_to_decl (cp_type_quals (restype), resdecl); + cp_apply_type_quals_to_decl (cp_type_quals (restype), resdecl); } /* Initialize RTL machinery. We cannot do this until @@ -10086,6 +10294,15 @@ start_preparsed_function (tree decl1, tree attrs, int flags) } } + honor_interface = (!DECL_TEMPLATE_INSTANTIATION (decl1) + /* Implicitly-defined methods (like the + destructor for a class in which no destructor + is explicitly declared) must not be defined + until their definition is needed. So, we + ignore interface specifications for + compiler-generated functions. */ + && !DECL_ARTIFICIAL (decl1)); + if (DECL_INTERFACE_KNOWN (decl1)) { tree ctx = decl_function_context (decl1); @@ -10102,8 +10319,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags) /* If this function belongs to an interface, it is public. If it belongs to someone else's interface, it is also external. This only affects inlines and template instantiations. */ - else if (finfo->interface_unknown == 0 - && ! DECL_TEMPLATE_INSTANTIATION (decl1)) + else if (!finfo->interface_unknown && honor_interface) { if (DECL_DECLARED_INLINE_P (decl1) || DECL_TEMPLATE_INSTANTIATION (decl1) @@ -10120,16 +10336,15 @@ start_preparsed_function (tree decl1, tree attrs, int flags) } else DECL_EXTERNAL (decl1) = 0; - DECL_NOT_REALLY_EXTERN (decl1) = 0; DECL_INTERFACE_KNOWN (decl1) = 1; /* If this function is in an interface implemented in this file, - make sure that the backend knows to emit this function + make sure that the backend knows to emit this function here. */ if (!DECL_EXTERNAL (decl1)) mark_needed (decl1); } else if (finfo->interface_unknown && finfo->interface_only - && ! DECL_TEMPLATE_INSTANTIATION (decl1)) + && honor_interface) { /* If MULTIPLE_SYMBOL_SPACES is defined and we saw a #pragma interface, we will have both finfo->interface_unknown and @@ -10450,14 +10665,16 @@ finish_destructor_body (void) /* Do the necessary processing for the beginning of a function body, which in this case includes member-initializers, but not the catch clauses of a function-try-block. Currently, this means opening a binding level - for the member-initializers (in a ctor) and member cleanups (in a dtor). - In other functions, this isn't necessary, but it doesn't hurt. */ + for the member-initializers (in a ctor) and member cleanups (in a dtor). */ tree begin_function_body (void) { tree stmt; + if (! FUNCTION_NEEDS_BODY_BLOCK (current_function_decl)) + return NULL_TREE; + if (processing_template_decl) /* Do nothing now. */; else @@ -10488,6 +10705,9 @@ begin_function_body (void) void finish_function_body (tree compstmt) { + if (compstmt == NULL_TREE) + return; + /* Close the block. */ finish_compound_stmt (compstmt); @@ -10499,6 +10719,20 @@ finish_function_body (tree compstmt) finish_destructor_body (); } +/* Given a function, returns the BLOCK corresponding to the outermost level + of curly braces, skipping the artificial block created for constructor + initializers. */ + +static tree +outer_curly_brace_block (tree fndecl) +{ + tree block = BLOCK_SUBBLOCKS (DECL_INITIAL (fndecl)); + if (FUNCTION_NEEDS_BODY_BLOCK (current_function_decl)) + /* Skip the artificial function body block. */ + block = BLOCK_SUBBLOCKS (block); + return block; +} + /* Finish up a function declaration and compile that function all the way to assembler language output. The free the storage for the function definition. @@ -10558,7 +10792,11 @@ finish_function (int flags) /* Hack. We don't want the middle-end to warn that this return is unreachable, so put the statement on the special line 0. */ +#ifdef USE_MAPPED_LOCATION + SET_EXPR_LOCATION (stmt, UNKNOWN_LOCATION); +#else annotate_with_file_line (stmt, input_filename, 0); +#endif } /* Finish dealing with exception specifiers. */ @@ -10594,7 +10832,7 @@ finish_function (int flags) gcc_assert (errorcount); /* Throw away the broken statement tree and extra binding - levels. */ + levels. */ DECL_SAVED_TREE (fndecl) = alloc_stmt_list (); while (current_binding_level->kind != sk_function_parms) @@ -10626,9 +10864,7 @@ finish_function (int flags) 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 we were to do this optimization in tree-ssa. */ - && (outer = BLOCK_SUBBLOCKS (DECL_INITIAL (fndecl))) - /* Skip the artificial function body block. */ - && (outer = BLOCK_SUBBLOCKS (outer)) + && (outer = outer_curly_brace_block (fndecl)) && chain_member (r, BLOCK_VARS (outer))) finalize_nrv (&DECL_SAVED_TREE (fndecl), r, DECL_RESULT (fndecl)); @@ -10664,7 +10900,7 @@ finish_function (int flags) /* Structor return values (if any) are set by the compiler. */ && !DECL_CONSTRUCTOR_P (fndecl) && !DECL_DESTRUCTOR_P (fndecl)) - warning ("no return statement in function returning non-void"); + warning (0, "no return statement in function returning non-void"); /* Store the end of the function, so that we get good line number info for the epilogue. */ @@ -10742,7 +10978,7 @@ finish_function (int flags) tree start_method (cp_decl_specifier_seq *declspecs, - const cp_declarator *declarator, tree attrlist) + const cp_declarator *declarator, tree attrlist) { tree fndecl = grokdeclarator (declarator, declspecs, MEMFUNCDEF, 0, &attrlist); @@ -10769,7 +11005,7 @@ start_method (cp_decl_specifier_seq *declspecs, && TREE_CODE( DECL_CONTEXT (fndecl)) != NAMESPACE_DECL) error ("%qD is already defined in class %qT", fndecl, DECL_CONTEXT (fndecl)); - return void_type_node; + return error_mark_node; } check_template_shadow (fndecl); @@ -10857,7 +11093,7 @@ finish_method (tree decl) for String.cc in libg++. */ if (DECL_FRIEND_P (fndecl)) { - VEC_safe_push (tree, CLASSTYPE_INLINE_FRIENDS (current_class_type), + VEC_safe_push (tree, gc, CLASSTYPE_INLINE_FRIENDS (current_class_type), fndecl); decl = void_type_node; } @@ -10907,9 +11143,11 @@ complete_vars (tree type) if (same_type_p (type, TREE_PURPOSE (*list))) { tree var = TREE_VALUE (*list); + tree type = TREE_TYPE (var); /* Complete the type of the variable. The VAR_DECL itself will be laid out in expand_expr. */ - complete_type (TREE_TYPE (var)); + complete_type (type); + cp_apply_type_quals_to_decl (cp_type_quals (type), var); /* Remove this entry from the list. */ *list = TREE_CHAIN (*list); } @@ -11043,7 +11281,7 @@ cp_tree_node_structure (union lang_tree_node * t) case TEMPLATE_PARM_INDEX: return TS_CP_TPI; case TINST_LEVEL: return TS_CP_TINST_LEVEL; case PTRMEM_CST: return TS_CP_PTRMEM; - case BASELINK: return TS_CP_BASELINK; + case BASELINK: return TS_CP_BASELINK; default: return TS_CP_GENERIC; } } @@ -11078,7 +11316,22 @@ cxx_comdat_group (tree decl) /* For all other DECLs, the COMDAT group is the mangled name of the declaration itself. */ else - name = DECL_ASSEMBLER_NAME (decl); + { + while (DECL_THUNK_P (decl)) + { + /* If TARGET_USE_LOCAL_THUNK_ALIAS_P, use_thunk puts the thunk + into the same section as the target function. In that case + we must return target's name. */ + tree target = THUNK_TARGET (decl); + if (TARGET_USE_LOCAL_THUNK_ALIAS_P (target) + && DECL_SECTION_NAME (target) != NULL + && DECL_ONE_ONLY (target)) + decl = target; + else + break; + } + name = DECL_ASSEMBLER_NAME (decl); + } return IDENTIFIER_POINTER (name); }