Skip to content

Conversation

Michael137
Copy link
Member

This patch creates a helper to retrieve the name from a lambda capture and only calls createFieldType once.

This will simplify reviewing some upcoming changes in this function.

This patch creates a helper to retrieve the name from a lambda capture and only calls `createFieldType` once.

This will simplify reviewing some upcoming changes in this function.
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:codegen IR generation bugs: mangling, exceptions, etc. debuginfo labels Sep 25, 2025
@llvmbot
Copy link
Member

llvmbot commented Sep 25, 2025

@llvm/pr-subscribers-clang-codegen
@llvm/pr-subscribers-debuginfo

@llvm/pr-subscribers-clang

Author: Michael Buch (Michael137)

Changes

This patch creates a helper to retrieve the name from a lambda capture and only calls createFieldType once.

This will simplify reviewing some upcoming changes in this function.


Full diff: https://github.com/llvm/llvm-project/pull/160690.diff

2 Files Affected:

  • (modified) clang/lib/CodeGen/CGDebugInfo.cpp (+38-24)
  • (modified) clang/lib/CodeGen/CGDebugInfo.h (+1)
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index 12c7d48e20d67..68080711c4ace 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -26,6 +26,7 @@
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/Expr.h"
+#include "clang/AST/LambdaCapture.h"
 #include "clang/AST/RecordLayout.h"
 #include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/AST/VTableBuilder.h"
@@ -1903,46 +1904,59 @@ CGDebugInfo::createInlinedSubprogram(StringRef FuncName,
   return SP;
 }
 
