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

>From d341a122032a1614aa16f408790752d5f2ee6574 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 | 34 +++++++++++++++++++++++
 2 files changed, 43 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..87186b02e44f3 100644
--- a/clang/test/DebugInfo/CXX/limited-ctor.cpp
+++ b/clang/test/DebugInfo/CXX/limited-ctor.cpp
@@ -27,6 +27,40 @@ 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 delegating constructor where delegated constructor is defined out of
+// line should emit full debug info.
+// CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: 
"DelegatingToOutOfLine"{{.*}}DIFlagTypePassByValue
+struct DelegatingToOutOfLine {
+  DelegatingToOutOfLine() : DelegatingToOutOfLine(42) {}
+  DelegatingToOutOfLine(int);
+} TestDelegatingToOutOfLine;
+DelegatingToOutOfLine::DelegatingToOutOfLine(int) {}
+
+// 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) {}
+} TestDelegatingOutOfLine;
+DelegatingOutOfLine::DelegatingOutOfLine() : DelegatingOutOfLine(42) {}
+
 // 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