[clang] [llvm] [clang][DebugInfo] Add virtual call-site target information in DWARF. (PR #167666)
Carlos Alberto Enciso via cfe-commits
cfe-commits at lists.llvm.org
Tue Feb 17 06:18:59 PST 2026
https://github.com/CarlosAlbertoEnciso updated https://github.com/llvm/llvm-project/pull/167666
>From 0bc830e2f2db510fa53ab65dc1e3d593b4cd39cf Mon Sep 17 00:00:00 2001
From: Carlos Alberto Enciso <Carlos.Enciso at sony.com>
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 75f1061c471c6..50b83884c851a 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 e4b4d80896fa7..fc7c57f24e41f 100644
--- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -12763,3 +12763,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 66c22db0491d1..ba9cebd3deda9 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -9928,8 +9928,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 4d38ee354d86f..91dde57f431b8 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -24481,8 +24481,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 db78449ff8d35c26b557e6a9219722abc0571645 Mon Sep 17 00:00:00 2001
From: Carlos Alberto Enciso <Carlos.Enciso at sony.com>
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())
More information about the cfe-commits
mailing list