akhuang created this revision.
akhuang added reviewers: rnk, dblaikie.
akhuang requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.
Currently (for codeview) lambdas have a string like `<lambda_0>` in
their mangled name, and don't have any display name. This change uses the
`<lambda_0>` as the display name, which helps distinguish between lambdas
in -gline-tables-only, since there are no linkage names there.
It also changes how we display lambda names; previously we used
`<unnamed-tag>`; now it will show `<lambda_0>`.
I added a function to the mangling context code to create this string;
for Itanium it just returns an empty string.
Bug: https://bugs.llvm.org/show_bug.cgi?id=48432
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D95187
Files:
clang/include/clang/AST/Mangle.h
clang/lib/AST/ItaniumMangle.cpp
clang/lib/AST/MicrosoftMangle.cpp
clang/lib/CodeGen/CGDebugInfo.cpp
clang/test/CodeGenCXX/debug-info-codeview-unnamed.cpp
clang/test/CodeGenCXX/debug-info-gline-tables-only-codeview.cpp
Index: clang/test/CodeGenCXX/debug-info-gline-tables-only-codeview.cpp
===================================================================
--- clang/test/CodeGenCXX/debug-info-gline-tables-only-codeview.cpp
+++ clang/test/CodeGenCXX/debug-info-gline-tables-only-codeview.cpp
@@ -10,6 +10,8 @@
void f() {}
}
+auto lambda1 = []() { return 1; };
+
NS::C c;
void test() {
@@ -27,4 +29,10 @@
// CHECK-NOT: identifier
// CHECK: ![[MTYPE]] = !DISubroutineType(types: !{{.*}})
c.m();
+
+ // CHECK: !DISubprogram(name: "operator()", scope: ![[LAMBDA1:[0-9]+]]
+ // CHECK: ![[LAMBDA1]] = !DICompositeType(tag: DW_TAG_class_type,
+ // CHECK-SAME: name: "<lambda_0>"
+ // CHECK-SAME: flags: DIFlagFwdDecl
+ lambda1();
}
Index: clang/test/CodeGenCXX/debug-info-codeview-unnamed.cpp
===================================================================
--- clang/test/CodeGenCXX/debug-info-codeview-unnamed.cpp
+++ clang/test/CodeGenCXX/debug-info-codeview-unnamed.cpp
@@ -100,7 +100,7 @@
// MSVC-SAME: )
// MSVC: [[TYPE_OF_FOUR]] = distinct !DICompositeType
// MSVC-SAME: tag: DW_TAG_class_type
- // MSVC-NOT: name:
+ // MSVC-SAME: name: "<lambda_0>"
// MSVC-SAME: identifier: ".?AV<lambda_0>@?0??main@@9@"
// MSVC-SAME: )
Index: clang/lib/CodeGen/CGDebugInfo.cpp
===================================================================
--- clang/lib/CodeGen/CGDebugInfo.cpp
+++ clang/lib/CodeGen/CGDebugInfo.cpp
@@ -342,6 +342,12 @@
// associate typedef mangled in if they have one.
Name = TND->getName();
+ // Give lambdas a display name based on their name mangling.
+ if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
+ if (CXXRD->isLambda())
+ return internString(
+ CGM.getCXXABI().getMangleContext().getLambdaString(CXXRD));
+
if (!Name.empty()) {
SmallString<256> UnnamedType("<unnamed-type-");
UnnamedType += Name;
Index: clang/lib/AST/MicrosoftMangle.cpp
===================================================================
--- clang/lib/AST/MicrosoftMangle.cpp
+++ clang/lib/AST/MicrosoftMangle.cpp
@@ -228,6 +228,34 @@
return true;
}
+ StringRef getLambdaString(const CXXRecordDecl *Lambda) override {
+ assert(Lambda->isLambda() && "RD must be a lambda!");
+ llvm::SmallString<10> Name("<lambda_");
+
+ Decl *LambdaContextDecl = Lambda->getLambdaContextDecl();
+ unsigned LambdaManglingNumber = Lambda->getLambdaManglingNumber();
+ unsigned LambdaId;
+ const ParmVarDecl *Parm = dyn_cast_or_null<ParmVarDecl>(LambdaContextDecl);
+ const FunctionDecl *Func =
+ Parm ? dyn_cast<FunctionDecl>(Parm->getDeclContext()) : nullptr;
+
+ if (Func) {
+ unsigned DefaultArgNo =
+ Func->getNumParams() - Parm->getFunctionScopeIndex();
+ Name += llvm::utostr(DefaultArgNo);
+ Name += "_";
+ }
+
+ if (LambdaManglingNumber)
+ LambdaId = LambdaManglingNumber;
+ else
+ LambdaId = getLambdaId(Lambda);
+
+ Name += llvm::utostr(LambdaId);
+ Name += ">";
+ return StringRef(Name);
+ }
+
unsigned getLambdaId(const CXXRecordDecl *RD) {
assert(RD->isLambda() && "RD must be a lambda!");
assert(!RD->isExternallyVisible() && "RD must not be visible!");
@@ -972,32 +1000,10 @@
if (const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(TD)) {
if (Record->isLambda()) {
- llvm::SmallString<10> Name("<lambda_");
+ mangleSourceName(Context.getLambdaString(Record).str());
- Decl *LambdaContextDecl = Record->getLambdaContextDecl();
unsigned LambdaManglingNumber = Record->getLambdaManglingNumber();
- unsigned LambdaId;
- const ParmVarDecl *Parm =
- dyn_cast_or_null<ParmVarDecl>(LambdaContextDecl);
- const FunctionDecl *Func =
- Parm ? dyn_cast<FunctionDecl>(Parm->getDeclContext()) : nullptr;
-
- if (Func) {
- unsigned DefaultArgNo =
- Func->getNumParams() - Parm->getFunctionScopeIndex();
- Name += llvm::utostr(DefaultArgNo);
- Name += "_";
- }
-
- if (LambdaManglingNumber)
- LambdaId = LambdaManglingNumber;
- else
- LambdaId = Context.getLambdaId(Record);
-
- Name += llvm::utostr(LambdaId);
- Name += ">";
-
- mangleSourceName(Name);
+ Decl *LambdaContextDecl = Record->getLambdaContextDecl();
// If the context is a variable or a class member and not a parameter,
// it is encoded in a qualified name.
Index: clang/lib/AST/ItaniumMangle.cpp
===================================================================
--- clang/lib/AST/ItaniumMangle.cpp
+++ clang/lib/AST/ItaniumMangle.cpp
@@ -203,6 +203,10 @@
disc = discriminator-2;
return true;
}
+
+ StringRef getLambdaString(const CXXRecordDecl *Lambda) override {
+ return StringRef();
+ }
/// @}
};
Index: clang/include/clang/AST/Mangle.h
===================================================================
--- clang/include/clang/AST/Mangle.h
+++ clang/include/clang/AST/Mangle.h
@@ -89,6 +89,8 @@
return Result.first->second;
}
+ virtual StringRef getLambdaString(const CXXRecordDecl *Lambda) = 0;
+
/// @name Mangler Entry Points
/// @{
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits