https://github.com/CarlosAlbertoEnciso updated 
https://github.com/llvm/llvm-project/pull/167666

>From eec7cbeb452465ef56de22ffb8d043aceb9e3951 Mon Sep 17 00:00:00 2001
From: Carlos Alberto Enciso <[email protected]>
Date: Wed, 11 Feb 2026 13:27:59 +0000
Subject: [PATCH 1/2] [clang][DebugInfo] Add call site target information in
 DWARF.

These changes are intended to address the concern about
the 'CallTargetCache' map.

The map is removed by:
- injecting a function declaration if one is not available
  at the point where the function is invoked.
- always pointing the 'call_target' to the function declaraion.
---
 clang/lib/CodeGen/CGCall.cpp                  |   2 +
 clang/lib/CodeGen/CGDebugInfo.cpp             |  23 ++++
 clang/lib/CodeGen/CGDebugInfo.h               |   9 ++
 clang/test/DebugInfo/CXX/callsite-base.cpp    |  38 ++++++
 clang/test/DebugInfo/CXX/callsite-derived.cpp |  58 +++++++++
 clang/test/DebugInfo/CXX/callsite-edges.cpp   | 117 ++++++++++++++++++
 .../clang_llvm_roundtrip/callsite-dwarf.cpp   |  68 ++++++++++
 llvm/include/llvm/BinaryFormat/Dwarf.def      |   1 +
 llvm/include/llvm/CodeGen/MachineFunction.h   |   6 +
 llvm/include/llvm/CodeGen/TargetLowering.h    |   4 +
 llvm/include/llvm/IR/FixedMetadataKinds.def   |   1 +
 .../CodeGen/AsmPrinter/DwarfCompileUnit.cpp   |  15 ++-
 .../lib/CodeGen/AsmPrinter/DwarfCompileUnit.h |   4 +
 llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp    |  29 ++++-
 llvm/lib/CodeGen/MIRPrinter.cpp               |   2 +-
 llvm/lib/CodeGen/MachineFunction.cpp          |   3 +
 .../CodeGen/SelectionDAG/TargetLowering.cpp   |  14 +++
 llvm/lib/DebugInfo/DWARF/DWARFDie.cpp         |   3 +-
 .../Target/AArch64/AArch64ISelLowering.cpp    |   3 +-
 llvm/lib/Target/ARM/ARMISelLowering.cpp       |   3 +-
 llvm/lib/Target/Mips/MipsISelLowering.cpp     |   4 +-
 llvm/lib/Target/RISCV/RISCVISelLowering.cpp   |   3 +-
 llvm/lib/Target/X86/X86ISelLoweringCall.cpp   |   3 +-
 .../MIR/X86/callsite-emit-calleetypeid.ll     |   8 +-
 24 files changed, 398 insertions(+), 23 deletions(-)
 create mode 100644 clang/test/DebugInfo/CXX/callsite-base.cpp
 create mode 100644 clang/test/DebugInfo/CXX/callsite-derived.cpp
 create mode 100644 clang/test/DebugInfo/CXX/callsite-edges.cpp
 create mode 100644 
cross-project-tests/debuginfo-tests/clang_llvm_roundtrip/callsite-dwarf.cpp

diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 224b2997b7db4..6e06235b52dab 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -6322,6 +6322,8 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo 
&CallInfo,
       DI->EmitFuncDeclForCallSite(
           CI, DI->getFunctionType(CalleeDecl, ResTy, Args), CalleeGlobalDecl);
     }
+    // Generate call site target information.
+    DI->addCallTarget(CalleeDecl, CI);
   }
 
   return Ret;
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp 
b/clang/lib/CodeGen/CGDebugInfo.cpp
index 5e452245ee627..19b5ed2da3e1a 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -4978,6 +4978,29 @@ void CGDebugInfo::EmitFunctionDecl(GlobalDecl GD, 
SourceLocation Loc,
     Fn->setSubprogram(SP);
 }
 
