aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/decl.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/decl.c')
-rw-r--r--gcc/cp/decl.c130
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);