https://github.com/ClaytonKnittel updated 
https://github.com/llvm/llvm-project/pull/218807

>From a2808e08dfee3f63bafb3ca0adc7da1e845a9cd1 Mon Sep 17 00:00:00 2001
From: Clayton Knittel <[email protected]>
Date: Tue, 25 Aug 2026 23:08:05 +0000
Subject: [PATCH] [DebugInfo] Ignore delegating constructors in constructor
 homing.

The constructor homing optimization limits the amount of redundant debug info 
generated for classes by only emitting forward declarations to debug info in 
translation units that can't instantiate the class on their own (i.e. they 
don't see the definitions of any constructors).

Currently, classes that have any user-defined constructors are excluded from 
the optimization. This is being changed to only exclude non-delegating 
constructors, as we can rely on the delegated constructor to instantiate debug 
info.

Signed-off-by: Clayton Knittel <[email protected]>
---
 clang/lib/CodeGen/CGDebugInfo.cpp         | 13 ++++++---
 clang/test/DebugInfo/CXX/limited-ctor.cpp | 33 +++++++++++++++++++++++
 2 files changed, 42 insertions(+), 4 deletions(-)

diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp 
b/clang/lib/CodeGen/CGDebugInfo.cpp
index 2c7af395c4562..0dff3a10881a6 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -2535,10 +2535,15 @@ llvm::DISubprogram 
*CGDebugInfo::CreateCXXMemberFunction(
     SPFlags |= llvm::DISubprogram::SPFlagOptimized;
 
   // In this debug mode, emit type info for a class when its constructor type
-  // info is emitted.
-  if (DebugKind == llvm::codegenoptions::DebugInfoConstructor)
-    if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(Method))
-      completeUnusedClass(*CD->getParent());
+  // info is emitted. Delegating constructors are ignored because the target
+  // constructor's definition will emit the type info.
+  if (DebugKind == llvm::codegenoptions::DebugInfoConstructor) {
+    if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(Method)) {
+      const FunctionDecl *Def = nullptr;
+      if (!CD->isDefined(Def) || !CD->isDelegatingConstructor())
+        completeUnusedClass(*CD->getParent());
+    }
+  }
 
   llvm::DINodeArray TParamsArray = CollectFunctionTemplateParams(Method, Unit);
   llvm::DISubprogram *SP = DBuilder.createMethod(
diff --git a/clang/test/DebugInfo/CXX/limited-ctor.cpp 
b/clang/test/DebugInfo/CXX/limited-ctor.cpp
index 18adfdeed0480..e042684b1a133 100644
--- a/clang/test/DebugInfo/CXX/limited-ctor.cpp
+++ b/clang/test/DebugInfo/CXX/limited-ctor.cpp
@@ -27,6 +27,39 @@ struct E {
   constexpr E(){};
 } TestE;
 
+// Defined delegating constructor where delegated constructor is not defined
+// should not emit full debug info.
+// CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: 
"Delegating"{{.*}}flags: DIFlagFwdDecl
+struct Delegating {
+  Delegating() : Delegating(42) {}
+  Delegating(int);
+} TestDelegating;
+
+// Defined delegating constructor where delegated constructor is defined should
+// emit full debug info.
+// CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: 
"DelegatingToDefined"{{.*}}DIFlagTypePassByValue
+struct DelegatingToDefined {
+  DelegatingToDefined() : DelegatingToDefined(42) {}
+  DelegatingToDefined(int) {}
+} TestDelegatingToDefined;
+
+// Defined out-of-line delegating constructor where delegated constructor is
+// defined should emit full debug info.
+// CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: 
"DelegatingOutOfLine"{{.*}}DIFlagTypePassByValue
+struct DelegatingOutOfLine {
+  DelegatingOutOfLine();
+  DelegatingOutOfLine(int) {}
+};
+DelegatingOutOfLine d;
+DelegatingOutOfLine::DelegatingOutOfLine() : DelegatingOutOfLine(42) {}
+
+// Defined delegating constructor where delegated constructor is from a base
+// class should emit full debug info.
+// CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: 
"DelegatingToBaseClass"{{.*}}DIFlagTypePassByValue
+struct DelegatingToBaseClass : public Delegating {
+  DelegatingToBaseClass() : Delegating(42) {}
+} TestDelegatingToBaseClass;
+
 // Test for trivial constructor.
 // CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: 
"F"{{.*}}DIFlagTypePassByValue
 struct F {

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to