https://github.com/OCHyams updated https://github.com/llvm/llvm-project/pull/222263
>From 1b8ab0c426edf89de665ce86481742f39f086054 Mon Sep 17 00:00:00 2001
From: Orlando Cazalet-Hyams <orlando.hyams at sony.com>
Date: Tue, 8 Sep 2026 16:34:44 +0100
Subject: [PATCH 1/3] fix method fwd-decl-for-callsite
---
clang/lib/CodeGen/CGDebugInfo.cpp | 13 ++++++++++---
.../test/DebugInfo/CXX/fwd-decl-for-call-site.cpp | 15 +++++++++++++++
2 files changed, 25 insertions(+), 3 deletions(-)
create mode 100644 clang/test/DebugInfo/CXX/fwd-decl-for-call-site.cpp
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index 27db6a3110695dc..e78c065897e227f 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -5181,9 +5181,16 @@ void CGDebugInfo::EmitFuncDeclForCallSite(llvm::CallBase *CallOrInvoke,
// If there is no DISubprogram attached to the function being called,
// create the one describing the function in order to have complete
// call site debug info.
- if (!CalleeDecl->isStatic() && !CalleeDecl->isInlined())
- EmitFunctionDecl(CalleeGlobalDecl, CalleeDecl->getLocation(), CalleeType,
- Func);
+ if (!CalleeDecl->isStatic() && !CalleeDecl->isInlined()) {
+ if (isa<CXXMethodDecl>(CalleeDecl->getCanonicalDecl())) {
+ auto *SP = getFunctionDeclaration(CalleeDecl);
+ assert(SP && "Couldn't create CXX method DISubprogram?");
+ Func->setSubprogram(SP);
+ } else {
+ EmitFunctionDecl(CalleeGlobalDecl, CalleeDecl->getLocation(), CalleeType,
+ Func);
+ }
+ }
}
void CGDebugInfo::EmitInlineFunctionStart(CGBuilderTy &Builder, GlobalDecl GD) {
diff --git a/clang/test/DebugInfo/CXX/fwd-decl-for-call-site.cpp b/clang/test/DebugInfo/CXX/fwd-decl-for-call-site.cpp
new file mode 100644
index 000000000000000..d588561216567c2
--- /dev/null
+++ b/clang/test/DebugInfo/CXX/fwd-decl-for-call-site.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -O1 -disable-llvm-passes -gcall-site-info -dwarf-version=5 -emit-llvm \
+// RUN: -debug-info-kind=constructor -triple x86_64-unknown-unknown %s -o - \
+// RUN: | FileCheck %s
+
+// Check that DISubprogram metadata that is attached to methods out of
+// necessity for call-site-info inclues all the fields/info that would be
+// otherwise used for method fwd decls. Tested in this case by checking for the
+// presence of `scopeLine`, which would be omitted if the method were treated
+// as free function fwd decl.
+
+struct a {
+ a();
+} b;
+
+// CHECK: !DISubprogram(name: "a", linkageName: "_ZN1aC4Ev", scope: ![[#]], file: ![[#]], line: [[# @LINE - 3]], type: ![[#]], scopeLine: [[# @LINE - 3]], flags: DIFlagPrototyped, spFlags: DISPFlagOptimized)
>From 3526b805d984b160159c60ab84165c623711b1f4 Mon Sep 17 00:00:00 2001
From: Orlando Cazalet-Hyams <orlando.hyams at sony.com>
Date: Wed, 9 Sep 2026 14:05:38 +0100
Subject: [PATCH 2/3] comment
---
clang/lib/CodeGen/CGDebugInfo.cpp | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index e78c065897e227f..0bb2ca75b9f2f50 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -5182,6 +5182,10 @@ void CGDebugInfo::EmitFuncDeclForCallSite(llvm::CallBase *CallOrInvoke,
// create the one describing the function in order to have complete
// call site debug info.
if (!CalleeDecl->isStatic() && !CalleeDecl->isInlined()) {
+ // If this is a CXX method, use getFunctionDeclaration which checks the
+ // SPCache first otherwise calls CreateCXXMemberFunction. This ensures that
+ // debug info generated for a declaration here is consistent with that
+ // generated for methods via other means.
if (isa<CXXMethodDecl>(CalleeDecl->getCanonicalDecl())) {
auto *SP = getFunctionDeclaration(CalleeDecl);
assert(SP && "Couldn't create CXX method DISubprogram?");
>From f8fc7295f532851930b21589aacd5f76398ebc05 Mon Sep 17 00:00:00 2001
From: Orlando Cazalet-Hyams <orlando.hyams at sony.com>
Date: Wed, 30 Sep 2026 10:06:37 +0100
Subject: [PATCH 3/3] getFunctionDeclaration returns nullptr if debug-info is
disabled, so check the value rather than assert
---
clang/lib/CodeGen/CGDebugInfo.cpp | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index 116413907d3ff39..2254958923b8085 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -5277,9 +5277,8 @@ void CGDebugInfo::EmitFuncDeclForCallSite(llvm::CallBase *CallOrInvoke,
// debug info generated for a declaration here is consistent with that
// generated for methods via other means.
if (isa<CXXMethodDecl>(CalleeDecl->getCanonicalDecl())) {
- auto *SP = getFunctionDeclaration(CalleeDecl);
- assert(SP && "Couldn't create CXX method DISubprogram?");
- Func->setSubprogram(SP);
+ if (auto *SP = getFunctionDeclaration(CalleeDecl))
+ Func->setSubprogram(SP);
} else {
EmitFunctionDecl(CalleeGlobalDecl, CalleeDecl->getLocation(), CalleeType,
Func);