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 cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits