[clang] 6345b00 - [C++20] [Modules] Add mangling number for lambda in non-internal module unit context
Chuanqi Xu via cfe-commits
cfe-commits at lists.llvm.org
Thu Mar 13 00:05:11 PDT 2025
Author: Chuanqi Xu
Date: 2025-03-13T15:04:06+08:00
New Revision: 6345b009c3e58a6cd0eca835d5a935f8784cfda6
URL: https://github.com/llvm/llvm-project/commit/6345b009c3e58a6cd0eca835d5a935f8784cfda6
DIFF: https://github.com/llvm/llvm-project/commit/6345b009c3e58a6cd0eca835d5a935f8784cfda6.diff
LOG: [C++20] [Modules] Add mangling number for lambda in non-internal module unit context
Close https://github.com/llvm/llvm-project/issues/59513
Close https://github.com/llvm/llvm-project/issues/110146
As we discussed, this is related to ABI:
https://github.com/itanium-cxx-abi/cxx-abi/issues/186
I was intending to fix this after it gets merged into the ItaniumC++ABI
formally. But it looks like ItaniumC++ABI doesn't update it yet and
there are more issue reports for it.
Luckily Richard had a clear direction guide here though. So I think it
should be good to do this without a formal ItaniumC++ABI wording.
The diff of the patch is slightly larger than it was by a simple
refacoration to simple the control flow a little bit.
Added:
clang/test/Modules/lambda-in-module-purview-2.cppm
clang/test/Modules/lambda-in-module-purview.cppm
Modified:
clang/lib/Sema/SemaLambda.cpp
Removed:
################################################################################
diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp
index ceb32ee15dfa3..292406f886362 100644
--- a/clang/lib/Sema/SemaLambda.cpp
+++ b/clang/lib/Sema/SemaLambda.cpp
@@ -292,7 +292,8 @@ Sema::getCurrentMangleNumberContext(const DeclContext *DC) {
DataMember,
InlineVariable,
TemplatedVariable,
- Concept
+ Concept,
+ NonInlineInModulePurview
} Kind = Normal;
bool IsInNonspecializedTemplate =
@@ -301,29 +302,50 @@ Sema::getCurrentMangleNumberContext(const DeclContext *DC) {
// Default arguments of member function parameters that appear in a class
// definition, as well as the initializers of data members, receive special
// treatment. Identify them.
- if (ManglingContextDecl) {
+ Kind = [&]() {
+ if (!ManglingContextDecl)
+ return Normal;
+
+ if (auto *ND = dyn_cast<NamedDecl>(ManglingContextDecl)) {
+ // See discussion in https://github.com/itanium-cxx-abi/cxx-abi/issues/186
+ //
+ // zygoloid:
+ // Yeah, I think the only cases left where lambdas don't need a
+ // mangling are when they have (effectively) internal linkage or appear
+ // in a non-inline function in a non-module translation unit.
+ Module *M = ManglingContextDecl->getOwningModule();
+ if (M && M->getTopLevelModule()->isNamedModuleUnit() &&
+ ND->isExternallyVisible())
+ return NonInlineInModulePurview;
+ }
+
if (ParmVarDecl *Param = dyn_cast<ParmVarDecl>(ManglingContextDecl)) {
if (const DeclContext *LexicalDC
= Param->getDeclContext()->getLexicalParent())
if (LexicalDC->isRecord())
- Kind = DefaultArgument;
+ return DefaultArgument;
} else if (VarDecl *Var = dyn_cast<VarDecl>(ManglingContextDecl)) {
if (Var->getMostRecentDecl()->isInline())
- Kind = InlineVariable;
- else if (Var->getDeclContext()->isRecord() && IsInNonspecializedTemplate)
- Kind = TemplatedVariable;
- else if (Var->getDescribedVarTemplate())
- Kind = TemplatedVariable;
- else if (auto *VTS = dyn_cast<VarTemplateSpecializationDecl>(Var)) {
+ return InlineVariable;
+
+ if (Var->getDeclContext()->isRecord() && IsInNonspecializedTemplate)
+ return TemplatedVariable;
+
+ if (Var->getDescribedVarTemplate())
+ return TemplatedVariable;
+
+ if (auto *VTS = dyn_cast<VarTemplateSpecializationDecl>(Var)) {
if (!VTS->isExplicitSpecialization())
- Kind = TemplatedVariable;
+ return TemplatedVariable;
}
} else if (isa<FieldDecl>(ManglingContextDecl)) {
- Kind = DataMember;
+ return DataMember;
} else if (isa<ImplicitConceptSpecializationDecl>(ManglingContextDecl)) {
- Kind = Concept;
+ return Concept;
}
- }
+
+ return Normal;
+ }();
// Itanium ABI [5.1.7]:
// In the following contexts [...] the one-definition rule requires closure
@@ -342,6 +364,7 @@ Sema::getCurrentMangleNumberContext(const DeclContext *DC) {
return std::make_tuple(nullptr, nullptr);
}
+ case NonInlineInModulePurview:
case Concept:
// Concept definitions aren't code generated and thus aren't mangled,
// however the ManglingContextDecl is important for the purposes of
diff --git a/clang/test/Modules/lambda-in-module-purview-2.cppm b/clang/test/Modules/lambda-in-module-purview-2.cppm
new file mode 100644
index 0000000000000..7c971ffbbec61
--- /dev/null
+++ b/clang/test/Modules/lambda-in-module-purview-2.cppm
@@ -0,0 +1,22 @@
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+// RUN: split-file %s %t
+//
+// RUN: %clang_cc1 -std=c++20 %t/a.cppm -emit-module-interface -o %t/a.pcm
+// RUN: %clang_cc1 -std=c++20 %t/use.cpp -fmodule-file=a=%t/a.pcm -fsyntax-only -verify
+
+//--- lambda.h
+auto cmp = [](auto l, auto r) {
+ return l < r;
+};
+
+//--- a.cppm
+module;
+#include "lambda.h"
+export module a;
+export using ::cmp;
+
+//--- use.cpp
+// expected-no-diagnostics
+import a;
+auto x = cmp;
diff --git a/clang/test/Modules/lambda-in-module-purview.cppm b/clang/test/Modules/lambda-in-module-purview.cppm
new file mode 100644
index 0000000000000..4f765432a0d1a
--- /dev/null
+++ b/clang/test/Modules/lambda-in-module-purview.cppm
@@ -0,0 +1,17 @@
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+// RUN: split-file %s %t
+//
+// RUN: %clang_cc1 -std=c++20 %t/a.cppm -emit-module-interface -o %t/a.pcm
+// RUN: %clang_cc1 -std=c++20 %t/use.cpp -fmodule-file=a=%t/a.pcm -fsyntax-only -verify
+
+//--- a.cppm
+export module a;
+export auto cmp = [](auto l, auto r) {
+ return l < r;
+};
+
+//--- use.cpp
+// expected-no-diagnostics
+import a;
+auto x = cmp;
More information about the cfe-commits
mailing list