[PATCH] D87049: Exploratory patch - capture DebugInfo for constexpr variables used within lambda

Melanie Blower via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Wed Sep 2 11:54:38 PDT 2020


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 *


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D87049.289523.patch
Type: text/x-patch
Size: 1824 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20200902/b9134683/attachment.bin>


More information about the cfe-commits mailing list