Skip to content

Commit dc84180

Browse files
[DebugInfo] Add symbol for debugger with VTable information.
Address comments from reviewers: - Add 'vtable' string to the 'getGlobalVarAlignment()' function name to avoid any confusion on its usage. - Add test cases to cover when a class is defined inside a function: - CBase (global) and CDerived (local) - CBase (local) and CDerived (local).
1 parent e811ab7 commit dc84180

File tree

5 files changed

+366
-3
lines changed

5 files changed

+366
-3
lines changed

clang/lib/CodeGen/CGDebugInfo.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2556,7 +2556,7 @@ void CGDebugInfo::emitVTableSymbol(llvm::GlobalVariable *VTable,
25562556
/*Val=*/nullptr, Tag);
25572557

25582558
// Use the same vtable pointer to global alignment for the symbol.
2559-
unsigned PAlign = CGM.getGlobalVarAlignment();
2559+
unsigned PAlign = CGM.getVtableGlobalVarAlignment();
25602560

25612561
// The global variable is in the CU scope, and links back to the type it's
25622562
// "within" via the declaration field.

clang/lib/CodeGen/CodeGenModule.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1817,7 +1817,7 @@ class CodeGenModule : public CodeGenTypeCache {
18171817
bool classNeedsVectorDestructor(const CXXRecordDecl *RD);
18181818

18191819
// Helper to get the alignment for a variable.
1820-
unsigned getGlobalVarAlignment(const VarDecl *D = nullptr) {
1820+
unsigned getVtableGlobalVarAlignment(const VarDecl *D = nullptr) {
18211821
LangAS AS = GetGlobalVarAddressSpace(D);
18221822
unsigned PAlign = getItaniumVTableContext().isRelativeLayout()
18231823
? 32

clang/lib/CodeGen/ItaniumCXXABI.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2168,7 +2168,7 @@ llvm::GlobalVariable *ItaniumCXXABI::getAddrOfVTable(const CXXRecordDecl *RD,
21682168
// Use pointer to global alignment for the vtable. Otherwise we would align
21692169
// them based on the size of the initializer which doesn't make sense as only
21702170
// single values are read.
2171-
unsigned PAlign = CGM.getGlobalVarAlignment();
2171+
unsigned PAlign = CGM.getVtableGlobalVarAlignment();
21722172

21732173
VTable = CGM.CreateOrReplaceCXXRuntimeVariable(
21742174
Name, VTableType, llvm::GlobalValue::ExternalLinkage,
Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
; REQUIRES: target={{x86_64.*-linux.*}}
2+
; RUN: llc %s -o %t -filetype=obj
3+
; RUN: llvm-dwarfdump -debug-info %t | FileCheck %s
4+
5+
; Simple inheritance case:
6+
; CBase defined at global scope.
7+
; CDerived defined at function scope.
8+
; For CBase and CDerived we check:
9+
; - Generation of their vtables (including attributes).
10+
; - Generation of their '_vtable$' data members:
11+
; * Correct scope and attributes
12+
13+
; struct CBase {
14+
; unsigned B = 1;
15+
; virtual void zero() {}
16+
; virtual int one() { return 1; }
17+
; };
18+
;
19+
; int main() {
20+
; {
21+
; struct CDerived : CBase {
22+
; unsigned D = 2;
23+
; void zero() override {}
24+
; int one() override { return 11; };
25+
; };
26+
;
27+
; {
28+
; CBase Base;
29+
; {
30+
; CDerived Derived;
31+
; }
32+
; }
33+
; }
34+
;
35+
; return 0;
36+
; }
37+
38+
source_filename = "vtable-debug-info-base-global-derived-local.cpp"
39+
target triple = "x86_64-pc-linux-gnu"
40+
41+
%struct.CBase = type <{ ptr, i32, [4 x i8] }>
42+
%struct.CDerived = type { %struct.CBase.base, i32 }
43+
%struct.CBase.base = type <{ ptr, i32 }>
44+
45+
$_ZN5CBaseC2Ev = comdat any
46+
47+
$_ZN5CBase4zeroEv = comdat any
48+
49+
$_ZN5CBase3oneEv = comdat any
50+
51+
$_ZTV5CBase = comdat any
52+
53+
$_ZTI5CBase = comdat any
54+
55+
$_ZTS5CBase = comdat any
56+
57+
@_ZTV5CBase = linkonce_odr dso_local unnamed_addr constant { [4 x ptr] } { [4 x ptr] [ptr null, ptr @_ZTI5CBase, ptr @_ZN5CBase4zeroEv, ptr @_ZN5CBase3oneEv] }, comdat, align 8, !dbg !0
58+
@_ZTI5CBase = linkonce_odr dso_local constant { ptr, ptr } { ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i64 2), ptr @_ZTS5CBase }, comdat, align 8
59+
@_ZTVN10__cxxabiv117__class_type_infoE = external global [0 x ptr]
60+
@_ZTS5CBase = linkonce_odr dso_local constant [7 x i8] c"5CBase\00", comdat, align 1
61+
@_ZTVZ4mainE8CDerived = internal unnamed_addr constant { [4 x ptr] } { [4 x ptr] [ptr null, ptr @_ZTIZ4mainE8CDerived, ptr @_ZZ4mainEN8CDerived4zeroEv, ptr @_ZZ4mainEN8CDerived3oneEv] }, align 8, !dbg !5
62+
@_ZTIZ4mainE8CDerived = internal constant { ptr, ptr, ptr } { ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv120__si_class_type_infoE, i64 2), ptr @_ZTSZ4mainE8CDerived, ptr @_ZTI5CBase }, align 8
63+
@_ZTVN10__cxxabiv120__si_class_type_infoE = external global [0 x ptr]
64+
@_ZTSZ4mainE8CDerived = internal constant [17 x i8] c"Z4mainE8CDerived\00", align 1
65+
66+
define dso_local noundef i32 @main() #0 !dbg !10 {
67+
entry:
68+
%retval = alloca i32, align 4
69+
%Base = alloca %struct.CBase, align 8
70+
%Derived = alloca %struct.CDerived, align 8
71+
store i32 0, ptr %retval, align 4
72+
#dbg_declare(ptr %Base, !48, !DIExpression(), !51)
73+
call void @_ZN5CBaseC2Ev(ptr noundef nonnull align 8 dereferenceable(12) %Base), !dbg !51
74+
#dbg_declare(ptr %Derived, !52, !DIExpression(), !54)
75+
call void @_ZZ4mainEN8CDerivedC2Ev(ptr noundef nonnull align 8 dereferenceable(16) %Derived) , !dbg !54
76+
ret i32 0
77+
}
78+
79+
define linkonce_odr dso_local void @_ZN5CBaseC2Ev(ptr noundef nonnull align 8 dereferenceable(12) %this) unnamed_addr comdat align 2 {
80+
entry:
81+
ret void
82+
}
83+
84+
define internal void @_ZZ4mainEN8CDerivedC2Ev(ptr noundef nonnull align 8 dereferenceable(16) %this) unnamed_addr align 2 {
85+
entry:
86+
ret void
87+
}
88+
89+
define linkonce_odr dso_local void @_ZN5CBase4zeroEv(ptr noundef nonnull align 8 dereferenceable(12) %this) unnamed_addr comdat align 2 {
90+
entry:
91+
ret void
92+
}
93+
94+
define linkonce_odr dso_local noundef i32 @_ZN5CBase3oneEv(ptr noundef nonnull align 8 dereferenceable(12) %this) unnamed_addr comdat align 2 {
95+
entry:
96+
ret i32 1
97+
}
98+
99+
define internal void @_ZZ4mainEN8CDerived4zeroEv(ptr noundef nonnull align 8 dereferenceable(16) %this) unnamed_addr align 2 {
100+
entry:
101+
ret void
102+
}
103+
104+
define internal noundef i32 @_ZZ4mainEN8CDerived3oneEv(ptr noundef nonnull align 8 dereferenceable(16) %this) unnamed_addr align 2 {
105+
entry:
106+
ret i32 11
107+
}
108+
109+
attributes #0 = { mustprogress noinline norecurse nounwind uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
110+
111+
!llvm.dbg.cu = !{!2}
112+
!llvm.module.flags = !{!40, !41}
113+
114+
!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
115+
!1 = distinct !DIGlobalVariable(name: "_vtable$", linkageName: "_ZTV5CBase", scope: !2, file: !3, type: !7, isLocal: false, isDefinition: true, declaration: !39, align: 64)
116+
!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !3, emissionKind: FullDebug, globals: !4)
117+
!3 = !DIFile(filename: "vtable-debug-info-base-global-derived-local.cpp", directory: "")
118+
!4 = !{!0, !5}
119+
!5 = !DIGlobalVariableExpression(var: !6, expr: !DIExpression())
120+
!6 = distinct !DIGlobalVariable(name: "_vtable$", linkageName: "_ZTVZ4mainE8CDerived", scope: !2, file: !3, type: !7, isLocal: true, isDefinition: true, declaration: !8, align: 64)
121+
!7 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64)
122+
!8 = !DIDerivedType(tag: DW_TAG_variable, name: "_vtable$", scope: !9, file: !3, baseType: !7, flags: DIFlagPrivate | DIFlagArtificial | DIFlagStaticMember)
123+
!9 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "CDerived", scope: !10, file: !3, line: 9, size: 128, flags: DIFlagTypePassByReference | DIFlagNonTrivial, elements: !15, vtableHolder: !17)
124+
!10 = distinct !DISubprogram(name: "main", scope: !3, file: !3, line: 7, type: !11, scopeLine: 7, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !14)
125+
!11 = !DISubroutineType(types: !12)
126+
!12 = !{!13}
127+
!13 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
128+
!14 = !{}
129+
!15 = !{!16}
130+
!16 = !DIDerivedType(tag: DW_TAG_inheritance, scope: !9, baseType: !17, extraData: i32 0)
131+
!17 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "CBase", file: !3, line: 1, size: 128, flags: DIFlagTypePassByReference | DIFlagNonTrivial, elements: !18, vtableHolder: !17, identifier: "_ZTS5CBase")
132+
!18 = !{}
133+
!39 = !DIDerivedType(tag: DW_TAG_variable, name: "_vtable$", scope: !17, file: !3, baseType: !7, flags: DIFlagPrivate | DIFlagArtificial | DIFlagStaticMember)
134+
!40 = !{i32 7, !"Dwarf Version", i32 5}
135+
!41 = !{i32 2, !"Debug Info Version", i32 3}
136+
!48 = !DILocalVariable(name: "Base", scope: !49, file: !3, line: 16, type: !17)
137+
!49 = distinct !DILexicalBlock(scope: !50, file: !3, line: 15, column: 5)
138+
!50 = distinct !DILexicalBlock(scope: !10, file: !3, line: 8, column: 3)
139+
!51 = !DILocation(line: 16, column: 13, scope: !49)
140+
!52 = !DILocalVariable(name: "Derived", scope: !53, file: !3, line: 18, type: !9)
141+
!53 = distinct !DILexicalBlock(scope: !49, file: !3, line: 17, column: 7)
142+
!54 = !DILocation(line: 18, column: 18, scope: !53)
143+
144+
; CHECK: .debug_info contents:
145+
; CHECK-NEXT: 0x00000000: Compile Unit:
146+
; CHECK: {{.*}}DW_TAG_variable
147+
; CHECK-NEXT: DW_AT_specification ([[VARDIE_1:.+]] "_vtable$")
148+
; CHECK-NEXT: DW_AT_alignment (8)
149+
; CHECK-NEXT: DW_AT_location (DW_OP_addrx 0x0)
150+
; CHECK-NEXT: DW_AT_linkage_name ("_ZTV5CBase")
151+
152+
; CHECK: {{.*}}DW_TAG_structure_type
153+
; CHECK: DW_AT_name ("CBase")
154+
155+
; CHECK: [[VARDIE_1]]: DW_TAG_variable
156+
; CHECK-NEXT: DW_AT_name ("_vtable$")
157+
; CHECK-NEXT: DW_AT_type ({{.*}} "void *")
158+
; CHECK: DW_AT_artificial (true)
159+
; CHECK-NEXT: DW_AT_accessibility (DW_ACCESS_private)
160+
161+
; CHECK: {{.*}}DW_TAG_variable
162+
; CHECK-NEXT: DW_AT_specification ([[VARDIE_2:.+]] "_vtable$")
163+
; CHECK-NEXT: DW_AT_alignment (8)
164+
; CHECK-NEXT: DW_AT_location (DW_OP_addrx 0x1)
165+
; CHECK-NEXT: DW_AT_linkage_name ("_ZTVZ4mainE8CDerived")
166+
167+
; CHECK: {{.*}}DW_TAG_subprogram
168+
; CHECK-NEXT: DW_AT_low_pc
169+
; CHECK-NEXT: DW_AT_high_pc
170+
; CHECK-NEXT: DW_AT_frame_base
171+
; CHECK-NEXT: DW_AT_name ("main")
172+
173+
; CHECK: {{.*}}DW_TAG_structure_type
174+
; CHECK: DW_AT_name ("CDerived")
175+
176+
; CHECK: [[VARDIE_2]]: DW_TAG_variable
177+
; CHECK-NEXT: DW_AT_name ("_vtable$")
178+
; CHECK-NEXT: DW_AT_type ({{.*}} "void *")
179+
; CHECK: DW_AT_artificial (true)
180+
; CHECK-NEXT: DW_AT_accessibility (DW_ACCESS_private)
Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
; REQUIRES: target={{x86_64.*-linux.*}}
2+
; RUN: llc %s -o %t -filetype=obj
3+
; RUN: llvm-dwarfdump -debug-info %t | FileCheck %s
4+
5+
; Simple inheritance case:
6+
; CBase defined at function scope.
7+
; CDerived defined at function scope.
8+
; For CBase and CDerived we check:
9+
; - Generation of their vtables (including attributes).
10+
; - Generation of their '_vtable$' data members:
11+
; * Correct scope and attributes
12+
13+
; int main() {
14+
; {
15+
; struct CBase {
16+
; unsigned B = 1;
17+
; virtual void zero() {}
18+
; virtual int one() { return 1; }
19+
; };
20+
; {
21+
; struct CDerived : CBase {
22+
; unsigned D = 2;
23+
; void zero() override {}
24+
; int one() override { return 11; };
25+
; };
26+
;
27+
; {
28+
; CBase Base;
29+
; {
30+
; CDerived Derived;
31+
; }
32+
; }
33+
; }
34+
; }
35+
;
36+
; return 0;
37+
; }
38+
39+
source_filename = "vtable-debug-info-base-local-derived-local.cpp"
40+
target triple = "x86_64-pc-linux-gnu"
41+
42+
%struct.CBase = type <{ ptr, i32, [4 x i8] }>
43+
%struct.CDerived = type { %struct.CBase.base, i32 }
44+
%struct.CBase.base = type <{ ptr, i32 }>
45+
46+
@_ZTVZ4mainE5CBase = internal unnamed_addr constant { [4 x ptr] } { [4 x ptr] [ptr null, ptr @_ZTIZ4mainE5CBase, ptr @_ZZ4mainEN5CBase4zeroEv, ptr @_ZZ4mainEN5CBase3oneEv] }, align 8, !dbg !0
47+
@_ZTIZ4mainE5CBase = internal constant { ptr, ptr } { ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i64 2), ptr @_ZTSZ4mainE5CBase }, align 8
48+
@_ZTVN10__cxxabiv117__class_type_infoE = external global [0 x ptr]
49+
@_ZTSZ4mainE5CBase = internal constant [14 x i8] c"Z4mainE5CBase\00", align 1
50+
@_ZTVZ4mainE8CDerived = internal unnamed_addr constant { [4 x ptr] } { [4 x ptr] [ptr null, ptr @_ZTIZ4mainE8CDerived, ptr @_ZZ4mainEN8CDerived4zeroEv, ptr @_ZZ4mainEN8CDerived3oneEv] }, align 8, !dbg !5
51+
@_ZTIZ4mainE8CDerived = internal constant { ptr, ptr, ptr } { ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv120__si_class_type_infoE, i64 2), ptr @_ZTSZ4mainE8CDerived, ptr @_ZTIZ4mainE5CBase }, align 8
52+
@_ZTVN10__cxxabiv120__si_class_type_infoE = external global [0 x ptr]
53+
@_ZTSZ4mainE8CDerived = internal constant [17 x i8] c"Z4mainE8CDerived\00", align 1
54+
55+
define dso_local noundef i32 @main() #0 !dbg !10 {
56+
entry:
57+
%retval = alloca i32, align 4
58+
%Base = alloca %struct.CBase, align 8
59+
%Derived = alloca %struct.CDerived, align 8
60+
store i32 0, ptr %retval, align 4
61+
#dbg_declare(ptr %Base, !48, !DIExpression(), !52)
62+
call void @_ZZ4mainEN5CBaseC2Ev(ptr noundef nonnull align 8 dereferenceable(12) %Base) #2, !dbg !52
63+
#dbg_declare(ptr %Derived, !53, !DIExpression(), !55)
64+
call void @_ZZ4mainEN8CDerivedC2Ev(ptr noundef nonnull align 8 dereferenceable(16) %Derived) #2, !dbg !55
65+
ret i32 0
66+
}
67+
68+
define internal void @_ZZ4mainEN5CBaseC2Ev(ptr noundef nonnull align 8 dereferenceable(12) %this) unnamed_addr align 2 {
69+
entry:
70+
ret void
71+
}
72+
73+
define internal void @_ZZ4mainEN8CDerivedC2Ev(ptr noundef nonnull align 8 dereferenceable(16) %this) unnamed_addr align 2 {
74+
entry:
75+
ret void
76+
}
77+
78+
define internal void @_ZZ4mainEN5CBase4zeroEv(ptr noundef nonnull align 8 dereferenceable(12) %this) unnamed_addr align 2 {
79+
entry:
80+
ret void
81+
}
82+
83+
define internal noundef i32 @_ZZ4mainEN5CBase3oneEv(ptr noundef nonnull align 8 dereferenceable(12) %this) unnamed_addr align 2 {
84+
entry:
85+
ret i32 1
86+
}
87+
88+
define internal void @_ZZ4mainEN8CDerived4zeroEv(ptr noundef nonnull align 8 dereferenceable(16) %this) unnamed_addr align 2 {
89+
entry:
90+
ret void
91+
}
92+
93+
define internal noundef i32 @_ZZ4mainEN8CDerived3oneEv(ptr noundef nonnull align 8 dereferenceable(16) %this) unnamed_addr align 2 {
94+
entry:
95+
ret i32 11
96+
}
97+
98+
attributes #0 = { mustprogress noinline norecurse nounwind uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
99+
100+
!llvm.dbg.cu = !{!2}
101+
!llvm.module.flags = !{!40, !41}
102+
103+
!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
104+
!1 = distinct !DIGlobalVariable(name: "_vtable$", linkageName: "_ZTVZ4mainE5CBase", scope: !2, file: !3, type: !7, isLocal: true, isDefinition: true, declaration: !39, align: 64)
105+
!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !3, isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !4)
106+
!3 = !DIFile(filename: "vtable-debug-info-base-local-derived-local.cpp", directory: "")
107+
!4 = !{!0, !5}
108+
!5 = !DIGlobalVariableExpression(var: !6, expr: !DIExpression())
109+
!6 = distinct !DIGlobalVariable(name: "_vtable$", linkageName: "_ZTVZ4mainE8CDerived", scope: !2, file: !3, type: !7, isLocal: true, isDefinition: true, declaration: !8, align: 64)
110+
!7 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64)
111+
!8 = !DIDerivedType(tag: DW_TAG_variable, name: "_vtable$", scope: !9, file: !3, baseType: !7, flags: DIFlagPrivate | DIFlagArtificial | DIFlagStaticMember)
112+
!9 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "CDerived", scope: !10, file: !3, line: 9, size: 128, flags: DIFlagTypePassByReference | DIFlagNonTrivial, elements: !15, vtableHolder: !17)
113+
!10 = distinct !DISubprogram(name: "main", scope: !3, file: !3, line: 1, type: !11, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !14)
114+
!11 = !DISubroutineType(types: !12)
115+
!12 = !{!13}
116+
!13 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
117+
!14 = !{}
118+
!15 = !{!16}
119+
!16 = !DIDerivedType(tag: DW_TAG_inheritance, scope: !9, baseType: !17, extraData: i32 0)
120+
!17 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "CBase", scope: !10, file: !3, line: 3, size: 128, flags: DIFlagTypePassByReference | DIFlagNonTrivial, elements: !18, vtableHolder: !17)
121+
!18 = !{}
122+
!39 = !DIDerivedType(tag: DW_TAG_variable, name: "_vtable$", scope: !17, file: !3, baseType: !7, flags: DIFlagPrivate | DIFlagArtificial | DIFlagStaticMember)
123+
!40 = !{i32 7, !"Dwarf Version", i32 5}
124+
!41 = !{i32 2, !"Debug Info Version", i32 3}
125+
!48 = !DILocalVariable(name: "Base", scope: !49, file: !3, line: 16, type: !17)
126+
!49 = distinct !DILexicalBlock(scope: !50, file: !3, line: 15, column: 7)
127+
!50 = distinct !DILexicalBlock(scope: !51, file: !3, line: 8, column: 5)
128+
!51 = distinct !DILexicalBlock(scope: !10, file: !3, line: 2, column: 3)
129+
!52 = !DILocation(line: 16, column: 15, scope: !49)
130+
!53 = !DILocalVariable(name: "Derived", scope: !54, file: !3, line: 18, type: !9)
131+
!54 = distinct !DILexicalBlock(scope: !49, file: !3, line: 17, column: 9)
132+
!55 = !DILocation(line: 18, column: 20, scope: !54)
133+
134+
; CHECK: .debug_info contents:
135+
; CHECK-NEXT: 0x00000000: Compile Unit:
136+
137+
; CHECK: {{.*}}DW_TAG_variable
138+
; CHECK-NEXT: DW_AT_specification ([[VARDIE_1:.+]] "_vtable$")
139+
; CHECK-NEXT: DW_AT_alignment (8)
140+
; CHECK-NEXT: DW_AT_location (DW_OP_addrx 0x0)
141+
; CHECK-NEXT: DW_AT_linkage_name ("_ZTVZ4mainE5CBase")
142+
143+
; CHECK: {{.*}}DW_TAG_subprogram
144+
; CHECK-NEXT: DW_AT_low_pc
145+
; CHECK-NEXT: DW_AT_high_pc
146+
; CHECK-NEXT: DW_AT_frame_base
147+
; CHECK-NEXT: DW_AT_name ("main")
148+
149+
; CHECK: {{.*}}DW_TAG_structure_type
150+
; CHECK: DW_AT_name ("CBase")
151+
152+
; CHECK: [[VARDIE_1]]: DW_TAG_variable
153+
; CHECK-NEXT: DW_AT_name ("_vtable$")
154+
; CHECK-NEXT: DW_AT_type ({{.*}} "void *")
155+
; CHECK: DW_AT_artificial (true)
156+
; CHECK-NEXT: DW_AT_accessibility (DW_ACCESS_private)
157+
158+
; CHECK: {{.*}}DW_TAG_structure_type
159+
; CHECK: DW_AT_name ("CDerived")
160+
161+
; CHECK: [[VARDIE_2:.+]]: DW_TAG_variable
162+
; CHECK-NEXT: DW_AT_name ("_vtable$")
163+
; CHECK-NEXT: DW_AT_type ({{.*}} "void *")
164+
; CHECK: DW_AT_artificial (true)
165+
; CHECK-NEXT: DW_AT_accessibility (DW_ACCESS_private)
166+
167+
; CHECK: {{.*}}DW_TAG_lexical_block
168+
; CHECK-NEXT: DW_AT_low_pc
169+
170+
; CHECK: {{.*}}DW_TAG_variable
171+
; CHECK: DW_AT_name ("Base")
172+
173+
; CHECK: {{.*}}DW_TAG_lexical_block
174+
; CHECK-NEXT: DW_AT_low_pc
175+
176+
; CHECK: {{.*}}DW_TAG_variable
177+
; CHECK: DW_AT_name ("Derived")
178+
179+
; CHECK: {{.*}}DW_TAG_variable
180+
; CHECK-NEXT: DW_AT_specification ([[VARDIE_2]] "_vtable$")
181+
; CHECK-NEXT: DW_AT_alignment (8)
182+
; CHECK-NEXT: DW_AT_location (DW_OP_addrx 0x1)
183+
; CHECK-NEXT: DW_AT_linkage_name ("_ZTVZ4mainE8CDerived")

0 commit comments

Comments
 (0)