+void CGDebugInfo::addCallTarget(const FunctionDecl *FD, llvm::CallBase *CI) {
+  if (!generateVirtualCallSite())
+    return;
+
+  if (!FD)
+    return;
+
+  // Ignore method types that never can be indirect calls.
+  if (isa<CXXConstructorDecl>(FD) || isa<CXXDestructorDecl>(FD) ||
+      FD->hasAttr<CUDAGlobalAttr>())
+    return;
+
+  // Record only indirect calls.
+  assert(CI && "Invalid Call Instruction.");
+  if (!CI->isIndirectCall())
+    return;
+
+  // Always get method definition.
+  if (llvm::DISubprogram *MD = getFunctionDeclaration(FD))
+    // Attach the target metadata
+    CI->setMetadata(llvm::LLVMContext::MD_call_target, MD);
+}
+
 void CGDebugInfo::EmitFuncDeclForCallSite(llvm::CallBase *CallOrInvoke,
                                           QualType CalleeType,
                                           GlobalDecl CalleeGlobalDecl) {
diff --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h
index 31b40f06f09d0..478306f8aea7d 100644
--- a/clang/lib/CodeGen/CGDebugInfo.h
+++ b/clang/lib/CodeGen/CGDebugInfo.h
@@ -682,6 +682,9 @@ class CGDebugInfo {
   /// that it is supported and enabled.
   llvm::DINode::DIFlags getCallSiteRelatedAttrs() const;
 
+  /// Add call target information.
+  void addCallTarget(const FunctionDecl *FD, llvm::CallBase *CI);
+
 private:
   /// Amend \p I's DebugLoc with \p Group (its source atom group) and \p
   /// Rank (lower nonzero rank is higher precedence). Does nothing if \p I
@@ -906,6 +909,12 @@ class CGDebugInfo {
   /// If one exists, returns the linkage name of the specified \
   /// (non-null) \c Method. Returns empty string otherwise.
   llvm::StringRef GetMethodLinkageName(const CXXMethodDecl *Method) const;
+
+  /// Generate call target information.
+  bool generateVirtualCallSite() const {
+    // Check general conditions for call site generation.
+    return (getCallSiteRelatedAttrs() != llvm::DINode::FlagZero);
+  }
 };
 
 /// A scoped helper to set the current debug location to the specified
diff --git a/clang/test/DebugInfo/CXX/callsite-base.cpp 
b/clang/test/DebugInfo/CXX/callsite-base.cpp
new file mode 100644
index 0000000000000..576fdacd2722f
--- /dev/null
+++ b/clang/test/DebugInfo/CXX/callsite-base.cpp
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -triple=x86_64-linux -disable-llvm-passes -emit-llvm \
+// RUN:            -debug-info-kind=constructor -dwarf-version=5 -O1 %s \
+// RUN: -o - | FileCheck %s -check-prefix CHECK-BASE
+
+// Simple class with only virtual methods: inlined and not-inlined
+// We check for a generated 'call_target' for:
+// - 'f1', 'f2' and 'f3'.
+
+struct CBase {
+  virtual void f1();
+  virtual void f2();
+  virtual void f3() {}
+};
+void CBase::f1() {}
+
+void bar(CBase *Base) {
+  Base->f1();
+  Base->f2();
+  Base->f3();
+
+  CBase B;
+  B.f1();
+}
+
+// CHECK-BASE: define {{.*}} @_Z3barP5CBase{{.*}} {
+// CHECK-BASE:   call void %1{{.*}} !dbg {{![0-9]+}}, !call_target 
[[BASE_F1_DCL:![0-9]+]]
+// CHECK-BASE:   call void %3{{.*}} !dbg {{![0-9]+}}, !call_target 
[[BASE_F2_DCL:![0-9]+]]
+// CHECK-BASE:   call void %5{{.*}} !dbg {{![0-9]+}}, !call_target 
[[BASE_F3_DCL:![0-9]+]]
+// CHECK-BASE:   call void @_ZN5CBaseC1Ev{{.*}} !dbg {{![0-9]+}}
+// CHECK-BASE:   call void @_ZN5CBase2f1Ev{{.*}} !dbg {{![0-9]+}}
+// CHECK-BASE: }
+
+// CHECK-BASE: [[BASE_F1_DCL]] = {{.*}}!DISubprogram(name: "f1", linkageName: 
"_ZN5CBase2f1Ev", {{.*}}containingType
+// CHECK-BASE: [[BASE_F2_DCL]] = {{.*}}!DISubprogram(name: "f2", linkageName: 
"_ZN5CBase2f2Ev", {{.*}}containingType
+// CHECK-BASE: [[BASE_F3_DCL]] = {{.*}}!DISubprogram(name: "f3", linkageName: 
"_ZN5CBase2f3Ev", {{.*}}containingType
+
+// CHECK-BASE: [[BASE_F1_DEF:![0-9]+]] = {{.*}}!DISubprogram(name: "f1", 
linkageName: "_ZN5CBase2f1Ev", {{.*}}DISPFlagDefinition
+// CHECK-BASE: [[BASE_F3_DEF:![0-9]+]] = {{.*}}!DISubprogram(name: "f3", 
linkageName: "_ZN5CBase2f3Ev", {{.*}}DISPFlagDefinition
diff --git a/clang/test/DebugInfo/CXX/callsite-derived.cpp 
b/clang/test/DebugInfo/CXX/callsite-derived.cpp
new file mode 100644
index 0000000000000..3338290bdd829
--- /dev/null
+++ b/clang/test/DebugInfo/CXX/callsite-derived.cpp
@@ -0,0 +1,58 @@
+// RUN: %clang_cc1 -triple=x86_64-linux -disable-llvm-passes -emit-llvm \
+// RUN:            -debug-info-kind=constructor -dwarf-version=5 -O1 %s \
+// RUN:            -o - | FileCheck %s -check-prefix CHECK-DERIVED
+
+// Simple base and derived class with virtual and static methods:
+// We check for:
+// - a generated 'call_target' for 'f1'.
+// - not generated 'call_target' for 'f3'.
+
+struct CBase {
+  virtual void f1() {}
+  static void f3();
+};
+
+void CBase::f3() {
+}
+
+void foo(CBase *Base) {
+  CBase::f3();
+}
+
+struct CDerived : public CBase {
+  void f1() {}
+};
+void foo(CDerived *Derived);
+
+int main() {
+  CDerived D;
+  foo(&D);
+
+  return 0;
+}
+
+void foo(CDerived *Derived) {
+  Derived->f1();
+}
+
+// CHECK-DERIVED: define {{.*}} @_Z3fooP5CBase{{.*}} {
+// CHECK-DERIVED: call void @_ZN5CBase2f3Ev{{.*}} !dbg {{![0-9]+}}
+// CHECK-DERIVED: }
+
+// CHECK-DERIVED: define {{.*}} @main{{.*}} {
+// CHECK-DERIVED:  call void @_ZN8CDerivedC1Ev{{.*}} !dbg {{![0-9]+}}
+// CHECK-DERIVED:  call void @_Z3fooP8CDerived{{.*}} !dbg {{![0-9]+}}
+// CHECK-DERIVED: }
+
+// CHECK-DERIVED: define {{.*}} @_ZN8CDerivedC1Ev{{.*}} {
+// CHECK-DERIVED:  call void @_ZN8CDerivedC2Ev{{.*}} !dbg {{![0-9]+}}
+// CHECK-DERIVED: }
+
+// CHECK-DERIVED: define {{.*}} @_Z3fooP8CDerived{{.*}} {
+// CHECK-DERIVED:  call void %1{{.*}} !dbg {{![0-9]+}}, !call_target 
[[DERIVED_F1_DCL:![0-9]+]]
+// CHECK-DERIVED: }
+
+// CHECK-DERIVED: [[BASE_F1_DCL:![0-9]+]] = {{.*}}!DISubprogram(name: "f1", 
linkageName: "_ZN5CBase2f1Ev", {{.*}}containingType
+// CHECK-DERIVED: [[DERIVED_F1_DCL]] = {{.*}}!DISubprogram(name: "f1", 
linkageName: "_ZN8CDerived2f1Ev", {{.*}}containingType
+// CHECK-DERIVED: [[DERIVED_F1_DEF:![0-9]+]] = {{.*}}!DISubprogram(name: "f1", 
linkageName: "_ZN8CDerived2f1Ev", {{.*}}DISPFlagDefinition
+// CHECK-DERIVED: [[BASE_F1_DEF:![0-9]+]] = {{.*}}!DISubprogram(name: "f1", 
linkageName: "_ZN5CBase2f1Ev", {{.*}}DISPFlagDefinition
diff --git a/clang/test/DebugInfo/CXX/callsite-edges.cpp 
b/clang/test/DebugInfo/CXX/callsite-edges.cpp
new file mode 100644
index 0000000000000..ac969ba1bef83
--- /dev/null
+++ b/clang/test/DebugInfo/CXX/callsite-edges.cpp
@@ -0,0 +1,117 @@
+// RUN: %clang_cc1 -triple=x86_64-linux -disable-llvm-passes -emit-llvm \
+// RUN:            -debug-info-kind=constructor -dwarf-version=5 -O1 %s \
+// RUN:            -o - | FileCheck %s -check-prefix CHECK-EDGES
+
+// The following are identified edge cases involving the method being called:
+// 1) Method is declared but not defined in current CU.
+// 2) Pure virtual method but not defined in current CU.
+// 3) Virtual method defined in a deeply nested structure hierarchy.
+
+//---------------------------------------------------------------------
+// 1) Method is declared but not defined in current CU - Pass.
+//    Generate 'call_target' metadata for 'f1' and 'f2'.
+//---------------------------------------------------------------------
+struct CEmpty {
+  virtual void f1();
+  virtual void f2();
+};
+
+void CEmpty::f2() {
+}
+
+void edge_a(CEmpty *Empty) {
+  Empty->f1();
+  Empty->f2();
+}
+
+//---------------------------------------------------------------------
+// 2) Pure virtual method but not defined in current CU - Pass.
+//    Generate 'call_target' metadata for 'f1' and 'f2'.
+//---------------------------------------------------------------------
+struct CBase {
+  virtual void f1() = 0;
+  virtual void f2();
+};
+
+void CBase::f2() {
+}
+
+void edge_b(CBase *Base) {
+  Base->f1();
+  Base->f2();
+}
+
+//---------------------------------------------------------------------
+// 3) Virtual method defined in a deeply nested structure hierarchy - Pass.
+//    Generate 'call_target' metadata for 'd0', 'd1', 'd2' and 'd3'.
+//---------------------------------------------------------------------
+struct CDeep {
+  struct CD1 {
+    struct CD2 {
+      struct CD3 {
+        virtual void d3();
+      };
+
+      CD3 D3;
+      virtual void d2();
+    };
+
+    CD2 D2;
+    virtual void d1();
+  };
+
+  CD1 D1;
+  virtual void d0();
+};
+
+void CDeep::d0() {}
+void CDeep::CD1::d1() {}
+void CDeep::CD1::CD2::d2() {}
+void CDeep::CD1::CD2::CD3::d3() {}
+
+void edge_c(CDeep *Deep) {
+  Deep->d0();
+
+  CDeep::CD1 *D1 = &Deep->D1;
+  D1->d1();
+
+  CDeep::CD1::CD2 *D2 = &D1->D2;
+  D2->d2();
+
+  CDeep::CD1::CD2::CD3 *D3 = &D2->D3;
+  D3->d3();
+}
+
+// CHECK-EDGES: define {{.*}} @_Z6edge_aP6CEmpty{{.*}} {
+// CHECK-EDGES:  call void %1{{.*}} !dbg {{![0-9]+}}, !call_target 
[[CEMPTY_F1_DCL:![0-9]+]]
+// CHECK-EDGES:  call void %3{{.*}} !dbg {{![0-9]+}}, !call_target 
[[CEMPTY_F2_DCL:![0-9]+]]
+// CHECK-EDGES: }
+
+// CHECK-EDGES: define {{.*}} @_Z6edge_bP5CBase{{.*}} {
+// CHECK-EDGES:  call void %1{{.*}} !dbg {{![0-9]+}}, !call_target 
[[CBASE_F1_DCL:![0-9]+]]
+// CHECK-EDGES:  call void %3{{.*}} !dbg {{![0-9]+}}, !call_target 
[[CBASE_F2_DCL:![0-9]+]]
+// CHECK-EDGES: }
+
+// CHECK-EDGES: define {{.*}} @_Z6edge_cP5CDeep{{.*}} {
+// CHECK-EDGES:  call void %1{{.*}} !dbg {{![0-9]+}}, !call_target 
[[CDEEP_D0_DCL:![0-9]+]]
+// CHECK-EDGES:  call void %4{{.*}} !dbg {{![0-9]+}}, !call_target 
[[CDEEP_D1_DCL:![0-9]+]]
+// CHECK-EDGES:  call void %7{{.*}} !dbg {{![0-9]+}}, !call_target 
[[CDEEP_D2_DCL:![0-9]+]]
+// CHECK-EDGES:  call void %10{{.*}} !dbg {{![0-9]+}}, !call_target 
[[CDEEP_D3_DCL:![0-9]+]]
+// CHECK-EDGES: }
+
+// CHECK-EDGES:  [[CDEEP_D3_DCL]] = {{.*}}!DISubprogram(name: "d3", 
linkageName: "_ZN5CDeep3CD13CD23CD32d3Ev", {{.*}}containingType
+// CHECK-EDGES:  [[CDEEP_D2_DCL]] = {{.*}}!DISubprogram(name: "d2", 
linkageName: "_ZN5CDeep3CD13CD22d2Ev", {{.*}}containingType
+// CHECK-EDGES:  [[CDEEP_D1_DCL]] = {{.*}}!DISubprogram(name: "d1", 
linkageName: "_ZN5CDeep3CD12d1Ev", {{.*}}containingType
+// CHECK-EDGES:  [[CDEEP_D0_DCL]] = {{.*}}!DISubprogram(name: "d0", 
linkageName: "_ZN5CDeep2d0Ev", {{.*}}containingType
+
+// CHECK-EDGES:  [[CBASE_F1_DCL]] = {{.*}}!DISubprogram(name: "f1", 
linkageName: "_ZN5CBase2f1Ev", {{.*}}containingType
+// CHECK-EDGES:  [[CBASE_F2_DCL]] = {{.*}}!DISubprogram(name: "f2", 
linkageName: "_ZN5CBase2f2Ev", {{.*}}containingType
+// CHECK-EDGES:  [[CEMPTY_F2_DEF:![0-9]+]] = {{.*}}!DISubprogram(name: "f2", 
linkageName: "_ZN6CEmpty2f2Ev", {{.*}}DISPFlagDefinition
+// CHECK-EDGES:  [[CEMPTY_F2_DCL]] = {{.*}}!DISubprogram(name: "f2", 
linkageName: "_ZN6CEmpty2f2Ev", {{.*}}containingType
+// CHECK-EDGES:  [[CEMPTY_F1_DCL]] = {{.*}}!DISubprogram(name: "f1", 
linkageName: "_ZN6CEmpty2f1Ev", {{.*}}containingType
+// CHECK-EDGES:  [[CBASE_F2_DEF:![0-9]+]] = {{.*}}!DISubprogram(name: "f2", 
linkageName: "_ZN5CBase2f2Ev", {{.*}}DISPFlagDefinition
+
+// CHECK-EDGES:  [[CDEEP_D0_DEF:![0-9]+]] = {{.*}}!DISubprogram(name: "d0", 
linkageName: "_ZN5CDeep2d0Ev", {{.*}}DISPFlagDefinition
+// CHECK-EDGES:  [[CDEEP_D1_DEF:![0-9]+]] = {{.*}}!DISubprogram(name: "d1", 
linkageName: "_ZN5CDeep3CD12d1Ev", {{.*}}DISPFlagDefinition
+// CHECK-EDGES:  [[CDEEP_D2_DEF:![0-9]+]] = {{.*}}!DISubprogram(name: "d2", 
linkageName: "_ZN5CDeep3CD13CD22d2Ev", {{.*}}DISPFlagDefinition
+// CHECK-EDGES:  [[CDEEP_D3_DEF:![0-9]+]] = {{.*}}!DISubprogram(name: "d3", 
linkageName: "_ZN5CDeep3CD13CD23CD32d3Ev", {{.*}}DISPFlagDefinition
diff --git 
a/cross-project-tests/debuginfo-tests/clang_llvm_roundtrip/callsite-dwarf.cpp 
b/cross-project-tests/debuginfo-tests/clang_llvm_roundtrip/callsite-dwarf.cpp
new file mode 100644
index 0000000000000..269bb04f8ffe6
--- /dev/null
+++ 
b/cross-project-tests/debuginfo-tests/clang_llvm_roundtrip/callsite-dwarf.cpp
@@ -0,0 +1,68 @@
+// RUN: %clang --target=x86_64-unknown-linux -c -g -O1 %s -o - | \
+// RUN: llvm-dwarfdump --debug-info - | FileCheck %s --check-prefix=CHECK
+
+// Simple base and derived class with virtual:
+// We check for a generated 'DW_AT_LLVM_virtual_call_origin' for 'foo', that
+// corresponds to the 'call_target' metadata added to the indirect call
+// instruction.
+
+struct CBaseOne {
+  virtual void foo(int &);
+};
+
+struct CDerivedOne : CBaseOne {
+  void foo(int &);
+};
+
+void CDerivedOne::foo(int &) {}
+
+struct CBaseTwo {
+  CDerivedOne *DerivedOne;
+};
+
+struct CDerivedTwo : CBaseTwo {
+  void bar(int &);
+};
+
+void CDerivedTwo::bar(int &j) { DerivedOne->foo(j); }
+
+// The IR generated looks like:
+//
+// define dso_local void @_ZN11CDerivedTwo3barERi(...) !dbg !40 {
+// entry:
+//   ..
+//   %vtable = load ptr, ptr %0, align 8
+//   %vfn = getelementptr inbounds ptr, ptr %vtable, i64 0
+//   %2 = load ptr, ptr %vfn, align 8
+//   call void %2(...), !dbg !65, !call_target !25
+//   ret void
+// }
+//
+// !25 = !DISubprogram(name: "foo", linkageName: "_ZN11CDerivedOne3fooERi", 
...)
+// !40 = !DISubprogram(name: "bar", linkageName: "_ZN11CDerivedTwo3barERi", 
...)
+// !65 = !DILocation(line: 25, column: 15, scope: !40)
+
+// CHECK: DW_TAG_compile_unit
+// CHECK:   DW_TAG_structure_type
+// CHECK:     DW_AT_name       ("CDerivedOne")
+// CHECK: [[FOO_DCL:0x[a-f0-9]+]]:    DW_TAG_subprogram
+// CHECK:       DW_AT_name     ("foo")
+// CHECK:   DW_TAG_structure_type
+// CHECK:     DW_AT_name       ("CBaseOne")
+// CHECK: [[FOO_DEF:0x[a-f0-9]+]]:  DW_TAG_subprogram
+// CHECK:     DW_AT_call_all_calls     (true)
+// CHECK:     DW_AT_specification      ([[FOO_DCL]] "{{.*}}foo{{.*}}")
+// CHECK:   DW_TAG_structure_type
+// CHECK:     DW_AT_name       ("CDerivedTwo")
+// CHECK:     DW_TAG_subprogram
+// CHECK:       DW_AT_name     ("bar")
+// CHECK:   DW_TAG_structure_type
+// CHECK:     DW_AT_name       ("CBaseTwo")
+// CHECK:   DW_TAG_subprogram
+// CHECK:     DW_AT_call_all_calls     (true)
+// CHECK:     DW_AT_specification      (0x{{.*}} "{{.*}}bar{{.*}}")
+// CHECK:     DW_TAG_call_site
+// CHECK:       DW_AT_call_target_clobbered    (DW_OP_reg0 RAX)
+// CHECK:       DW_AT_call_tail_call   (true)
+// CHECK:       DW_AT_call_pc  (0x{{.*}})
+// CHECK:       DW_AT_LLVM_virtual_call_origin ([[FOO_DCL]] "{{.*}}foo{{.*}}")
diff --git a/llvm/include/llvm/BinaryFormat/Dwarf.def 
b/llvm/include/llvm/BinaryFormat/Dwarf.def
index fbf22cc6f760b..d201f62ead2cc 100644
--- a/llvm/include/llvm/BinaryFormat/Dwarf.def
+++ b/llvm/include/llvm/BinaryFormat/Dwarf.def
@@ -647,6 +647,7 @@ HANDLE_DW_AT(0x3e10, LLVM_address_space, 0, LLVM)
 HANDLE_DW_AT(0x3e11, LLVM_lanes, 0, LLVM)
 HANDLE_DW_AT(0x3e12, LLVM_lane_pc, 0, LLVM)
 HANDLE_DW_AT(0x3e13, LLVM_vector_size, 0, LLVM)