+llvm::StringRef
+CGDebugInfo::GetLambdaCaptureName(const LambdaCapture &Capture) {
+  if (Capture.capturesThis())
+    return CGM.getCodeGenOpts().EmitCodeView ? "__this" : "this";
+
+  assert(Capture.capturesVariable());
+
+  const ValueDecl *CaptureDecl = Capture.getCapturedVar();
+  assert(CaptureDecl && "Expected valid decl for captured variable.");
+
+  return CaptureDecl->getName();
+}
+
 void CGDebugInfo::CollectRecordLambdaFields(
     const CXXRecordDecl *CXXDecl, SmallVectorImpl<llvm::Metadata *> &elements,
     llvm::DIType *RecordTy) {
   // For C++11 Lambdas a Field will be the same as a Capture, but the Capture
   // has the name and the location of the variable so we should iterate over
   // both concurrently.
-  const ASTRecordLayout &layout = CGM.getContext().getASTRecordLayout(CXXDecl);
   RecordDecl::field_iterator Field = CXXDecl->field_begin();
   unsigned fieldno = 0;
   for (CXXRecordDecl::capture_const_iterator I = CXXDecl->captures_begin(),
                                              E = CXXDecl->captures_end();
        I != E; ++I, ++Field, ++fieldno) {
-    const LambdaCapture &C = *I;
-    if (C.capturesVariable()) {
-      SourceLocation Loc = C.getLocation();
-      assert(!Field->isBitField() && "lambdas don't have bitfield members!");
-      ValueDecl *V = C.getCapturedVar();
-      StringRef VName = V->getName();
-      llvm::DIFile *VUnit = getOrCreateFile(Loc);
-      auto Align = getDeclAlignIfRequired(V, CGM.getContext());
-      llvm::DIType *FieldType = createFieldType(
-          VName, Field->getType(), Loc, Field->getAccess(),
-          layout.getFieldOffset(fieldno), Align, VUnit, RecordTy, CXXDecl);
-      elements.push_back(FieldType);
-    } else if (C.capturesThis()) {
+    const LambdaCapture &Capture = *I;
+    const uint64_t FieldOffset =
+        CGM.getContext().getASTRecordLayout(CXXDecl).getFieldOffset(fieldno);
+
+    assert(!Field->isBitField() && "lambdas don't have bitfield members!");
+
+    SourceLocation Loc;
+    uint32_t Align = 0;
+
+    if (Capture.capturesThis()) {
       // TODO: Need to handle 'this' in some way by probably renaming the
       // this of the lambda class and having a field member of 'this' or
       // by using AT_object_pointer for the function and having that be
       // used as 'this' for semantic references.
-      FieldDecl *f = *Field;
-      llvm::DIFile *VUnit = getOrCreateFile(f->getLocation());
-      QualType type = f->getType();
-      StringRef ThisName =
-          CGM.getCodeGenOpts().EmitCodeView ? "__this" : "this";
-      llvm::DIType *fieldType = createFieldType(
-          ThisName, type, f->getLocation(), f->getAccess(),
-          layout.getFieldOffset(fieldno), VUnit, RecordTy, CXXDecl);
-
-      elements.push_back(fieldType);
+      Loc = Field->getLocation();
+    } else {
+      Loc = Capture.getLocation();
+
+      const ValueDecl *CaptureDecl = Capture.getCapturedVar();
+      assert(CaptureDecl && "Expected valid decl for captured variable.");
+
+      Align = getDeclAlignIfRequired(CaptureDecl, CGM.getContext());
     }
+
+    llvm::DIFile *VUnit = getOrCreateFile(Loc);
+
+    elements.push_back(createFieldType(
+        GetLambdaCaptureName(Capture), Field->getType(), Loc,
+        Field->getAccess(), FieldOffset, Align, VUnit, RecordTy, CXXDecl));
   }
 }
 
diff --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h
index f86077369a42a..78c3eb9c5792e 100644
--- a/clang/lib/CodeGen/CGDebugInfo.h
+++ b/clang/lib/CodeGen/CGDebugInfo.h
@@ -397,6 +397,7 @@ class CGDebugInfo {
   void CollectRecordFields(const RecordDecl *Decl, llvm::DIFile *F,
                            SmallVectorImpl<llvm::Metadata *> &E,
                            llvm::DICompositeType *RecordTy);
+  llvm::StringRef GetLambdaCaptureName(const LambdaCapture &Capture);
 
   /// If the C++ class has vtable info then insert appropriate debug
   /// info entry in EltTys vector.

@Michael137 Michael137 merged commit 0963cc2 into llvm:main Sep 25, 2025
13 checks passed
@Michael137 Michael137 deleted the clang/lambda-pack-capture-names branch September 25, 2025 22:53
@petrhosek
Copy link
Member

We started seeing the assertion introduced in this PR to trigger on our builders:

FAILED: [code=1] host_x64/obj/third_party/android/platform/system/libbase/libbase.logging.cpp.o
../../prebuilt/third_party/clang/custom/bin/clang++ -MD -MF host_x64/obj/third_party/android/platform/system/libbase/libbase.logging.cpp.o.d -D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS -D_LIBCPP_REMOVE_TRANSITIVE_INCLUDES -I../.. -Ihost_x64/gen -I../../third_party/android/platform/system/libbase/include -I../../third_party/fmtlib/src/include -I../../third_party/android/platform/system/logging/libl...
clang++: clang/include/clang/AST/LambdaCapture.h:105: ValueDecl *clang::LambdaCapture::getCapturedVar() const: Assertion `capturesVariable() && "No variable available for capture"' failed.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace, preprocessed source, and associated run script.
Stack dump:
0.	Program arguments: ../../prebuilt/third_party/clang/custom/bin/clang++ -MD -MF host_x64/obj/third_party/android/platform/system/libbase/libbase.logging.cpp.o.d -D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS -D_LIBCPP_REMOVE_TRANSITIVE_INCLUDES -I../.. -Ihost_x64/gen -I../../third_party/android/platform/system/libbase/include -I../../third_party/fmtlib/src/include -I../../third_party/android/platfo...
1.	<eof> parser at end of file
2.	Per-file LLVM IR generation
3.	../../third_party/android/platform/system/libbase/logging_splitters.h:49:13: Generating code for declaration 'android::base::SplitByLogdChunks'
#0 0x00005565e78313d8 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (../../prebuilt/third_party/clang/custom/bin/clang+++0x93a13d8)
clang++: error: clang frontend command failed with exit code 134 (use -v to see invocation)
Fuchsia clang version 22.0.0git (https://llvm.googlesource.com/llvm-project 8553bd2b29ad2b17a9a884f14da6c43b606ec776)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: ../../prebuilt/third_party/clang/custom/bin
Build config: +assertions
clang++: note: diagnostic msg:
********************

PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:
Preprocessed source(s) and associated run script(s) are located at:
clang++: note: diagnostic msg: clang-crashreports/logging-a37c8e.cpp
clang++: note: diagnostic msg: clang-crashreports/logging-a37c8e.sh
clang++: note: diagnostic msg:

********************

You can download the reproducer from https://storage.googleapis.com/fuchsia-artifacts/builds/8702649026706718113/build-debug/clang-crashreports/logging-e0f475.tar.

Would it be possible to revert this PR while the issue is being investigated?

@Michael137
Copy link
Member Author

We started seeing the assertion introduced in this PR to trigger on our builders:


FAILED: [code=1] host_x64/obj/third_party/android/platform/system/libbase/libbase.logging.cpp.o

../../prebuilt/third_party/clang/custom/bin/clang++ -MD -MF host_x64/obj/third_party/android/platform/system/libbase/libbase.logging.cpp.o.d -D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS -D_LIBCPP_REMOVE_TRANSITIVE_INCLUDES -I../.. -Ihost_x64/gen -I../../third_party/android/platform/system/libbase/include -I../../third_party/fmtlib/src/include -I../../third_party/android/platform/system/logging/libl...

clang++: clang/include/clang/AST/LambdaCapture.h:105: ValueDecl *clang::LambdaCapture::getCapturedVar() const: Assertion `capturesVariable() && "No variable available for capture"' failed.

PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace, preprocessed source, and associated run script.

Stack dump:

0.	Program arguments: ../../prebuilt/third_party/clang/custom/bin/clang++ -MD -MF host_x64/obj/third_party/android/platform/system/libbase/libbase.logging.cpp.o.d -D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS -D_LIBCPP_REMOVE_TRANSITIVE_INCLUDES -I../.. -Ihost_x64/gen -I../../third_party/android/platform/system/libbase/include -I../../third_party/fmtlib/src/include -I../../third_party/android/platfo...

1.	<eof> parser at end of file

2.	Per-file LLVM IR generation

3.	../../third_party/android/platform/system/libbase/logging_splitters.h:49:13: Generating code for declaration 'android::base::SplitByLogdChunks'

#0 0x00005565e78313d8 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (../../prebuilt/third_party/clang/custom/bin/clang+++0x93a13d8)

clang++: error: clang frontend command failed with exit code 134 (use -v to see invocation)

Fuchsia clang version 22.0.0git (https://llvm.googlesource.com/llvm-project 8553bd2b29ad2b17a9a884f14da6c43b606ec776)

Target: x86_64-unknown-linux-gnu

Thread model: posix

InstalledDir: ../../prebuilt/third_party/clang/custom/bin

Build config: +assertions

clang++: note: diagnostic msg:

********************



PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:

Preprocessed source(s) and associated run script(s) are located at:

clang++: note: diagnostic msg: clang-crashreports/logging-a37c8e.cpp

clang++: note: diagnostic msg: clang-crashreports/logging-a37c8e.sh

clang++: note: diagnostic msg:



********************

You can download the reproducer from https://storage.googleapis.com/fuchsia-artifacts/builds/8702649026706718113/build-debug/clang-crashreports/logging-e0f475.tar.

Would it be possible to revert this PR while the issue is being investigated?

Ah interesting, probably too strict of an assert. Feel free to revert. Will check later

petrhosek added a commit that referenced this pull request Sep 26, 2025
llvm-sync bot pushed a commit to arm/arm-toolchain that referenced this pull request Sep 26, 2025
mahesh-attarde pushed a commit to mahesh-attarde/llvm-project that referenced this pull request Oct 3, 2025
This patch creates a helper to retrieve the name from a lambda capture
and only calls `createFieldType` once.

This will simplify reviewing some upcoming changes in this function.
mahesh-attarde pushed a commit to mahesh-attarde/llvm-project that referenced this pull request Oct 3, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang:codegen IR generation bugs: mangling, exceptions, etc. clang Clang issues not falling into any other category debuginfo

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants