Author: Orlando Cazalet-Hyams
Date: 2026-10-05T08:54:42Z
New Revision: df323e01896b1ae31b99960eb88b369bdf4e8f64

URL: 
https://github.com/llvm/llvm-project/commit/df323e01896b1ae31b99960eb88b369bdf4e8f64
DIFF: 
https://github.com/llvm/llvm-project/commit/df323e01896b1ae31b99960eb88b369bdf4e8f64.diff

LOG: [clang][DebugInfo] Make fwd decl call site debug info consistent for 
methods (#222263)

Prior to this patch, using `EmitFunctionDecl` for methods results in
different fields and flags than if `getFunctionDeclaration` (which calls
`CreateCXXMemberFunction`) is used. This can arbitrarily result in
differences depending on the shape of the source code (missing
`scopeLine` or access flags in some cases which are present in others).

Added: 
    clang/test/DebugInfo/CXX/fwd-decl-for-call-site.cpp

Modified: 
    clang/lib/CodeGen/CGDebugInfo.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/CodeGen/CGDebugInfo.cpp 
b/clang/lib/CodeGen/CGDebugInfo.cpp
index c63a840dedf7c..93428777b9b24 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -5277,9 +5277,19 @@ 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 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())) {
+      if (auto *SP = getFunctionDeclaration(CalleeDecl))
+        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 0000000000000..d588561216567
--- /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)


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

Reply via email to