mibintc created this revision. mibintc added a reviewer: debug-info. Herald added a project: clang. mibintc requested review of this revision.
This is an exploratory patch, an attempt to solve bugs.llvm.org/show_bug.cgi?id=47400 That bug report shows a simple test case where the constexpr variable, declared outside the scope of the lambda but used within the lambda, is simply unknown in the DebugInfo. This is different from a gcc compilation where gdb knows the symbol, and knows that the value is "optimized out". The problem is constexpr variables like n_steps (see example in the bug report) are not captured and so do not appear in the record type. These still appear in the AST so if we gather them it is possible to emit static data member. As a proof of concept, this is prototyped here. I didn't think about exactly which variables should be gathered but this might be a framework. This is a little hacky since the constexpr variable is not really a static member of the lambda but the use is roughly correct. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D87049 Files: clang/lib/CodeGen/CGDebugInfo.cpp Index: clang/lib/CodeGen/CGDebugInfo.cpp =================================================================== --- clang/lib/CodeGen/CGDebugInfo.cpp +++ clang/lib/CodeGen/CGDebugInfo.cpp @@ -25,6 +25,7 @@ #include "clang/AST/DeclTemplate.h" #include "clang/AST/Expr.h" #include "clang/AST/RecordLayout.h" +#include "clang/AST/StmtVisitor.h" #include "clang/Basic/CodeGenOptions.h" #include "clang/Basic/FileManager.h" #include "clang/Basic/SourceManager.h" @@ -1358,6 +1359,29 @@ offsetInBits, flags, debugType); } +namespace { +/// Locate the non_odr_use constant variables in a statement. +struct NonODRUseVarFinder final : public ConstStmtVisitor<NonODRUseVarFinder> { + llvm::SmallSetVector<const VarDecl *, 4> NonODRUseVars; + + NonODRUseVarFinder(const Stmt *S) { + Visit(S); + } + + void VisitStmt(const Stmt *S) { + for (const Stmt *Child : S->children()) + if (Child) + Visit(Child); + } + + void VisitDeclRefExpr(const DeclRefExpr *E) { + if (E->isNonOdrUse() == NOUR_Constant) + if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) + NonODRUseVars.insert(VD); + } +}; +} // namespace + void CGDebugInfo::CollectRecordLambdaFields( const CXXRecordDecl *CXXDecl, SmallVectorImpl<llvm::Metadata *> &elements, llvm::DIType *RecordTy) { @@ -1397,6 +1421,13 @@ elements.push_back(fieldType); } } + // constexpr variables do not need to be captured, so to view them + // in the debugger pretend they are const static data members. + CXXMethodDecl *CallOp = CXXDecl->getLambdaCallOperator(); + assert(CallOp); + NonODRUseVarFinder Finder(CallOp->getBody()); + for (const auto *VD : Finder.NonODRUseVars) + elements.push_back(CreateRecordStaticField(VD, RecordTy, CXXDecl)); } llvm::DIDerivedType *
Index: clang/lib/CodeGen/CGDebugInfo.cpp =================================================================== --- clang/lib/CodeGen/CGDebugInfo.cpp +++ clang/lib/CodeGen/CGDebugInfo.cpp @@ -25,6 +25,7 @@ #include "clang/AST/DeclTemplate.h" #include "clang/AST/Expr.h" #include "clang/AST/RecordLayout.h" +#include "clang/AST/StmtVisitor.h" #include "clang/Basic/CodeGenOptions.h" #include "clang/Basic/FileManager.h" #include "clang/Basic/SourceManager.h" @@ -1358,6 +1359,29 @@ offsetInBits, flags, debugType); } +namespace { +/// Locate the non_odr_use constant variables in a statement. +struct NonODRUseVarFinder final : public ConstStmtVisitor<NonODRUseVarFinder> { + llvm::SmallSetVector<const VarDecl *, 4> NonODRUseVars; + + NonODRUseVarFinder(const Stmt *S) { + Visit(S); + } + + void VisitStmt(const Stmt *S) { + for (const Stmt *Child : S->children()) + if (Child) + Visit(Child); + } + + void VisitDeclRefExpr(const DeclRefExpr *E) { + if (E->isNonOdrUse() == NOUR_Constant) + if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) + NonODRUseVars.insert(VD); + } +}; +} // namespace + void CGDebugInfo::CollectRecordLambdaFields( const CXXRecordDecl *CXXDecl, SmallVectorImpl<llvm::Metadata *> &elements, llvm::DIType *RecordTy) { @@ -1397,6 +1421,13 @@ elements.push_back(fieldType); } } + // constexpr variables do not need to be captured, so to view them + // in the debugger pretend they are const static data members. + CXXMethodDecl *CallOp = CXXDecl->getLambdaCallOperator(); + assert(CallOp); + NonODRUseVarFinder Finder(CallOp->getBody()); + for (const auto *VD : Finder.NonODRUseVars) + elements.push_back(CreateRecordStaticField(VD, RecordTy, CXXDecl)); } llvm::DIDerivedType *
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits