13
13
14
14
// --- methods.h
15
15
16
- struct A {
16
+ struct Base {
17
+ virtual void virt0 ();
18
+ };
19
+
20
+ struct A : Base {
17
21
int by_val () const { return n; }
18
22
int by_ref () { return n; }
23
+ virtual void virt1 ();
19
24
int n;
20
25
};
21
26
@@ -39,6 +44,17 @@ fn UseVal(a: Cpp.A*) -> i32 {
39
44
return a- > by_ref ();
40
45
}
41
46
47
+ // --- call_virtual.carbon
48
+
49
+ library "[[@TEST_NAME]]" ;
50
+
51
+ import Cpp library "methods.h" ;
52
+
53
+ fn UseVal (a: Cpp.A* ) {
54
+ a- > virt0 ();
55
+ a- > virt1 ();
56
+ }
57
+
42
58
// --- thunk.h
43
59
44
60
struct NeedThunk {
@@ -62,7 +78,8 @@ fn Call(n: Cpp.NeedThunk) {
62
78
// CHECK:STDOUT: target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
63
79
// CHECK:STDOUT: target triple = "x86_64-unknown-linux-gnu"
64
80
// CHECK:STDOUT:
65
- // CHECK:STDOUT: %struct.A = type { i32 }
81
+ // CHECK:STDOUT: %struct.A = type <{ %struct.Base, i32, [4 x i8] }>
82
+ // CHECK:STDOUT: %struct.Base = type { ptr }
66
83
// CHECK:STDOUT:
67
84
// CHECK:STDOUT: $_ZNK1A6by_valEv = comdat any
68
85
// CHECK:STDOUT:
@@ -73,13 +90,13 @@ fn Call(n: Cpp.NeedThunk) {
73
90
// CHECK:STDOUT: }
74
91
// CHECK:STDOUT:
75
92
// CHECK:STDOUT: ; Function Attrs: mustprogress noinline nounwind optnone
76
- // CHECK:STDOUT: define linkonce_odr dso_local i32 @_ZNK1A6by_valEv(ptr nonnull align 4 dereferenceable(4 ) %this) #0 comdat align 2 {
93
+ // CHECK:STDOUT: define linkonce_odr dso_local i32 @_ZNK1A6by_valEv(ptr nonnull align 8 dereferenceable(12 ) %this) #0 comdat align 2 {
77
94
// CHECK:STDOUT: entry:
78
95
// CHECK:STDOUT: %this.addr = alloca ptr, align 8
79
96
// CHECK:STDOUT: store ptr %this, ptr %this.addr, align 8
80
97
// CHECK:STDOUT: %this1 = load ptr, ptr %this.addr, align 8
81
- // CHECK:STDOUT: %n = getelementptr inbounds nuw %struct.A, ptr %this1, i32 0, i32 0
82
- // CHECK:STDOUT: %0 = load i32, ptr %n, align 4
98
+ // CHECK:STDOUT: %n = getelementptr inbounds nuw %struct.A, ptr %this1, i32 0, i32 1
99
+ // CHECK:STDOUT: %0 = load i32, ptr %n, align 8
83
100
// CHECK:STDOUT: ret i32 %0
84
101
// CHECK:STDOUT: }
85
102
// CHECK:STDOUT:
@@ -89,7 +106,7 @@ fn Call(n: Cpp.NeedThunk) {
89
106
// CHECK:STDOUT: %this.addr = alloca ptr, align 8
90
107
// CHECK:STDOUT: store ptr %this, ptr %this.addr, align 8
91
108
// CHECK:STDOUT: %0 = load ptr, ptr %this.addr, align 8
92
- // CHECK:STDOUT: %call = call i32 @_ZNK1A6by_valEv(ptr nonnull align 4 dereferenceable(4 ) %0)
109
+ // CHECK:STDOUT: %call = call i32 @_ZNK1A6by_valEv(ptr nonnull align 8 dereferenceable(12 ) %0)
93
110
// CHECK:STDOUT: ret i32 %call
94
111
// CHECK:STDOUT: }
95
112
// CHECK:STDOUT:
@@ -116,7 +133,8 @@ fn Call(n: Cpp.NeedThunk) {
116
133
// CHECK:STDOUT: target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
117
134
// CHECK:STDOUT: target triple = "x86_64-unknown-linux-gnu"
118
135
// CHECK:STDOUT:
119
- // CHECK:STDOUT: %struct.A = type { i32 }
136
+ // CHECK:STDOUT: %struct.A = type <{ %struct.Base, i32, [4 x i8] }>
137
+ // CHECK:STDOUT: %struct.Base = type { ptr }
120
138
// CHECK:STDOUT:
121
139
// CHECK:STDOUT: $_ZN1A6by_refEv = comdat any
122
140
// CHECK:STDOUT:
@@ -127,13 +145,13 @@ fn Call(n: Cpp.NeedThunk) {
127
145
// CHECK:STDOUT: }
128
146
// CHECK:STDOUT:
129
147
// CHECK:STDOUT: ; Function Attrs: mustprogress noinline nounwind optnone
130
- // CHECK:STDOUT: define linkonce_odr dso_local i32 @_ZN1A6by_refEv(ptr nonnull align 4 dereferenceable(4 ) %this) #0 comdat align 2 {
148
+ // CHECK:STDOUT: define linkonce_odr dso_local i32 @_ZN1A6by_refEv(ptr nonnull align 8 dereferenceable(12 ) %this) #0 comdat align 2 {
131
149
// CHECK:STDOUT: entry:
132
150
// CHECK:STDOUT: %this.addr = alloca ptr, align 8
133
151
// CHECK:STDOUT: store ptr %this, ptr %this.addr, align 8
134
152
// CHECK:STDOUT: %this1 = load ptr, ptr %this.addr, align 8
135
- // CHECK:STDOUT: %n = getelementptr inbounds nuw %struct.A, ptr %this1, i32 0, i32 0
136
- // CHECK:STDOUT: %0 = load i32, ptr %n, align 4
153
+ // CHECK:STDOUT: %n = getelementptr inbounds nuw %struct.A, ptr %this1, i32 0, i32 1
154
+ // CHECK:STDOUT: %0 = load i32, ptr %n, align 8
137
155
// CHECK:STDOUT: ret i32 %0
138
156
// CHECK:STDOUT: }
139
157
// CHECK:STDOUT:
@@ -154,6 +172,45 @@ fn Call(n: Cpp.NeedThunk) {
154
172
// CHECK:STDOUT: !9 = !{}
155
173
// CHECK:STDOUT: !10 = !DILocation(line: 7, column: 10, scope: !7)
156
174
// CHECK:STDOUT: !11 = !DILocation(line: 7, column: 3, scope: !7)
175
+ // CHECK:STDOUT: ; ModuleID = 'call_virtual.carbon'
176
+ // CHECK:STDOUT: source_filename = "call_virtual.carbon"
177
+ // CHECK:STDOUT: target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
178
+ // CHECK:STDOUT: target triple = "x86_64-unknown-linux-gnu"
179
+ // CHECK:STDOUT:
180
+ // CHECK:STDOUT: define void @_CUseVal.Main(ptr %a) !dbg !7 {
181
+ // CHECK:STDOUT: entry:
182
+ // CHECK:STDOUT: %.loc7_4.3.base = getelementptr inbounds nuw [16 x i8], ptr %a, i32 0, i32 0, !dbg !10
183
+ // CHECK:STDOUT: %Base.virt0.call.vtable = load ptr, ptr %.loc7_4.3.base, align 8, !dbg !10
184
+ // CHECK:STDOUT: %Base.virt0.call = getelementptr ptr, ptr %Base.virt0.call.vtable, i32 0, !dbg !10
185
+ // CHECK:STDOUT: %Base.virt0.call.memptr.virtualfn = load ptr, ptr %Base.virt0.call, align 8, !dbg !10
186
+ // CHECK:STDOUT: call void %Base.virt0.call.memptr.virtualfn(ptr %.loc7_4.3.base), !dbg !10
187
+ // CHECK:STDOUT: %A.virt1.call.vtable = load ptr, ptr %a, align 8, !dbg !11
188
+ // CHECK:STDOUT: %A.virt1.call = getelementptr ptr, ptr %A.virt1.call.vtable, i32 1, !dbg !11
189
+ // CHECK:STDOUT: %A.virt1.call.memptr.virtualfn = load ptr, ptr %A.virt1.call, align 8, !dbg !11
190
+ // CHECK:STDOUT: call void %A.virt1.call.memptr.virtualfn(ptr %a), !dbg !11
191
+ // CHECK:STDOUT: ret void, !dbg !12
192
+ // CHECK:STDOUT: }
193
+ // CHECK:STDOUT:
194
+ // CHECK:STDOUT: declare void @_ZN4Base5virt0Ev(ptr)
195
+ // CHECK:STDOUT:
196
+ // CHECK:STDOUT: declare void @_ZN1A5virt1Ev(ptr)
197
+ // CHECK:STDOUT:
198
+ // CHECK:STDOUT: !llvm.module.flags = !{!0, !1, !2, !3, !4}
199
+ // CHECK:STDOUT: !llvm.dbg.cu = !{!5}
200
+ // CHECK:STDOUT:
201
+ // CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
202
+ // CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
203
+ // CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4}
204
+ // CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 0}
205
+ // CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2}
206
+ // CHECK:STDOUT: !5 = distinct !DICompileUnit(language: DW_LANG_C, file: !6, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
207
+ // CHECK:STDOUT: !6 = !DIFile(filename: "call_virtual.carbon", directory: "")
208
+ // CHECK:STDOUT: !7 = distinct !DISubprogram(name: "UseVal", linkageName: "_CUseVal.Main", scope: null, file: !6, line: 6, type: !8, spFlags: DISPFlagDefinition, unit: !5)
209
+ // CHECK:STDOUT: !8 = !DISubroutineType(types: !9)
210
+ // CHECK:STDOUT: !9 = !{}
211
+ // CHECK:STDOUT: !10 = !DILocation(line: 7, column: 3, scope: !7)
212
+ // CHECK:STDOUT: !11 = !DILocation(line: 8, column: 3, scope: !7)
213
+ // CHECK:STDOUT: !12 = !DILocation(line: 6, column: 1, scope: !7)
157
214
// CHECK:STDOUT: ; ModuleID = 'call_thunk.carbon'
158
215
// CHECK:STDOUT: source_filename = "call_thunk.carbon"
159
216
// CHECK:STDOUT: target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
0 commit comments