+HANDLE_DW_AT(0x3e14, LLVM_virtual_call_origin, 0, LLVM)
 
 // https://llvm.org/docs/AMDGPUUsage.html#address-space-identifier
 HANDLE_DW_ASPACE(0x0, none)
diff --git a/llvm/include/llvm/CodeGen/MachineFunction.h 
b/llvm/include/llvm/CodeGen/MachineFunction.h
index edb8963ce42b6..a548151b940a6 100644
--- a/llvm/include/llvm/CodeGen/MachineFunction.h
+++ b/llvm/include/llvm/CodeGen/MachineFunction.h
@@ -526,11 +526,17 @@ class LLVM_ABI MachineFunction {
     /// Callee type ids.
     SmallVector<ConstantInt *, 4> CalleeTypeIds;
 
+    /// 'call_target' metadata for the DISubprogram. It is the declaration
+    /// or definition of the target function and might be indirect.
+    MDNode *MD = nullptr;
+
     CallSiteInfo() = default;
 
     /// Extracts the numeric type id from the CallBase's callee_type Metadata,
     /// and sets CalleeTypeIds. This is used as type id for the indirect call 
in
     /// the call graph section.
+    /// Extracts the MDNode from the CallBase's call_target Metadata to be used
+    /// during the construction of the debug info call site entries.
     LLVM_ABI CallSiteInfo(const CallBase &CB);
   };
 
diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h 
b/llvm/include/llvm/CodeGen/TargetLowering.h
index f6d5578412d1e..941e0a19ebb49 100644
--- a/llvm/include/llvm/CodeGen/TargetLowering.h
+++ b/llvm/include/llvm/CodeGen/TargetLowering.h
@@ -5930,6 +5930,10 @@ class LLVM_ABI TargetLowering : public 
TargetLoweringBase {
                                        LoadSDNode *OriginalLoad,
                                        SelectionDAG &DAG) const;
 
+protected:
+  void setTypeIdForCallsiteInfo(const CallBase *CB, MachineFunction &MF,
+                                MachineFunction::CallSiteInfo &CSInfo) const;
+
 private:
   SDValue foldSetCCWithAnd(EVT VT, SDValue N0, SDValue N1, ISD::CondCode Cond,
                            const SDLoc &DL, DAGCombinerInfo &DCI) const;
diff --git a/llvm/include/llvm/IR/FixedMetadataKinds.def 
b/llvm/include/llvm/IR/FixedMetadataKinds.def
index 98129985714b2..0d79677d7079e 100644
--- a/llvm/include/llvm/IR/FixedMetadataKinds.def
+++ b/llvm/include/llvm/IR/FixedMetadataKinds.def
@@ -59,3 +59,4 @@ LLVM_FIXED_MD_KIND(MD_captures, "captures", 44)
 LLVM_FIXED_MD_KIND(MD_alloc_token, "alloc_token", 45)
 LLVM_FIXED_MD_KIND(MD_implicit_ref, "implicit.ref", 46)
 LLVM_FIXED_MD_KIND(MD_nofpclass, "nofpclass", 47)
