X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fcp%2Fdecl.c;h=83d2c4ea5a73a7c5d26226dd32bc83324d337ca9;hb=4e4968182203cdcc62922d799ea2f6f7c5955183;hp=6172296d73f349a97967a84f55f85fa1f333711a;hpb=f8fd23c043e25507321039cc26eaa28d6d1f63f1;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 6172296d73f..83d2c4ea5a7 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -1,6 +1,7 @@ /* Process declarations and variables for C++ compiler. Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, - 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. + 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 + Free Software Foundation, Inc. Contributed by Michael Tiemann (tiemann@cygnus.com) This file is part of GCC. @@ -356,12 +357,7 @@ pop_label (tree label, tree old_value) location_t location; 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.line = 0; -#endif /* Avoid crashing later. */ define_label (location, DECL_NAME (label)); } @@ -587,7 +583,7 @@ poplevel (int keep, int reverse, int functionbody) /* In each subblock, record that this is its superior. */ if (keep >= 0) - for (link = subblocks; link; link = TREE_CHAIN (link)) + for (link = subblocks; link; link = BLOCK_CHAIN (link)) BLOCK_SUPERCONTEXT (link) = block; /* We still support the old for-scope rules, whereby the variables @@ -1059,8 +1055,8 @@ warn_extern_redeclared_static (tree newdecl, tree olddecl) return; name = DECL_ASSEMBLER_NAME (newdecl); - pedwarn ("%qD was declared % and later %", newdecl); - pedwarn ("previous declaration of %q+D", olddecl); + permerror ("%qD was declared % and later %", newdecl); + permerror ("previous declaration of %q+D", olddecl); } /* NEW_DECL is a redeclaration of OLD_DECL; both are functions or @@ -1098,6 +1094,10 @@ check_redeclaration_exception_specification (tree new_decl, } } +#define GNU_INLINE_P(fn) (DECL_DECLARED_INLINE_P (fn) \ + && lookup_attribute ("gnu_inline", \ + DECL_ATTRIBUTES (fn))) + /* If NEWDECL is a redeclaration of OLDDECL, merge the declarations. If the redeclaration is invalid, a diagnostic is issued, and the error_mark_node is returned. Otherwise, OLDDECL is returned. @@ -1276,6 +1276,17 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) TREE_TYPE (newdecl) = TREE_TYPE (olddecl) = type; } + /* If a function is explicitly declared "throw ()", propagate that to + the corresponding builtin. */ + if (DECL_BUILT_IN_CLASS (olddecl) == BUILT_IN_NORMAL + && DECL_ANTICIPATED (olddecl) + && TREE_NOTHROW (newdecl) + && !TREE_NOTHROW (olddecl) + && built_in_decls [DECL_FUNCTION_CODE (olddecl)] != NULL_TREE + && built_in_decls [DECL_FUNCTION_CODE (olddecl)] != olddecl + && types_match) + TREE_NOTHROW (built_in_decls [DECL_FUNCTION_CODE (olddecl)]) = 1; + /* Whether or not the builtin can throw exceptions has no bearing on this declarator. */ TREE_NOTHROW (olddecl) = 0; @@ -1528,9 +1539,9 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) if (1 == simple_cst_equal (TREE_PURPOSE (t1), TREE_PURPOSE (t2))) { - pedwarn ("default argument given for parameter %d of %q#D", - i, newdecl); - pedwarn ("after previous specification in %q+#D", olddecl); + permerror ("default argument given for parameter %d of %q#D", + i, newdecl); + permerror ("after previous specification in %q+#D", olddecl); } else { @@ -1634,20 +1645,51 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) = chainon (DECL_TEMPLATE_SPECIALIZATIONS (olddecl), DECL_TEMPLATE_SPECIALIZATIONS (newdecl)); + DECL_ATTRIBUTES (old_result) + = (*targetm.merge_decl_attributes) (old_result, new_result); + if (DECL_FUNCTION_TEMPLATE_P (newdecl)) { - DECL_INLINE (old_result) - |= DECL_INLINE (new_result); - DECL_DECLARED_INLINE_P (old_result) - |= DECL_DECLARED_INLINE_P (new_result); - check_redeclaration_exception_specification (newdecl, olddecl); + if (GNU_INLINE_P (old_result) != GNU_INLINE_P (new_result) + && DECL_INITIAL (new_result)) + { + if (DECL_INITIAL (old_result)) + { + DECL_INLINE (old_result) = 0; + DECL_UNINLINABLE (old_result) = 1; + } + else + { + DECL_INLINE (old_result) = DECL_INLINE (new_result); + DECL_UNINLINABLE (old_result) = DECL_UNINLINABLE (new_result); + } + DECL_EXTERNAL (old_result) = DECL_EXTERNAL (new_result); + DECL_NOT_REALLY_EXTERN (old_result) + = DECL_NOT_REALLY_EXTERN (new_result); + DECL_INTERFACE_KNOWN (old_result) + = DECL_INTERFACE_KNOWN (new_result); + DECL_DECLARED_INLINE_P (old_result) + = DECL_DECLARED_INLINE_P (new_result); + DECL_DISREGARD_INLINE_LIMITS (old_result) + |= DECL_DISREGARD_INLINE_LIMITS (new_result); + + } + else + { + DECL_INLINE (old_result) + |= DECL_INLINE (new_result); + DECL_DECLARED_INLINE_P (old_result) + |= DECL_DECLARED_INLINE_P (new_result); + DECL_DISREGARD_INLINE_LIMITS (old_result) + |= DECL_DISREGARD_INLINE_LIMITS (new_result); + check_redeclaration_exception_specification (newdecl, olddecl); + } } /* If the new declaration is a definition, update the file and line information on the declaration, and also make the old declaration the same definition. */ - if (DECL_INITIAL (old_result) == NULL_TREE - && DECL_INITIAL (new_result) != NULL_TREE) + if (DECL_INITIAL (new_result) != NULL_TREE) { DECL_SOURCE_LOCATION (olddecl) = DECL_SOURCE_LOCATION (old_result) @@ -1760,10 +1802,13 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) |= DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (olddecl); DECL_NO_LIMIT_STACK (newdecl) |= DECL_NO_LIMIT_STACK (olddecl); TREE_THIS_VOLATILE (newdecl) |= TREE_THIS_VOLATILE (olddecl); - TREE_READONLY (newdecl) |= TREE_READONLY (olddecl); TREE_NOTHROW (newdecl) |= TREE_NOTHROW (olddecl); DECL_IS_MALLOC (newdecl) |= DECL_IS_MALLOC (olddecl); - DECL_IS_PURE (newdecl) |= DECL_IS_PURE (olddecl); + DECL_IS_OPERATOR_NEW (newdecl) |= DECL_IS_OPERATOR_NEW (olddecl); + DECL_PURE_P (newdecl) |= DECL_PURE_P (olddecl); + TREE_READONLY (newdecl) |= TREE_READONLY (olddecl); + DECL_LOOPING_CONST_OR_PURE_P (newdecl) + |= DECL_LOOPING_CONST_OR_PURE_P (olddecl); /* Keep the old RTL. */ COPY_DECL_RTL (olddecl, newdecl); } @@ -1805,9 +1850,29 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) new_template = NULL_TREE; if (DECL_LANG_SPECIFIC (newdecl) && DECL_LANG_SPECIFIC (olddecl)) { - DECL_INTERFACE_KNOWN (newdecl) |= DECL_INTERFACE_KNOWN (olddecl); - DECL_NOT_REALLY_EXTERN (newdecl) |= DECL_NOT_REALLY_EXTERN (olddecl); - DECL_COMDAT (newdecl) |= DECL_COMDAT (olddecl); + bool new_redefines_gnu_inline = false; + + if (new_defines_function + && ((DECL_INTERFACE_KNOWN (olddecl) + && TREE_CODE (olddecl) == FUNCTION_DECL) + || (TREE_CODE (olddecl) == TEMPLATE_DECL + && (TREE_CODE (DECL_TEMPLATE_RESULT (olddecl)) + == FUNCTION_DECL)))) + { + tree fn = olddecl; + + if (TREE_CODE (fn) == TEMPLATE_DECL) + fn = DECL_TEMPLATE_RESULT (olddecl); + + new_redefines_gnu_inline = GNU_INLINE_P (fn) && DECL_INITIAL (fn); + } + + if (!new_redefines_gnu_inline) + { + DECL_INTERFACE_KNOWN (newdecl) |= DECL_INTERFACE_KNOWN (olddecl); + DECL_NOT_REALLY_EXTERN (newdecl) |= DECL_NOT_REALLY_EXTERN (olddecl); + DECL_COMDAT (newdecl) |= DECL_COMDAT (olddecl); + } DECL_TEMPLATE_INSTANTIATED (newdecl) |= DECL_TEMPLATE_INSTANTIATED (olddecl); @@ -1881,6 +1946,13 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) /* [temp.expl.spec/14] We don't inline explicit specialization just because the primary template says so. */ } + else if (new_defines_function && DECL_INITIAL (olddecl)) + { + /* C++ is always in in unit-at-a-time mode, so we never + inline re-defined extern inline functions. */ + DECL_INLINE (newdecl) = 0; + DECL_UNINLINABLE (newdecl) = 1; + } else { if (DECL_PENDING_INLINE_INFO (newdecl) == 0) @@ -1896,6 +1968,11 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) DECL_UNINLINABLE (newdecl) = DECL_UNINLINABLE (olddecl) = (DECL_UNINLINABLE (newdecl) || DECL_UNINLINABLE (olddecl)); + + DECL_DISREGARD_INLINE_LIMITS (newdecl) + = DECL_DISREGARD_INLINE_LIMITS (olddecl) + = (DECL_DISREGARD_INLINE_LIMITS (newdecl) + || DECL_DISREGARD_INLINE_LIMITS (olddecl)); } /* Preserve abstractness on cloned [cd]tors. */ @@ -2123,9 +2200,25 @@ redeclaration_error_message (tree newdecl, tree olddecl) { if (DECL_NAME (olddecl) == NULL_TREE) return "%q#D not declared in class"; - else + else if (!GNU_INLINE_P (olddecl) + || GNU_INLINE_P (newdecl)) return "redefinition of %q#D"; } + + if (DECL_DECLARED_INLINE_P (olddecl) && DECL_DECLARED_INLINE_P (newdecl)) + { + bool olda = GNU_INLINE_P (olddecl); + bool newa = GNU_INLINE_P (newdecl); + + if (olda != newa) + { + if (newa) + return "%q+D redeclared inline with % attribute"; + else + return "%q+D redeclared inline without % attribute"; + } + } + return NULL; } else if (TREE_CODE (newdecl) == TEMPLATE_DECL) @@ -2151,9 +2244,24 @@ redeclaration_error_message (tree newdecl, tree olddecl) ot = DECL_TEMPLATE_RESULT (olddecl); if (DECL_TEMPLATE_INFO (ot)) ot = DECL_TEMPLATE_RESULT (template_for_substitution (ot)); - if (DECL_INITIAL (nt) && DECL_INITIAL (ot)) + if (DECL_INITIAL (nt) && DECL_INITIAL (ot) + && (!GNU_INLINE_P (ot) || GNU_INLINE_P (nt))) return "redefinition of %q#D"; + if (DECL_DECLARED_INLINE_P (ot) && DECL_DECLARED_INLINE_P (nt)) + { + bool olda = GNU_INLINE_P (ot); + bool newa = GNU_INLINE_P (nt); + + if (olda != newa) + { + if (newa) + return "%q+D redeclared inline with % attribute"; + else + return "%q+D redeclared inline without % attribute"; + } + } + /* Core issue #226 (C++0x): If a friend function template declaration specifies a @@ -2350,11 +2458,11 @@ static void identify_goto (tree decl, const location_t *locus) { if (decl) - pedwarn ("jump to label %qD", decl); + permerror ("jump to label %qD", decl); else - pedwarn ("jump to case label"); + permerror ("jump to case label"); if (locus) - pedwarn ("%H from here", locus); + permerror ("%H from here", locus); } /* Check that a single previously seen jump to a newly defined label @@ -2396,7 +2504,7 @@ check_previous_goto_1 (tree decl, struct cp_binding_level* level, tree names, if (problem > 1) error (" crosses initialization of %q+#D", new_decls); else - pedwarn (" enters scope of non-POD %q+#D", new_decls); + permerror (" enters scope of non-POD %q+#D", new_decls); } if (b == level) @@ -2492,8 +2600,8 @@ check_goto (tree decl) if (ent->in_try_scope || ent->in_catch_scope || ent->in_omp_scope || ent->bad_decls) { - pedwarn ("jump to label %q+D", decl); - pedwarn (" from here"); + permerror ("jump to label %q+D", decl); + permerror (" from here"); identified = true; } @@ -2511,7 +2619,7 @@ check_goto (tree decl) else if (u > 1) error (" skips initialization of %q+#D", b); else - pedwarn (" enters scope of non-POD %q+#D", b); + permerror (" enters scope of non-POD %q+#D", b); } if (ent->in_try_scope) @@ -2532,8 +2640,8 @@ check_goto (tree decl) { if (!identified) { - pedwarn ("jump to label %q+D", decl); - pedwarn (" from here"); + permerror ("jump to label %q+D", decl); + permerror (" from here"); identified = true; } error (" exits OpenMP structured block"); @@ -2585,7 +2693,7 @@ define_label (location_t location, tree name) p->more_cleanups_ok = 0; if (name == get_identifier ("wchar_t")) - pedwarn ("label named wchar_t"); + permerror ("label named wchar_t"); if (DECL_INITIAL (decl) != NULL_TREE) { @@ -2785,7 +2893,7 @@ build_typename_type (tree context, tree name, tree fullname, else { /* Build the TYPENAME_TYPE. */ - t = make_aggr_type (TYPENAME_TYPE); + t = cxx_make_type (TYPENAME_TYPE); TYPE_CONTEXT (t) = ti.scope; TYPENAME_TYPE_FULLNAME (t) = ti.template_id; TYPENAME_IS_ENUM_P (t) = ti.enum_p; @@ -2873,7 +2981,7 @@ make_typename_type (tree context, tree name, enum tag_types tag_type, if (dependent_type_p (context)) return build_typename_type (context, name, fullname, tag_type); - if (!IS_AGGR_TYPE (context)) + if (!MAYBE_CLASS_TYPE_P (context)) { if (complain & tf_error) error ("%q#T is not a class", context); @@ -2950,7 +3058,7 @@ make_unbound_class_template (tree context, tree name, tree parm_list, { tree tmpl = NULL_TREE; - if (IS_AGGR_TYPE (context)) + if (MAYBE_CLASS_TYPE_P (context)) tmpl = lookup_field (context, name, 0, false); if (!tmpl || !DECL_CLASS_TEMPLATE_P (tmpl)) @@ -2978,7 +3086,7 @@ make_unbound_class_template (tree context, tree name, tree parm_list, } /* Build the UNBOUND_CLASS_TEMPLATE. */ - t = make_aggr_type (UNBOUND_CLASS_TEMPLATE); + t = cxx_make_type (UNBOUND_CLASS_TEMPLATE); TYPE_CONTEXT (t) = FROB_CONTEXT (context); TREE_TYPE (t) = NULL_TREE; SET_TYPE_STRUCTURAL_EQUALITY (t); @@ -3236,6 +3344,9 @@ cxx_init_decl_processing (void) TYPE_POINTER_TO (unknown_type_node) = unknown_type_node; TYPE_REFERENCE_TO (unknown_type_node) = unknown_type_node; + init_list_type_node = make_node (UNKNOWN_TYPE); + record_unknown_type (init_list_type_node, "init list"); + { /* Make sure we get a unique function type, so we can give its pointer type a name. (This wins for gdb.) */ @@ -3276,7 +3387,7 @@ cxx_init_decl_processing (void) push_namespace (std_identifier); bad_alloc_id = get_identifier ("bad_alloc"); - bad_alloc_type_node = make_aggr_type (RECORD_TYPE); + bad_alloc_type_node = make_class_type (RECORD_TYPE); TYPE_CONTEXT (bad_alloc_type_node) = current_namespace; bad_alloc_decl = create_implicit_typedef (bad_alloc_id, bad_alloc_type_node); @@ -3368,7 +3479,7 @@ cp_make_fname_decl (tree id, int type_dep) tree decl = build_decl (VAR_DECL, id, type); if (name) - free (CONST_CAST (name)); + free (CONST_CAST (char *, name)); /* As we're using pushdecl_with_scope, we must set the context. */ DECL_CONTEXT (decl) = current_function_decl; @@ -3424,6 +3535,17 @@ builtin_function_1 (tree decl, tree context) anticipated but not actually declared. */ if (name[0] != '_' || name[1] != '_') DECL_ANTICIPATED (decl) = 1; + else if (strncmp (name + 2, "builtin_", strlen ("builtin_")) != 0) + { + size_t len = strlen (name); + + /* Treat __*_chk fortification functions as anticipated as well, + unless they are __builtin_*. */ + if (len > strlen ("___chk") + && memcmp (name + len - strlen ("_chk"), + "_chk", strlen ("_chk") + 1) == 0) + DECL_ANTICIPATED (decl) = 1; + } return decl; } @@ -3569,7 +3691,7 @@ fixup_anonymous_aggr (tree t) tree *q; /* Wipe out memory of synthesized methods. */ - TYPE_HAS_CONSTRUCTOR (t) = 0; + TYPE_HAS_USER_CONSTRUCTOR (t) = 0; TYPE_HAS_DEFAULT_CONSTRUCTOR (t) = 0; TYPE_HAS_INIT_REF (t) = 0; TYPE_HAS_CONST_INIT_REF (t) = 0; @@ -3589,8 +3711,14 @@ fixup_anonymous_aggr (tree t) /* ISO C++ 9.5.3. Anonymous unions may not have function members. */ if (TYPE_METHODS (t)) - error ("%Jan anonymous union cannot have function members", - TYPE_MAIN_DECL (t)); + { + tree decl = TYPE_MAIN_DECL (t); + + if (TREE_CODE (t) != UNION_TYPE) + error ("%Jan anonymous struct cannot have function members", decl); + else + error ("%Jan anonymous union cannot have function members", decl); + } /* Anonymous aggregates cannot have fields with ctors, dtors or complex assignment operators (because they cannot have these methods themselves). @@ -3642,23 +3770,23 @@ check_tag_decl (cp_decl_specifier_seq *declspecs) else if (declspecs->redefined_builtin_type) { if (!in_system_header) - pedwarn ("redeclaration of C++ built-in type %qT", - declspecs->redefined_builtin_type); + permerror ("redeclaration of C++ built-in type %qT", + declspecs->redefined_builtin_type); return NULL_TREE; } if (declspecs->type && TYPE_P (declspecs->type) && ((TREE_CODE (declspecs->type) != TYPENAME_TYPE - && IS_AGGR_TYPE (declspecs->type)) + && MAYBE_CLASS_TYPE_P (declspecs->type)) || TREE_CODE (declspecs->type) == ENUMERAL_TYPE)) declared_type = declspecs->type; else if (declspecs->type == error_mark_node) error_p = true; if (declared_type == NULL_TREE && ! saw_friend && !error_p) - pedwarn ("declaration does not declare anything"); + permerror ("declaration does not declare anything"); /* Check for an anonymous union. */ - else if (declared_type && IS_AGGR_TYPE_CODE (TREE_CODE (declared_type)) + else if (declared_type && RECORD_OR_UNION_CODE_P (TREE_CODE (declared_type)) && TYPE_ANONYMOUS_P (declared_type)) { /* 7/3 In a simple-declaration, the optional init-declarator-list @@ -3782,25 +3910,35 @@ groktypename (cp_decl_specifier_seq *type_specifiers, attrs = type_specifiers->attributes; type_specifiers->attributes = NULL_TREE; type = grokdeclarator (declarator, type_specifiers, TYPENAME, 0, &attrs); - if (attrs) - cplus_decl_attributes (&type, attrs, 0); + if (attrs && type != error_mark_node) + { + if (CLASS_TYPE_P (type)) + warning (OPT_Wattributes, "ignoring attributes applied to class type %qT " + "outside of definition", type); + else if (MAYBE_CLASS_TYPE_P (type)) + /* A template type parameter or other dependent type. */ + warning (OPT_Wattributes, "ignoring attributes applied to dependent " + "type %qT without an associated declaration", type); + else + cplus_decl_attributes (&type, attrs, 0); + } return type; } -/* Decode a declarator in an ordinary declaration or data definition. - This is called as soon as the type information and variable name - have been parsed, before parsing the initializer if any. - Here we create the ..._DECL node, fill in its type, - and put it on the list of decls for the current context. - The ..._DECL node is returned as the value. - - Exception: for arrays where the length is not specified, - the type is left null, to be filled in by `cp_finish_decl'. - - Function definitions do not come here; they go to start_function - instead. However, external and forward declarations of functions - do go through here. Structure field declarations are done by - grokfield and not through here. */ +/* Process a DECLARATOR for a function-scope variable declaration, + namespace-scope variable declaration, or function declaration. + (Function definitions go through start_function; class member + declarations appearing in the body of the class go through + grokfield.) The DECL corresponding to the DECLARATOR is returned. + If an error occurs, the error_mark_node is returned instead. + + DECLSPECS are the decl-specifiers for the declaration. INITIALIZED + is true if an explicit initializer is present, but false if this is + a variable implicitly initialized via a default constructor. + ATTRIBUTES and PREFIX_ATTRIBUTES are GNU attributes associated with + this declaration. *PUSHED_SCOPE_P is set to the scope entered in + this function, if any; if set, the caller is responsible for + calling pop_scope. */ tree start_decl (const cp_declarator *declarator, @@ -3811,9 +3949,10 @@ start_decl (const cp_declarator *declarator, tree *pushed_scope_p) { tree decl; - tree type, tem; + tree type; tree context; bool was_public; + int flags; *pushed_scope_p = NULL_TREE; @@ -3875,8 +4014,17 @@ start_decl (const cp_declarator *declarator, TREE_STATIC (decl) = 1; } + /* If this is a typedef that names the class for linkage purposes + (7.1.3p8), apply any attributes directly to the type. */ + if (TREE_CODE (decl) == TYPE_DECL + && TAGGED_TYPE_P (TREE_TYPE (decl)) + && decl == TYPE_NAME (TYPE_MAIN_VARIANT (TREE_TYPE (decl)))) + flags = ATTR_FLAG_TYPE_IN_PLACE; + else + flags = 0; + /* Set attributes here so if duplicate decl, will have proper attributes. */ - cplus_decl_attributes (&decl, attributes, 0); + cplus_decl_attributes (&decl, attributes, flags); /* Dllimported symbols cannot be defined. Static data members (which can be initialized in-class and dllimported) go through grokfield, @@ -3909,10 +4057,10 @@ start_decl (const cp_declarator *declarator, if (DECL_CONTEXT (field) != context) { if (!same_type_p (DECL_CONTEXT (field), context)) - pedwarn ("ISO C++ does not permit %<%T::%D%> " - "to be defined as %<%T::%D%>", - DECL_CONTEXT (field), DECL_NAME (decl), - context, DECL_NAME (decl)); + permerror ("ISO C++ does not permit %<%T::%D%> " + "to be defined as %<%T::%D%>", + DECL_CONTEXT (field), DECL_NAME (decl), + context, DECL_NAME (decl)); DECL_CONTEXT (decl) = DECL_CONTEXT (field); } if (processing_specialization @@ -3965,18 +4113,18 @@ start_decl (const cp_declarator *declarator, } if (DECL_EXTERNAL (decl) && ! DECL_TEMPLATE_SPECIALIZATION (decl)) - pedwarn ("declaration of %q#D outside of class is not definition", - decl); + permerror ("declaration of %q#D outside of class is not definition", + decl); } was_public = TREE_PUBLIC (decl); /* Enter this declaration into the symbol table. */ - tem = maybe_push_decl (decl); + decl = maybe_push_decl (decl); if (processing_template_decl) - tem = push_template_decl (tem); - if (tem == error_mark_node) + decl = push_template_decl (decl); + if (decl == error_mark_node) return error_mark_node; /* Tell the back end to use or not use .common as appropriate. If we say @@ -3985,33 +4133,42 @@ start_decl (const cp_declarator *declarator, produce errors about redefs; to do this we force variables into the data segment. */ if (flag_conserve_space - && TREE_CODE (tem) == VAR_DECL - && TREE_PUBLIC (tem) - && !DECL_THREAD_LOCAL_P (tem) + && TREE_CODE (decl) == VAR_DECL + && TREE_PUBLIC (decl) + && !DECL_THREAD_LOCAL_P (decl) && !have_global_bss_p ()) - DECL_COMMON (tem) = 1; + DECL_COMMON (decl) = 1; - if (TREE_CODE (tem) == VAR_DECL - && DECL_NAMESPACE_SCOPE_P (tem) && !TREE_PUBLIC (tem) && !was_public - && !DECL_THIS_STATIC (tem) && !DECL_ARTIFICIAL (tem)) + if (TREE_CODE (decl) == VAR_DECL + && DECL_NAMESPACE_SCOPE_P (decl) && !TREE_PUBLIC (decl) && !was_public + && !DECL_THIS_STATIC (decl) && !DECL_ARTIFICIAL (decl)) { /* This is a const variable with implicit 'static'. Set DECL_THIS_STATIC so we can tell it from variables that are !TREE_PUBLIC because of the anonymous namespace. */ - gcc_assert (cp_type_readonly (TREE_TYPE (tem))); - DECL_THIS_STATIC (tem) = 1; + gcc_assert (cp_type_readonly (TREE_TYPE (decl))); + DECL_THIS_STATIC (decl) = 1; } - if (!processing_template_decl && TREE_CODE (tem) == VAR_DECL) - start_decl_1 (tem, initialized); + if (!processing_template_decl && TREE_CODE (decl) == VAR_DECL) + start_decl_1 (decl, initialized); - return tem; + return decl; } +/* Process the declaration of a variable DECL. INITIALIZED is true + iff DECL is explicitly initialized. (INITIALIZED is false if the + variable is initialized via an implicitly-called constructor.) + This function must be called for ordinary variables (including, for + example, implicit instantiations of templates), but must not be + called for template declarations. */ + void start_decl_1 (tree decl, bool initialized) { tree type; + bool complete_p; + bool aggregate_definition_p; gcc_assert (!processing_template_decl); @@ -4019,21 +4176,37 @@ start_decl_1 (tree decl, bool initialized) return; gcc_assert (TREE_CODE (decl) == VAR_DECL); + type = TREE_TYPE (decl); + complete_p = COMPLETE_TYPE_P (type); + aggregate_definition_p = MAYBE_CLASS_TYPE_P (type) && !DECL_EXTERNAL (decl); + + /* If an explicit initializer is present, or if this is a definition + of an aggregate, then we need a complete type at this point. + (Scalars are always complete types, so there is nothing to + check.) This code just sets COMPLETE_P; errors (if necessary) + are issued below. */ + if ((initialized || aggregate_definition_p) + && !complete_p + && COMPLETE_TYPE_P (complete_type (type))) + { + complete_p = true; + /* We will not yet have set TREE_READONLY on DECL if the type + was "const", but incomplete, before this point. But, now, we + have a complete type, so we can try again. */ + cp_apply_type_quals_to_decl (cp_type_quals (type), decl); + } if (initialized) - /* Is it valid for this decl to have an initializer at all? - If not, set INITIALIZED to zero, which will indirectly - tell `cp_finish_decl' to ignore the initializer once it is parsed. */ + /* Is it valid for this decl to have an initializer at all? */ { /* Don't allow initializations for incomplete types except for arrays which might be completed by the initialization. */ - if (COMPLETE_TYPE_P (complete_type (type))) + if (complete_p) ; /* A complete type is ok. */ else if (TREE_CODE (type) != ARRAY_TYPE) { error ("variable %q#D has initializer but incomplete type", decl); - initialized = 0; type = TREE_TYPE (decl) = error_mark_node; } else if (!COMPLETE_TYPE_P (complete_type (TREE_TYPE (type)))) @@ -4041,30 +4214,15 @@ start_decl_1 (tree decl, bool initialized) if (DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl)) error ("elements of array %q#D have incomplete type", decl); /* else we already gave an error in start_decl. */ - initialized = 0; } } - else if (IS_AGGR_TYPE (type) - && ! DECL_EXTERNAL (decl)) + else if (aggregate_definition_p && !complete_p) { - if (!COMPLETE_TYPE_P (complete_type (type))) - { - error ("aggregate %q#D has incomplete type and cannot be defined", - decl); - /* Change the type so that assemble_variable will give - DECL an rtl we can live with: (mem (const_int 0)). */ - type = TREE_TYPE (decl) = error_mark_node; - } - else - { - /* If any base type in the hierarchy of TYPE needs a constructor, - then we set initialized to 1. This way any nodes which are - created for the purposes of initializing this aggregate - will live as long as it does. This is necessary for global - aggregates which do not have their initializers processed until - the end of the file. */ - initialized = TYPE_NEEDS_CONSTRUCTING (type); - } + error ("aggregate %q#D has incomplete type and cannot be defined", + decl); + /* Change the type so that assemble_variable will give + DECL an rtl we can live with: (mem (const_int 0)). */ + type = TREE_TYPE (decl) = error_mark_node; } /* Create a new scope to hold this declaration if necessary. @@ -4140,6 +4298,39 @@ grok_reference_init (tree decl, tree type, tree init, tree *cleanup) return NULL_TREE; } +/* Subroutine of check_initializer. We're initializing a DECL of + std::initializer_list TYPE from a braced-init-list INIT, and need to + extend the lifetime of the underlying array to match that of the decl, + just like for reference initialization. CLEANUP is as for + grok_reference_init. */ + +static tree +build_init_list_var_init (tree decl, tree type, tree init, tree *cleanup) +{ + tree aggr_init, array, arrtype; + init = perform_implicit_conversion (type, init, tf_warning_or_error); + aggr_init = TARGET_EXPR_INITIAL (init); + init = build2 (INIT_EXPR, type, decl, init); + + array = AGGR_INIT_EXPR_ARG (aggr_init, 1); + arrtype = TREE_TYPE (array); + STRIP_NOPS (array); + gcc_assert (TREE_CODE (array) == ADDR_EXPR); + array = TREE_OPERAND (array, 0); + /* If the array is constant, finish_compound_literal already made it a + static variable and we don't need to do anything here. */ + if (decl && TREE_CODE (array) == TARGET_EXPR) + { + tree subinit; + tree var = set_up_extended_ref_temp (decl, array, cleanup, &subinit); + var = build_address (var); + var = convert (arrtype, var); + AGGR_INIT_EXPR_ARG (aggr_init, 1) = var; + init = build2 (COMPOUND_EXPR, TREE_TYPE (init), subinit, init); + } + return init; +} + /* Designated initializers in arrays are not supported in GNU C++. The parser cannot detect this error since it does not know whether a given brace-enclosed initializer is for a class type or for an @@ -4194,7 +4385,7 @@ maybe_deduce_size_from_array_init (tree decl, tree init) HOST_WIDE_INT i; for (i = 0; VEC_iterate (constructor_elt, v, i, ce); - ++i) + ++i) if (!check_array_designated_initializer (ce)) failure = 1; } @@ -4274,7 +4465,7 @@ layout_var_decl (tree decl) /* Keep this code around in case we later want to control debug info based on whether a type is "used". (jason 1999-11-11) */ - else if (!DECL_EXTERNAL (decl) && IS_AGGR_TYPE (ttype)) + else if (!DECL_EXTERNAL (decl) && MAYBE_CLASS_TYPE_P (ttype)) /* Let debugger know it should output info for this type. */ note_debug_info_needed (ttype); @@ -4289,7 +4480,10 @@ layout_var_decl (tree decl) if (TREE_CODE (DECL_SIZE (decl)) == INTEGER_CST) constant_expression_warning (DECL_SIZE (decl)); else - error ("storage size of %qD isn't constant", decl); + { + error ("storage size of %qD isn't constant", decl); + TREE_TYPE (decl) = error_mark_node; + } } } @@ -4415,7 +4609,7 @@ reshape_init_array_1 (tree elt_type, tree max_index, reshape_iter *d) unsigned HOST_WIDE_INT index; /* The initializer for an array is always a CONSTRUCTOR. */ - new_init = build_constructor (NULL_TREE, NULL); + new_init = build_constructor (init_list_type_node, NULL); if (sized_array_p) { @@ -4510,7 +4704,7 @@ reshape_init_class (tree type, reshape_iter *d, bool first_initializer_p) gcc_assert (CLASS_TYPE_P (type)); /* The initializer for a class is always a CONSTRUCTOR. */ - new_init = build_constructor (NULL_TREE, NULL); + new_init = build_constructor (init_list_type_node, NULL); field = next_initializable_field (TYPE_FIELDS (type)); if (!field) @@ -4736,6 +4930,58 @@ reshape_init (tree type, tree init) return new_init; } +/* Verify array initializer. Returns true if errors have been reported. */ + +bool +check_array_initializer (tree decl, tree type, tree init) +{ + tree element_type = TREE_TYPE (type); + + /* The array type itself need not be complete, because the + initializer may tell us how many elements are in the array. + But, the elements of the array must be complete. */ + if (!COMPLETE_TYPE_P (complete_type (element_type))) + { + if (decl) + error ("elements of array %q#D have incomplete type", decl); + else + error ("elements of array %q#T have incomplete type", type); + return true; + } + /* It is not valid to initialize a VLA. */ + if (init + && ((COMPLETE_TYPE_P (type) && !TREE_CONSTANT (TYPE_SIZE (type))) + || !TREE_CONSTANT (TYPE_SIZE (element_type)))) + { + if (decl) + error ("variable-sized object %qD may not be initialized", decl); + else + error ("variable-sized compound literal"); + return true; + } + return false; +} + +/* Subroutine of check_initializer; args are passed down from that function. + Set stmts_are_full_exprs_p to 1 across a call to build_aggr_init. */ + +static tree +build_aggr_init_full_exprs (tree decl, tree init, int flags) + +{ + int saved_stmts_are_full_exprs_p = 0; + if (building_stmt_tree ()) + { + saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p (); + current_stmt_tree ()->stmts_are_full_exprs_p = 1; + } + init = build_aggr_init (decl, init, flags, tf_warning_or_error); + if (building_stmt_tree ()) + current_stmt_tree ()->stmts_are_full_exprs_p = + saved_stmts_are_full_exprs_p; + return init; +} + /* Verify INIT (the initializer for DECL), and record the initialization in DECL_INITIAL, if appropriate. CLEANUP is as for grok_reference_init. @@ -4759,24 +5005,8 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup) if (TREE_CODE (type) == ARRAY_TYPE) { - tree element_type = TREE_TYPE (type); - - /* The array type itself need not be complete, because the - initializer may tell us how many elements are in the array. - But, the elements of the array must be complete. */ - if (!COMPLETE_TYPE_P (complete_type (element_type))) - { - error ("elements of array %q#D have incomplete type", decl); - return NULL_TREE; - } - /* It is not valid to initialize a VLA. */ - if (init - && ((COMPLETE_TYPE_P (type) && !TREE_CONSTANT (TYPE_SIZE (type))) - || !TREE_CONSTANT (TYPE_SIZE (element_type)))) - { - error ("variable-sized object %qD may not be initialized", decl); - return NULL_TREE; - } + if (check_array_initializer (decl, type, init)) + return NULL_TREE; } else if (!COMPLETE_TYPE_P (type)) { @@ -4793,7 +5023,12 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup) int init_len = VEC_length (constructor_elt, CONSTRUCTOR_ELTS (init)); if (SCALAR_TYPE_P (type)) { - if (init_len != 1) + if (init_len == 0) + { + maybe_warn_cpp0x ("extended initializer lists"); + init = build_zero_init (type, NULL_TREE, false); + } + else if (init_len != 1) { error ("scalar object %qD requires one element in initializer", decl); @@ -4801,15 +5036,6 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup) return NULL_TREE; } } - else if ((cxx_dialect == cxx98) && !CP_AGGREGATE_TYPE_P (type)) - { - /* A non-aggregate that is not a scalar cannot be initialized - via an initializer-list in C++98. */ - error ("braces around initializer for non-aggregate type %qT", - type); - TREE_TYPE (decl) = error_mark_node; - return NULL_TREE; - } } if (TREE_CODE (decl) == CONST_DECL) @@ -4827,17 +5053,26 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup) { /* Do not reshape constructors of vectors (they don't need to be reshaped. */ - if (TREE_CODE (init) == CONSTRUCTOR - && !COMPOUND_LITERAL_P (init) - && !TREE_TYPE (init)) /* ptrmemfunc */ + if (BRACE_ENCLOSED_INITIALIZER_P (init)) { - init = reshape_init (type, init); - - if ((*targetm.vector_opaque_p) (type)) + if (is_std_init_list (type)) + return build_init_list_var_init (decl, type, init, cleanup); + else if (TYPE_NON_AGGREGATE_CLASS (type)) + { + /* Don't reshape if the class has constructors. */ + if (cxx_dialect == cxx98) + error ("in C++98 %qD must be initialized by constructor, " + "not by %<{...}%>", + decl); + init = build_tree_list (NULL_TREE, init); + } + else if ((*targetm.vector_opaque_p) (type)) { error ("opaque vector types cannot be initialized"); init = error_mark_node; } + else + init = reshape_init (type, init); } /* If DECL has an array type without a specific bound, deduce the @@ -4847,61 +5082,27 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup) if (type == error_mark_node) return NULL_TREE; - if (TYPE_HAS_CONSTRUCTOR (type) || TYPE_NEEDS_CONSTRUCTING (type)) - { - if (TREE_CODE (type) == ARRAY_TYPE) - goto initialize_aggr; - else if (TREE_CODE (init) == CONSTRUCTOR) - { - if (TYPE_NON_AGGREGATE_CLASS (type)) - { - error ("%qD must be initialized by constructor, " - "not by %<{...}%>", - decl); - init = error_mark_node; - } - else - goto dont_use_constructor; - } - else - { - int saved_stmts_are_full_exprs_p; - - initialize_aggr: - saved_stmts_are_full_exprs_p = 0; - if (building_stmt_tree ()) - { - saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p (); - current_stmt_tree ()->stmts_are_full_exprs_p = 1; - } - init = build_aggr_init (decl, init, flags); - if (building_stmt_tree ()) - current_stmt_tree ()->stmts_are_full_exprs_p = - saved_stmts_are_full_exprs_p; - return init; - } - } - else + if (TYPE_NEEDS_CONSTRUCTING (type) + || (CLASS_TYPE_P (type) + && !BRACE_ENCLOSED_INITIALIZER_P (init))) + return build_aggr_init_full_exprs (decl, init, flags); + else if (TREE_CODE (init) != TREE_VEC) { - dont_use_constructor: - if (TREE_CODE (init) != TREE_VEC) - { - init_code = store_init_value (decl, init); - if (pedantic && TREE_CODE (type) == ARRAY_TYPE - && DECL_INITIAL (decl) - && TREE_CODE (DECL_INITIAL (decl)) == STRING_CST - && PAREN_STRING_LITERAL_P (DECL_INITIAL (decl))) - warning (0, "array %qD initialized by parenthesized string literal %qE", - decl, DECL_INITIAL (decl)); - init = NULL; - } + init_code = store_init_value (decl, init); + if (pedantic && TREE_CODE (type) == ARRAY_TYPE + && DECL_INITIAL (decl) + && TREE_CODE (DECL_INITIAL (decl)) == STRING_CST + && PAREN_STRING_LITERAL_P (DECL_INITIAL (decl))) + warning (0, "array %qD initialized by parenthesized string literal %qE", + decl, DECL_INITIAL (decl)); + init = NULL; } } else if (DECL_EXTERNAL (decl)) ; else if (TYPE_P (type) && TYPE_NEEDS_CONSTRUCTING (type)) - goto initialize_aggr; - else if (IS_AGGR_TYPE (type)) + return build_aggr_init_full_exprs (decl, init, flags); + else if (MAYBE_CLASS_TYPE_P (type)) { tree core_type = strip_array_types (type); @@ -4965,7 +5166,7 @@ make_rtl_for_nonlocal_decl (tree decl, tree init, const char* asmspec) /* An in-class declaration of a static data member should be external; it is only a declaration, and not a definition. */ if (init == NULL_TREE) - gcc_assert (DECL_EXTERNAL (decl)); + gcc_assert (DECL_EXTERNAL (decl) || !TREE_PUBLIC (decl)); } /* We don't create any RTL for local variables. */ @@ -5009,6 +5210,55 @@ make_rtl_for_nonlocal_decl (tree decl, tree init, const char* asmspec) rest_of_decl_compilation (decl, toplev, at_eof); } +/* walk_tree helper for wrap_temporary_cleanups, below. */ + +static tree +wrap_cleanups_r (tree *stmt_p, int *walk_subtrees, void *data) +{ + if (TYPE_P (*stmt_p)) + { + *walk_subtrees = 0; + return NULL_TREE; + } + + if (TREE_CODE (*stmt_p) == TARGET_EXPR) + { + tree guard = (tree)data; + tree tcleanup = TARGET_EXPR_CLEANUP (*stmt_p); + + tcleanup = build2 (TRY_CATCH_EXPR, void_type_node, tcleanup, guard); + /* Tell honor_protect_cleanup_actions to handle this as a separate + cleanup. */ + TRY_CATCH_IS_CLEANUP (tcleanup) = 1; + + TARGET_EXPR_CLEANUP (*stmt_p) = tcleanup; + } + + return NULL_TREE; +} + +/* We're initializing a local variable which has a cleanup GUARD. If there + are any temporaries used in the initializer INIT of this variable, we + need to wrap their cleanups with TRY_CATCH_EXPR (, GUARD) so that the + variable will be cleaned up properly if one of them throws. + + Unfortunately, there's no way to express this properly in terms of + nesting, as the regions for the temporaries overlap the region for the + variable itself; if there are two temporaries, the variable needs to be + the first thing destroyed if either of them throws. However, we only + want to run the variable's cleanup if it actually got constructed. So + we need to guard the temporary cleanups with the variable's cleanup if + they are run on the normal path, but not if they are run on the + exceptional path. We implement this by telling + honor_protect_cleanup_actions to strip the variable cleanup from the + exceptional path. */ + +static void +wrap_temporary_cleanups (tree init, tree guard) +{ + cp_walk_tree_without_duplicates (&init, wrap_cleanups_r, (void *)guard); +} + /* Generate code to initialize DECL (a local variable). */ static void @@ -5016,6 +5266,7 @@ initialize_local_var (tree decl, tree init) { tree type = TREE_TYPE (decl); tree cleanup; + int already_used; gcc_assert (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == RESULT_DECL); @@ -5026,46 +5277,53 @@ initialize_local_var (tree decl, tree init) /* If we used it already as memory, it must stay in memory. */ DECL_INITIAL (decl) = NULL_TREE; TREE_ADDRESSABLE (decl) = TREE_USED (decl); + return; } - if (DECL_SIZE (decl) && type != error_mark_node) - { - int already_used; + if (type == error_mark_node) + return; - /* Compute and store the initial value. */ - already_used = TREE_USED (decl) || TREE_USED (type); + /* Compute and store the initial value. */ + already_used = TREE_USED (decl) || TREE_USED (type); - /* Perform the initialization. */ - if (init) - { - int saved_stmts_are_full_exprs_p; + /* Generate a cleanup, if necessary. */ + cleanup = cxx_maybe_build_cleanup (decl); - gcc_assert (building_stmt_tree ()); - saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p (); - current_stmt_tree ()->stmts_are_full_exprs_p = 1; - finish_expr_stmt (init); - current_stmt_tree ()->stmts_are_full_exprs_p = - saved_stmts_are_full_exprs_p; - } + /* Perform the initialization. */ + if (init) + { + int saved_stmts_are_full_exprs_p; - /* Set this to 0 so we can tell whether an aggregate which was - initialized was ever used. Don't do this if it has a - destructor, so we don't complain about the 'resource - allocation is initialization' idiom. Now set - attribute((unused)) on types so decls of that type will be - marked used. (see TREE_USED, above.) */ - if (TYPE_NEEDS_CONSTRUCTING (type) - && ! already_used - && TYPE_HAS_TRIVIAL_DESTRUCTOR (type) - && DECL_NAME (decl)) - TREE_USED (decl) = 0; - else if (already_used) - TREE_USED (decl) = 1; - } + /* If we're only initializing a single object, guard the destructors + of any temporaries used in its initializer with its destructor. + This isn't right for arrays because each element initialization is + a full-expression. */ + if (cleanup && TREE_CODE (type) != ARRAY_TYPE) + wrap_temporary_cleanups (init, cleanup); - /* Generate a cleanup, if necessary. */ - cleanup = cxx_maybe_build_cleanup (decl); - if (DECL_SIZE (decl) && cleanup) + gcc_assert (building_stmt_tree ()); + saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p (); + current_stmt_tree ()->stmts_are_full_exprs_p = 1; + finish_expr_stmt (init); + current_stmt_tree ()->stmts_are_full_exprs_p = + saved_stmts_are_full_exprs_p; + } + + /* Set this to 0 so we can tell whether an aggregate which was + initialized was ever used. Don't do this if it has a + destructor, so we don't complain about the 'resource + allocation is initialization' idiom. Now set + attribute((unused)) on types so decls of that type will be + marked used. (see TREE_USED, above.) */ + if (TYPE_NEEDS_CONSTRUCTING (type) + && ! already_used + && TYPE_HAS_TRIVIAL_DESTRUCTOR (type) + && DECL_NAME (decl)) + TREE_USED (decl) = 0; + else if (already_used) + TREE_USED (decl) = 1; + + if (cleanup) finish_decl_cleanup (decl, cleanup); } @@ -5080,7 +5338,7 @@ initialize_artificial_var (tree decl, tree init) { gcc_assert (DECL_ARTIFICIAL (decl)); if (TREE_CODE (init) == TREE_LIST) - init = build_constructor_from_list (NULL_TREE, init); + init = build_constructor_from_list (TREE_TYPE (decl), init); gcc_assert (TREE_CODE (init) == CONSTRUCTOR); DECL_INITIAL (decl) = init; DECL_INITIALIZED_P (decl) = 1; @@ -5185,6 +5443,12 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, type_dependent_p = dependent_type_p (type); + if (check_for_bare_parameter_packs (init)) + { + init = NULL_TREE; + DECL_INITIAL (decl) = NULL_TREE; + } + if (init && init_const_expr_p) { DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) = 1; @@ -5212,7 +5476,21 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, goto finish_end; } - init = fold_non_dependent_expr (init); + if (TREE_CODE (init) == TREE_LIST) + { + /* If the parenthesized-initializer form was used (e.g., + "int A::i(X)"), then INIT will be a TREE_LIST of initializer + arguments. (There is generally only one.) We convert them + individually. */ + tree list = init; + for (; list; list = TREE_CHAIN (list)) + { + tree elt = TREE_VALUE (list); + TREE_VALUE (list) = fold_non_dependent_expr (elt); + } + } + else + init = fold_non_dependent_expr (init); processing_template_decl = 0; } @@ -5220,7 +5498,7 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, if (TREE_CODE (decl) == TYPE_DECL) { if (type != error_mark_node - && IS_AGGR_TYPE (type) && DECL_NAME (decl)) + && MAYBE_CLASS_TYPE_P (type) && DECL_NAME (decl)) { if (TREE_TYPE (DECL_NAME (decl)) && TREE_TYPE (decl) != type) warning (0, "shadowing previous type declaration of %q#D", decl); @@ -5261,8 +5539,7 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, require a guard variable, and since the mangled name of the guard variable will depend on the mangled name of this variable. */ - if (!processing_template_decl - && DECL_FUNCTION_SCOPE_P (decl) + if (DECL_FUNCTION_SCOPE_P (decl) && TREE_STATIC (decl) && !DECL_ARTIFICIAL (decl)) push_local_name (decl); @@ -5275,6 +5552,20 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, is *not* defined. */ && (!DECL_EXTERNAL (decl) || init)) { + if (TYPE_FOR_JAVA (type) && MAYBE_CLASS_TYPE_P (type)) + { + tree jclass + = IDENTIFIER_GLOBAL_VALUE (get_identifier ("jclass")); + /* Allow libjava/prims.cc define primitive classes. */ + if (init != NULL_TREE + || jclass == NULL_TREE + || TREE_CODE (jclass) != TYPE_DECL + || !POINTER_TYPE_P (TREE_TYPE (jclass)) + || !same_type_ignoring_top_level_qualifiers_p + (type, TREE_TYPE (TREE_TYPE (jclass)))) + error ("Java object %qD not allocated with %", decl); + init = NULL_TREE; + } if (init) { DECL_NONTRIVIALLY_INITIALIZED_P (decl) = 1; @@ -5345,6 +5636,9 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, else if (TREE_CODE (type) == ARRAY_TYPE) layout_type (type); } + else if (TREE_CODE (decl) == FIELD_DECL + && TYPE_FOR_JAVA (type) && MAYBE_CLASS_TYPE_P (type)) + error ("non-static data member %qD has Java class type", decl); /* Add this declaration to the statement-tree. This needs to happen after the call to check_initializer so that the DECL_EXPR for a @@ -5364,6 +5658,24 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, maybe_commonize_var (decl); } + /* This needs to happen after the linkage is set. */ + determine_visibility (decl); + + if (var_definition_p && TREE_STATIC (decl)) + { + /* If a TREE_READONLY variable needs initialization + at runtime, it is no longer readonly and we need to + avoid MEM_READONLY_P being set on RTL created for it. */ + if (init) + { + if (TREE_READONLY (decl)) + TREE_READONLY (decl) = 0; + was_readonly = 0; + } + else if (was_readonly) + TREE_READONLY (decl) = 1; + } + make_rtl_for_nonlocal_decl (decl, init, asmspec); /* Check for abstractness of the type. Notice that there is no @@ -5375,9 +5687,6 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, else abstract_virtuals_error (decl, type); - /* This needs to happen after the linkage is set. */ - determine_visibility (decl); - if (TREE_CODE (decl) == FUNCTION_DECL || TREE_TYPE (decl) == error_mark_node) /* No initialization required. */ @@ -5389,40 +5698,21 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, if (init) DECL_INITIAL (decl) = init; } - else - { - /* A variable definition. */ - if (DECL_FUNCTION_SCOPE_P (decl)) - { - /* Initialize the local variable. */ - if (processing_template_decl) - DECL_INITIAL (decl) = init; - else if (!TREE_STATIC (decl)) - initialize_local_var (decl, init); - } + /* A variable definition. */ + else if (DECL_FUNCTION_SCOPE_P (decl) && !TREE_STATIC (decl)) + /* Initialize the local variable. */ + 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 - calling expand_static_init more than once. For variables - that are not static data members, we can call - expand_static_init only when we actually process the - 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)) - { - /* If a TREE_READONLY variable needs initialization - at runtime, it is no longer readonly and we need to - avoid MEM_READONLY_P being set on RTL created for it. */ - if (init) - { - if (TREE_READONLY (decl)) - TREE_READONLY (decl) = 0; - was_readonly = 0; - } - expand_static_init (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 + calling expand_static_init more than once. For variables + that are not static data members, we can call + expand_static_init only when we actually process the + initializer. It is not legal to redeclare a static data + member, so this issue does not arise in that case. */ + else if (var_definition_p && TREE_STATIC (decl)) + expand_static_init (decl, init); } /* If a CLEANUP_STMT was created to destroy a temporary bound to a @@ -5736,7 +6026,7 @@ register_dtor_fn (tree decl) addr = build_address (decl); /* The declared type of the parameter to "__cxa_atexit" is "void *". For plain "T*", we could just let the - machinery in build_function_call convert it -- but if the + machinery in cp_build_function_call convert it -- but if the type is "cv-qualified T *", then we need to convert it before passing it in, to avoid spurious errors. */ addr = build_nop (ptr_type_node, addr); @@ -5748,7 +6038,8 @@ register_dtor_fn (tree decl) other value. */ addr = null_pointer_node; args = tree_cons (NULL_TREE, - build_unary_op (ADDR_EXPR, get_dso_handle_node (), 0), + cp_build_unary_op (ADDR_EXPR, get_dso_handle_node (), 0, + tf_warning_or_error), NULL_TREE); if (targetm.cxx.use_aeabi_atexit ()) { @@ -5763,7 +6054,8 @@ register_dtor_fn (tree decl) } else args = tree_cons (NULL_TREE, cleanup, NULL_TREE); - return build_function_call (get_atexit_node (), args); + return cp_build_function_call (get_atexit_node (), args, + tf_warning_or_error); } /* DECL is a VAR_DECL with static storage duration. INIT, if present, @@ -5921,6 +6213,9 @@ cp_complete_array_type (tree *ptype, tree initial_value, bool do_default) if (initial_value) { + unsigned HOST_WIDE_INT i; + tree value; + /* An array of character type can be initialized from a brace-enclosed string constant. @@ -5937,6 +6232,18 @@ cp_complete_array_type (tree *ptype, tree initial_value, bool do_default) && VEC_length (constructor_elt, v) == 1) initial_value = value; } + + /* If any of the elements are parameter packs, we can't actually + complete this type now because the array size is dependent. */ + if (TREE_CODE (initial_value) == CONSTRUCTOR) + { + FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (initial_value), + i, value) + { + if (PACK_EXPANSION_P (value)) + return 0; + } + } } failure = complete_array_type (ptype, initial_value, do_default); @@ -6039,8 +6346,8 @@ check_class_member_definition_namespace (tree decl) 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)); + permerror ("definition of %qD is not in namespace enclosing %qT", + decl, DECL_CONTEXT (decl)); } /* Build a PARM_DECL for the "this" parameter. TYPE is the @@ -6273,16 +6580,16 @@ grokfndecl (tree ctype, /* Allow this; it's pretty common in C. */; else { - pedwarn ("non-local function %q#D uses anonymous type", + permerror ("non-local function %q#D uses anonymous type", decl); if (DECL_ORIGINAL_TYPE (TYPE_NAME (t))) - pedwarn ("%q+#D does not refer to the unqualified " - "type, so it is not used for linkage", - TYPE_NAME (t)); + permerror ("%q+#D does not refer to the unqualified " + "type, so it is not used for linkage", + TYPE_NAME (t)); } } else - pedwarn ("non-local function %q#D uses local type %qT", decl, t); + permerror ("non-local function %q#D uses local type %qT", decl, t); } } @@ -6393,7 +6700,10 @@ grokfndecl (tree ctype, XXX Isn't this done in start_function, too? */ revert_static_member_fn (decl); if (DECL_ARTIFICIAL (old_decl)) - error ("definition of implicitly-declared %qD", old_decl); + { + error ("definition of implicitly-declared %qD", old_decl); + return NULL_TREE; + } /* Since we've smashed OLD_DECL to its DECL_TEMPLATE_RESULT, we must do the same to DECL. */ @@ -6594,13 +6904,13 @@ build_ptrmemfunc_type (tree type) unqualified_variant = build_ptrmemfunc_type (TYPE_MAIN_VARIANT (type)); - t = make_aggr_type (RECORD_TYPE); + t = make_class_type (RECORD_TYPE); xref_basetypes (t, NULL_TREE); /* Let the front end know this is a pointer to member function... */ TYPE_PTRMEMFUNC_FLAG (t) = 1; - /* ... and not really an aggregate. */ - SET_IS_AGGR_TYPE (t, 0); + /* ... and not really a class type. */ + SET_CLASS_TYPE_P (t, 0); field = build_decl (FIELD_DECL, pfn_identifier, type); fields = field; @@ -6759,12 +7069,7 @@ compute_array_index_type (tree name, tree size) { /* Check to see if the array bound overflowed. Make that an error, no matter how generous we're being. */ - int old_flag_pedantic_errors = flag_pedantic_errors; - int old_pedantic = pedantic; - pedantic = flag_pedantic_errors = 1; - constant_expression_warning (size); - pedantic = old_pedantic; - flag_pedantic_errors = old_flag_pedantic_errors; + constant_expression_error (size); /* An array must have a positive number of elements. */ if (INT_CST_LT (size, integer_zero_node)) @@ -6827,7 +7132,8 @@ compute_array_index_type (tree name, tree size) processing_template_decl = 0; itype = cp_build_binary_op (MINUS_EXPR, cp_convert (ssizetype, size), - cp_convert (ssizetype, integer_one_node)); + cp_convert (ssizetype, integer_one_node), + tf_warning_or_error); itype = fold (itype); processing_template_decl = saved_processing_template_decl; @@ -7355,6 +7661,12 @@ grokdeclarator (const cp_declarator *declarator, return error_mark_node; } + if (declspecs->conflicting_specifiers_p) + { + error ("conflicting specifiers in declaration of %qs", name); + return error_mark_node; + } + /* Extract the basic type from the decl-specifier-seq. */ type = declspecs->type; if (type == error_mark_node) @@ -7371,6 +7683,10 @@ grokdeclarator (const cp_declarator *declarator, { typedef_decl = type; type = TREE_TYPE (typedef_decl); + if (TREE_DEPRECATED (type) + && DECL_ARTIFICIAL (typedef_decl) + && deprecated_state != DEPRECATED_SUPPRESS) + warn_deprecated_use (type); } /* No type at all: default to `int', and set DEFAULTED_INT because it was not a user-defined typedef. */ @@ -7417,7 +7733,9 @@ grokdeclarator (const cp_declarator *declarator, /* We've already issued an error, don't complain more. */; else if (in_system_header || flag_ms_extensions) /* Allow it, sigh. */; - else if (pedantic || ! is_main) + else if (! is_main) + permerror ("ISO C++ forbids declaration of %qs with no type", name); + else if (pedantic) pedwarn ("ISO C++ forbids declaration of %qs with no type", name); else warning (OPT_Wreturn_type, @@ -7461,6 +7779,13 @@ grokdeclarator (const cp_declarator *declarator, error ("% or % specified with char for %qs", name); else if (long_p && short_p) error ("% and % specified together for %qs", name); + else if (type == char16_type_node || type == char32_type_node) + { + if (signed_p || unsigned_p) + error ("% or % invalid for %qs", name); + else if (short_p || long_p) + error ("% or % invalid for %qs", name); + } else { ok = 1; @@ -7624,7 +7949,7 @@ grokdeclarator (const cp_declarator *declarator, if (virtualp && (current_class_name == NULL_TREE || decl_context != FIELD)) { - error ("virtual outside class declaration"); + error ("% outside class declaration"); virtualp = 0; } @@ -7645,15 +7970,10 @@ grokdeclarator (const cp_declarator *declarator, error ("multiple storage classes in declaration of %qs", name); thread_p = false; } - if (declspecs->conflicting_specifiers_p) - { - error ("conflicting specifiers in declaration of %qs", name); - storage_class = sc_none; - } - else if (decl_context != NORMAL - && ((storage_class != sc_none - && storage_class != sc_mutable) - || thread_p)) + if (decl_context != NORMAL + && ((storage_class != sc_none + && storage_class != sc_mutable) + || thread_p)) { if ((decl_context == PARM || decl_context == CATCHPARM) && (storage_class == sc_register @@ -7685,19 +8005,6 @@ grokdeclarator (const cp_declarator *declarator, storage_class = sc_none; } } - else if (storage_class == sc_extern && initialized - && !funcdef_flag) - { - if (toplevel_bindings_p ()) - { - /* It's common practice (and completely valid) to have a const - be initialized and declared extern. */ - if (!(type_quals & TYPE_QUAL_CONST)) - warning (0, "%qs initialized and declared %", name); - } - else - error ("%qs has both % and initializer", name); - } else if (storage_class == sc_extern && funcdef_flag && ! toplevel_bindings_p ()) error ("nested function %qs declared %", name); @@ -7716,7 +8023,11 @@ grokdeclarator (const cp_declarator *declarator, } if (storage_class && friendp) - error ("storage class specifiers invalid in friend function declarations"); + { + error ("storage class specifiers invalid in friend function declarations"); + storage_class = sc_none; + staticp = 0; + } if (!id_declarator) unqualified_id = NULL_TREE; @@ -7789,7 +8100,7 @@ grokdeclarator (const cp_declarator *declarator, if (type_quals != TYPE_UNQUALIFIED) { if (SCALAR_TYPE_P (type) || VOID_TYPE_P (type)) - warning (OPT_Wreturn_type, + warning (OPT_Wignored_qualifiers, "type qualifiers ignored on function return type"); /* We now know that the TYPE_QUALS don't apply to the decl, but to its return type. */ @@ -7797,17 +8108,17 @@ grokdeclarator (const cp_declarator *declarator, set_no_warning = true; } - /* Warn about some types functions can't return. */ + /* Error about some types functions can't return. */ if (TREE_CODE (type) == FUNCTION_TYPE) { error ("%qs declared as function returning a function", name); - type = integer_type_node; + return error_mark_node; } if (TREE_CODE (type) == ARRAY_TYPE) { error ("%qs declared as function returning an array", name); - type = integer_type_node; + return error_mark_node; } /* Pick up type qualifiers which should be applied to `this'. */ @@ -7866,7 +8177,7 @@ grokdeclarator (const cp_declarator *declarator, explicitp = 2; if (virtualp) { - pedwarn ("constructors cannot be declared virtual"); + permerror ("constructors cannot be declared virtual"); virtualp = 0; } if (decl_context == FIELD @@ -7951,7 +8262,8 @@ grokdeclarator (const cp_declarator *declarator, type_quals = TYPE_UNQUALIFIED; if (declarator->kind == cdk_ptrmem - && (TREE_CODE (type) == FUNCTION_TYPE || memfn_quals)) + && (TREE_CODE (type) == FUNCTION_TYPE + || (memfn_quals && TREE_CODE (type) == METHOD_TYPE))) { memfn_quals |= cp_type_quals (type); type = build_memfn_type (type, @@ -8088,12 +8400,12 @@ grokdeclarator (const cp_declarator *declarator, { if (friendp) { - pedwarn ("member functions are implicitly friends of their class"); + permerror ("member functions are implicitly friends of their class"); friendp = 0; } else - pedwarn ("extra qualification %<%T::%> on member %qs", - ctype, name); + permerror ("extra qualification %<%T::%> on member %qs", + ctype, name); } else if (/* If the qualifying type is already complete, then we can skip the following checks. */ @@ -8277,9 +8589,9 @@ grokdeclarator (const cp_declarator *declarator, DECL_ABSTRACT (decl) = 1; } else if (constructor_name_p (unqualified_id, current_class_type)) - pedwarn ("ISO C++ forbids nested type %qD with same name " - "as enclosing class", - unqualified_id); + permerror ("ISO C++ forbids nested type %qD with same name " + "as enclosing class", + unqualified_id); /* If the user declares "typedef struct {...} foo" then the struct will have an anonymous name. Fill that name in now. @@ -8290,8 +8602,6 @@ grokdeclarator (const cp_declarator *declarator, && TYPE_NAME (type) && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL && TYPE_ANONYMOUS_P (type) - /* Don't do this if there are attributes. */ - && (!attrlist || !*attrlist) && cp_type_quals (type) == TYPE_UNQUALIFIED) { tree oldname = TYPE_NAME (type); @@ -8404,15 +8714,15 @@ grokdeclarator (const cp_declarator *declarator, { /* Don't allow friend declaration without a class-key. */ if (TREE_CODE (type) == TEMPLATE_TYPE_PARM) - pedwarn ("template parameters cannot be friends"); + permerror ("template parameters cannot be friends"); else if (TREE_CODE (type) == TYPENAME_TYPE) - pedwarn ("friend declaration requires class-key, " - "i.e. %", - TYPE_CONTEXT (type), TYPENAME_TYPE_FULLNAME (type)); + permerror ("friend declaration requires class-key, " + "i.e. %", + TYPE_CONTEXT (type), TYPENAME_TYPE_FULLNAME (type)); else - pedwarn ("friend declaration requires class-key, " - "i.e. %", - type); + permerror ("friend declaration requires class-key, " + "i.e. %", + type); } /* Only try to do this stuff if we didn't already give up. */ @@ -8588,6 +8898,13 @@ grokdeclarator (const cp_declarator *declarator, return error_mark_node; } } + else if (sfk == sfk_constructor && friendp) + { + error ("expected qualified name in friend declaration " + "for constructor %qD", + id_declarator->u.id.unqualified_name); + return error_mark_node; + } /* Tell grokfndecl if it needs to set TREE_PUBLIC on the node. */ function_context = (ctype != NULL_TREE) ? @@ -8622,17 +8939,11 @@ grokdeclarator (const cp_declarator *declarator, DECL_NONCONVERTING_P (decl) = 1; else if (DECL_CONSTRUCTOR_P (decl)) { - /* The constructor can be called with exactly one - parameter if there is at least one parameter, and - any subsequent parameters have default arguments. + /* A constructor with no parms is not a conversion. Ignore any compiler-added parms. */ tree arg_types = FUNCTION_FIRST_USER_PARMTYPE (decl); - if (arg_types == void_list_node - || (arg_types - && TREE_CHAIN (arg_types) - && TREE_CHAIN (arg_types) != void_list_node - && !TREE_PURPOSE (TREE_CHAIN (arg_types)))) + if (arg_types == void_list_node) DECL_NONCONVERTING_P (decl) = 1; } } @@ -8690,7 +9001,7 @@ grokdeclarator (const cp_declarator *declarator, { /* Friends are treated specially. */ if (ctype == current_class_type) - ; /* We already issued a pedwarn. */ + ; /* We already issued a permerror. */ else if (decl && DECL_NAME (decl)) { if (template_class_depth (current_class_type) == 0) @@ -8731,9 +9042,9 @@ grokdeclarator (const cp_declarator *declarator, the rest of the compiler does not correctly handle the initialization unless the member is static so we make it static below. */ - pedwarn ("ISO C++ forbids initialization of member %qD", - unqualified_id); - pedwarn ("making %qD static", unqualified_id); + permerror ("ISO C++ forbids initialization of member %qD", + unqualified_id); + permerror ("making %qD static", unqualified_id); staticp = 1; } @@ -8855,8 +9166,8 @@ grokdeclarator (const cp_declarator *declarator, declaring main to be static. */ if (TREE_CODE (type) == METHOD_TYPE) { - pedwarn ("cannot declare member function %qD to have " - "static linkage", decl); + permerror ("cannot declare member function %qD to have " + "static linkage", decl); invalid_static = 1; } else if (current_function_decl) @@ -8892,8 +9203,8 @@ 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"); + permerror ("% may not be used when defining " + "(as opposed to declaring) a static data member"); staticp = 0; storage_class = sc_none; } @@ -8912,6 +9223,19 @@ grokdeclarator (const cp_declarator *declarator, } } + if (storage_class == sc_extern && initialized && !funcdef_flag) + { + if (toplevel_bindings_p ()) + { + /* It's common practice (and completely valid) to have a const + be initialized and declared extern. */ + if (!(type_quals & TYPE_QUAL_CONST)) + warning (0, "%qs initialized and declared %", name); + } + else + error ("%qs has both % and initializer", name); + } + /* Record `register' declaration for warnings on & and in case doing stupid register allocation. */ @@ -8922,9 +9246,9 @@ grokdeclarator (const cp_declarator *declarator, else if (storage_class == sc_static) DECL_THIS_STATIC (decl) = 1; - /* Record constancy and volatility. There's no need to do this - when processing a template; we'll do this for the instantiated - declaration based on the type of DECL. */ + /* Record constancy and volatility on the DECL itself . There's + no need to do this when processing a template; we'll do this + for the instantiated declaration based on the type of DECL. */ if (!processing_template_decl) cp_apply_type_quals_to_decl (type_quals, decl); @@ -8976,18 +9300,6 @@ local_variable_p (const_tree t) return 0; } -/* Returns nonzero if T is an automatic local variable or a label. - (These are the declarations that need to be remapped when the code - containing them is duplicated.) */ - -int -nonstatic_local_decl_p (const_tree t) -{ - return ((local_variable_p (t) && !TREE_STATIC (t)) - || TREE_CODE (t) == LABEL_DECL - || TREE_CODE (t) == RESULT_DECL); -} - /* Like local_variable_p, but suitable for use as a tree-walking function. */ @@ -9061,8 +9373,7 @@ check_default_argument (tree decl, tree arg) The keyword `this' shall not be used in a default argument of a member function. */ - var = walk_tree_without_duplicates (&arg, local_variable_p_walkfn, - NULL); + var = cp_walk_tree_without_duplicates (&arg, local_variable_p_walkfn, NULL); if (var) { error ("default argument %qE uses local variable %qD", arg, var); @@ -9128,6 +9439,16 @@ grokparms (cp_parameter_declarator *first_parm, tree *parms) TREE_TYPE (decl) = error_mark_node; } + if (type != error_mark_node + && TYPE_FOR_JAVA (type) + && MAYBE_CLASS_TYPE_P (type)) + { + error ("parameter %qD has Java class type", decl); + type = error_mark_node; + TREE_TYPE (decl) = error_mark_node; + init = NULL_TREE; + } + if (type != error_mark_node) { /* Top-level qualifiers on the parameters are @@ -9217,7 +9538,7 @@ grokparms (cp_parameter_declarator *first_parm, tree *parms) operator. */ int -copy_fn_p (tree d) +copy_fn_p (const_tree d) { tree args; tree arg_type; @@ -9273,7 +9594,7 @@ copy_fn_p (tree d) operator, false otherwise. */ bool -move_fn_p (tree d) +move_fn_p (const_tree d) { tree args; tree arg_type; @@ -9319,7 +9640,8 @@ move_fn_p (tree d) /* Remember any special properties of member function DECL. */ -void grok_special_member_properties (tree decl) +void +grok_special_member_properties (tree decl) { tree class_type; @@ -9331,7 +9653,8 @@ void grok_special_member_properties (tree decl) { int ctor = copy_fn_p (decl); - TYPE_HAS_CONSTRUCTOR (class_type) = 1; + if (!DECL_ARTIFICIAL (decl)) + TYPE_HAS_USER_CONSTRUCTOR (class_type) = 1; if (ctor > 0) { @@ -9348,6 +9671,8 @@ void grok_special_member_properties (tree decl) } else if (sufficient_parms_p (FUNCTION_FIRST_USER_PARMTYPE (decl))) TYPE_HAS_DEFAULT_CONSTRUCTOR (class_type) = 1; + else if (is_list_ctor (decl)) + TYPE_HAS_LIST_CTOR (class_type) = 1; } else if (DECL_OVERLOADED_OPERATOR_P (decl) == NOP_EXPR) { @@ -9372,7 +9697,7 @@ void grok_special_member_properties (tree decl) if the class has a constructor of the form X(X). */ int -grok_ctor_properties (tree ctype, tree decl) +grok_ctor_properties (const_tree ctype, const_tree decl) { int ctor_parm = copy_fn_p (decl); @@ -9475,7 +9800,7 @@ grok_op_properties (tree decl, bool complain) gcc_unreachable (); } while (0); - gcc_assert (operator_code != LAST_CPLUS_TREE_CODE); + gcc_assert (operator_code != MAX_TREE_CODES); SET_OVERLOADED_OPERATOR_CODE (decl, operator_code); if (class_type) @@ -9527,7 +9852,10 @@ grok_op_properties (tree decl, bool complain) } if (operator_code == NEW_EXPR || operator_code == VEC_NEW_EXPR) - TREE_TYPE (decl) = coerce_new_type (TREE_TYPE (decl)); + { + TREE_TYPE (decl) = coerce_new_type (TREE_TYPE (decl)); + DECL_IS_OPERATOR_NEW (decl) = 1; + } else if (operator_code == DELETE_EXPR || operator_code == VEC_DELETE_EXPR) TREE_TYPE (decl) = coerce_delete_type (TREE_TYPE (decl)); else @@ -9563,10 +9891,11 @@ grok_op_properties (tree decl, bool complain) if (arg == error_mark_node) return false; - /* IS_AGGR_TYPE, rather than CLASS_TYPE_P, is used + /* MAYBE_CLASS_TYPE_P, rather than CLASS_TYPE_P, is used because these checks are performed even on template functions. */ - if (IS_AGGR_TYPE (arg) || TREE_CODE (arg) == ENUMERAL_TYPE) + if (MAYBE_CLASS_TYPE_P (arg) + || TREE_CODE (arg) == ENUMERAL_TYPE) break; } @@ -9607,7 +9936,7 @@ grok_op_properties (tree decl, bool complain) if (t == class_type) what = "the same type"; /* Don't force t to be complete here. */ - else if (IS_AGGR_TYPE (t) + else if (MAYBE_CLASS_TYPE_P (t) && COMPLETE_TYPE_P (t) && DERIVED_FROM_P (t, class_type)) what = "a base class"; @@ -10081,14 +10410,14 @@ xref_tag (enum tag_types tag_code, tree name, } else { - t = make_aggr_type (code); + t = make_class_type (code); TYPE_CONTEXT (t) = context; t = pushtag (name, t, scope); } } else { - if (template_header_p && IS_AGGR_TYPE (t)) + if (template_header_p && MAYBE_CLASS_TYPE_P (t)) { if (!redeclare_class_template (t, current_template_parms)) POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); @@ -10551,7 +10880,8 @@ finish_enum (tree enumtype) saved_location = input_location; input_location = DECL_SOURCE_LOCATION (decl); value = perform_implicit_conversion (underlying_type, - DECL_INITIAL (decl)); + DECL_INITIAL (decl), + tf_warning_or_error); input_location = saved_location; /* Do not clobber shared ints. */ @@ -10684,7 +11014,6 @@ build_enumerator (tree name, tree value, tree enumtype) DECL_CONTEXT (decl) = FROB_CONTEXT (context); TREE_CONSTANT (decl) = 1; - TREE_INVARIANT (decl) = 1; TREE_READONLY (decl) = 1; DECL_INITIAL (decl) = value; @@ -10714,11 +11043,15 @@ check_function_type (tree decl, tree current_function_parms) if (dependent_type_p (return_type)) return; - if (!COMPLETE_OR_VOID_TYPE_P (return_type)) + if (!COMPLETE_OR_VOID_TYPE_P (return_type) + || (TYPE_FOR_JAVA (return_type) && MAYBE_CLASS_TYPE_P (return_type))) { tree args = TYPE_ARG_TYPES (fntype); - error ("return type %q#T is incomplete", return_type); + if (!COMPLETE_OR_VOID_TYPE_P (return_type)) + error ("return type %q#T is incomplete", return_type); + else + error ("return type has Java class type %q#T", return_type); /* Make it return void instead. */ if (TREE_CODE (fntype) == METHOD_TYPE) @@ -10799,6 +11132,15 @@ start_preparsed_function (tree decl1, tree attrs, int flags) && lookup_attribute ("noinline", attrs)) warning (0, "inline function %q+D given attribute noinline", decl1); + /* Handle gnu_inline attribute. */ + if (GNU_INLINE_P (decl1)) + { + DECL_EXTERNAL (decl1) = 1; + DECL_NOT_REALLY_EXTERN (decl1) = 0; + DECL_INTERFACE_KNOWN (decl1) = 1; + DECL_DISREGARD_INLINE_LIMITS (decl1) = 1; + } + if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (decl1)) /* This is a constructor, we must ensure that any default args introduced by this definition are propagated to the clones @@ -10971,14 +11313,19 @@ start_preparsed_function (tree decl1, tree attrs, int flags) CFUN set up, and our per-function variables initialized. FIXME factor out the non-RTL stuff. */ bl = current_binding_level; - allocate_struct_function (decl1); + allocate_struct_function (decl1, processing_template_decl); + + /* Initialize the language data structures. Whenever we start + a new function, we destroy temporaries in the usual way. */ + cfun->language = GGC_CNEW (struct language_function); + current_stmt_tree ()->stmts_are_full_exprs_p = 1; current_binding_level = bl; /* Even though we're inside a function body, we still don't want to call expand_expr to calculate the size of a variable-sized array. We haven't necessarily assigned RTL to all variables yet, so it's not safe to try to expand expressions involving them. */ - cfun->x_dont_save_pending_sizes_p = 1; + cfun->dont_save_pending_sizes_p = 1; /* Start the statement-tree, start the tree now. */ DECL_SAVED_TREE (decl1) = push_stmt_list (); @@ -11000,7 +11347,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags) gcc_assert (TREE_CODE (TREE_TYPE (t)) == POINTER_TYPE); cp_function_chain->x_current_class_ref - = build_indirect_ref (t, NULL); + = cp_build_indirect_ref (t, NULL, tf_warning_or_error); cp_function_chain->x_current_class_ptr = t; /* Constructors and destructors need to know whether they're "in @@ -11084,8 +11431,9 @@ start_preparsed_function (tree decl1, tree attrs, int flags) else { /* This is a definition, not a reference. - So clear DECL_EXTERNAL. */ - DECL_EXTERNAL (decl1) = 0; + So clear DECL_EXTERNAL, unless this is a GNU extern inline. */ + if (!GNU_INLINE_P (decl1)) + DECL_EXTERNAL (decl1) = 0; if ((DECL_DECLARED_INLINE_P (decl1) || DECL_TEMPLATE_INSTANTIATION (decl1)) @@ -11285,7 +11633,8 @@ finish_constructor_body (void) tree val; tree exprstmt; - if (targetm.cxx.cdtor_returns_this ()) + if (targetm.cxx.cdtor_returns_this () + && (! TYPE_FOR_JAVA (current_class_type))) { /* Any return from a constructor will end up here. */ add_stmt (build_stmt (LABEL_EXPR, cdtor_label)); @@ -11440,7 +11789,7 @@ finish_function_body (tree compstmt) of curly braces, skipping the artificial block created for constructor initializers. */ -static tree +tree outer_curly_brace_block (tree fndecl) { tree block = BLOCK_SUBBLOCKS (DECL_INITIAL (fndecl)); @@ -11513,11 +11862,10 @@ 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 + { + location_t linezero = linemap_line_start (line_table, 0, 1); + SET_EXPR_LOCATION (stmt, linezero); + } } if (use_eh_spec_block (current_function_decl)) @@ -11648,7 +11996,7 @@ finish_function (int flags) /* We're leaving the context of this function, so zap cfun. It's still in DECL_STRUCT_FUNCTION, and we'll restore it in tree_rest_of_compilation. */ - cfun = NULL; + set_cfun (NULL); current_function_decl = NULL; /* If this is an in-class inline definition, we may have to pop the @@ -11917,8 +12265,9 @@ cxx_maybe_build_cleanup (tree decl) fn = lookup_name (id); arg = build_address (decl); mark_used (decl); - cleanup = build_function_call (fn, build_tree_list (NULL_TREE, - arg)); + cleanup = cp_build_function_call (fn, build_tree_list (NULL_TREE, + arg), + tf_warning_or_error); } /* Handle ordinary C++ destructors. */ type = TREE_TYPE (decl); @@ -11933,10 +12282,7 @@ cxx_maybe_build_cleanup (tree decl) if (TREE_CODE (type) == ARRAY_TYPE) addr = decl; else - { - cxx_mark_addressable (decl); - addr = build_unary_op (ADDR_EXPR, decl, 0); - } + addr = build_address (decl); /* Optimize for space over speed here. */ if (!has_vbases || flag_expensive_optimizations) @@ -11985,47 +12331,6 @@ revert_static_member_fn (tree decl) DECL_STATIC_FUNCTION_P (decl) = 1; } -/* Initialize the variables used during compilation of a C++ - function. */ - -void -cxx_push_function_context (struct function * f) -{ - struct language_function *p = GGC_CNEW (struct language_function); - f->language = p; - - /* Whenever we start a new function, we destroy temporaries in the - usual way. */ - current_stmt_tree ()->stmts_are_full_exprs_p = 1; - - if (f->decl) - { - tree fn = f->decl; - - if (DECL_SAVED_FUNCTION_DATA (fn)) - { - /* If we already parsed this function, and we're just expanding it - now, restore saved state. */ - *cp_function_chain = *DECL_SAVED_FUNCTION_DATA (fn); - - /* We don't need the saved data anymore. Unless this is an inline - function; we need the named return value info for - declare_return_variable. */ - if (! DECL_INLINE (fn)) - DECL_SAVED_FUNCTION_DATA (fn) = NULL; - } - } -} - -/* Free the language-specific parts of F, now that we've finished - compiling the function. */ - -void -cxx_pop_function_context (struct function * f) -{ - f->language = 0; -} - /* Return which tree structure is used by T, or TS_CP_GENERIC if T is one of the language-independent trees. */ @@ -12038,7 +12343,6 @@ cp_tree_node_structure (union lang_tree_node * t) case IDENTIFIER_NODE: return TS_CP_IDENTIFIER; case OVERLOAD: return TS_CP_OVERLOAD; 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 STATIC_ASSERT: return TS_CP_STATIC_ASSERT;