diff options
Diffstat (limited to 'gcc/cp/decl.c')
-rw-r--r-- | gcc/cp/decl.c | 130 |
1 files changed, 69 insertions, 61 deletions
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index d3544172bc4..6b278ae2878 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -1672,13 +1672,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); @@ -3715,22 +3716,22 @@ start_decl (const cp_declarator *declarator, /* 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; } @@ -5609,7 +5610,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; @@ -8586,7 +8587,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); @@ -8607,7 +8608,7 @@ unary_op_p (enum tree_code code) errors are issued for invalid declarations. */ void -grok_op_properties (tree decl, int friendp, bool complain) +grok_op_properties (tree decl, bool complain) { tree argtypes = TYPE_ARG_TYPES (TREE_TYPE (decl)); tree argtype; @@ -8615,6 +8616,7 @@ grok_op_properties (tree decl, int friendp, bool complain) tree name = DECL_NAME (decl); enum tree_code operator_code; int arity; + tree class_type; /* Count the number of arguments. */ for (argtype = argtypes, arity = 0; @@ -8622,8 +8624,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; @@ -8652,30 +8655,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: @@ -8754,32 +8755,38 @@ grok_op_properties (tree decl, int friendp, bool complain) if (operator_code == CALL_EXPR) 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 (0, "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) { @@ -8806,7 +8813,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; @@ -9878,7 +9885,8 @@ 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)))); /* Sanity check. */ gcc_assert (TREE_CODE (TREE_VALUE (void_list_node)) == VOID_TYPE); |