Skip to content

Commit fc8fe46

Browse files
authored
Merge branch 'llvm:main' into main
2 parents 75c2fe5 + 2b9ded6 commit fc8fe46

File tree

45 files changed

+1181
-345
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+1181
-345
lines changed

clang/lib/CodeGen/CGDebugInfo.cpp

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2635,6 +2635,55 @@ StringRef CGDebugInfo::getVTableName(const CXXRecordDecl *RD) {
26352635
return internString("_vptr$", RD->getNameAsString());
26362636
}
26372637

2638+
// Emit symbol for the debugger that points to the vtable address for
2639+
// the given class. The symbol is named as '_vtable$'.
2640+
// The debugger does not need to know any details about the contents of the
2641+
// vtable as it can work this out using its knowledge of the ABI and the
2642+
// existing information in the DWARF. The type is assumed to be 'void *'.
2643+
void CGDebugInfo::emitVTableSymbol(llvm::GlobalVariable *VTable,
2644+
const CXXRecordDecl *RD) {
2645+
if (!CGM.getTarget().getCXXABI().isItaniumFamily())
2646+
return;
2647+
2648+
ASTContext &Context = CGM.getContext();
2649+
StringRef SymbolName = "_vtable$";
2650+
SourceLocation Loc;
2651+
QualType VoidPtr = Context.getPointerType(Context.VoidTy);
2652+
2653+
// We deal with two different contexts:
2654+
// - The type for the variable, which is part of the class that has the
2655+
// vtable, is placed in the context of the DICompositeType metadata.
2656+
// - The DIGlobalVariable for the vtable is put in the DICompileUnitScope.
2657+
2658+
// The created non-member should be mark as 'artificial'. It will be
2659+
// placed inside the scope of the C++ class/structure.
2660+
llvm::DIScope *DContext = getContextDescriptor(RD, TheCU);
2661+
auto *Ctxt = cast<llvm::DICompositeType>(DContext);
2662+
llvm::DIFile *Unit = getOrCreateFile(Loc);
2663+
llvm::DIType *VTy = getOrCreateType(VoidPtr, Unit);
2664+
llvm::DINode::DIFlags Flags = getAccessFlag(AccessSpecifier::AS_private, RD) |
2665+
llvm::DINode::FlagArtificial;
2666+
auto Tag = CGM.getCodeGenOpts().DwarfVersion >= 5
2667+
? llvm::dwarf::DW_TAG_variable
2668+
: llvm::dwarf::DW_TAG_member;
2669+
llvm::DIDerivedType *DT = DBuilder.createStaticMemberType(
2670+
Ctxt, SymbolName, Unit, /*LineNumber=*/0, VTy, Flags,
2671+
/*Val=*/nullptr, Tag);
2672+
2673+
// Use the same vtable pointer to global alignment for the symbol.
2674+
unsigned PAlign = CGM.getVtableGlobalVarAlignment();
2675+
2676+
// The global variable is in the CU scope, and links back to the type it's
2677+
// "within" via the declaration field.
2678+
llvm::DIGlobalVariableExpression *GVE =
2679+
DBuilder.createGlobalVariableExpression(
2680+
TheCU, SymbolName, VTable->getName(), Unit, /*LineNo=*/0,
2681+
getOrCreateType(VoidPtr, Unit), VTable->hasLocalLinkage(),
2682+
/*isDefined=*/true, nullptr, DT, /*TemplateParameters=*/nullptr,
2683+
PAlign);
2684+
VTable->addDebugInfo(GVE);
2685+
}
2686+
26382687
StringRef CGDebugInfo::getDynamicInitializerName(const VarDecl *VD,
26392688
DynamicInitKind StubKind,
26402689
llvm::Function *InitFn) {

clang/lib/CodeGen/CGDebugInfo.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -669,6 +669,9 @@ class CGDebugInfo {
669669
void addInstToSpecificSourceAtom(llvm::Instruction *KeyInstruction,
670670
llvm::Value *Backup, uint64_t Atom);
671671

672+
/// Emit symbol for debugger that holds the pointer to the vtable.
673+
void emitVTableSymbol(llvm::GlobalVariable *VTable, const CXXRecordDecl *RD);
674+
672675
private:
673676
/// Amend \p I's DebugLoc with \p Group (its source atom group) and \p
674677
/// Rank (lower nonzero rank is higher precedence). Does nothing if \p I

clang/lib/CodeGen/CodeGenModule.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1810,6 +1810,15 @@ class CodeGenModule : public CodeGenTypeCache {
18101810
return !getLangOpts().CPlusPlus;
18111811
}
18121812

1813+
// Helper to get the alignment for a variable.
1814+
unsigned getVtableGlobalVarAlignment(const VarDecl *D = nullptr) {
1815+
LangAS AS = GetGlobalVarAddressSpace(D);
1816+
unsigned PAlign = getItaniumVTableContext().isRelativeLayout()
1817+
? 32
1818+
: getTarget().getPointerAlign(AS);
1819+
return PAlign;
1820+
}
1821+
18131822
private:
18141823
bool shouldDropDLLAttribute(const Decl *D, const llvm::GlobalValue *GV) const;
18151824

clang/lib/CodeGen/ItaniumCXXABI.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2061,6 +2061,10 @@ void ItaniumCXXABI::emitVTableDefinitions(CodeGenVTables &CGVT,
20612061
if (!VTable->isDSOLocal())
20622062
CGVT.GenerateRelativeVTableAlias(VTable, VTable->getName());
20632063
}
2064+
2065+
// Emit symbol for debugger only if requested debug info.
2066+
if (CGDebugInfo *DI = CGM.getModuleDebugInfo())
2067+
DI->emitVTableSymbol(VTable, RD);
20642068
}
20652069

20662070
bool ItaniumCXXABI::isVirtualOffsetNeededForVTableField(
@@ -2166,10 +2170,7 @@ llvm::GlobalVariable *ItaniumCXXABI::getAddrOfVTable(const CXXRecordDecl *RD,
21662170
// Use pointer to global alignment for the vtable. Otherwise we would align
21672171
// them based on the size of the initializer which doesn't make sense as only
21682172
// single values are read.
2169-
LangAS AS = CGM.GetGlobalVarAddressSpace(nullptr);
2170-
unsigned PAlign = CGM.getItaniumVTableContext().isRelativeLayout()
2171-
? 32
2172-
: CGM.getTarget().getPointerAlign(AS);
2173+
unsigned PAlign = CGM.getVtableGlobalVarAlignment();
21732174

21742175
VTable = CGM.CreateOrReplaceCXXRuntimeVariable(
21752176
Name, VTableType, llvm::GlobalValue::ExternalLinkage,

clang/test/CodeGenCXX/debug-info-class.cpp

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -122,14 +122,6 @@ int main(int argc, char **argv) {
122122
// CHECK-SAME: ){{$}}
123123

124124
// CHECK: ![[INT:[0-9]+]] = !DIBasicType(name: "int"
125-
// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "foo"
126-
// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "bar"
127-
// CHECK: !DICompositeType(tag: DW_TAG_union_type, name: "baz"
128-
// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "B"
129-
// CHECK-NOT: DIFlagFwdDecl
130-
// CHECK-SAME: ){{$}}
131-
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "_vptr$B",
132-
// CHECK-SAME: DIFlagArtificial
133125

134126
// CHECK: [[C:![0-9]*]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "C",
135127
// CHECK-NOT: DIFlagFwdDecl
@@ -145,6 +137,20 @@ int main(int argc, char **argv) {
145137
// CHECK-SAME: DIFlagStaticMember
146138
// CHECK: [[C_DTOR]] = !DISubprogram(name: "~C"
147139

140+
// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "K"
141+
// CHECK-SAME: identifier: "_ZTS1K"
142+
// CHECK-SAME: ){{$}}
143+
144+
// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "B"
145+
// CHECK-NOT: DIFlagFwdDecl
146+
// CHECK-SAME: ){{$}}
147+
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "_vptr$B",
148+
// CHECK-SAME: DIFlagArtificial
149+
150+
// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "foo"
151+
// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "bar"
152+
// CHECK: !DICompositeType(tag: DW_TAG_union_type, name: "baz"
153+
148154
// CHECK: [[D:![0-9]+]] = !DICompositeType(tag: DW_TAG_structure_type, name: "D"
149155
// CHECK-SAME: size:
150156
// CHECK-SAME: DIFlagFwdDecl
@@ -156,10 +162,6 @@ int main(int argc, char **argv) {
156162
// CHECK-NOT: identifier:
157163
// CHECK-SAME: ){{$}}
158164

159-
// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "K"
160-
// CHECK-SAME: identifier: "_ZTS1K"
161-
// CHECK-SAME: ){{$}}
162-
163165
// CHECK: [[L:![0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "L"
164166
// CHECK-SAME: ){{$}}
165167
// CHECK: [[L_FUNC_DECL:![0-9]*]] = !DISubprogram(name: "func",{{.*}} scope: [[L]]

clang/test/CodeGenCXX/debug-info-template-member.cpp

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -22,29 +22,6 @@ inline int add3(int x) {
2222
// CHECK: [[X]] = !DIGlobalVariableExpression(var: [[XV:.*]], expr: !DIExpression())
2323
// CHECK: [[XV]] = distinct !DIGlobalVariable(name: "x",
2424
// CHECK-SAME: type: ![[OUTER_FOO_INNER_ID:[0-9]+]]
25-
//
26-
// CHECK: {{![0-9]+}} = distinct !DIGlobalVariable(
27-
// CHECK-SAME: name: "var"
28-
// CHECK-SAME: templateParams: {{![0-9]+}}
29-
// CHECK: !DITemplateTypeParameter(name: "T", type: [[TY:![0-9]+]])
30-
// CHECK: {{![0-9]+}} = distinct !DIGlobalVariable(
31-
// CHECK-SAME: name: "var"
32-
// CHECK-SAME: templateParams: {{![0-9]+}}
33-
// CHECK: !DITemplateTypeParameter(name: "T", type: {{![0-9]+}})
34-
// CHECK: {{![0-9]+}} = distinct !DIGlobalVariable(
35-
// CHECK-SAME: name: "varray"
36-
// CHECK-SAME: templateParams: {{![0-9]+}}
37-
// CHECK: !DITemplateValueParameter(name: "N", type: [[TY]], value: i32 1)
38-
39-
// CHECK: ![[OUTER_FOO_INNER_ID:[0-9]*]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "inner"{{.*}}, identifier:
40-
// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "foo"
41-
// CHECK-SAME: elements: [[FOO_MEM:![0-9]*]]
42-
// CHECK-SAME: identifier: "_ZTS3foo"
43-
// CHECK: [[FOO_MEM]] = !{[[FOO_FUNC:![0-9]*]]}
44-
// CHECK: [[FOO_FUNC]] = !DISubprogram(name: "func", linkageName: "_ZN3foo4funcEN5outerIS_E5innerE",
45-
// CHECK-SAME: type: [[FOO_FUNC_TYPE:![0-9]*]]
46-
// CHECK: [[FOO_FUNC_TYPE]] = !DISubroutineType(types: [[FOO_FUNC_PARAMS:![0-9]*]])
47-
// CHECK: [[FOO_FUNC_PARAMS]] = !{null, !{{[0-9]*}}, ![[OUTER_FOO_INNER_ID]]}
4825

4926
// CHECK: [[C:![0-9]*]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "MyClass"
5027
// CHECK-SAME: elements: [[C_MEM:![0-9]*]]
@@ -55,9 +32,6 @@ inline int add3(int x) {
5532

5633
// CHECK: [[C_FUNC]] = !DISubprogram(name: "func",{{.*}} line: 9,
5734

58-
// CHECK: !DISubprogram(name: "add<2>"
59-
// CHECK-SAME: scope: [[C]]
60-
//
6135
// CHECK: [[VIRT_TEMP:![0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "virt<elem>"
6236
// CHECK-SAME: elements: [[VIRT_MEM:![0-9]*]]
6337
// CHECK-SAME: vtableHolder: [[VIRT_TEMP]]
@@ -74,6 +48,32 @@ inline int add3(int x) {
7448
// CHECK: [[VIRT_TEMP_PARAM]] = !{[[VIRT_T:![0-9]*]]}
7549
// CHECK: [[VIRT_T]] = !DITemplateTypeParameter(name: "T", type: [[ELEM]])
7650

51+
// CHECK: {{![0-9]+}} = distinct !DIGlobalVariable(
52+
// CHECK-SAME: name: "var"
53+
// CHECK-SAME: templateParams: {{![0-9]+}}
54+
// CHECK: !DITemplateTypeParameter(name: "T", type: [[TY:![0-9]+]])
55+
// CHECK: {{![0-9]+}} = distinct !DIGlobalVariable(
56+
// CHECK-SAME: name: "var"
57+
// CHECK-SAME: templateParams: {{![0-9]+}}
58+
// CHECK: !DITemplateTypeParameter(name: "T", type: {{![0-9]+}})
59+
// CHECK: {{![0-9]+}} = distinct !DIGlobalVariable(
60+
// CHECK-SAME: name: "varray"
61+
// CHECK-SAME: templateParams: {{![0-9]+}}
62+
// CHECK: !DITemplateValueParameter(name: "N", type: [[TY]], value: i32 1)
63+
64+
// CHECK: ![[OUTER_FOO_INNER_ID:[0-9]*]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "inner"{{.*}}, identifier:
65+
// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "foo"
66+
// CHECK-SAME: elements: [[FOO_MEM:![0-9]*]]
67+
// CHECK-SAME: identifier: "_ZTS3foo"
68+
// CHECK: [[FOO_MEM]] = !{[[FOO_FUNC:![0-9]*]]}
69+
// CHECK: [[FOO_FUNC]] = !DISubprogram(name: "func", linkageName: "_ZN3foo4funcEN5outerIS_E5innerE",
70+
// CHECK-SAME: type: [[FOO_FUNC_TYPE:![0-9]*]]
71+
// CHECK: [[FOO_FUNC_TYPE]] = !DISubroutineType(types: [[FOO_FUNC_PARAMS:![0-9]*]])
72+
// CHECK: [[FOO_FUNC_PARAMS]] = !{null, !{{[0-9]*}}, ![[OUTER_FOO_INNER_ID]]}
73+
74+
// CHECK: !DISubprogram(name: "add<2>"
75+
// CHECK-SAME: scope: [[C]]
76+
7777
template<typename T>
7878
struct outer {
7979
struct inner {
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
// REQUIRES: target={{x86_64.*-linux.*}}
2+
3+
// Diamond inheritance case:
4+
// For CBase, CLeft, CRight and CDerived we check:
5+
// - Generation of their vtables (including attributes).
6+
// - Generation of their '_vtable$' data members:
7+
// * Correct scope and attributes
8+
9+
namespace NSP {
10+
struct CBase {
11+
int B = 0;
12+
virtual char fooBase() { return 'B'; }
13+
};
14+
}
15+
16+
namespace NSP_1 {
17+
struct CLeft : NSP::CBase {
18+
int M1 = 1;
19+
char fooBase() override { return 'O'; };
20+
virtual int fooLeft() { return 1; }
21+
};
22+
}
23+
24+
namespace NSP_2 {
25+
struct CRight : NSP::CBase {
26+
int M2 = 2;
27+
char fooBase() override { return 'T'; };
28+
virtual int fooRight() { return 2; }
29+
};
30+
}
31+
32+
struct CDerived : NSP_1::CLeft, NSP_2::CRight {
33+
int D = 3;
34+
char fooBase() override { return 'D'; };
35+
int fooDerived() { return 3; };
36+
};
37+
38+
int main() {
39+
NSP::CBase Base;
40+
NSP_1::CLeft Left;
41+
NSP_2::CRight Right;
42+
CDerived Derived;
43+
44+
return 0;
45+
}
46+
47+
// RUN: %clang --target=x86_64-linux -Xclang -disable-O0-optnone -Xclang -disable-llvm-passes -emit-llvm -S -g %s -o - | FileCheck %s
48+
49+
// CHECK: $_ZTVN3NSP5CBaseE = comdat any
50+
// CHECK: $_ZTVN5NSP_15CLeftE = comdat any
51+
// CHECK: $_ZTVN5NSP_26CRightE = comdat any
52+
// CHECK: $_ZTV8CDerived = comdat any
53+
54+
// CHECK: @_ZTVN3NSP5CBaseE = linkonce_odr {{dso_local|hidden}} unnamed_addr constant {{.*}}, comdat, align 8, !dbg [[BASE_VTABLE_VAR:![0-9]*]]
55+
// CHECK: @_ZTVN5NSP_15CLeftE = linkonce_odr {{dso_local|hidden}} unnamed_addr constant {{.*}}, comdat, align 8, !dbg [[LEFT_VTABLE_VAR:![0-9]*]]
56+
// CHECK: @_ZTVN5NSP_26CRightE = linkonce_odr {{dso_local|hidden}} unnamed_addr constant {{.*}}, comdat, align 8, !dbg [[RIGHT_VTABLE_VAR:![0-9]*]]
57+
// CHECK: @_ZTV8CDerived = linkonce_odr {{dso_local|hidden}} unnamed_addr constant {{.*}}, comdat, align 8, !dbg [[DERIVED_VTABLE_VAR:![0-9]*]]
58+
59+
// CHECK: [[BASE_VTABLE_VAR]] = !DIGlobalVariableExpression(var: [[BASE_VTABLE:![0-9]*]], expr: !DIExpression())
60+
// CHECK-NEXT: [[BASE_VTABLE]] = distinct !DIGlobalVariable(name: "_vtable$", linkageName: "_ZTVN3NSP5CBaseE"
61+
62+
// CHECK: [[LEFT_VTABLE_VAR]] = !DIGlobalVariableExpression(var: [[LEFT_VTABLE:![0-9]*]], expr: !DIExpression())
63+
// CHECK-NEXT: [[LEFT_VTABLE]] = distinct !DIGlobalVariable(name: "_vtable$", linkageName: "_ZTVN5NSP_15CLeftE"
64+
65+
// CHECK: [[TYPE:![0-9]*]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64)
66+
67+
// CHECK: !DIDerivedType(tag: DW_TAG_variable, name: "_vtable$", scope: [[LEFT:![0-9]*]], file: {{.*}}, baseType: [[TYPE]], flags: DIFlagPrivate | DIFlagArtificial | DIFlagStaticMember)
68+
69+
// CHECK: [[LEFT]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "CLeft"
70+
71+
// CHECK: [[BASE:![0-9]*]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "CBase"
72+
73+
// CHECK: [[RIGHT_VTABLE_VAR]] = !DIGlobalVariableExpression(var: [[RIGHT_VTABLE:![0-9]*]], expr: !DIExpression())
74+
// CHECK-NEXT: [[RIGHT_VTABLE]] = distinct !DIGlobalVariable(name: "_vtable$", linkageName: "_ZTVN5NSP_26CRightE"
75+
76+
// CHECK: !DIDerivedType(tag: DW_TAG_variable, name: "_vtable$", scope: [[RIGHT:![0-9]*]], file: {{.*}}, baseType: [[TYPE]], flags: DIFlagPrivate | DIFlagArtificial | DIFlagStaticMember)
77+
78+
// CHECK: [[RIGHT]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "CRight"
79+
80+
// CHECK: [[DERIVED_VTABLE_VAR]] = !DIGlobalVariableExpression(var: [[DERIVED_VTABLE:![0-9]*]], expr: !DIExpression())
81+
// CHECK-NEXT: [[DERIVED_VTABLE]] = distinct !DIGlobalVariable(name: "_vtable$", linkageName: "_ZTV8CDerived"
82+
83+
// CHECK: !DIDerivedType(tag: DW_TAG_variable, name: "_vtable$", scope: [[DERIVED:![0-9]*]], file: {{.*}}, baseType: [[TYPE]], flags: DIFlagPrivate | DIFlagArtificial | DIFlagStaticMember)
84+
85+
// CHECK: [[DERIVED]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "CDerived"
86+
87+
// CHECK: !DIDerivedType(tag: DW_TAG_variable, name: "_vtable$", scope: [[BASE]], file: {{.*}}, baseType: [[TYPE]], flags: DIFlagPrivate | DIFlagArtificial | DIFlagStaticMember)
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
// REQUIRES: target={{x86_64.*-linux.*}}
2+
3+
// Multiple inheritance case:
4+
// For CBaseOne, CBaseTwo and CDerived we check:
5+
// - Generation of their vtables (including attributes).
6+
// - Generation of their '_vtable$' data members:
7+
// * Correct scope and attributes
8+
9+
namespace NSP_1 {
10+
struct CBaseOne {
11+
int B1 = 1;
12+
virtual int one() { return 1; }
13+
virtual int two() { return 2; }
14+
virtual int three() { return 3; }
15+
};
16+
}
17+
18+
namespace NSP_2 {
19+
struct CBaseTwo {
20+
int B2 = 1;
21+
virtual int four() { return 4; }
22+
virtual int five() { return 5; }
23+
virtual int six() { return 6; }
24+
};
25+
}
26+
27+
struct CDerived : NSP_1::CBaseOne, NSP_2::CBaseTwo {
28+
int D = 1;
29+
int two() override { return 22; };
30+
int six() override { return 66; }
31+
};
32+
33+
int main() {
34+
NSP_1::CBaseOne BaseOne;
35+
NSP_2::CBaseTwo BaseTwo;
36+
CDerived Derived;
37+
38+
return 0;
39+
}
40+
41+
// RUN: %clang --target=x86_64-linux -Xclang -disable-O0-optnone -Xclang -disable-llvm-passes -emit-llvm -S -g %s -o - | FileCheck %s
42+
43+
// CHECK: $_ZTVN5NSP_18CBaseOneE = comdat any
44+
// CHECK: $_ZTVN5NSP_28CBaseTwoE = comdat any
45+
// CHECK: $_ZTV8CDerived = comdat any
46+
47+
// CHECK: @_ZTVN5NSP_18CBaseOneE = linkonce_odr {{dso_local|hidden}} unnamed_addr constant {{.*}}, comdat, align 8, !dbg [[BASE_ONE_VTABLE_VAR:![0-9]*]]
48+
// CHECK: @_ZTVN5NSP_28CBaseTwoE = linkonce_odr {{dso_local|hidden}} unnamed_addr constant {{.*}}, comdat, align 8, !dbg [[BASE_TWO_VTABLE_VAR:![0-9]*]]
49+
// CHECK: @_ZTV8CDerived = linkonce_odr {{dso_local|hidden}} unnamed_addr constant {{.*}}, comdat, align 8, !dbg [[DERIVED_VTABLE_VAR:![0-9]*]]
50+
51+
// CHECK: [[BASE_ONE_VTABLE_VAR]] = !DIGlobalVariableExpression(var: [[BASE_ONE_VTABLE:![0-9]*]], expr: !DIExpression())
52+
// CHECK-NEXT: [[BASE_ONE_VTABLE]] = distinct !DIGlobalVariable(name: "_vtable$", linkageName: "_ZTVN5NSP_18CBaseOneE"
53+
54+
// CHECK: [[BASE_TWO_VTABLE_VAR]] = !DIGlobalVariableExpression(var: [[BASE_TWO_VTABLE:![0-9]*]], expr: !DIExpression())
55+
// CHECK-NEXT: [[BASE_TWO_VTABLE]] = distinct !DIGlobalVariable(name: "_vtable$", linkageName: "_ZTVN5NSP_28CBaseTwoE"
56+
57+
// CHECK: [[TYPE:![0-9]*]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64)
58+
59+
// CHECK: !DIDerivedType(tag: DW_TAG_variable, name: "_vtable$", scope: [[BASE_TWO:![0-9]*]], file: {{.*}}, baseType: [[TYPE]], flags: DIFlagPrivate | DIFlagArtificial | DIFlagStaticMember)
60+
61+
// check: [[BASE_TWO]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "CBaseTwo"
62+
63+
// CHECK: [[DERIVED_VTABLE_VAR]] = !DIGlobalVariableExpression(var: [[DERIVED_VTABLE:![0-9]*]], expr: !DIExpression())
64+
// CHECK: [[DERIVED_VTABLE]] = distinct !DIGlobalVariable(name: "_vtable$", linkageName: "_ZTV8CDerived"
65+
66+
// CHECK: !DIDerivedType(tag: DW_TAG_variable, name: "_vtable$", scope: [[DERIVED:![0-9]*]], file: {{.*}}, baseType: [[TYPE]], flags: DIFlagPrivate | DIFlagArtificial | DIFlagStaticMember)
67+
68+
// CHECK: [[DERIVED]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "CDerived"
69+
70+
// CHECK: [[BASE_ONE:![0-9]*]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "CBaseOne"
71+
72+
// CHECK: !DIDerivedType(tag: DW_TAG_variable, name: "_vtable$", scope: [[BASE_ONE]], file: {{.*}}, baseType: [[TYPE]], flags: DIFlagPrivate | DIFlagArtificial | DIFlagStaticMember)

0 commit comments

Comments
 (0)