|| TREE_TYPE (olddecl) == error_mark_node)
return error_mark_node;
- if (DECL_NAME (newdecl)
- && DECL_NAME (olddecl)
- && UDLIT_OPER_P (DECL_NAME (newdecl))
- && UDLIT_OPER_P (DECL_NAME (olddecl)))
- {
- if (TREE_CODE (newdecl) == TEMPLATE_DECL
- && TREE_CODE (olddecl) != TEMPLATE_DECL
- && check_raw_literal_operator (olddecl))
- error_at (newdecl_loc,
- "literal operator template %qD conflicts with"
- " raw literal operator %qD", newdecl, olddecl);
- else if (TREE_CODE (newdecl) != TEMPLATE_DECL
- && TREE_CODE (olddecl) == TEMPLATE_DECL
- && check_raw_literal_operator (newdecl))
- error_at (newdecl_loc,
- "raw literal operator %qD conflicts with"
- " literal operator template %qD", newdecl, olddecl);
- }
-
- /* True to merge attributes between the declarations, false to
- set OLDDECL's attributes to those of NEWDECL (for template
- explicit specializations that specify their own attributes
- independent of those specified for the primary template). */
- const bool merge_attr = (TREE_CODE (newdecl) != FUNCTION_DECL
- || !DECL_TEMPLATE_SPECIALIZATION (newdecl)
- || DECL_TEMPLATE_SPECIALIZATION (olddecl));
-
- if (DECL_P (olddecl)
- && TREE_CODE (newdecl) == FUNCTION_DECL
- && TREE_CODE (olddecl) == FUNCTION_DECL
- && merge_attr
- && diagnose_mismatched_attributes (olddecl, newdecl))
- {
- if (DECL_INITIAL (olddecl))
- inform (olddecl_loc,
- "previous definition of %qD was here", olddecl);
- else
- inform (olddecl_loc,
- "previous declaration of %qD was here", olddecl);
- }
-
/* Check for redeclaration and other discrepancies. */
if (TREE_CODE (olddecl) == FUNCTION_DECL
&& DECL_ARTIFICIAL (olddecl))
/* C++ Standard, 3.3, clause 4:
"[Note: a namespace name or a class template name must be unique
in its declarative region (7.3.2, clause 14). ]" */
- if (TREE_CODE (olddecl) != NAMESPACE_DECL
- && TREE_CODE (newdecl) != NAMESPACE_DECL
- && (TREE_CODE (olddecl) != TEMPLATE_DECL
- || TREE_CODE (DECL_TEMPLATE_RESULT (olddecl)) != TYPE_DECL)
- && (TREE_CODE (newdecl) != TEMPLATE_DECL
- || TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) != TYPE_DECL))
- {
- if ((TREE_CODE (olddecl) == TYPE_DECL && DECL_ARTIFICIAL (olddecl)
- && TREE_CODE (newdecl) != TYPE_DECL)
- || (TREE_CODE (newdecl) == TYPE_DECL && DECL_ARTIFICIAL (newdecl)
- && TREE_CODE (olddecl) != TYPE_DECL))
- {
- /* We do nothing special here, because C++ does such nasty
- things with TYPE_DECLs. Instead, just let the TYPE_DECL
- get shadowed, and know that if we need to find a TYPE_DECL
- for a given name, we can look in the IDENTIFIER_TYPE_VALUE
- slot of the identifier. */
- return NULL_TREE;
- }
-
- if ((TREE_CODE (newdecl) == FUNCTION_DECL
- && DECL_FUNCTION_TEMPLATE_P (olddecl))
- || (TREE_CODE (olddecl) == FUNCTION_DECL
- && DECL_FUNCTION_TEMPLATE_P (newdecl)))
- return NULL_TREE;
+ if (TREE_CODE (olddecl) == NAMESPACE_DECL
+ || TREE_CODE (newdecl) == NAMESPACE_DECL)
+ /* Namespace conflicts with not namespace. */;
+ else if (DECL_TYPE_TEMPLATE_P (olddecl)
+ || DECL_TYPE_TEMPLATE_P (newdecl))
+ /* Class template conflicts. */;
+ else if ((TREE_CODE (newdecl) == FUNCTION_DECL
+ && DECL_FUNCTION_TEMPLATE_P (olddecl))
+ || (TREE_CODE (olddecl) == FUNCTION_DECL
+ && DECL_FUNCTION_TEMPLATE_P (newdecl)))
+ {
+ /* One is a function and the other is a template
+ function. */
+ if (!UDLIT_OPER_P (DECL_NAME (newdecl)))
+ return NULL_TREE;
+
+ /* There can only be one! */
+ if (TREE_CODE (newdecl) == TEMPLATE_DECL
+ && check_raw_literal_operator (olddecl))
+ error_at (newdecl_loc,
+ "literal operator %q#D conflicts with"
+ " raw literal operator", newdecl);
+ else if (check_raw_literal_operator (newdecl))
+ error_at (newdecl_loc,
+ "raw literal operator %q#D conflicts with"
+ " literal operator template", newdecl);
+ else
+ return NULL_TREE;
+
+ inform (olddecl_loc, "previous declaration %q#D", olddecl);
+ return error_mark_node;
}
+ else if (DECL_IMPLICIT_TYPEDEF_P (olddecl)
+ || DECL_IMPLICIT_TYPEDEF_P (newdecl))
+ /* One is an implicit typedef, that's ok. */
+ return NULL_TREE;
- error ("%q#D redeclared as different kind of symbol", newdecl);
- if (TREE_CODE (olddecl) == TREE_LIST)
- olddecl = TREE_VALUE (olddecl);
- inform (olddecl_loc,
- "previous declaration %q#D", olddecl);
+ error ("%q#D redeclared as different kind of entity", newdecl);
+ inform (olddecl_loc, "previous declaration %q#D", olddecl);
return error_mark_node;
}
return type. */
&& same_type_p (TREE_TYPE (TREE_TYPE (newdecl)),
TREE_TYPE (TREE_TYPE (olddecl)))
- // Template functions can also be disambiguated by
- // constraints.
+ /* Template functions can also be disambiguated by
+ constraints. */
&& equivalently_constrained (olddecl, newdecl))
{
error_at (newdecl_loc, "ambiguating new declaration %q#D",
|| DECL_IMPLICIT_TYPEDEF_P (newdecl)))
return NULL_TREE;
+ if (!validate_constexpr_redeclaration (olddecl, newdecl))
+ return error_mark_node;
+
+ /* We have committed to returning OLDDECL at this point. */
+
/* If new decl is `static' and an `extern' was seen previously,
warn about it. */
warn_extern_redeclared_static (newdecl, olddecl);
- if (!validate_constexpr_redeclaration (olddecl, newdecl))
- return error_mark_node;
+ /* True to merge attributes between the declarations, false to
+ set OLDDECL's attributes to those of NEWDECL (for template
+ explicit specializations that specify their own attributes
+ independent of those specified for the primary template). */
+ const bool merge_attr = (TREE_CODE (newdecl) != FUNCTION_DECL
+ || !DECL_TEMPLATE_SPECIALIZATION (newdecl)
+ || DECL_TEMPLATE_SPECIALIZATION (olddecl));
- /* We have committed to returning 1 at this point. */
if (TREE_CODE (newdecl) == FUNCTION_DECL)
{
+ if (merge_attr && diagnose_mismatched_attributes (olddecl, newdecl))
+ inform (olddecl_loc, DECL_INITIAL (olddecl)
+ ? G_("previous definition of %qD here")
+ : G_("previous declaration of %qD here"), olddecl);
+
/* Now that functions must hold information normally held
by field decls, there is extra work to do so that
declaration information does not get destroyed during
else
DECL_ATTRIBUTES (olddecl) = DECL_ATTRIBUTES (newdecl);
- if (DECL_DECLARES_FUNCTION_P (olddecl) && DECL_DECLARES_FUNCTION_P (newdecl))
+ if (DECL_DECLARES_FUNCTION_P (olddecl))
{
olddecl_friend = DECL_FRIEND_P (olddecl);
olddecl_hidden_friend = DECL_HIDDEN_FRIEND_P (olddecl);