Skip to content

Commit 6345b00

Browse files
committed
[C++20] [Modules] Add mangling number for lambda in non-internal module unit context
Close #59513 Close #110146 As we discussed, this is related to ABI: itanium-cxx-abi/cxx-abi#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.
1 parent 9e91725 commit 6345b00

File tree

3 files changed

+75
-13
lines changed

3 files changed

+75
-13
lines changed

clang/lib/Sema/SemaLambda.cpp

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,8 @@ Sema::getCurrentMangleNumberContext(const DeclContext *DC) {
292292
DataMember,
293293
InlineVariable,
294294
TemplatedVariable,
295-
Concept
295+
Concept,
296+
NonInlineInModulePurview
296297
} Kind = Normal;
297298

298299
bool IsInNonspecializedTemplate =
@@ -301,29 +302,50 @@ Sema::getCurrentMangleNumberContext(const DeclContext *DC) {
301302
// Default arguments of member function parameters that appear in a class
302303
// definition, as well as the initializers of data members, receive special
303304
// treatment. Identify them.
304-
if (ManglingContextDecl) {
305+
Kind = [&]() {
306+
if (!ManglingContextDecl)
307+
return Normal;
308+
309+
if (auto *ND = dyn_cast<NamedDecl>(ManglingContextDecl)) {
310+
// See discussion in https://github.com/itanium-cxx-abi/cxx-abi/issues/186
311+
//
312+
// zygoloid:
313+
// Yeah, I think the only cases left where lambdas don't need a
314+
// mangling are when they have (effectively) internal linkage or appear
315+
// in a non-inline function in a non-module translation unit.
316+
Module *M = ManglingContextDecl->getOwningModule();
317+
if (M && M->getTopLevelModule()->isNamedModuleUnit() &&
318+
ND->isExternallyVisible())
319+
return NonInlineInModulePurview;
320+
}
321+
305322
if (ParmVarDecl *Param = dyn_cast<ParmVarDecl>(ManglingContextDecl)) {
306323
if (const DeclContext *LexicalDC
307324
= Param->getDeclContext()->getLexicalParent())
308325
if (LexicalDC->isRecord())
309-
Kind = DefaultArgument;
326+
return DefaultArgument;
310327
} else if (VarDecl *Var = dyn_cast<VarDecl>(ManglingContextDecl)) {
311328
if (Var->getMostRecentDecl()->isInline())
312-
Kind = InlineVariable;
313-
else if (Var->getDeclContext()->isRecord() && IsInNonspecializedTemplate)
314-
Kind = TemplatedVariable;
315-
else if (Var->getDescribedVarTemplate())
316-
Kind = TemplatedVariable;
317-
else if (auto *VTS = dyn_cast<VarTemplateSpecializationDecl>(Var)) {
329+
return InlineVariable;
330+
331+
if (Var->getDeclContext()->isRecord() && IsInNonspecializedTemplate)
332+
return TemplatedVariable;
333+
334+
if (Var->getDescribedVarTemplate())
335+
return TemplatedVariable;
336+
337+
if (auto *VTS = dyn_cast<VarTemplateSpecializationDecl>(Var)) {
318338
if (!VTS->isExplicitSpecialization())
319-
Kind = TemplatedVariable;
339+
return TemplatedVariable;
320340
}
321341
} else if (isa<FieldDecl>(ManglingContextDecl)) {
322-
Kind = DataMember;
342+
return DataMember;
323343
} else if (isa<ImplicitConceptSpecializationDecl>(ManglingContextDecl)) {
324-
Kind = Concept;
344+
return Concept;
325345
}
326-
}
346+
347+
return Normal;
348+
}();
327349

328350
// Itanium ABI [5.1.7]:
329351
// In the following contexts [...] the one-definition rule requires closure
@@ -342,6 +364,7 @@ Sema::getCurrentMangleNumberContext(const DeclContext *DC) {
342364
return std::make_tuple(nullptr, nullptr);
343365
}
344366

367+
case NonInlineInModulePurview:
345368
case Concept:
346369
// Concept definitions aren't code generated and thus aren't mangled,
347370
// however the ManglingContextDecl is important for the purposes of
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// RUN: rm -rf %t
2+
// RUN: mkdir -p %t
3+
// RUN: split-file %s %t
4+
//
5+
// RUN: %clang_cc1 -std=c++20 %t/a.cppm -emit-module-interface -o %t/a.pcm
6+
// RUN: %clang_cc1 -std=c++20 %t/use.cpp -fmodule-file=a=%t/a.pcm -fsyntax-only -verify
7+
8+
//--- lambda.h
9+
auto cmp = [](auto l, auto r) {
10+
return l < r;
11+
};
12+
13+
//--- a.cppm
14+
module;
15+
#include "lambda.h"
16+
export module a;
17+
export using ::cmp;
18+
19+
//--- use.cpp
20+
// expected-no-diagnostics
21+
import a;
22+
auto x = cmp;
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// RUN: rm -rf %t
2+
// RUN: mkdir -p %t
3+
// RUN: split-file %s %t
4+
//
5+
// RUN: %clang_cc1 -std=c++20 %t/a.cppm -emit-module-interface -o %t/a.pcm
6+
// RUN: %clang_cc1 -std=c++20 %t/use.cpp -fmodule-file=a=%t/a.pcm -fsyntax-only -verify
7+
8+
//--- a.cppm
9+
export module a;
10+
export auto cmp = [](auto l, auto r) {
11+
return l < r;
12+
};
13+
14+
//--- use.cpp
15+
// expected-no-diagnostics
16+
import a;
17+
auto x = cmp;

0 commit comments

Comments
 (0)