xref: /llvm-project/llvm/test/DebugInfo/COFF/thunk.ll (revision 3a05e01d1a76984fe1532bd237edbbb7ed9db6ea)
1; RUN: llc < %s -filetype=obj | llvm-readobj - --codeview | FileCheck %s
2; RUN: llc < %s | FileCheck %s --check-prefix=ASM
3; RUN: opt -S -debugger-tune=lldb %s | FileCheck -check-prefix=OPT %s
4
5; Do the same for experimental debuginfo iterators.
6; RUN: llc --try-experimental-debuginfo-iterators < %s -filetype=obj | llvm-readobj - --codeview | FileCheck %s
7; RUN: llc --try-experimental-debuginfo-iterators < %s | FileCheck %s --check-prefix=ASM
8; RUN: opt --try-experimental-debuginfo-iterators -S -debugger-tune=lldb %s | FileCheck -check-prefix=OPT %s
9
10; -- "thunk.cpp" begin --------------------------------------------------------
11; class A { public: virtual bool MyMethod() { return true; } };
12; class B { public: virtual bool MyMethod() { return true; } };
13; class C : public virtual A, public virtual B {
14; public:
15;     virtual bool MyMethod() { return true; }
16; };
17;
18; int main()
19; {
20;     A* a = new C();
21;     B* b = new C();
22;     C* c = new C();
23;     a->MyMethod();
24;     b->MyMethod();
25;     c->MyMethod();
26;     bool (A::*mp)() = &A::MyMethod;
27;     return 0;
28; }
29; -- "thunk.cpp" end ----------------------------------------------------------
30;
31; Build command:
32;   $ clang -S -emit-llvm -g -gcodeview thunk.cpp
33;
34; CHECK:       Thunk32Sym {
35; CHECK-NEXT:    Kind: S_THUNK32 ({{.*}})
36; CHECK-NEXT:    Name: {{.*_9A.*}}
37; CHECK-NEXT:    Parent: 0
38; CHECK-NEXT:    End: 0
39; CHECK-NEXT:    Next: 0
40; CHECK-NEXT:    Off: 0
41; CHECK-NEXT:    Seg: 0
42; CHECK-NEXT:    Len: {{[0-9]+}}
43; CHECK-NEXT:    Ordinal: Standard (0x0)
44; CHECK-NEXT:  }
45; CHECK-NEXT:  ProcEnd {
46; CHECK-NEXT:    Kind: S_PROC_ID_END ({{.*}})
47; CHECK-NEXT:  }
48;
49; CHECK:       Thunk32Sym {
50; CHECK-NEXT:    Kind: S_THUNK32 ({{.*}})
51; CHECK-NEXT:    Name: {{.*MyMethod.*C.*}}
52; CHECK-NEXT:    Parent: 0
53; CHECK-NEXT:    End: 0
54; CHECK-NEXT:    Next: 0
55; CHECK-NEXT:    Off: 0
56; CHECK-NEXT:    Seg: 0
57; CHECK-NEXT:    Len: {{[0-9]+}}
58; CHECK-NEXT:    Ordinal: Standard (0x0)
59; CHECK-NEXT:  }
60; CHECK-NEXT:  ProcEnd {
61; CHECK-NEXT:    Kind: S_PROC_ID_END ({{.*}})
62; CHECK-NEXT:  }
63
64; ASM:        .long   241                     # Symbol subsection for [[NAME1:.*_9A.*]]
65; ASM-NEXT:   .long   {{.*}}                  # Subsection size
66; ASM-NEXT: {{L.*}}:
67; ASM-NEXT:   .short  [[END1:.?L.*]]-[[BEGIN1:.?L.*]]   # Record length
68; ASM-NEXT: [[BEGIN1]]:
69; ASM-NEXT:   .short  4354                    # Record kind: S_THUNK32
70; ASM-NEXT:   .long   0                       # PtrParent
71; ASM-NEXT:   .long   0                       # PtrEnd
72; ASM-NEXT:   .long   0                       # PtrNext
73; ASM-NEXT:   .secrel32 "[[NAME1]]"           # Thunk section relative address
74; ASM-NEXT:   .secidx "[[NAME1]]"             # Thunk section index
75; ASM-NEXT:   .short  Lfunc_end{{.*}}-"[[NAME1]]" # Code size
76; ASM-NEXT:   .byte   0                       # Ordinal
77; ASM-NEXT:   .asciz  "[[NAME1]]"             # Function name
78; ASM-NEXT:   .p2align 2
79; ASM-NEXT: [[END1]]:
80; ASM-NEXT:   .short  2                       # Record length
81; ASM-NEXT:   .short  4431                    # Record kind: S_PROC_ID_END
82;
83; ASM:        .long 241                       # Symbol subsection for [[NAME2:.*MyMethod.*C.*]]
84; ASM-NEXT:   .long {{.*}}                    # Subsection size
85; ASM-NEXT: {{L.*}}:
86; ASM-NEXT:   .short [[END2:.?L.*]]-[[BEGIN2:.?L.*]] # Record length
87; ASM-NEXT: [[BEGIN2]]:
88; ASM-NEXT:   .short 4354                     # Record kind: S_THUNK32
89; ASM-NEXT:   .long 0                         # PtrParent
90; ASM-NEXT:   .long 0                         # PtrEnd
91; ASM-NEXT:   .long 0                         # PtrNext
92; ASM-NEXT:   .secrel32 "[[NAME2]]"           # Thunk section relative address
93; ASM-NEXT:   .secidx   "[[NAME2]]"           # Thunk section index
94; ASM-NEXT:   .short Lfunc_end{{.*}}-"[[NAME2]]" # Code size
95; ASM-NEXT:   .byte 0                         # Ordinal
96; ASM-NEXT:   .asciz "[[NAME2]]"              # Function name
97; ASM-NEXT:   .p2align 2
98; ASM-NEXT: [[END2]]:
99; ASM-NEXT:   .short 2                        # Record length
100; ASM-NEXT:   .short 4431                     # Record kind: S_PROC_ID_END
101
102; OPT: DISubprogram(linkageName: "{{.*MyMethod.*C.*}}",{{.*}} line: 5,{{.*}} flags: DIFlagArtificial | DIFlagThunk{{.*}})
103
104
105; ModuleID = 'thunk.cpp'
106source_filename = "thunk.cpp"
107target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
108target triple = "i686-pc-windows-msvc19.0.24210"
109
110%rtti.CompleteObjectLocator = type { i32, i32, i32, ptr, ptr }
111%rtti.ClassHierarchyDescriptor = type { i32, i32, i32, ptr }
112%rtti.BaseClassDescriptor = type { ptr, i32, i32, i32, i32, i32, ptr }
113%rtti.TypeDescriptor7 = type { ptr, ptr, [8 x i8] }
114%class.A = type { ptr }
115%class.B = type { ptr }
116%class.C = type { ptr, %class.A, %class.B }
117
118$"\01??0C@@QAE@XZ" = comdat any
119
120$"\01??_9A@@$BA@AE" = comdat any
121
122$"\01??0A@@QAE@XZ" = comdat any
123
124$"\01??0B@@QAE@XZ" = comdat any
125
126$"\01?MyMethod@C@@UAE_NXZ" = comdat any
127
128$"\01?MyMethod@C@@W3AE_NXZ" = comdat any
129
130$"\01?MyMethod@A@@UAE_NXZ" = comdat any
131
132$"\01?MyMethod@B@@UAE_NXZ" = comdat any
133
134$"\01??_8C@@7B@" = comdat any
135
136$"\01??_7C@@6BA@@@" = comdat largest
137
138$"\01??_7C@@6BB@@@" = comdat largest
139
140$"\01??_R4C@@6BA@@@" = comdat any
141
142$"\01??_R0?AVC@@@8" = comdat any
143
144$"\01??_R3C@@8" = comdat any
145
146$"\01??_R2C@@8" = comdat any
147
148$"\01??_R1A@?0A@EA@C@@8" = comdat any
149
150$"\01??_R1A@A@3FA@A@@8" = comdat any
151
152$"\01??_R0?AVA@@@8" = comdat any
153
154$"\01??_R3A@@8" = comdat any
155
156$"\01??_R2A@@8" = comdat any
157
158$"\01??_R1A@?0A@EA@A@@8" = comdat any
159
160$"\01??_R1A@A@7FA@B@@8" = comdat any
161
162$"\01??_R0?AVB@@@8" = comdat any
163
164$"\01??_R3B@@8" = comdat any
165
166$"\01??_R2B@@8" = comdat any
167
168$"\01??_R1A@?0A@EA@B@@8" = comdat any
169
170$"\01??_R4C@@6BB@@@" = comdat any
171
172$"\01??_7A@@6B@" = comdat largest
173
174$"\01??_R4A@@6B@" = comdat any
175
176$"\01??_7B@@6B@" = comdat largest
177
178$"\01??_R4B@@6B@" = comdat any
179
180@"\01??_8C@@7B@" = linkonce_odr unnamed_addr constant [3 x i32] [i32 0, i32 4, i32 8], comdat
181@0 = private unnamed_addr constant { [2 x ptr] } { [2 x ptr] [ptr @"\01??_R4C@@6BA@@@", ptr @"\01?MyMethod@C@@UAE_NXZ"] }, comdat($"\01??_7C@@6BA@@@")
182@1 = private unnamed_addr constant { [2 x ptr] } { [2 x ptr] [ptr @"\01??_R4C@@6BB@@@", ptr @"\01?MyMethod@C@@W3AE_NXZ"] }, comdat($"\01??_7C@@6BB@@@")
183@"\01??_R4C@@6BA@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 4, i32 0, ptr @"\01??_R0?AVC@@@8", ptr @"\01??_R3C@@8" }, comdat
184@"\01??_7type_info@@6B@" = external constant ptr
185@"\01??_R0?AVC@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { ptr @"\01??_7type_info@@6B@", ptr null, [8 x i8] c".?AVC@@\00" }, comdat
186@"\01??_R3C@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 3, i32 3, ptr @"\01??_R2C@@8" }, comdat
187@"\01??_R2C@@8" = linkonce_odr constant [4 x ptr] [ptr @"\01??_R1A@?0A@EA@C@@8", ptr @"\01??_R1A@A@3FA@A@@8", ptr @"\01??_R1A@A@7FA@B@@8", ptr null], comdat
188@"\01??_R1A@?0A@EA@C@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { ptr @"\01??_R0?AVC@@@8", i32 2, i32 0, i32 -1, i32 0, i32 64, ptr @"\01??_R3C@@8" }, comdat
189@"\01??_R1A@A@3FA@A@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { ptr @"\01??_R0?AVA@@@8", i32 0, i32 0, i32 0, i32 4, i32 80, ptr @"\01??_R3A@@8" }, comdat
190@"\01??_R0?AVA@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { ptr @"\01??_7type_info@@6B@", ptr null, [8 x i8] c".?AVA@@\00" }, comdat
191@"\01??_R3A@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, ptr @"\01??_R2A@@8" }, comdat
192@"\01??_R2A@@8" = linkonce_odr constant [2 x ptr] [ptr @"\01??_R1A@?0A@EA@A@@8", ptr null], comdat
193@"\01??_R1A@?0A@EA@A@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { ptr @"\01??_R0?AVA@@@8", i32 0, i32 0, i32 -1, i32 0, i32 64, ptr @"\01??_R3A@@8" }, comdat
194@"\01??_R1A@A@7FA@B@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { ptr @"\01??_R0?AVB@@@8", i32 0, i32 0, i32 0, i32 8, i32 80, ptr @"\01??_R3B@@8" }, comdat
195@"\01??_R0?AVB@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { ptr @"\01??_7type_info@@6B@", ptr null, [8 x i8] c".?AVB@@\00" }, comdat
196@"\01??_R3B@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, ptr @"\01??_R2B@@8" }, comdat
197@"\01??_R2B@@8" = linkonce_odr constant [2 x ptr] [ptr @"\01??_R1A@?0A@EA@B@@8", ptr null], comdat
198@"\01??_R1A@?0A@EA@B@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { ptr @"\01??_R0?AVB@@@8", i32 0, i32 0, i32 -1, i32 0, i32 64, ptr @"\01??_R3B@@8" }, comdat
199@"\01??_R4C@@6BB@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 8, i32 0, ptr @"\01??_R0?AVC@@@8", ptr @"\01??_R3C@@8" }, comdat
200@2 = private unnamed_addr constant { [2 x ptr] } { [2 x ptr] [ptr @"\01??_R4A@@6B@", ptr @"\01?MyMethod@A@@UAE_NXZ"] }, comdat($"\01??_7A@@6B@")
201@"\01??_R4A@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 0, i32 0, ptr @"\01??_R0?AVA@@@8", ptr @"\01??_R3A@@8" }, comdat
202@3 = private unnamed_addr constant { [2 x ptr] } { [2 x ptr] [ptr @"\01??_R4B@@6B@", ptr @"\01?MyMethod@B@@UAE_NXZ"] }, comdat($"\01??_7B@@6B@")
203@"\01??_R4B@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 0, i32 0, ptr @"\01??_R0?AVB@@@8", ptr @"\01??_R3B@@8" }, comdat
204
205@"\01??_7C@@6BA@@@" = unnamed_addr alias ptr, getelementptr inbounds ({ [2 x ptr] }, ptr @0, i32 0, i32 0, i32 1)
206@"\01??_7C@@6BB@@@" = unnamed_addr alias ptr, getelementptr inbounds ({ [2 x ptr] }, ptr @1, i32 0, i32 0, i32 1)
207@"\01??_7A@@6B@" = unnamed_addr alias ptr, getelementptr inbounds ({ [2 x ptr] }, ptr @2, i32 0, i32 0, i32 1)
208@"\01??_7B@@6B@" = unnamed_addr alias ptr, getelementptr inbounds ({ [2 x ptr] }, ptr @3, i32 0, i32 0, i32 1)
209
210; Function Attrs: noinline norecurse optnone
211define i32 @main() #0 !dbg !8 {
212entry:
213  %retval = alloca i32, align 4
214  %a = alloca ptr, align 4
215  %b = alloca ptr, align 4
216  %c = alloca ptr, align 4
217  %mp = alloca ptr, align 4
218  store i32 0, ptr %retval, align 4
219  call void @llvm.dbg.declare(metadata ptr %a, metadata !12, metadata !DIExpression()), !dbg !24
220  %call = call ptr @"\01??2@YAPAXI@Z"(i32 12) #7, !dbg !25
221  %0 = bitcast ptr %call to ptr, !dbg !25
222  %1 = bitcast ptr %0 to ptr, !dbg !26
223  call void @llvm.memset.p0.i32(ptr align 8 %1, i8 0, i32 12, i1 false), !dbg !26
224  %call1 = call x86_thiscallcc ptr @"\01??0C@@QAE@XZ"(ptr %0, i32 1) #8, !dbg !26
225  %2 = icmp eq ptr %0, null, !dbg !25
226  br i1 %2, label %cast.end, label %cast.notnull, !dbg !25
227
228cast.notnull:                                     ; preds = %entry
229  %3 = bitcast ptr %0 to ptr, !dbg !25
230  %vbptr = getelementptr inbounds i8, ptr %3, i32 0, !dbg !25
231  %4 = bitcast ptr %vbptr to ptr, !dbg !25
232  %vbtable = load ptr, ptr %4, align 4, !dbg !25
233  %5 = getelementptr inbounds i32, ptr %vbtable, i32 1, !dbg !25
234  %vbase_offs = load i32, ptr %5, align 4, !dbg !25
235  %6 = add nsw i32 0, %vbase_offs, !dbg !25
236  %7 = bitcast ptr %0 to ptr, !dbg !25
237  %add.ptr = getelementptr inbounds i8, ptr %7, i32 %6, !dbg !25
238  %8 = bitcast ptr %add.ptr to ptr, !dbg !25
239  br label %cast.end, !dbg !25
240
241cast.end:                                         ; preds = %cast.notnull, %entry
242  %cast.result = phi ptr [ %8, %cast.notnull ], [ null, %entry ], !dbg !25
243  store ptr %cast.result, ptr %a, align 4, !dbg !24
244  call void @llvm.dbg.declare(metadata ptr %b, metadata !27, metadata !DIExpression()), !dbg !36
245  %call2 = call ptr @"\01??2@YAPAXI@Z"(i32 12) #7, !dbg !37
246  %9 = bitcast ptr %call2 to ptr, !dbg !37
247  %10 = bitcast ptr %9 to ptr, !dbg !38
248  call void @llvm.memset.p0.i32(ptr align 8 %10, i8 0, i32 12, i1 false), !dbg !38
249  %call3 = call x86_thiscallcc ptr @"\01??0C@@QAE@XZ"(ptr %9, i32 1) #8, !dbg !38
250  %11 = icmp eq ptr %9, null, !dbg !37
251  br i1 %11, label %cast.end9, label %cast.notnull4, !dbg !37
252
253cast.notnull4:                                    ; preds = %cast.end
254  %12 = bitcast ptr %9 to ptr, !dbg !37
255  %vbptr5 = getelementptr inbounds i8, ptr %12, i32 0, !dbg !37
256  %13 = bitcast ptr %vbptr5 to ptr, !dbg !37
257  %vbtable6 = load ptr, ptr %13, align 4, !dbg !37
258  %14 = getelementptr inbounds i32, ptr %vbtable6, i32 2, !dbg !37
259  %vbase_offs7 = load i32, ptr %14, align 4, !dbg !37
260  %15 = add nsw i32 0, %vbase_offs7, !dbg !37
261  %16 = bitcast ptr %9 to ptr, !dbg !37
262  %add.ptr8 = getelementptr inbounds i8, ptr %16, i32 %15, !dbg !37
263  %17 = bitcast ptr %add.ptr8 to ptr, !dbg !37
264  br label %cast.end9, !dbg !37
265
266cast.end9:                                        ; preds = %cast.notnull4, %cast.end
267  %cast.result10 = phi ptr [ %17, %cast.notnull4 ], [ null, %cast.end ], !dbg !37
268  store ptr %cast.result10, ptr %b, align 4, !dbg !36
269  call void @llvm.dbg.declare(metadata ptr %c, metadata !39, metadata !DIExpression()), !dbg !49
270  %call11 = call ptr @"\01??2@YAPAXI@Z"(i32 12) #7, !dbg !50
271  %18 = bitcast ptr %call11 to ptr, !dbg !50
272  %19 = bitcast ptr %18 to ptr, !dbg !51
273  call void @llvm.memset.p0.i32(ptr align 8 %19, i8 0, i32 12, i1 false), !dbg !51
274  %call12 = call x86_thiscallcc ptr @"\01??0C@@QAE@XZ"(ptr %18, i32 1) #8, !dbg !51
275  store ptr %18, ptr %c, align 4, !dbg !49
276  %20 = load ptr, ptr %a, align 4, !dbg !52
277  %21 = bitcast ptr %20 to ptr, !dbg !53
278  %vtable = load ptr, ptr %21, align 4, !dbg !53
279  %vfn = getelementptr inbounds ptr, ptr %vtable, i64 0, !dbg !53
280  %22 = load ptr, ptr %vfn, align 4, !dbg !53
281  %call13 = call x86_thiscallcc zeroext i1 %22(ptr %20), !dbg !53
282  %23 = load ptr, ptr %b, align 4, !dbg !54
283  %24 = bitcast ptr %23 to ptr, !dbg !55
284  %vtable14 = load ptr, ptr %24, align 4, !dbg !55
285  %vfn15 = getelementptr inbounds ptr, ptr %vtable14, i64 0, !dbg !55
286  %25 = load ptr, ptr %vfn15, align 4, !dbg !55
287  %call16 = call x86_thiscallcc zeroext i1 %25(ptr %23), !dbg !55
288  %26 = load ptr, ptr %c, align 4, !dbg !56
289  %27 = bitcast ptr %26 to ptr, !dbg !57
290  %vbptr17 = getelementptr inbounds i8, ptr %27, i32 0, !dbg !57
291  %28 = bitcast ptr %vbptr17 to ptr, !dbg !57
292  %vbtable18 = load ptr, ptr %28, align 4, !dbg !57
293  %29 = getelementptr inbounds i32, ptr %vbtable18, i32 1, !dbg !57
294  %vbase_offs19 = load i32, ptr %29, align 4, !dbg !57
295  %30 = add nsw i32 0, %vbase_offs19, !dbg !57
296  %31 = getelementptr inbounds i8, ptr %27, i32 %30, !dbg !57
297  %32 = bitcast ptr %26 to ptr, !dbg !57
298  %vbptr20 = getelementptr inbounds i8, ptr %32, i32 0, !dbg !57
299  %33 = bitcast ptr %vbptr20 to ptr, !dbg !57
300  %vbtable21 = load ptr, ptr %33, align 4, !dbg !57
301  %34 = getelementptr inbounds i32, ptr %vbtable21, i32 1, !dbg !57
302  %vbase_offs22 = load i32, ptr %34, align 4, !dbg !57
303  %35 = add nsw i32 0, %vbase_offs22, !dbg !57
304  %36 = getelementptr inbounds i8, ptr %32, i32 %35, !dbg !57
305  %37 = bitcast ptr %36 to ptr, !dbg !57
306  %vtable23 = load ptr, ptr %37, align 4, !dbg !57
307  %vfn24 = getelementptr inbounds ptr, ptr %vtable23, i64 0, !dbg !57
308  %38 = load ptr, ptr %vfn24, align 4, !dbg !57
309  %call25 = call x86_thiscallcc zeroext i1 %38(ptr %31), !dbg !57
310  call void @llvm.dbg.declare(metadata ptr %mp, metadata !58, metadata !DIExpression()), !dbg !60
311  store ptr @"\01??_9A@@$BA@AE", ptr %mp, align 4, !dbg !60
312  ret i32 0, !dbg !61
313}
314
315; Function Attrs: nounwind readnone speculatable
316declare void @llvm.dbg.declare(metadata, metadata, metadata) #1
317
318; Function Attrs: nobuiltin
319declare noalias ptr @"\01??2@YAPAXI@Z"(i32) #2
320
321; Function Attrs: argmemonly nounwind
322declare void @llvm.memset.p0.i32(ptr nocapture writeonly, i8, i32, i1) #3
323
324; Function Attrs: noinline nounwind optnone
325define linkonce_odr x86_thiscallcc ptr @"\01??0C@@QAE@XZ"(ptr returned %this, i32 %is_most_derived) unnamed_addr #4 comdat align 2 !dbg !62 {
326entry:
327  %retval = alloca ptr, align 4
328  %is_most_derived.addr = alloca i32, align 4
329  %this.addr = alloca ptr, align 4
330  store i32 %is_most_derived, ptr %is_most_derived.addr, align 4
331  call void @llvm.dbg.declare(metadata ptr %is_most_derived.addr, metadata !66, metadata !DIExpression()), !dbg !67
332  store ptr %this, ptr %this.addr, align 4
333  call void @llvm.dbg.declare(metadata ptr %this.addr, metadata !68, metadata !DIExpression()), !dbg !67
334  %this1 = load ptr, ptr %this.addr, align 4
335  store ptr %this1, ptr %retval, align 4
336  %is_most_derived2 = load i32, ptr %is_most_derived.addr, align 4
337  %is_complete_object = icmp ne i32 %is_most_derived2, 0, !dbg !69
338  br i1 %is_complete_object, label %ctor.init_vbases, label %ctor.skip_vbases, !dbg !69
339
340ctor.init_vbases:                                 ; preds = %entry
341  %this.int8 = bitcast ptr %this1 to ptr, !dbg !69
342  %0 = getelementptr inbounds i8, ptr %this.int8, i32 0, !dbg !69
343  %vbptr.C = bitcast ptr %0 to ptr, !dbg !69
344  store ptr @"\01??_8C@@7B@", ptr %vbptr.C, align 4, !dbg !69
345  %1 = bitcast ptr %this1 to ptr, !dbg !69
346  %2 = getelementptr inbounds i8, ptr %1, i32 4, !dbg !69
347  %3 = bitcast ptr %2 to ptr, !dbg !69
348  %call = call x86_thiscallcc ptr @"\01??0A@@QAE@XZ"(ptr %3) #8, !dbg !69
349  %4 = bitcast ptr %this1 to ptr, !dbg !69
350  %5 = getelementptr inbounds i8, ptr %4, i32 8, !dbg !69
351  %6 = bitcast ptr %5 to ptr, !dbg !69
352  %call3 = call x86_thiscallcc ptr @"\01??0B@@QAE@XZ"(ptr %6) #8, !dbg !69
353  br label %ctor.skip_vbases, !dbg !69
354
355ctor.skip_vbases:                                 ; preds = %ctor.init_vbases, %entry
356  %7 = bitcast ptr %this1 to ptr, !dbg !69
357  %vbptr = getelementptr inbounds i8, ptr %7, i32 0, !dbg !69
358  %8 = bitcast ptr %vbptr to ptr, !dbg !69
359  %vbtable = load ptr, ptr %8, align 4, !dbg !69
360  %9 = getelementptr inbounds i32, ptr %vbtable, i32 1, !dbg !69
361  %vbase_offs = load i32, ptr %9, align 4, !dbg !69
362  %10 = add nsw i32 0, %vbase_offs, !dbg !69
363  %11 = bitcast ptr %this1 to ptr, !dbg !69
364  %add.ptr = getelementptr inbounds i8, ptr %11, i32 %10, !dbg !69
365  %12 = bitcast ptr %add.ptr to ptr, !dbg !69
366  store ptr @"\01??_7C@@6BA@@@", ptr %12, align 4, !dbg !69
367  %13 = bitcast ptr %this1 to ptr, !dbg !69
368  %vbptr4 = getelementptr inbounds i8, ptr %13, i32 0, !dbg !69
369  %14 = bitcast ptr %vbptr4 to ptr, !dbg !69
370  %vbtable5 = load ptr, ptr %14, align 4, !dbg !69
371  %15 = getelementptr inbounds i32, ptr %vbtable5, i32 2, !dbg !69
372  %vbase_offs6 = load i32, ptr %15, align 4, !dbg !69
373  %16 = add nsw i32 0, %vbase_offs6, !dbg !69
374  %17 = bitcast ptr %this1 to ptr, !dbg !69
375  %add.ptr7 = getelementptr inbounds i8, ptr %17, i32 %16, !dbg !69
376  %18 = bitcast ptr %add.ptr7 to ptr, !dbg !69
377  store ptr @"\01??_7C@@6BB@@@", ptr %18, align 4, !dbg !69
378  %19 = load ptr, ptr %retval, align 4, !dbg !69
379  ret ptr %19, !dbg !69
380}
381
382; Function Attrs: noinline optnone
383define linkonce_odr x86_thiscallcc void @"\01??_9A@@$BA@AE"(ptr %this, ...) #5 comdat align 2 !dbg !70 {
384entry:
385  %this.addr = alloca ptr, align 4
386  store ptr %this, ptr %this.addr, align 4
387  call void @llvm.dbg.declare(metadata ptr %this.addr, metadata !72, metadata !DIExpression()), !dbg !73
388  %this1 = load ptr, ptr %this.addr, align 4
389  %0 = bitcast ptr %this1 to ptr
390  %vtable = load ptr, ptr %0, align 4
391  %vfn = getelementptr inbounds ptr, ptr %vtable, i64 0
392  %1 = load ptr, ptr %vfn, align 4
393  musttail call x86_thiscallcc void (ptr, ...) %1(ptr %this1, ...)
394  ret void
395                                                  ; No predecessors!
396  ret void
397}
398
399; Function Attrs: noinline nounwind optnone
400define linkonce_odr x86_thiscallcc ptr @"\01??0A@@QAE@XZ"(ptr returned %this) unnamed_addr #4 comdat align 2 !dbg !74 {
401entry:
402  %this.addr = alloca ptr, align 4
403  store ptr %this, ptr %this.addr, align 4
404  call void @llvm.dbg.declare(metadata ptr %this.addr, metadata !78, metadata !DIExpression()), !dbg !79
405  %this1 = load ptr, ptr %this.addr, align 4
406  %0 = bitcast ptr %this1 to ptr, !dbg !80
407  store ptr @"\01??_7A@@6B@", ptr %0, align 4, !dbg !80
408  ret ptr %this1, !dbg !80
409}
410
411; Function Attrs: noinline nounwind optnone
412define linkonce_odr x86_thiscallcc ptr @"\01??0B@@QAE@XZ"(ptr returned %this) unnamed_addr #4 comdat align 2 !dbg !81 {
413entry:
414  %this.addr = alloca ptr, align 4
415  store ptr %this, ptr %this.addr, align 4
416  call void @llvm.dbg.declare(metadata ptr %this.addr, metadata !85, metadata !DIExpression()), !dbg !86
417  %this1 = load ptr, ptr %this.addr, align 4
418  %0 = bitcast ptr %this1 to ptr, !dbg !87
419  store ptr @"\01??_7B@@6B@", ptr %0, align 4, !dbg !87
420  ret ptr %this1, !dbg !87
421}
422
423; Function Attrs: noinline nounwind optnone
424define linkonce_odr x86_thiscallcc zeroext i1 @"\01?MyMethod@C@@UAE_NXZ"(ptr %this.coerce) unnamed_addr #4 comdat align 2 !dbg !88 {
425entry:
426  %this = alloca ptr, align 4
427  %this.addr = alloca ptr, align 4
428  %coerce.val = bitcast ptr %this.coerce to ptr
429  store ptr %coerce.val, ptr %this, align 4
430  %this1 = load ptr, ptr %this, align 4
431  store ptr %this1, ptr %this.addr, align 4
432  call void @llvm.dbg.declare(metadata ptr %this.addr, metadata !89, metadata !DIExpression()), !dbg !90
433  %this2 = load ptr, ptr %this.addr, align 4
434  %0 = bitcast ptr %this2 to ptr
435  %1 = getelementptr inbounds i8, ptr %0, i32 -4
436  %this.adjusted = bitcast ptr %1 to ptr
437  ret i1 true, !dbg !91
438}
439
440; Function Attrs: noinline optnone
441define linkonce_odr x86_thiscallcc zeroext i1 @"\01?MyMethod@C@@W3AE_NXZ"(ptr %this.coerce) unnamed_addr #6 comdat align 2 !dbg !92 {
442entry:
443  %this = alloca ptr, align 4
444  %this.addr = alloca ptr, align 4
445  %coerce.val = bitcast ptr %this.coerce to ptr
446  store ptr %coerce.val, ptr %this, align 4
447  %this1 = load ptr, ptr %this, align 4
448  store ptr %this1, ptr %this.addr, align 4
449  call void @llvm.dbg.declare(metadata ptr %this.addr, metadata !93, metadata !DIExpression()), !dbg !94
450  %this2 = load ptr, ptr %this.addr, align 4, !dbg !94
451  %0 = bitcast ptr %this2 to ptr, !dbg !94
452  %1 = getelementptr i8, ptr %0, i32 -4, !dbg !94
453  %call = tail call x86_thiscallcc zeroext i1 @"\01?MyMethod@C@@UAE_NXZ"(ptr %1), !dbg !94
454  ret i1 %call, !dbg !94
455}
456
457; Function Attrs: noinline nounwind optnone
458define linkonce_odr x86_thiscallcc zeroext i1 @"\01?MyMethod@A@@UAE_NXZ"(ptr %this) unnamed_addr #4 comdat align 2 !dbg !95 {
459entry:
460  %this.addr = alloca ptr, align 4
461  store ptr %this, ptr %this.addr, align 4
462  call void @llvm.dbg.declare(metadata ptr %this.addr, metadata !96, metadata !DIExpression()), !dbg !97
463  %this1 = load ptr, ptr %this.addr, align 4
464  ret i1 true, !dbg !98
465}
466
467; Function Attrs: noinline nounwind optnone
468define linkonce_odr x86_thiscallcc zeroext i1 @"\01?MyMethod@B@@UAE_NXZ"(ptr %this) unnamed_addr #4 comdat align 2 !dbg !99 {
469entry:
470  %this.addr = alloca ptr, align 4
471  store ptr %this, ptr %this.addr, align 4
472  call void @llvm.dbg.declare(metadata ptr %this.addr, metadata !100, metadata !DIExpression()), !dbg !101
473  %this1 = load ptr, ptr %this.addr, align 4
474  ret i1 true, !dbg !102
475}
476
477attributes #0 = { noinline norecurse optnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "frame-pointer"="all" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="pentium4" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
478attributes #1 = { nounwind readnone speculatable }
479attributes #2 = { nobuiltin "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "frame-pointer"="all" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="pentium4" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
480attributes #3 = { argmemonly nounwind }
481attributes #4 = { noinline nounwind optnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "frame-pointer"="all" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="pentium4" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
482attributes #5 = { noinline optnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "frame-pointer"="all" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="pentium4" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "thunk" "unsafe-fp-math"="false" "use-soft-float"="false" }
483attributes #6 = { noinline optnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "frame-pointer"="all" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="pentium4" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
484attributes #7 = { builtin }
485attributes #8 = { nounwind }
486
487!llvm.dbg.cu = !{!0}
488!llvm.module.flags = !{!3, !4, !5, !6}
489!llvm.ident = !{!7}
490
491!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 7.0.0 (trunk)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
492!1 = !DIFile(filename: "thunk.cpp", directory: "C:\5Cpath\5Cto", checksumkind: CSK_MD5, checksum: "d4b977fc614313c5a4fbdc980b2f4243")
493!2 = !{}
494!3 = !{i32 1, !"NumRegisterParameters", i32 0}
495!4 = !{i32 2, !"CodeView", i32 1}
496!5 = !{i32 2, !"Debug Info Version", i32 3}
497!6 = !{i32 1, !"wchar_size", i32 2}
498!7 = !{!"clang version 7.0.0 (trunk)"}
499!8 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 8, type: !9, isLocal: false, isDefinition: true, scopeLine: 9, flags: DIFlagPrototyped, isOptimized: false, unit: !0, retainedNodes: !2)
500!9 = !DISubroutineType(types: !10)
501!10 = !{!11}
502!11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
503!12 = !DILocalVariable(name: "a", scope: !8, file: !1, line: 10, type: !13)
504!13 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !14, size: 32)
505!14 = distinct !DICompositeType(tag: DW_TAG_class_type, name: "A", file: !1, line: 1, size: 32, flags: DIFlagTypePassByValue, elements: !15, vtableHolder: !14, identifier: ".?AVA@@")
506!15 = !{!16, !17, !19}
507!16 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "__vtbl_ptr_type", baseType: null, size: 32)
508!17 = !DIDerivedType(tag: DW_TAG_member, name: "_vptr$A", scope: !1, file: !1, baseType: !18, size: 32, flags: DIFlagArtificial)
509!18 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !16, size: 32)
510!19 = !DISubprogram(name: "MyMethod", linkageName: "\01?MyMethod@A@@UAE_NXZ", scope: !14, file: !1, line: 1, type: !20, isLocal: false, isDefinition: false, scopeLine: 1, containingType: !14, virtuality: DW_VIRTUALITY_virtual, virtualIndex: 0, flags: DIFlagPublic | DIFlagPrototyped | DIFlagIntroducedVirtual, isOptimized: false)
511!20 = !DISubroutineType(cc: DW_CC_BORLAND_thiscall, types: !21)
512!21 = !{!22, !23}
513!22 = !DIBasicType(name: "bool", size: 8, encoding: DW_ATE_boolean)
514!23 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !14, size: 32, flags: DIFlagArtificial | DIFlagObjectPointer)
515!24 = !DILocation(line: 10, column: 8, scope: !8)
516!25 = !DILocation(line: 10, column: 12, scope: !8)
517!26 = !DILocation(line: 10, column: 16, scope: !8)
518!27 = !DILocalVariable(name: "b", scope: !8, file: !1, line: 11, type: !28)
519!28 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !29, size: 32)
520!29 = distinct !DICompositeType(tag: DW_TAG_class_type, name: "B", file: !1, line: 2, size: 32, flags: DIFlagTypePassByValue, elements: !30, vtableHolder: !29, identifier: ".?AVB@@")
521!30 = !{!16, !31, !32}
522!31 = !DIDerivedType(tag: DW_TAG_member, name: "_vptr$B", scope: !1, file: !1, baseType: !18, size: 32, flags: DIFlagArtificial)
523!32 = !DISubprogram(name: "MyMethod", linkageName: "\01?MyMethod@B@@UAE_NXZ", scope: !29, file: !1, line: 2, type: !33, isLocal: false, isDefinition: false, scopeLine: 2, containingType: !29, virtuality: DW_VIRTUALITY_virtual, virtualIndex: 0, flags: DIFlagPublic | DIFlagPrototyped | DIFlagIntroducedVirtual, isOptimized: false)
524!33 = !DISubroutineType(cc: DW_CC_BORLAND_thiscall, types: !34)
525!34 = !{!22, !35}
526!35 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !29, size: 32, flags: DIFlagArtificial | DIFlagObjectPointer)
527!36 = !DILocation(line: 11, column: 8, scope: !8)
528!37 = !DILocation(line: 11, column: 12, scope: !8)
529!38 = !DILocation(line: 11, column: 16, scope: !8)
530!39 = !DILocalVariable(name: "c", scope: !8, file: !1, line: 12, type: !40)
531!40 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !41, size: 32)
532!41 = distinct !DICompositeType(tag: DW_TAG_class_type, name: "C", file: !1, line: 3, size: 96, flags: DIFlagTypePassByValue, elements: !42, vtableHolder: !41, identifier: ".?AVC@@")
533!42 = !{!43, !44, !45}
534!43 = !DIDerivedType(tag: DW_TAG_inheritance, scope: !41, baseType: !14, offset: 4, flags: DIFlagPublic | DIFlagVirtual)
535!44 = !DIDerivedType(tag: DW_TAG_inheritance, scope: !41, baseType: !29, offset: 8, flags: DIFlagPublic | DIFlagVirtual)
536!45 = !DISubprogram(name: "MyMethod", linkageName: "\01?MyMethod@C@@UAE_NXZ", scope: !41, file: !1, line: 5, type: !46, isLocal: false, isDefinition: false, scopeLine: 5, containingType: !41, virtuality: DW_VIRTUALITY_virtual, virtualIndex: 0, thisAdjustment: 4, flags: DIFlagPublic | DIFlagPrototyped, isOptimized: false)
537!46 = !DISubroutineType(cc: DW_CC_BORLAND_thiscall, types: !47)
538!47 = !{!22, !48}
539!48 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !41, size: 32, flags: DIFlagArtificial | DIFlagObjectPointer)
540!49 = !DILocation(line: 12, column: 8, scope: !8)
541!50 = !DILocation(line: 12, column: 12, scope: !8)
542!51 = !DILocation(line: 12, column: 16, scope: !8)
543!52 = !DILocation(line: 13, column: 5, scope: !8)
544!53 = !DILocation(line: 13, column: 8, scope: !8)
545!54 = !DILocation(line: 14, column: 5, scope: !8)
546!55 = !DILocation(line: 14, column: 8, scope: !8)
547!56 = !DILocation(line: 15, column: 5, scope: !8)
548!57 = !DILocation(line: 15, column: 8, scope: !8)
549!58 = !DILocalVariable(name: "mp", scope: !8, file: !1, line: 16, type: !59)
550!59 = !DIDerivedType(tag: DW_TAG_ptr_to_member_type, baseType: !20, size: 32, flags: DIFlagSingleInheritance, extraData: !14)
551!60 = !DILocation(line: 16, column: 15, scope: !8)
552!61 = !DILocation(line: 17, column: 5, scope: !8)
553!62 = distinct !DISubprogram(name: "C", linkageName: "\01??0C@@QAE@XZ", scope: !41, file: !1, line: 3, type: !63, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagArtificial | DIFlagPrototyped, isOptimized: false, unit: !0, declaration: !65, retainedNodes: !2)
554!63 = !DISubroutineType(cc: DW_CC_BORLAND_thiscall, types: !64)
555!64 = !{null, !48}
556!65 = !DISubprogram(name: "C", scope: !41, type: !63, isLocal: false, isDefinition: false, flags: DIFlagPublic | DIFlagArtificial | DIFlagPrototyped, isOptimized: false)
557!66 = !DILocalVariable(name: "is_most_derived", arg: 2, scope: !62, type: !11, flags: DIFlagArtificial)
558!67 = !DILocation(line: 0, scope: !62)
559!68 = !DILocalVariable(name: "this", arg: 1, scope: !62, type: !40, flags: DIFlagArtificial | DIFlagObjectPointer)
560!69 = !DILocation(line: 3, column: 7, scope: !62)
561!70 = distinct !DISubprogram(linkageName: "\01??_9A@@$BA@AE", scope: !1, file: !1, line: 1, type: !71, isLocal: false, isDefinition: true, flags: DIFlagArtificial | DIFlagThunk, isOptimized: false, unit: !0, retainedNodes: !2)
562!71 = !DISubroutineType(types: !2)
563!72 = !DILocalVariable(name: "this", arg: 1, scope: !70, type: !13, flags: DIFlagArtificial | DIFlagObjectPointer)
564!73 = !DILocation(line: 0, scope: !70)
565!74 = distinct !DISubprogram(name: "A", linkageName: "\01??0A@@QAE@XZ", scope: !14, file: !1, line: 1, type: !75, isLocal: false, isDefinition: true, scopeLine: 1, flags: DIFlagArtificial | DIFlagPrototyped, isOptimized: false, unit: !0, declaration: !77, retainedNodes: !2)
566!75 = !DISubroutineType(cc: DW_CC_BORLAND_thiscall, types: !76)
567!76 = !{null, !23}
568!77 = !DISubprogram(name: "A", scope: !14, type: !75, isLocal: false, isDefinition: false, flags: DIFlagPublic | DIFlagArtificial | DIFlagPrototyped, isOptimized: false)
569!78 = !DILocalVariable(name: "this", arg: 1, scope: !74, type: !13, flags: DIFlagArtificial | DIFlagObjectPointer)
570!79 = !DILocation(line: 0, scope: !74)
571!80 = !DILocation(line: 1, column: 7, scope: !74)
572!81 = distinct !DISubprogram(name: "B", linkageName: "\01??0B@@QAE@XZ", scope: !29, file: !1, line: 2, type: !82, isLocal: false, isDefinition: true, scopeLine: 2, flags: DIFlagArtificial | DIFlagPrototyped, isOptimized: false, unit: !0, declaration: !84, retainedNodes: !2)
573!82 = !DISubroutineType(cc: DW_CC_BORLAND_thiscall, types: !83)
574!83 = !{null, !35}
575!84 = !DISubprogram(name: "B", scope: !29, type: !82, isLocal: false, isDefinition: false, flags: DIFlagPublic | DIFlagArtificial | DIFlagPrototyped, isOptimized: false)
576!85 = !DILocalVariable(name: "this", arg: 1, scope: !81, type: !28, flags: DIFlagArtificial | DIFlagObjectPointer)
577!86 = !DILocation(line: 0, scope: !81)
578!87 = !DILocation(line: 2, column: 7, scope: !81)
579!88 = distinct !DISubprogram(name: "MyMethod", linkageName: "\01?MyMethod@C@@UAE_NXZ", scope: !41, file: !1, line: 5, type: !46, isLocal: false, isDefinition: true, scopeLine: 5, flags: DIFlagPrototyped, isOptimized: false, unit: !0, declaration: !45, retainedNodes: !2)
580!89 = !DILocalVariable(name: "this", arg: 1, scope: !88, type: !40, flags: DIFlagArtificial | DIFlagObjectPointer)
581!90 = !DILocation(line: 0, scope: !88)
582!91 = !DILocation(line: 5, column: 31, scope: !88)
583!92 = distinct !DISubprogram(linkageName: "\01?MyMethod@C@@W3AE_NXZ", scope: !1, file: !1, line: 5, type: !71, isLocal: false, isDefinition: true, flags: DIFlagArtificial | DIFlagThunk, isOptimized: false, unit: !0, retainedNodes: !2)
584!93 = !DILocalVariable(name: "this", arg: 1, scope: !92, type: !40, flags: DIFlagArtificial | DIFlagObjectPointer)
585!94 = !DILocation(line: 0, scope: !92)
586!95 = distinct !DISubprogram(name: "MyMethod", linkageName: "\01?MyMethod@A@@UAE_NXZ", scope: !14, file: !1, line: 1, type: !20, isLocal: false, isDefinition: true, scopeLine: 1, flags: DIFlagPrototyped, isOptimized: false, unit: !0, declaration: !19, retainedNodes: !2)
587!96 = !DILocalVariable(name: "this", arg: 1, scope: !95, type: !13, flags: DIFlagArtificial | DIFlagObjectPointer)
588!97 = !DILocation(line: 0, scope: !95)
589!98 = !DILocation(line: 1, column: 45, scope: !95)
590!99 = distinct !DISubprogram(name: "MyMethod", linkageName: "\01?MyMethod@B@@UAE_NXZ", scope: !29, file: !1, line: 2, type: !33, isLocal: false, isDefinition: true, scopeLine: 2, flags: DIFlagPrototyped, isOptimized: false, unit: !0, declaration: !32, retainedNodes: !2)
591!100 = !DILocalVariable(name: "this", arg: 1, scope: !99, type: !28, flags: DIFlagArtificial | DIFlagObjectPointer)
592!101 = !DILocation(line: 0, scope: !99)
593!102 = !DILocation(line: 2, column: 45, scope: !99)
594