From: Marek Polacek Date: Tue, 20 Jan 2026 21:16:33 +0000 (-0500) Subject: c++: add lk_module X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8b110daf57a8b9966a07ce5f18a2fbb1949a434e;p=thirdparty%2Fgcc.git c++: add lk_module 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 --- diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 8a4ac460059..3d1f6f99aad 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -6124,12 +6124,16 @@ enum special_function_kind { 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 { diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index a7245aae46a..896058d96d9 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -22139,7 +22139,7 @@ check_module_decl_linkage (tree decl) && 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 %", decl); diff --git a/gcc/cp/name-lookup.cc b/gcc/cp/name-lookup.cc index 2127cf99937..568e615918c 100644 --- a/gcc/cp/name-lookup.cc +++ b/gcc/cp/name-lookup.cc @@ -5488,12 +5488,8 @@ check_can_export_using_decl (tree binding) 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; diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index 3ec85e8416d..d07dc01650f 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -21993,6 +21993,7 @@ cp_parser_template_argument (cp_parser* parser) { linkage_kind linkage = decl_linkage (probe); if (linkage != lk_external + && linkage != lk_module && (cxx_dialect < cxx11 || linkage != lk_internal)) cp_parser_simulate_error (parser); } diff --git a/gcc/cp/reflect.cc b/gcc/cp/reflect.cc index b36c4be4273..09e99b5ef83 100644 --- a/gcc/cp/reflect.cc +++ b/gcc/cp/reflect.cc @@ -2031,10 +2031,7 @@ eval_has_module_linkage (tree r, reflect_kind kind) 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; @@ -2061,10 +2058,7 @@ eval_has_external_linkage (tree r, reflect_kind kind) 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; diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc index c57587dbeee..d3e202e8b04 100644 --- a/gcc/cp/tree.cc +++ b/gcc/cp/tree.cc @@ -6653,6 +6653,18 @@ decl_linkage (tree decl) 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. */ @@ -6660,17 +6672,17 @@ decl_linkage (tree decl) { 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 @@ -6678,7 +6690,7 @@ decl_linkage (tree decl) 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;