2017-06-30 Nathan Sidwell <nathan@acm.org>
+ * call.c (build_new_method_call_1): Use constructo_name to get
+ ctor name. Move argument processing earlier to merge cdtor
+ handling blocks.
+ * decl.c (grokfndecl): Cdtors have special names.
+ * method.c (implicitly_declare_fn): Likewise. Simplify flag setting.
+ * pt.c (check_explicit_specialization): Cdtor name is already
+ special.
+ * search.c (class_method_index_for_fn): Likewise.
+
PR c++/81229
* name-lookup.c (do_pushdecl): Reset IDENTIFIER_TYPE when finding
a matching TYPE_DECL.
if (! (complain & tf_error))
return error_mark_node;
+ name = constructor_name (basetype);
if (permerror (input_location,
"cannot call constructor %<%T::%D%> directly",
basetype, name))
return call;
}
+ /* Process the argument list. */
+ if (args != NULL && *args != NULL)
+ {
+ *args = resolve_args (*args, complain);
+ if (*args == NULL)
+ return error_mark_node;
+ }
+
+ /* Consider the object argument to be used even if we end up selecting a
+ static member function. */
+ instance = mark_type_use (instance);
+
+
/* Figure out whether to skip the first argument for the error
message we will display to users if an error occurs. We don't
want to display any compiler-generated arguments. The "this"
skip_first_for_error = false;
if (IDENTIFIER_CDTOR_P (name))
{
- /* Callers should explicitly indicate whether they want to construct
+ /* Callers should explicitly indicate whether they want to ctor
the complete object or just the part without virtual bases. */
gcc_assert (name != ctor_identifier);
- /* Similarly for destructors. */
- gcc_assert (name != dtor_identifier);
+
/* Remove the VTT pointer, if present. */
if ((name == base_ctor_identifier || name == base_dtor_identifier)
&& CLASSTYPE_VBASECLASSES (basetype))
skip_first_for_error = true;
- }
- /* Process the argument list. */
- if (args != NULL && *args != NULL)
- {
- *args = resolve_args (*args, complain);
- if (*args == NULL)
- return error_mark_node;
- }
-
- /* Consider the object argument to be used even if we end up selecting a
- static member function. */
- instance = mark_type_use (instance);
-
- /* It's OK to call destructors and constructors on cv-qualified objects.
- Therefore, convert the INSTANCE to the unqualified type, if
- necessary. */
- if (DECL_DESTRUCTOR_P (fn)
- || DECL_CONSTRUCTOR_P (fn))
- {
+ /* It's OK to call destructors and constructors on cv-qualified
+ objects. Therefore, convert the INSTANCE to the unqualified
+ type, if necessary. */
if (!same_type_p (basetype, TREE_TYPE (instance)))
{
instance = build_this (instance);
instance = build_fold_indirect_ref (instance);
}
}
- if (DECL_DESTRUCTOR_P (fn))
- name = complete_dtor_identifier;
+ else
+ gcc_assert (!DECL_DESTRUCTOR_P (fn) && !DECL_CONSTRUCTOR_P (fn));
/* For the overload resolution we need to find the actual `this`
that would be captured if the call turns out to be to a
case sfk_copy_constructor:
case sfk_move_constructor:
DECL_CONSTRUCTOR_P (decl) = 1;
+ DECL_NAME (decl) = ctor_identifier;
break;
case sfk_destructor:
DECL_DESTRUCTOR_P (decl) = 1;
+ DECL_NAME (decl) = dtor_identifier;
break;
default:
break;
{
case sfk_destructor:
/* Destructor. */
- name = constructor_name (type);
+ name = dtor_identifier;
break;
case sfk_constructor:
/* Default constructor. */
- name = constructor_name (type);
+ name = ctor_identifier;
break;
case sfk_copy_constructor:
name = cp_assignment_operator_id (NOP_EXPR);
}
else
- name = constructor_name (type);
+ name = ctor_identifier;
if (kind == sfk_inheriting_constructor)
parameter_types = inherited_parms;
fn = build_lang_decl (FUNCTION_DECL, name, fn_type);
if (kind != sfk_inheriting_constructor)
DECL_SOURCE_LOCATION (fn) = DECL_SOURCE_LOCATION (TYPE_NAME (type));
- if (kind == sfk_constructor || kind == sfk_copy_constructor
- || kind == sfk_move_constructor || kind == sfk_inheriting_constructor)
- DECL_CONSTRUCTOR_P (fn) = 1;
- else if (kind == sfk_destructor)
- DECL_DESTRUCTOR_P (fn) = 1;
- else
+
+ if (!IDENTIFIER_CDTOR_P (name))
+ /* Assignment operator. */
SET_OVERLOADED_OPERATOR_CODE (fn, NOP_EXPR);
+ else if (IDENTIFIER_CTOR_P (name))
+ DECL_CONSTRUCTOR_P (fn) = true;
+ else
+ DECL_DESTRUCTOR_P (fn) = true;
SET_DECL_ALIGN (fn, MINIMUM_METHOD_BOUNDARY);
if (constructor_name_p (name, ctype))
{
- int is_constructor = DECL_CONSTRUCTOR_P (decl);
-
- if (is_constructor ? !TYPE_HAS_USER_CONSTRUCTOR (ctype)
+ if (DECL_CONSTRUCTOR_P (decl)
+ ? !TYPE_HAS_USER_CONSTRUCTOR (ctype)
: !CLASSTYPE_DESTRUCTOR (ctype))
{
/* From [temp.expl.spec]:
return error_mark_node;
}
- name = is_constructor ? ctor_identifier : dtor_identifier;
+ name = DECL_NAME (decl);
}
if (!DECL_CONV_FN_P (decl))
{
gcc_assert (DECL_DECLARES_FUNCTION_P (function));
- return lookup_fnfields_1 (class_type,
- DECL_CONSTRUCTOR_P (function) ? ctor_identifier :
- DECL_DESTRUCTOR_P (function) ? dtor_identifier :
- DECL_NAME (function));
+ return lookup_fnfields_1 (class_type, DECL_NAME (function));
}
2017-06-30 Nathan Sidwell <nathan@acm.org>
+ * g++.dg/plugin/decl-plugin-test.C: Expect special ctor name.
+
PR c++/81229
* g++.dg/lookup/pr81229.C: New.
int class_field1; // { dg-warning "Decl Field class_field1" }
int class_field2; // { dg-warning "Decl Field class_field2" }
- test_class() // { dg-warning "Decl Function test_class" }
+ test_class() // { dg-warning "Decl Function __ct" }
: class_field1(0), class_field2(0)
{}