During Reflection review it came up that we don't have lk_module.
Instead, we're checking lk_external && DECL_MODULE_ATTACH_P &&
!DECL_MODULE_EXPORT_P. This patch adds lk_module which allows further
cleanups.
I'm not sure the cp_parser_template_argument change is required.
gcc/cp/ChangeLog:
* cp-tree.h (enum linkage_kind): Add lk_module.
* module.cc (check_module_decl_linkage): Use DECL_EXTERNAL_LINKAGE_P.
* name-lookup.cc (check_can_export_using_decl): Don't check for
attachment.
* parser.cc (cp_parser_template_argument): Check that linkage isn't
lk_module.
* reflect.cc (eval_has_module_linkage): Check lk_module.
(eval_has_external_linkage): Use DECL_EXTERNAL_LINKAGE_P.
* tree.cc (decl_linkage): Return lk_module if appropriate.
Reviewed-by: Jason Merrill <jason@redhat.com>
translation unit.
-- When a name has no linkage, the entity it denotes cannot be
- referred to by names from other scopes. */
+ referred to by names from other scopes.
+
+ -- When the declaration of the name is attached to a named module
+ and is not exported, the name has module linkage. */
enum linkage_kind {
lk_none, /* No linkage. */
lk_internal, /* Internal linkage. */
- lk_external /* External linkage. */
+ lk_external, /* External linkage. */
+ lk_module /* Module linkage. */
};
enum duration_kind {
&& decl_defined_p (decl)
&& !(DECL_LANG_SPECIFIC (decl)
&& DECL_TEMPLATE_INSTANTIATION (decl))
- && decl_linkage (decl) == lk_external)
+ && DECL_EXTERNAL_LINKAGE_P (decl))
error_at (DECL_SOURCE_LOCATION (decl),
"external linkage definition of %qD in header module must "
"be declared %<inline%>", decl);
not_tmpl = TYPE_NAME (DECL_CONTEXT (not_tmpl));
/* If the using decl is exported, the things it refers to must
- have external linkage. decl_linkage returns lk_external for
- module linkage so also check for attachment. */
- if (linkage != lk_external
- || (DECL_LANG_SPECIFIC (not_tmpl)
- && DECL_MODULE_ATTACH_P (not_tmpl)
- && !DECL_MODULE_EXPORT_P (not_tmpl)))
+ have external linkage. */
+ if (linkage != lk_external)
{
auto_diagnostic_group d;
bool diag = true;
{
linkage_kind linkage = decl_linkage (probe);
if (linkage != lk_external
+ && linkage != lk_module
&& (cxx_dialect < cxx11 || linkage != lk_internal))
cp_parser_simulate_error (parser);
}
if (!r)
return boolean_false_node;
}
- if (decl_linkage (r) == lk_external
- && DECL_LANG_SPECIFIC (r)
- && DECL_MODULE_ATTACH_P (r)
- && !DECL_MODULE_EXPORT_P (r))
+ if (decl_linkage (r) == lk_module)
return boolean_true_node;
else
return boolean_false_node;
if (!r)
return boolean_false_node;
}
- if (decl_linkage (r) == lk_external
- && !(DECL_LANG_SPECIFIC (r)
- && DECL_MODULE_ATTACH_P (r)
- && !DECL_MODULE_EXPORT_P (r)))
+ if (DECL_EXTERNAL_LINKAGE_P (r))
return boolean_true_node;
else
return boolean_false_node;
if (cxx_dialect >= cxx11 && decl_internal_context_p (decl))
return lk_internal;
+ /* Helper to decide if T is lk_module or lk_external. */
+ auto external_or_module = [] (tree t)
+ {
+ if (t
+ && DECL_LANG_SPECIFIC (t)
+ && DECL_MODULE_ATTACH_P (t)
+ && !DECL_MODULE_EXPORT_P (t))
+ return lk_module;
+
+ return lk_external;
+ };
+
/* Templates don't properly propagate TREE_PUBLIC, consider the
template result instead. Any template that isn't a variable
or function must be external linkage by this point. */
{
decl = DECL_TEMPLATE_RESULT (decl);
if (!decl || !VAR_OR_FUNCTION_DECL_P (decl))
- return lk_external;
+ return external_or_module (decl);
}
/* Things that are TREE_PUBLIC have external linkage. */
if (TREE_PUBLIC (decl))
- return lk_external;
+ return external_or_module (decl);
/* All types have external linkage in C++98, since anonymous namespaces
didn't explicitly confer internal linkage. */
if (TREE_CODE (decl) == TYPE_DECL && cxx_dialect < cxx11)
- return lk_external;
+ return external_or_module (decl);
/* Variables or function decls not marked as TREE_PUBLIC might still
be external linkage, such as for template instantiations on targets
or compiler-generated entities; in such cases, decls really meant to
have internal linkage will have DECL_THIS_STATIC set. */
if (VAR_OR_FUNCTION_DECL_P (decl) && !DECL_THIS_STATIC (decl))
- return lk_external;
+ return external_or_module (decl);
/* Everything else has internal linkage. */
return lk_internal;