+LLVM_FIXED_MD_KIND(MD_call_target, "call_target", 48)
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp 
b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
index e87d3f3ee02a0..d2389f06e23db 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
@@ -1349,11 +1349,7 @@ DIE &DwarfCompileUnit::constructCallSiteEntryDIE(
   } else if (CalleeSP) {
     DIE *CalleeDIE = getOrCreateSubprogramDIE(CalleeSP, CalleeF);
     assert(CalleeDIE && "Could not create DIE for call site entry origin");
-    if (AddLinkageNamesToDeclCallOriginsForTuning(DD) &&
-        !CalleeSP->isDefinition() &&
-        !CalleeDIE->findAttribute(dwarf::DW_AT_linkage_name)) {
-      addLinkageName(*CalleeDIE, CalleeSP->getLinkageName());
-    }
+    addLinkageNamesToDeclarations(DD, CalleeSP, CalleeDIE);
 
     addDIEEntry(CallSiteDIE, getDwarf5OrGNUAttr(dwarf::DW_AT_call_origin),
                 *CalleeDIE);
@@ -1891,3 +1887,12 @@ DIE *DwarfCompileUnit::getOrCreateSubprogramDIE(const 
DISubprogram *SP,
 
   return DwarfUnit::getOrCreateSubprogramDIE(SP, F, Minimal);
 }
+
+void DwarfCompileUnit::addLinkageNamesToDeclarations(
+    const DwarfDebug *DD, const DISubprogram *CalleeSP, DIE *CalleeDIE) {
+  if (AddLinkageNamesToDeclCallOriginsForTuning(DD) &&
+      !CalleeSP->isDefinition() &&
+      !CalleeDIE->findAttribute(dwarf::DW_AT_linkage_name)) {
+    addLinkageName(*CalleeDIE, CalleeSP->getLinkageName());
+  }
+}
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h 
b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
index 04d4556c3ce52..15becc77baaee 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
@@ -436,6 +436,10 @@ class DwarfCompileUnit final : public DwarfUnit {
   void addBaseTypeRef(DIEValueList &Die, int64_t Idx);
 
   MDNodeSetVector &getDeferredLocalDecls() { return DeferredLocalDecls; }
+
+  void addLinkageNamesToDeclarations(const DwarfDebug *DD,
+                                     const DISubprogram *CalleeSP,
+                                     DIE *CalleeDIE);
 };
 
 } // end namespace llvm
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp 
b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index f8c2c753b91ce..7b811f677fe77 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -955,6 +955,30 @@ void DwarfDebug::constructCallSiteEntryDIEs(const 
DISubprogram &SP,
     return true;
   };
 
+  // Create call_target connections for indirect calls.
+  auto addCallSiteTargetForIndirectCalls = [&](const MachineInstr *MI,
+                                               DIE &CallSiteDIE) {
+    const MachineFunction *MF = MI->getMF();
+    const auto &CalleesMap = MF->getCallSitesInfo();
+    auto CSInfo = CalleesMap.find(MI);
+    // Get the information for the call instruction.
+    if (CSInfo == CalleesMap.end() || !CSInfo->second.MD)
+      return;
+
+    MDNode *MD = CSInfo->second.MD;
+    // Add DW_AT_LLVM_virtual_call_origin with the 'call_target' metadata.
+    assert(!CallSiteDIE.findAttribute(dwarf::DW_AT_LLVM_virtual_call_origin) &&
+           "DW_AT_LLVM_virtual_call_origin already exists");
+    const DISubprogram *CalleeSP = dyn_cast<DISubprogram>(MD);
+    DIE *CalleeDIE = CU.getOrCreateSubprogramDIE(CalleeSP, nullptr);
+    assert(CalleeDIE && "Could not create DIE for call site entry origin");
+    CU.addDIEEntry(CallSiteDIE,
+                   
CU.getDwarf5OrGNUAttr(dwarf::DW_AT_LLVM_virtual_call_origin),
+                   *CalleeDIE);
+    // Add DW_AT_linkage_name to the method declaration if needed.
+    CU.addLinkageNamesToDeclarations(this, CalleeSP, CalleeDIE);
+  };
+
   // Emit call site entries for each call or tail call in the function.
   for (const MachineBasicBlock &MBB : MF) {
     for (const MachineInstr &MI : MBB.instrs()) {
@@ -1052,6 +1076,9 @@ void DwarfDebug::constructCallSiteEntryDIEs(const 
DISubprogram &SP,
           ScopeDIE, CalleeSP, CalleeDecl, IsTail, PCAddr, CallAddr, CallTarget,
           Offset, AllocSiteTy);
 
+      if (CallTarget.getReg())
+        addCallSiteTargetForIndirectCalls(TopLevelCallMI, CallSiteDIE);
+
       // Optionally emit call-site-param debug info.
       if (emitDebugEntryValues()) {
         ParamSet Params;
@@ -1460,7 +1487,7 @@ void DwarfDebug::finalizeModuleInfo() {
                             TLOF.getDwarfMacinfoSection()->getBeginSymbol());
       }
     }
-    }
+  }
 
   // Emit all frontend-produced Skeleton CUs, i.e., Clang modules.
   for (auto *CUNode : MMI->getModule()->debug_compile_units())
