c++: Small cleanup for do_type_instantiation

In working on a bigger cleanup I noticed some opportunities to make
do_type_instantiation's control flow simpler.

	gcc/cp/
	* parser.c (cp_parser_explicit_instantiation): Refactor some RAII.
	* pt.c (bt_instantiate_type_proc): DATA is the tree, pass type to
	do_type_instantiation.
	(do_type_instantiation): Require T to be a type.  Refactor for
	some RAII.
This commit is contained in:
Nathan Sidwell 2020-10-27 08:48:26 -07:00
parent 0f801e0b6c
commit 88f8b3dda5
2 changed files with 41 additions and 56 deletions

View file

@ -17642,10 +17642,8 @@ cp_parser_explicit_instantiation (cp_parser* parser)
instantiation. */
if (declares_class_or_enum && cp_parser_declares_only_class_p (parser))
{
tree type;
type = check_tag_decl (&decl_specifiers,
/*explicit_type_instantiation_p=*/true);
tree type = check_tag_decl (&decl_specifiers,
/*explicit_type_instantiation_p=*/true);
/* Turn access control back on for names used during
template instantiation. */
pop_deferring_access_checks ();
@ -25156,14 +25154,12 @@ cp_parser_member_declaration (cp_parser* parser)
}
else
{
tree type;
/* See if this declaration is a friend. */
friend_p = cp_parser_friend_p (&decl_specifiers);
/* If there were decl-specifiers, check to see if there was
a class-declaration. */
type = check_tag_decl (&decl_specifiers,
/*explicit_type_instantiation_p=*/false);
tree type = check_tag_decl (&decl_specifiers,
/*explicit_type_instantiation_p=*/false);
/* Nested classes have already been added to the class, but
a `friend' needs to be explicitly registered. */
if (friend_p)

View file

@ -24964,12 +24964,12 @@ mark_class_instantiated (tree t, int extern_p)
static void
bt_instantiate_type_proc (binding_entry entry, void *data)
{
tree storage = *(tree *) data;
tree storage = tree (data);
if (MAYBE_CLASS_TYPE_P (entry->type)
if (CLASS_TYPE_P (entry->type)
&& CLASSTYPE_TEMPLATE_INFO (entry->type)
&& !uses_template_parms (CLASSTYPE_TI_ARGS (entry->type)))
do_type_instantiation (TYPE_MAIN_DECL (entry->type), storage, 0);
do_type_instantiation (entry->type, storage, 0);
}
/* Perform an explicit instantiation of template class T. STORAGE, if
@ -24980,20 +24980,11 @@ bt_instantiate_type_proc (binding_entry entry, void *data)
void
do_type_instantiation (tree t, tree storage, tsubst_flags_t complain)
{
int extern_p = 0;
int nomem_p = 0;
int static_p = 0;
int previous_instantiation_extern_p = 0;
if (TREE_CODE (t) == TYPE_DECL)
t = TREE_TYPE (t);
if (! CLASS_TYPE_P (t) || ! CLASSTYPE_TEMPLATE_INFO (t))
if (!(CLASS_TYPE_P (t) && CLASSTYPE_TEMPLATE_INFO (t)))
{
tree tmpl =
(TYPE_TEMPLATE_INFO (t)) ? TYPE_TI_TEMPLATE (t) : NULL;
if (tmpl)
error ("explicit instantiation of non-class template %qD", tmpl);
if (tree ti = TYPE_TEMPLATE_INFO (t))
error ("explicit instantiation of non-class template %qD",
TI_TEMPLATE (ti));
else
error ("explicit instantiation of non-template type %qT", t);
return;
@ -25009,6 +25000,11 @@ do_type_instantiation (tree t, tree storage, tsubst_flags_t complain)
return;
}
/* At most one of these will be true. */
bool extern_p = false;
bool nomem_p = false;
bool static_p = false;
if (storage != NULL_TREE)
{
if (storage == ridpointers[(int) RID_EXTERN])
@ -25024,52 +25020,45 @@ do_type_instantiation (tree t, tree storage, tsubst_flags_t complain)
" on explicit instantiations", storage);
if (storage == ridpointers[(int) RID_INLINE])
nomem_p = 1;
nomem_p = true;
else if (storage == ridpointers[(int) RID_EXTERN])
extern_p = 1;
extern_p = true;
else if (storage == ridpointers[(int) RID_STATIC])
static_p = 1;
static_p = true;
else
{
error ("storage class %qD applied to template instantiation",
storage);
extern_p = 0;
}
error ("storage class %qD applied to template instantiation",
storage);
}
if (CLASSTYPE_TEMPLATE_SPECIALIZATION (t))
{
/* DR 259 [temp.spec].
/* DR 259 [temp.spec].
Both an explicit instantiation and a declaration of an explicit
specialization shall not appear in a program unless the explicit
instantiation follows a declaration of the explicit specialization.
Both an explicit instantiation and a declaration of an explicit
specialization shall not appear in a program unless the
explicit instantiation follows a declaration of the explicit
specialization.
For a given set of template parameters, if an explicit
instantiation of a template appears after a declaration of an
explicit specialization for that template, the explicit
instantiation has no effect. */
return;
}
else if (CLASSTYPE_EXPLICIT_INSTANTIATION (t))
For a given set of template parameters, if an explicit
instantiation of a template appears after a declaration of an
explicit specialization for that template, the explicit
instantiation has no effect. */
return;
if (CLASSTYPE_EXPLICIT_INSTANTIATION (t) && !CLASSTYPE_INTERFACE_ONLY (t))
{
/* We've already instantiated the template. */
/* [temp.spec]
No program shall explicitly instantiate any template more
than once.
If PREVIOUS_INSTANTIATION_EXTERN_P, then the first explicit
instantiation was `extern'. If EXTERN_P then the second is.
These cases are OK. */
previous_instantiation_extern_p = CLASSTYPE_INTERFACE_ONLY (t);
If EXTERN_P then this is ok. */
if (!extern_p && (complain & tf_error))
permerror (input_location,
"duplicate explicit instantiation of %q#T", t);
if (!previous_instantiation_extern_p && !extern_p
&& (complain & tf_error))
permerror (input_location, "duplicate explicit instantiation of %q#T", t);
/* If we've already instantiated the template, just return now. */
if (!CLASSTYPE_INTERFACE_ONLY (t))
return;
return;
}
check_explicit_instantiation_namespace (TYPE_NAME (t));
@ -25109,7 +25098,7 @@ do_type_instantiation (tree t, tree storage, tsubst_flags_t complain)
if (CLASSTYPE_NESTED_UTDS (t))
binding_table_foreach (CLASSTYPE_NESTED_UTDS (t),
bt_instantiate_type_proc, &storage);
bt_instantiate_type_proc, storage);
}
/* Given a function DECL, which is a specialization of TMPL, modify