[clang] c7ed65b - [C++20][Modules] Limit ModuleInternalLinkage to modules-ts.

Iain Sandoe via cfe-commits cfe-commits at lists.llvm.org
Fri Apr 1 01:11:08 PDT 2022


Author: Iain Sandoe
Date: 2022-04-01T09:10:30+01:00
New Revision: c7ed65b4bcbd8c26704efc4193243831e3c13d3c

URL: https://github.com/llvm/llvm-project/commit/c7ed65b4bcbd8c26704efc4193243831e3c13d3c
DIFF: https://github.com/llvm/llvm-project/commit/c7ed65b4bcbd8c26704efc4193243831e3c13d3c.diff

LOG: [C++20][Modules] Limit ModuleInternalLinkage to modules-ts.

At present, we are generating wrong code for C++20 modules entities which
should have internal linkage.  This is because we are assigning
'ModuleInternalLinkage' unconditionally to such entities.  However this mode
is only applicable to the modules-ts.

This change makes the special linkage mode conditional on fmodules-ts and
adds a unit test to verify that we generate the correct linkage.

Currently, static variables and functions in module purview are emitted into
object files as external. On some platforms, lambdas are emitted as global
weak defintions (on Windows this causes a mangler crash).

Differential Revision: https://reviews.llvm.org/D122413

Added: 
    

Modified: 
    clang/lib/AST/Decl.cpp
    clang/unittests/AST/DeclTest.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 46c888430bb07..6af7a37dfc7b2 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -596,11 +596,12 @@ static bool isExportedFromModuleInterfaceUnit(const NamedDecl *D) {
 }
 
 static LinkageInfo getInternalLinkageFor(const NamedDecl *D) {
-  // Internal linkage declarations within a module interface unit are modeled
-  // as "module-internal linkage", which means that they have internal linkage
-  // formally but can be indirectly accessed from outside the module via inline
-  // functions and templates defined within the module.
-  if (isInModulePurview(D))
+  // (for the modules ts) Internal linkage declarations within a module
+  // interface unit are modeled as "module-internal linkage", which means that
+  // they have internal linkage formally but can be indirectly accessed from
+  // outside the module via inline functions and templates defined within the
+  // module.
+  if (isInModulePurview(D) && D->getASTContext().getLangOpts().ModulesTS)
     return LinkageInfo(ModuleInternalLinkage, DefaultVisibility, false);
 
   return LinkageInfo::internal();

diff  --git a/clang/unittests/AST/DeclTest.cpp b/clang/unittests/AST/DeclTest.cpp
index 7c227d40af86b..560c6b3ddf434 100644
--- a/clang/unittests/AST/DeclTest.cpp
+++ b/clang/unittests/AST/DeclTest.cpp
@@ -194,3 +194,50 @@ TEST(Decl, InConsistLinkageForTemplates) {
   EXPECT_EQ(TemplateF->getLinkageInternal(),
             SpecializedF->getLinkageInternal());
 }
+
+TEST(Decl, ModuleAndInternalLinkage) {
+  llvm::Annotations Code(R"(
+    export module M;
+    static int a;
+    static int f(int x);
+
+    int b;
+    int g(int x);)");
+
+  auto AST =
+      tooling::buildASTFromCodeWithArgs(Code.code(), /*Args=*/{"-std=c++20"});
+  ASTContext &Ctx = AST->getASTContext();
+
+  const auto *a =
+      selectFirst<VarDecl>("a", match(varDecl(hasName("a")).bind("a"), Ctx));
+  const auto *f = selectFirst<FunctionDecl>(
+      "f", match(functionDecl(hasName("f")).bind("f"), Ctx));
+
+  EXPECT_EQ(a->getLinkageInternal(), InternalLinkage);
+  EXPECT_EQ(f->getLinkageInternal(), InternalLinkage);
+
+  const auto *b =
+      selectFirst<VarDecl>("b", match(varDecl(hasName("b")).bind("b"), Ctx));
+  const auto *g = selectFirst<FunctionDecl>(
+      "g", match(functionDecl(hasName("g")).bind("g"), Ctx));
+
+  EXPECT_EQ(b->getLinkageInternal(), ModuleLinkage);
+  EXPECT_EQ(g->getLinkageInternal(), ModuleLinkage);
+
+  AST = tooling::buildASTFromCodeWithArgs(
+      Code.code(), /*Args=*/{"-std=c++20", "-fmodules-ts"});
+  ASTContext &CtxTS = AST->getASTContext();
+  a = selectFirst<VarDecl>("a", match(varDecl(hasName("a")).bind("a"), CtxTS));
+  f = selectFirst<FunctionDecl>(
+      "f", match(functionDecl(hasName("f")).bind("f"), CtxTS));
+
+  EXPECT_EQ(a->getLinkageInternal(), ModuleInternalLinkage);
+  EXPECT_EQ(f->getLinkageInternal(), ModuleInternalLinkage);
+
+  b = selectFirst<VarDecl>("b", match(varDecl(hasName("b")).bind("b"), CtxTS));
+  g = selectFirst<FunctionDecl>(
+      "g", match(functionDecl(hasName("g")).bind("g"), CtxTS));
+
+  EXPECT_EQ(b->getLinkageInternal(), ModuleLinkage);
+  EXPECT_EQ(g->getLinkageInternal(), ModuleLinkage);
+}


        


More information about the cfe-commits mailing list