diff --git a/llvm/lib/CodeGen/MIRPrinter.cpp b/llvm/lib/CodeGen/MIRPrinter.cpp
index 9a48a0062549a..93c20394cf98c 100644
--- a/llvm/lib/CodeGen/MIRPrinter.cpp
+++ b/llvm/lib/CodeGen/MIRPrinter.cpp
@@ -541,7 +541,7 @@ static void convertCallSiteObjects(yaml::MachineFunction 
&YMF,
         std::distance(CallI->getParent()->instr_begin(), CallI);
     YmlCS.CallLocation = CallLocation;
 
-    auto [ArgRegPairs, CalleeTypeIds] = CallSiteInfo;
+    auto [ArgRegPairs, CalleeTypeIds, MD] = CallSiteInfo;
     // Construct call arguments and theirs forwarding register info.
     for (auto ArgReg : ArgRegPairs) {
       yaml::CallSiteInfo::ArgRegPair YmlArgReg;
diff --git a/llvm/lib/CodeGen/MachineFunction.cpp 
b/llvm/lib/CodeGen/MachineFunction.cpp
index fb35c7e62dad6..1bcd7b401a3d4 100644
--- a/llvm/lib/CodeGen/MachineFunction.cpp
+++ b/llvm/lib/CodeGen/MachineFunction.cpp
@@ -700,6 +700,9 @@ bool MachineFunction::needsFrameMoves() const {
 }
 
 MachineFunction::CallSiteInfo::CallSiteInfo(const CallBase &CB) {
+  if (MDNode *Node = CB.getMetadata(llvm::LLVMContext::MD_call_target))
+    MD = Node;
+
   // Numeric callee_type ids are only for indirect calls.
   if (!CB.isIndirectCall())
     return;
diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp 
b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index 99968baec98e4..21f8c42ff0206 100644
--- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -12760,3 +12760,17 @@ SDValue 
TargetLowering::scalarizeExtractedVectorLoad(EVT ResultVT,
 
   return Load;
 }
+
+// Set type id for call site info and metadata 'call_target'.
+// We are filtering for:
+// a) The call-graph-section use case that wants to know about indirect
+//    calls, or
+// b) We want to annotate indirect calls.
+void TargetLowering::setTypeIdForCallsiteInfo(
+    const CallBase *CB, MachineFunction &MF,
+    MachineFunction::CallSiteInfo &CSInfo) const {
+  if (CB && CB->isIndirectCall() &&
+      (MF.getTarget().Options.EmitCallGraphSection ||
+       MF.getTarget().Options.EmitCallSiteInfo))
+    CSInfo = MachineFunction::CallSiteInfo(*CB);
+}
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp 
b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
index cd8a2b305a0f9..f8357ed216f5f 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
@@ -246,7 +246,8 @@ static void dumpAttribute(raw_ostream &OS, const DWARFDie 
&Die,
   // having both the raw value and the pretty-printed value is
   // interesting. These attributes are handled below.
   if (Attr == DW_AT_specification || Attr == DW_AT_abstract_origin ||
-      Attr == DW_AT_call_origin || Attr == DW_AT_import) {
+      Attr == DW_AT_call_origin || Attr == DW_AT_import ||
+      Attr == DW_AT_LLVM_virtual_call_origin) {
     if (const char *Name =
             Die.getAttributeValueAsReferencedDie(FormValue).getName(
                 DINameKind::LinkageName))
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp 
b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index d130ca7b56ec0..d9c9e247f812b 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -9871,8 +9871,7 @@ AArch64TargetLowering::LowerCall(CallLoweringInfo &CLI,
   RetCCInfo.AnalyzeCallResult(Ins, RetCC);
 
   // Set type id for call site info.
-  if (MF.getTarget().Options.EmitCallGraphSection && CB && 
CB->isIndirectCall())
-    CSInfo = MachineFunction::CallSiteInfo(*CB);
+  setTypeIdForCallsiteInfo(CB, MF, CSInfo);
 
   // Check callee args/returns for SVE registers and set calling convention
   // accordingly.
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp 
b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index f9ce14b079826..c964dd912b777 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -2056,8 +2056,7 @@ 
ARMTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
     GuardWithBTI = AFI->branchTargetEnforcement();
 
   // Set type id for call site info.
-  if (MF.getTarget().Options.EmitCallGraphSection && CB && 
CB->isIndirectCall())
-    CSInfo = MachineFunction::CallSiteInfo(*CB);
+  setTypeIdForCallsiteInfo(CB, MF, CSInfo);
 
   // Determine whether this is a non-secure function call.
   if (CLI.CB && CLI.CB->getAttributes().hasFnAttr("cmse_nonsecure_call"))
diff --git a/llvm/lib/Target/Mips/MipsISelLowering.cpp 
b/llvm/lib/Target/Mips/MipsISelLowering.cpp
index c920e912f49ac..9d05ab1b83417 100644
--- a/llvm/lib/Target/Mips/MipsISelLowering.cpp
+++ b/llvm/lib/Target/Mips/MipsISelLowering.cpp
@@ -3342,9 +3342,9 @@ 
MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
 
   // Call site info for function parameters tracking and call base type info.
   MachineFunction::CallSiteInfo CSInfo;
+
   // Set type id for call site info.
-  if (MF.getTarget().Options.EmitCallGraphSection && CB && 
CB->isIndirectCall())
-    CSInfo = MachineFunction::CallSiteInfo(*CB);
+  setTypeIdForCallsiteInfo(CB, MF, CSInfo);
 
   // Check if it's really possible to do a tail call.
   // For non-musttail calls, restrict to functions that won't require $gp
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp 
b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 8f8f0e37b6fc0..f49d2e289265c 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -24368,8 +24368,7 @@ SDValue RISCVTargetLowering::LowerCall(CallLoweringInfo 
&CLI,
   MachineFunction::CallSiteInfo CSInfo;
 
   // Set type id for call site info.
-  if (MF.getTarget().Options.EmitCallGraphSection && CB && 
CB->isIndirectCall())
-    CSInfo = MachineFunction::CallSiteInfo(*CB);
+  setTypeIdForCallsiteInfo(CB, MF, CSInfo);
 
   // Analyze the operands of the call, assigning locations to each operand.
   SmallVector<CCValAssign, 16> ArgLocs;
diff --git a/llvm/lib/Target/X86/X86ISelLoweringCall.cpp 
b/llvm/lib/Target/X86/X86ISelLoweringCall.cpp
index 92348689f57f0..c0e120dc30b86 100644
--- a/llvm/lib/Target/X86/X86ISelLoweringCall.cpp
+++ b/llvm/lib/Target/X86/X86ISelLoweringCall.cpp
@@ -2078,8 +2078,7 @@ 
X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
     report_fatal_error("X86 interrupts may not be called directly");
 
   // Set type id for call site info.
-  if (MF.getTarget().Options.EmitCallGraphSection && CB && 
CB->isIndirectCall())
-    CSInfo = MachineFunction::CallSiteInfo(*CB);
+  setTypeIdForCallsiteInfo(CB, MF, CSInfo);
 
   if (IsIndirectCall && !IsWin64 &&
       M->getModuleFlag("import-call-optimization"))
diff --git a/llvm/test/CodeGen/MIR/X86/callsite-emit-calleetypeid.ll 
b/llvm/test/CodeGen/MIR/X86/callsite-emit-calleetypeid.ll
index 3f7590adf9182..fe1980e3f5605 100644
--- a/llvm/test/CodeGen/MIR/X86/callsite-emit-calleetypeid.ll
+++ b/llvm/test/CodeGen/MIR/X86/callsite-emit-calleetypeid.ll
@@ -32,14 +32,13 @@
 ;; Test printer and parser with -emit-call-site-info only.
 
 ;; Test printer.
-;; Verify that fwdArgRegs is set, calleeTypeIds is not set.
+;; Verify that fwdArgRegs and calleeTypeIds are set.
 ; RUN: llc -mtriple=x86_64 -emit-call-site-info %s -stop-after=finalize-isel 
-o %t2.mir
 ; RUN: cat %t2.mir | FileCheck %s --check-prefix=PRINTER_CSI
 ; PRINTER_CSI: name: main
 ; PRINTER_CSI: callSites:
 ; PRINTER_CSI-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs:
-; PRINTER_CSI-NEXT: { arg: 0, reg: {{.*}} }
-; PRINTER_CSI-NOT: calleeTypeIds:
+; PRINTER_CSI-NEXT: { arg: 0, reg: {{.*}} }, calleeTypeIds:
 
 
 ;; Test parser.
@@ -49,8 +48,7 @@
 ; PARSER_CSI: name: main
 ; PARSER_CSI: callSites:
 ; PARSER_CSI-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs:
-; PARSER_CSI-NEXT: { arg: 0, reg: {{.*}} }
-; PARSER_CSI-NOT: calleeTypeIds:
+; PARSER_CSI-NEXT: { arg: 0, reg: {{.*}} }, calleeTypeIds:
 
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Test printer and parser with both -emit-call-site-info and 
--call-graph-section.

>From a9f0b8f543fa7e8fefa06f975a6320a255b8657a Mon Sep 17 00:00:00 2001
From: Carlos Alberto Enciso <[email protected]>
Date: Mon, 16 Feb 2026 13:55:22 +0000
Subject: [PATCH 2/2] [clang][DebugInfo] Add call site target information in
 DWARF.

Address reviewer feedback:
- Rename 'MD' variable to a better descriptive name.
- Remove redundant code for indirect call check.
- Reduce nesting level in 'callsite-edges' test case.
- Improve comments and add check for CBase type definition.
---
 clang/lib/CodeGen/CGDebugInfo.cpp           |  5 ---
 clang/test/DebugInfo/CXX/callsite-base.cpp  | 16 +++++--
 clang/test/DebugInfo/CXX/callsite-edges.cpp | 50 ++++++---------------
 llvm/include/llvm/CodeGen/MachineFunction.h |  2 +-
 llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp  |  6 +--
 llvm/lib/CodeGen/MachineFunction.cpp        |  2 +-
 6 files changed, 31 insertions(+), 50 deletions(-)

diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp 
b/clang/lib/CodeGen/CGDebugInfo.cpp
index 19b5ed2da3e1a..6aa422101d4aa 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -4985,11 +4985,6 @@ void CGDebugInfo::addCallTarget(const FunctionDecl *FD, 
llvm::CallBase *CI) {
   if (!FD)
     return;
 
-  // Ignore method types that never can be indirect calls.
-  if (isa<CXXConstructorDecl>(FD) || isa<CXXDestructorDecl>(FD) ||
-      FD->hasAttr<CUDAGlobalAttr>())
-    return;
-
   // Record only indirect calls.
   assert(CI && "Invalid Call Instruction.");
   if (!CI->isIndirectCall())
diff --git a/clang/test/DebugInfo/CXX/callsite-base.cpp 
b/clang/test/DebugInfo/CXX/callsite-base.cpp
index 576fdacd2722f..cf26d62a03c0b 100644
--- a/clang/test/DebugInfo/CXX/callsite-base.cpp
+++ b/clang/test/DebugInfo/CXX/callsite-base.cpp
@@ -1,10 +1,16 @@
 // RUN: %clang_cc1 -triple=x86_64-linux -disable-llvm-passes -emit-llvm \
-// RUN:            -debug-info-kind=constructor -dwarf-version=5 -O1 %s \
+// RUN:            -debug-info-kind=standalone -dwarf-version=5 -O1 %s \
 // RUN: -o - | FileCheck %s -check-prefix CHECK-BASE
 
 // Simple class with only virtual methods: inlined and not-inlined
-// We check for a generated 'call_target' for:
-// - 'f1', 'f2' and 'f3'.
+//
+// The following three scenarios are considered:
+// - out-of-line defined virtual member function (f1)
+// - declared-but-not-defined virtual member function (f2)
+// - inline defined virtual member function (f3)
+//
+// 1) We check for a generated 'call_target' for: 'f1', 'f2' and 'f3'.
+// 2) Check that the 'CBase' type is defined.
 
 struct CBase {
   virtual void f1();
@@ -18,11 +24,15 @@ void bar(CBase *Base) {
   Base->f2();
   Base->f3();
 
+  // Because this will instantiate the ctor, the CBase type should be defined.
   CBase B;
   B.f1();
 }
 
+// CHECK-BASE: %struct.CBase = type { ptr }
+
 // CHECK-BASE: define {{.*}} @_Z3barP5CBase{{.*}} {
+// CHECK-BASE:   alloca %struct.CBase
 // CHECK-BASE:   call void %1{{.*}} !dbg {{![0-9]+}}, !call_target 
[[BASE_F1_DCL:![0-9]+]]
 // CHECK-BASE:   call void %3{{.*}} !dbg {{![0-9]+}}, !call_target 
[[BASE_F2_DCL:![0-9]+]]
 // CHECK-BASE:   call void %5{{.*}} !dbg {{![0-9]+}}, !call_target 
[[BASE_F3_DCL:![0-9]+]]
diff --git a/clang/test/DebugInfo/CXX/callsite-edges.cpp 
b/clang/test/DebugInfo/CXX/callsite-edges.cpp
index ac969ba1bef83..812cfc1fb4cf2 100644
--- a/clang/test/DebugInfo/CXX/callsite-edges.cpp
+++ b/clang/test/DebugInfo/CXX/callsite-edges.cpp
@@ -45,18 +45,8 @@ void edge_b(CBase *Base) {
 // 3) Virtual method defined in a deeply nested structure hierarchy - Pass.
 //    Generate 'call_target' metadata for 'd0', 'd1', 'd2' and 'd3'.
 //---------------------------------------------------------------------
-struct CDeep {
+struct CD0 {
   struct CD1 {
-    struct CD2 {
-      struct CD3 {
-        virtual void d3();
-      };
-
-      CD3 D3;
-      virtual void d2();
-    };
-
-    CD2 D2;
     virtual void d1();
   };
 
@@ -64,22 +54,14 @@ struct CDeep {
   virtual void d0();
 };
 
-void CDeep::d0() {}
-void CDeep::CD1::d1() {}
-void CDeep::CD1::CD2::d2() {}
-void CDeep::CD1::CD2::CD3::d3() {}
+void CD0::d0() {}
+void CD0::CD1::d1() {}
 
-void edge_c(CDeep *Deep) {
-  Deep->d0();
+void edge_c(CD0 *D0) {
+  D0->d0();
 
-  CDeep::CD1 *D1 = &Deep->D1;
+  CD0::CD1 *D1 = &D0->D1;
   D1->d1();
-
-  CDeep::CD1::CD2 *D2 = &D1->D2;
-  D2->d2();
-
-  CDeep::CD1::CD2::CD3 *D3 = &D2->D3;
-  D3->d3();
 }
 
 // CHECK-EDGES: define {{.*}} @_Z6edge_aP6CEmpty{{.*}} {
@@ -92,17 +74,13 @@ void edge_c(CDeep *Deep) {
 // CHECK-EDGES:  call void %3{{.*}} !dbg {{![0-9]+}}, !call_target 
[[CBASE_F2_DCL:![0-9]+]]
 // CHECK-EDGES: }
 
-// CHECK-EDGES: define {{.*}} @_Z6edge_cP5CDeep{{.*}} {
-// CHECK-EDGES:  call void %1{{.*}} !dbg {{![0-9]+}}, !call_target 
[[CDEEP_D0_DCL:![0-9]+]]
-// CHECK-EDGES:  call void %4{{.*}} !dbg {{![0-9]+}}, !call_target 
[[CDEEP_D1_DCL:![0-9]+]]
-// CHECK-EDGES:  call void %7{{.*}} !dbg {{![0-9]+}}, !call_target 
[[CDEEP_D2_DCL:![0-9]+]]
-// CHECK-EDGES:  call void %10{{.*}} !dbg {{![0-9]+}}, !call_target 
[[CDEEP_D3_DCL:![0-9]+]]
+// CHECK-EDGES: define {{.*}} @_Z6edge_cP3CD0{{.*}} {
+// CHECK-EDGES:  call void %1{{.*}} !dbg {{![0-9]+}}, !call_target 
[[CD0_D0_DCL:![0-9]+]]
+// CHECK-EDGES:  call void %4{{.*}} !dbg {{![0-9]+}}, !call_target 
[[CD0_D1_DCL:![0-9]+]]
 // CHECK-EDGES: }
 
-// CHECK-EDGES:  [[CDEEP_D3_DCL]] = {{.*}}!DISubprogram(name: "d3", 
linkageName: "_ZN5CDeep3CD13CD23CD32d3Ev", {{.*}}containingType
-// CHECK-EDGES:  [[CDEEP_D2_DCL]] = {{.*}}!DISubprogram(name: "d2", 
linkageName: "_ZN5CDeep3CD13CD22d2Ev", {{.*}}containingType
-// CHECK-EDGES:  [[CDEEP_D1_DCL]] = {{.*}}!DISubprogram(name: "d1", 
linkageName: "_ZN5CDeep3CD12d1Ev", {{.*}}containingType
-// CHECK-EDGES:  [[CDEEP_D0_DCL]] = {{.*}}!DISubprogram(name: "d0", 
linkageName: "_ZN5CDeep2d0Ev", {{.*}}containingType
+// CHECK-EDGES:  [[CD0_D1_DCL]] = {{.*}}!DISubprogram(name: "d1", linkageName: 
"_ZN3CD03CD12d1Ev", {{.*}}containingType
+// CHECK-EDGES:  [[CD0_D0_DCL]] = {{.*}}!DISubprogram(name: "d0", linkageName: 
"_ZN3CD02d0Ev", {{.*}}containingType
 
 // CHECK-EDGES:  [[CBASE_F1_DCL]] = {{.*}}!DISubprogram(name: "f1", 
linkageName: "_ZN5CBase2f1Ev", {{.*}}containingType
 // CHECK-EDGES:  [[CBASE_F2_DCL]] = {{.*}}!DISubprogram(name: "f2", 
linkageName: "_ZN5CBase2f2Ev", {{.*}}containingType
@@ -111,7 +89,5 @@ void edge_c(CDeep *Deep) {
 // CHECK-EDGES:  [[CEMPTY_F1_DCL]] = {{.*}}!DISubprogram(name: "f1", 
linkageName: "_ZN6CEmpty2f1Ev", {{.*}}containingType
 // CHECK-EDGES:  [[CBASE_F2_DEF:![0-9]+]] = {{.*}}!DISubprogram(name: "f2", 
linkageName: "_ZN5CBase2f2Ev", {{.*}}DISPFlagDefinition
 
-// CHECK-EDGES:  [[CDEEP_D0_DEF:![0-9]+]] = {{.*}}!DISubprogram(name: "d0", 
linkageName: "_ZN5CDeep2d0Ev", {{.*}}DISPFlagDefinition
-// CHECK-EDGES:  [[CDEEP_D1_DEF:![0-9]+]] = {{.*}}!DISubprogram(name: "d1", 
linkageName: "_ZN5CDeep3CD12d1Ev", {{.*}}DISPFlagDefinition
-// CHECK-EDGES:  [[CDEEP_D2_DEF:![0-9]+]] = {{.*}}!DISubprogram(name: "d2", 
linkageName: "_ZN5CDeep3CD13CD22d2Ev", {{.*}}DISPFlagDefinition
-// CHECK-EDGES:  [[CDEEP_D3_DEF:![0-9]+]] = {{.*}}!DISubprogram(name: "d3", 
linkageName: "_ZN5CDeep3CD13CD23CD32d3Ev", {{.*}}DISPFlagDefinition
+// CHECK-EDGES:  [[CD0_D0_DEF:![0-9]+]] = {{.*}}!DISubprogram(name: "d0", 
linkageName: "_ZN3CD02d0Ev", {{.*}}DISPFlagDefinition
+// CHECK-EDGES:  [[CD0_D1_DEF:![0-9]+]] = {{.*}}!DISubprogram(name: "d1", 
linkageName: "_ZN3CD03CD12d1Ev", {{.*}}DISPFlagDefinition
diff --git a/llvm/include/llvm/CodeGen/MachineFunction.h 
b/llvm/include/llvm/CodeGen/MachineFunction.h
index a548151b940a6..26b6c457a45ba 100644
--- a/llvm/include/llvm/CodeGen/MachineFunction.h
+++ b/llvm/include/llvm/CodeGen/MachineFunction.h
@@ -528,7 +528,7 @@ class LLVM_ABI MachineFunction {
 
     /// 'call_target' metadata for the DISubprogram. It is the declaration
     /// or definition of the target function and might be indirect.
-    MDNode *MD = nullptr;
+    MDNode *CallTarget = nullptr;
 
     CallSiteInfo() = default;
 
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp 
b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index 7b811f677fe77..80c16b103149d 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -962,14 +962,14 @@ void DwarfDebug::constructCallSiteEntryDIEs(const 
DISubprogram &SP,
     const auto &CalleesMap = MF->getCallSitesInfo();
     auto CSInfo = CalleesMap.find(MI);
     // Get the information for the call instruction.
-    if (CSInfo == CalleesMap.end() || !CSInfo->second.MD)
+    if (CSInfo == CalleesMap.end() || !CSInfo->second.CallTarget)
       return;
 
-    MDNode *MD = CSInfo->second.MD;
+    MDNode *CallTarget = CSInfo->second.CallTarget;
     // Add DW_AT_LLVM_virtual_call_origin with the 'call_target' metadata.
     assert(!CallSiteDIE.findAttribute(dwarf::DW_AT_LLVM_virtual_call_origin) &&
            "DW_AT_LLVM_virtual_call_origin already exists");
-    const DISubprogram *CalleeSP = dyn_cast<DISubprogram>(MD);
+    const DISubprogram *CalleeSP = dyn_cast<DISubprogram>(CallTarget);
     DIE *CalleeDIE = CU.getOrCreateSubprogramDIE(CalleeSP, nullptr);
     assert(CalleeDIE && "Could not create DIE for call site entry origin");
     CU.addDIEEntry(CallSiteDIE,
diff --git a/llvm/lib/CodeGen/MachineFunction.cpp 
b/llvm/lib/CodeGen/MachineFunction.cpp
index 1bcd7b401a3d4..fe876fe4dc3e8 100644
--- a/llvm/lib/CodeGen/MachineFunction.cpp
+++ b/llvm/lib/CodeGen/MachineFunction.cpp
@@ -701,7 +701,7 @@ bool MachineFunction::needsFrameMoves() const {
 
 MachineFunction::CallSiteInfo::CallSiteInfo(const CallBase &CB) {
   if (MDNode *Node = CB.getMetadata(llvm::LLVMContext::MD_call_target))
-    MD = Node;
+    CallTarget = Node;
 
   // Numeric callee_type ids are only for indirect calls.
   if (!CB.isIndirectCall())

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

Reply via email to