589 lines · plain
1; RUN: llc < %s -filetype=obj | llvm-readobj - --codeview | FileCheck %s2; RUN: llc < %s | FileCheck %s --check-prefix=ASM3; RUN: opt -S -debugger-tune=lldb %s | FileCheck -check-prefix=OPT %s4 5; -- "thunk.cpp" begin --------------------------------------------------------6; class A { public: virtual bool MyMethod() { return true; } }; 7; class B { public: virtual bool MyMethod() { return true; } }; 8; class C : public virtual A, public virtual B { 9; public: 10; virtual bool MyMethod() { return true; } 11; }; 12; 13; int main() 14; { 15; A* a = new C(); 16; B* b = new C(); 17; C* c = new C(); 18; a->MyMethod();19; b->MyMethod();20; c->MyMethod();21; bool (A::*mp)() = &A::MyMethod;22; return 0;23; } 24; -- "thunk.cpp" end ----------------------------------------------------------25;26; Build command:27; $ clang -S -emit-llvm -g -gcodeview thunk.cpp28;29; CHECK: Thunk32Sym {30; CHECK-NEXT: Kind: S_THUNK32 ({{.*}})31; CHECK-NEXT: Name: {{.*_9A.*}}32; CHECK-NEXT: Parent: 033; CHECK-NEXT: End: 034; CHECK-NEXT: Next: 035; CHECK-NEXT: Off: 036; CHECK-NEXT: Seg: 037; CHECK-NEXT: Len: {{[0-9]+}}38; CHECK-NEXT: Ordinal: Standard (0x0)39; CHECK-NEXT: }40; CHECK-NEXT: ProcEnd {41; CHECK-NEXT: Kind: S_PROC_ID_END ({{.*}})42; CHECK-NEXT: }43;44; CHECK: Thunk32Sym {45; CHECK-NEXT: Kind: S_THUNK32 ({{.*}})46; CHECK-NEXT: Name: {{.*MyMethod.*C.*}}47; CHECK-NEXT: Parent: 048; CHECK-NEXT: End: 049; CHECK-NEXT: Next: 050; CHECK-NEXT: Off: 051; CHECK-NEXT: Seg: 052; CHECK-NEXT: Len: {{[0-9]+}}53; CHECK-NEXT: Ordinal: Standard (0x0)54; CHECK-NEXT: }55; CHECK-NEXT: ProcEnd {56; CHECK-NEXT: Kind: S_PROC_ID_END ({{.*}})57; CHECK-NEXT: }58 59; ASM: .long 241 # Symbol subsection for [[NAME1:.*_9A.*]]60; ASM-NEXT: .long {{.*}} # Subsection size 61; ASM-NEXT: {{L.*}}:62; ASM-NEXT: .short [[END1:.?L.*]]-[[BEGIN1:.?L.*]] # Record length 63; ASM-NEXT: [[BEGIN1]]:64; ASM-NEXT: .short 4354 # Record kind: S_THUNK32 65; ASM-NEXT: .long 0 # PtrParent 66; ASM-NEXT: .long 0 # PtrEnd 67; ASM-NEXT: .long 0 # PtrNext 68; ASM-NEXT: .secrel32 "[[NAME1]]" # Thunk section relative address 69; ASM-NEXT: .secidx "[[NAME1]]" # Thunk section index 70; ASM-NEXT: .short Lfunc_end{{.*}}-"[[NAME1]]" # Code size 71; ASM-NEXT: .byte 0 # Ordinal 72; ASM-NEXT: .asciz "[[NAME1]]" # Function name 73; ASM-NEXT: .p2align 274; ASM-NEXT: [[END1]]:75; ASM-NEXT: .short 2 # Record length 76; ASM-NEXT: .short 4431 # Record kind: S_PROC_ID_END 77;78; ASM: .long 241 # Symbol subsection for [[NAME2:.*MyMethod.*C.*]]79; ASM-NEXT: .long {{.*}} # Subsection size80; ASM-NEXT: {{L.*}}:81; ASM-NEXT: .short [[END2:.?L.*]]-[[BEGIN2:.?L.*]] # Record length82; ASM-NEXT: [[BEGIN2]]:83; ASM-NEXT: .short 4354 # Record kind: S_THUNK3284; ASM-NEXT: .long 0 # PtrParent85; ASM-NEXT: .long 0 # PtrEnd86; ASM-NEXT: .long 0 # PtrNext87; ASM-NEXT: .secrel32 "[[NAME2]]" # Thunk section relative address88; ASM-NEXT: .secidx "[[NAME2]]" # Thunk section index89; ASM-NEXT: .short Lfunc_end{{.*}}-"[[NAME2]]" # Code size90; ASM-NEXT: .byte 0 # Ordinal91; ASM-NEXT: .asciz "[[NAME2]]" # Function name92; ASM-NEXT: .p2align 293; ASM-NEXT: [[END2]]:94; ASM-NEXT: .short 2 # Record length95; ASM-NEXT: .short 4431 # Record kind: S_PROC_ID_END 96 97; OPT: DISubprogram(linkageName: "{{.*MyMethod.*C.*}}",{{.*}} line: 5,{{.*}} flags: DIFlagArtificial | DIFlagThunk{{.*}})98 99 100; ModuleID = 'thunk.cpp'101source_filename = "thunk.cpp"102target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"103target triple = "i686-pc-windows-msvc19.0.24210"104 105%rtti.CompleteObjectLocator = type { i32, i32, i32, ptr, ptr }106%rtti.ClassHierarchyDescriptor = type { i32, i32, i32, ptr }107%rtti.BaseClassDescriptor = type { ptr, i32, i32, i32, i32, i32, ptr }108%rtti.TypeDescriptor7 = type { ptr, ptr, [8 x i8] }109%class.A = type { ptr }110%class.B = type { ptr }111%class.C = type { ptr, %class.A, %class.B }112 113$"\01??0C@@QAE@XZ" = comdat any114 115$"\01??_9A@@$BA@AE" = comdat any116 117$"\01??0A@@QAE@XZ" = comdat any118 119$"\01??0B@@QAE@XZ" = comdat any120 121$"\01?MyMethod@C@@UAE_NXZ" = comdat any122 123$"\01?MyMethod@C@@W3AE_NXZ" = comdat any124 125$"\01?MyMethod@A@@UAE_NXZ" = comdat any126 127$"\01?MyMethod@B@@UAE_NXZ" = comdat any128 129$"\01??_8C@@7B@" = comdat any130 131$"\01??_7C@@6BA@@@" = comdat largest132 133$"\01??_7C@@6BB@@@" = comdat largest134 135$"\01??_R4C@@6BA@@@" = comdat any136 137$"\01??_R0?AVC@@@8" = comdat any138 139$"\01??_R3C@@8" = comdat any140 141$"\01??_R2C@@8" = comdat any142 143$"\01??_R1A@?0A@EA@C@@8" = comdat any144 145$"\01??_R1A@A@3FA@A@@8" = comdat any146 147$"\01??_R0?AVA@@@8" = comdat any148 149$"\01??_R3A@@8" = comdat any150 151$"\01??_R2A@@8" = comdat any152 153$"\01??_R1A@?0A@EA@A@@8" = comdat any154 155$"\01??_R1A@A@7FA@B@@8" = comdat any156 157$"\01??_R0?AVB@@@8" = comdat any158 159$"\01??_R3B@@8" = comdat any160 161$"\01??_R2B@@8" = comdat any162 163$"\01??_R1A@?0A@EA@B@@8" = comdat any164 165$"\01??_R4C@@6BB@@@" = comdat any166 167$"\01??_7A@@6B@" = comdat largest168 169$"\01??_R4A@@6B@" = comdat any170 171$"\01??_7B@@6B@" = comdat largest172 173$"\01??_R4B@@6B@" = comdat any174 175@"\01??_8C@@7B@" = linkonce_odr unnamed_addr constant [3 x i32] [i32 0, i32 4, i32 8], comdat176@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@@@")177@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@@@")178@"\01??_R4C@@6BA@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 4, i32 0, ptr @"\01??_R0?AVC@@@8", ptr @"\01??_R3C@@8" }, comdat179@"\01??_7type_info@@6B@" = external constant ptr180@"\01??_R0?AVC@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { ptr @"\01??_7type_info@@6B@", ptr null, [8 x i8] c".?AVC@@\00" }, comdat181@"\01??_R3C@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 3, i32 3, ptr @"\01??_R2C@@8" }, comdat182@"\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], comdat183@"\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" }, comdat184@"\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" }, comdat185@"\01??_R0?AVA@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { ptr @"\01??_7type_info@@6B@", ptr null, [8 x i8] c".?AVA@@\00" }, comdat186@"\01??_R3A@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, ptr @"\01??_R2A@@8" }, comdat187@"\01??_R2A@@8" = linkonce_odr constant [2 x ptr] [ptr @"\01??_R1A@?0A@EA@A@@8", ptr null], comdat188@"\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" }, comdat189@"\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" }, comdat190@"\01??_R0?AVB@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { ptr @"\01??_7type_info@@6B@", ptr null, [8 x i8] c".?AVB@@\00" }, comdat191@"\01??_R3B@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, ptr @"\01??_R2B@@8" }, comdat192@"\01??_R2B@@8" = linkonce_odr constant [2 x ptr] [ptr @"\01??_R1A@?0A@EA@B@@8", ptr null], comdat193@"\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" }, comdat194@"\01??_R4C@@6BB@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 8, i32 0, ptr @"\01??_R0?AVC@@@8", ptr @"\01??_R3C@@8" }, comdat195@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@")196@"\01??_R4A@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 0, i32 0, ptr @"\01??_R0?AVA@@@8", ptr @"\01??_R3A@@8" }, comdat197@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@")198@"\01??_R4B@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 0, i32 0, ptr @"\01??_R0?AVB@@@8", ptr @"\01??_R3B@@8" }, comdat199 200@"\01??_7C@@6BA@@@" = unnamed_addr alias ptr, getelementptr inbounds ({ [2 x ptr] }, ptr @0, i32 0, i32 0, i32 1)201@"\01??_7C@@6BB@@@" = unnamed_addr alias ptr, getelementptr inbounds ({ [2 x ptr] }, ptr @1, i32 0, i32 0, i32 1)202@"\01??_7A@@6B@" = unnamed_addr alias ptr, getelementptr inbounds ({ [2 x ptr] }, ptr @2, i32 0, i32 0, i32 1)203@"\01??_7B@@6B@" = unnamed_addr alias ptr, getelementptr inbounds ({ [2 x ptr] }, ptr @3, i32 0, i32 0, i32 1)204 205; Function Attrs: noinline norecurse optnone206define i32 @main() #0 !dbg !8 {207entry:208 %retval = alloca i32, align 4209 %a = alloca ptr, align 4210 %b = alloca ptr, align 4211 %c = alloca ptr, align 4212 %mp = alloca ptr, align 4213 store i32 0, ptr %retval, align 4214 call void @llvm.dbg.declare(metadata ptr %a, metadata !12, metadata !DIExpression()), !dbg !24215 %call = call ptr @"\01??2@YAPAXI@Z"(i32 12) #7, !dbg !25216 %0 = bitcast ptr %call to ptr, !dbg !25217 %1 = bitcast ptr %0 to ptr, !dbg !26218 call void @llvm.memset.p0.i32(ptr align 8 %1, i8 0, i32 12, i1 false), !dbg !26219 %call1 = call x86_thiscallcc ptr @"\01??0C@@QAE@XZ"(ptr %0, i32 1) #8, !dbg !26220 %2 = icmp eq ptr %0, null, !dbg !25221 br i1 %2, label %cast.end, label %cast.notnull, !dbg !25222 223cast.notnull: ; preds = %entry224 %3 = bitcast ptr %0 to ptr, !dbg !25225 %vbptr = getelementptr inbounds i8, ptr %3, i32 0, !dbg !25226 %4 = bitcast ptr %vbptr to ptr, !dbg !25227 %vbtable = load ptr, ptr %4, align 4, !dbg !25228 %5 = getelementptr inbounds i32, ptr %vbtable, i32 1, !dbg !25229 %vbase_offs = load i32, ptr %5, align 4, !dbg !25230 %6 = add nsw i32 0, %vbase_offs, !dbg !25231 %7 = bitcast ptr %0 to ptr, !dbg !25232 %add.ptr = getelementptr inbounds i8, ptr %7, i32 %6, !dbg !25233 %8 = bitcast ptr %add.ptr to ptr, !dbg !25234 br label %cast.end, !dbg !25235 236cast.end: ; preds = %cast.notnull, %entry237 %cast.result = phi ptr [ %8, %cast.notnull ], [ null, %entry ], !dbg !25238 store ptr %cast.result, ptr %a, align 4, !dbg !24239 call void @llvm.dbg.declare(metadata ptr %b, metadata !27, metadata !DIExpression()), !dbg !36240 %call2 = call ptr @"\01??2@YAPAXI@Z"(i32 12) #7, !dbg !37241 %9 = bitcast ptr %call2 to ptr, !dbg !37242 %10 = bitcast ptr %9 to ptr, !dbg !38243 call void @llvm.memset.p0.i32(ptr align 8 %10, i8 0, i32 12, i1 false), !dbg !38244 %call3 = call x86_thiscallcc ptr @"\01??0C@@QAE@XZ"(ptr %9, i32 1) #8, !dbg !38245 %11 = icmp eq ptr %9, null, !dbg !37246 br i1 %11, label %cast.end9, label %cast.notnull4, !dbg !37247 248cast.notnull4: ; preds = %cast.end249 %12 = bitcast ptr %9 to ptr, !dbg !37250 %vbptr5 = getelementptr inbounds i8, ptr %12, i32 0, !dbg !37251 %13 = bitcast ptr %vbptr5 to ptr, !dbg !37252 %vbtable6 = load ptr, ptr %13, align 4, !dbg !37253 %14 = getelementptr inbounds i32, ptr %vbtable6, i32 2, !dbg !37254 %vbase_offs7 = load i32, ptr %14, align 4, !dbg !37255 %15 = add nsw i32 0, %vbase_offs7, !dbg !37256 %16 = bitcast ptr %9 to ptr, !dbg !37257 %add.ptr8 = getelementptr inbounds i8, ptr %16, i32 %15, !dbg !37258 %17 = bitcast ptr %add.ptr8 to ptr, !dbg !37259 br label %cast.end9, !dbg !37260 261cast.end9: ; preds = %cast.notnull4, %cast.end262 %cast.result10 = phi ptr [ %17, %cast.notnull4 ], [ null, %cast.end ], !dbg !37263 store ptr %cast.result10, ptr %b, align 4, !dbg !36264 call void @llvm.dbg.declare(metadata ptr %c, metadata !39, metadata !DIExpression()), !dbg !49265 %call11 = call ptr @"\01??2@YAPAXI@Z"(i32 12) #7, !dbg !50266 %18 = bitcast ptr %call11 to ptr, !dbg !50267 %19 = bitcast ptr %18 to ptr, !dbg !51268 call void @llvm.memset.p0.i32(ptr align 8 %19, i8 0, i32 12, i1 false), !dbg !51269 %call12 = call x86_thiscallcc ptr @"\01??0C@@QAE@XZ"(ptr %18, i32 1) #8, !dbg !51270 store ptr %18, ptr %c, align 4, !dbg !49271 %20 = load ptr, ptr %a, align 4, !dbg !52272 %21 = bitcast ptr %20 to ptr, !dbg !53273 %vtable = load ptr, ptr %21, align 4, !dbg !53274 %vfn = getelementptr inbounds ptr, ptr %vtable, i64 0, !dbg !53275 %22 = load ptr, ptr %vfn, align 4, !dbg !53276 %call13 = call x86_thiscallcc zeroext i1 %22(ptr %20), !dbg !53277 %23 = load ptr, ptr %b, align 4, !dbg !54278 %24 = bitcast ptr %23 to ptr, !dbg !55279 %vtable14 = load ptr, ptr %24, align 4, !dbg !55280 %vfn15 = getelementptr inbounds ptr, ptr %vtable14, i64 0, !dbg !55281 %25 = load ptr, ptr %vfn15, align 4, !dbg !55282 %call16 = call x86_thiscallcc zeroext i1 %25(ptr %23), !dbg !55283 %26 = load ptr, ptr %c, align 4, !dbg !56284 %27 = bitcast ptr %26 to ptr, !dbg !57285 %vbptr17 = getelementptr inbounds i8, ptr %27, i32 0, !dbg !57286 %28 = bitcast ptr %vbptr17 to ptr, !dbg !57287 %vbtable18 = load ptr, ptr %28, align 4, !dbg !57288 %29 = getelementptr inbounds i32, ptr %vbtable18, i32 1, !dbg !57289 %vbase_offs19 = load i32, ptr %29, align 4, !dbg !57290 %30 = add nsw i32 0, %vbase_offs19, !dbg !57291 %31 = getelementptr inbounds i8, ptr %27, i32 %30, !dbg !57292 %32 = bitcast ptr %26 to ptr, !dbg !57293 %vbptr20 = getelementptr inbounds i8, ptr %32, i32 0, !dbg !57294 %33 = bitcast ptr %vbptr20 to ptr, !dbg !57295 %vbtable21 = load ptr, ptr %33, align 4, !dbg !57296 %34 = getelementptr inbounds i32, ptr %vbtable21, i32 1, !dbg !57297 %vbase_offs22 = load i32, ptr %34, align 4, !dbg !57298 %35 = add nsw i32 0, %vbase_offs22, !dbg !57299 %36 = getelementptr inbounds i8, ptr %32, i32 %35, !dbg !57300 %37 = bitcast ptr %36 to ptr, !dbg !57301 %vtable23 = load ptr, ptr %37, align 4, !dbg !57302 %vfn24 = getelementptr inbounds ptr, ptr %vtable23, i64 0, !dbg !57303 %38 = load ptr, ptr %vfn24, align 4, !dbg !57304 %call25 = call x86_thiscallcc zeroext i1 %38(ptr %31), !dbg !57305 call void @llvm.dbg.declare(metadata ptr %mp, metadata !58, metadata !DIExpression()), !dbg !60306 store ptr @"\01??_9A@@$BA@AE", ptr %mp, align 4, !dbg !60307 ret i32 0, !dbg !61308}309 310; Function Attrs: nounwind readnone speculatable311declare void @llvm.dbg.declare(metadata, metadata, metadata) #1312 313; Function Attrs: nobuiltin314declare noalias ptr @"\01??2@YAPAXI@Z"(i32) #2315 316; Function Attrs: argmemonly nounwind317declare void @llvm.memset.p0.i32(ptr nocapture writeonly, i8, i32, i1) #3318 319; Function Attrs: noinline nounwind optnone320define linkonce_odr x86_thiscallcc ptr @"\01??0C@@QAE@XZ"(ptr returned %this, i32 %is_most_derived) unnamed_addr #4 comdat align 2 !dbg !62 {321entry:322 %retval = alloca ptr, align 4323 %is_most_derived.addr = alloca i32, align 4324 %this.addr = alloca ptr, align 4325 store i32 %is_most_derived, ptr %is_most_derived.addr, align 4326 call void @llvm.dbg.declare(metadata ptr %is_most_derived.addr, metadata !66, metadata !DIExpression()), !dbg !67327 store ptr %this, ptr %this.addr, align 4328 call void @llvm.dbg.declare(metadata ptr %this.addr, metadata !68, metadata !DIExpression()), !dbg !67329 %this1 = load ptr, ptr %this.addr, align 4330 store ptr %this1, ptr %retval, align 4331 %is_most_derived2 = load i32, ptr %is_most_derived.addr, align 4332 %is_complete_object = icmp ne i32 %is_most_derived2, 0, !dbg !69333 br i1 %is_complete_object, label %ctor.init_vbases, label %ctor.skip_vbases, !dbg !69334 335ctor.init_vbases: ; preds = %entry336 %this.int8 = bitcast ptr %this1 to ptr, !dbg !69337 %0 = getelementptr inbounds i8, ptr %this.int8, i32 0, !dbg !69338 %vbptr.C = bitcast ptr %0 to ptr, !dbg !69339 store ptr @"\01??_8C@@7B@", ptr %vbptr.C, align 4, !dbg !69340 %1 = bitcast ptr %this1 to ptr, !dbg !69341 %2 = getelementptr inbounds i8, ptr %1, i32 4, !dbg !69342 %3 = bitcast ptr %2 to ptr, !dbg !69343 %call = call x86_thiscallcc ptr @"\01??0A@@QAE@XZ"(ptr %3) #8, !dbg !69344 %4 = bitcast ptr %this1 to ptr, !dbg !69345 %5 = getelementptr inbounds i8, ptr %4, i32 8, !dbg !69346 %6 = bitcast ptr %5 to ptr, !dbg !69347 %call3 = call x86_thiscallcc ptr @"\01??0B@@QAE@XZ"(ptr %6) #8, !dbg !69348 br label %ctor.skip_vbases, !dbg !69349 350ctor.skip_vbases: ; preds = %ctor.init_vbases, %entry351 %7 = bitcast ptr %this1 to ptr, !dbg !69352 %vbptr = getelementptr inbounds i8, ptr %7, i32 0, !dbg !69353 %8 = bitcast ptr %vbptr to ptr, !dbg !69354 %vbtable = load ptr, ptr %8, align 4, !dbg !69355 %9 = getelementptr inbounds i32, ptr %vbtable, i32 1, !dbg !69356 %vbase_offs = load i32, ptr %9, align 4, !dbg !69357 %10 = add nsw i32 0, %vbase_offs, !dbg !69358 %11 = bitcast ptr %this1 to ptr, !dbg !69359 %add.ptr = getelementptr inbounds i8, ptr %11, i32 %10, !dbg !69360 %12 = bitcast ptr %add.ptr to ptr, !dbg !69361 store ptr @"\01??_7C@@6BA@@@", ptr %12, align 4, !dbg !69362 %13 = bitcast ptr %this1 to ptr, !dbg !69363 %vbptr4 = getelementptr inbounds i8, ptr %13, i32 0, !dbg !69364 %14 = bitcast ptr %vbptr4 to ptr, !dbg !69365 %vbtable5 = load ptr, ptr %14, align 4, !dbg !69366 %15 = getelementptr inbounds i32, ptr %vbtable5, i32 2, !dbg !69367 %vbase_offs6 = load i32, ptr %15, align 4, !dbg !69368 %16 = add nsw i32 0, %vbase_offs6, !dbg !69369 %17 = bitcast ptr %this1 to ptr, !dbg !69370 %add.ptr7 = getelementptr inbounds i8, ptr %17, i32 %16, !dbg !69371 %18 = bitcast ptr %add.ptr7 to ptr, !dbg !69372 store ptr @"\01??_7C@@6BB@@@", ptr %18, align 4, !dbg !69373 %19 = load ptr, ptr %retval, align 4, !dbg !69374 ret ptr %19, !dbg !69375}376 377; Function Attrs: noinline optnone378define linkonce_odr x86_thiscallcc void @"\01??_9A@@$BA@AE"(ptr %this, ...) #5 comdat align 2 !dbg !70 {379entry:380 %this.addr = alloca ptr, align 4381 store ptr %this, ptr %this.addr, align 4382 call void @llvm.dbg.declare(metadata ptr %this.addr, metadata !72, metadata !DIExpression()), !dbg !73383 %this1 = load ptr, ptr %this.addr, align 4384 %0 = bitcast ptr %this1 to ptr385 %vtable = load ptr, ptr %0, align 4386 %vfn = getelementptr inbounds ptr, ptr %vtable, i64 0387 %1 = load ptr, ptr %vfn, align 4388 musttail call x86_thiscallcc void (ptr, ...) %1(ptr %this1, ...)389 ret void390 ; No predecessors!391 ret void392}393 394; Function Attrs: noinline nounwind optnone395define linkonce_odr x86_thiscallcc ptr @"\01??0A@@QAE@XZ"(ptr returned %this) unnamed_addr #4 comdat align 2 !dbg !74 {396entry:397 %this.addr = alloca ptr, align 4398 store ptr %this, ptr %this.addr, align 4399 call void @llvm.dbg.declare(metadata ptr %this.addr, metadata !78, metadata !DIExpression()), !dbg !79400 %this1 = load ptr, ptr %this.addr, align 4401 %0 = bitcast ptr %this1 to ptr, !dbg !80402 store ptr @"\01??_7A@@6B@", ptr %0, align 4, !dbg !80403 ret ptr %this1, !dbg !80404}405 406; Function Attrs: noinline nounwind optnone407define linkonce_odr x86_thiscallcc ptr @"\01??0B@@QAE@XZ"(ptr returned %this) unnamed_addr #4 comdat align 2 !dbg !81 {408entry:409 %this.addr = alloca ptr, align 4410 store ptr %this, ptr %this.addr, align 4411 call void @llvm.dbg.declare(metadata ptr %this.addr, metadata !85, metadata !DIExpression()), !dbg !86412 %this1 = load ptr, ptr %this.addr, align 4413 %0 = bitcast ptr %this1 to ptr, !dbg !87414 store ptr @"\01??_7B@@6B@", ptr %0, align 4, !dbg !87415 ret ptr %this1, !dbg !87416}417 418; Function Attrs: noinline nounwind optnone419define linkonce_odr x86_thiscallcc zeroext i1 @"\01?MyMethod@C@@UAE_NXZ"(ptr %this.coerce) unnamed_addr #4 comdat align 2 !dbg !88 {420entry:421 %this = alloca ptr, align 4422 %this.addr = alloca ptr, align 4423 %coerce.val = bitcast ptr %this.coerce to ptr424 store ptr %coerce.val, ptr %this, align 4425 %this1 = load ptr, ptr %this, align 4426 store ptr %this1, ptr %this.addr, align 4427 call void @llvm.dbg.declare(metadata ptr %this.addr, metadata !89, metadata !DIExpression()), !dbg !90428 %this2 = load ptr, ptr %this.addr, align 4429 %0 = bitcast ptr %this2 to ptr430 %1 = getelementptr inbounds i8, ptr %0, i32 -4431 %this.adjusted = bitcast ptr %1 to ptr432 ret i1 true, !dbg !91433}434 435; Function Attrs: noinline optnone436define linkonce_odr x86_thiscallcc zeroext i1 @"\01?MyMethod@C@@W3AE_NXZ"(ptr %this.coerce) unnamed_addr #6 comdat align 2 !dbg !92 {437entry:438 %this = alloca ptr, align 4439 %this.addr = alloca ptr, align 4440 %coerce.val = bitcast ptr %this.coerce to ptr441 store ptr %coerce.val, ptr %this, align 4442 %this1 = load ptr, ptr %this, align 4443 store ptr %this1, ptr %this.addr, align 4444 call void @llvm.dbg.declare(metadata ptr %this.addr, metadata !93, metadata !DIExpression()), !dbg !94445 %this2 = load ptr, ptr %this.addr, align 4, !dbg !94446 %0 = bitcast ptr %this2 to ptr, !dbg !94447 %1 = getelementptr i8, ptr %0, i32 -4, !dbg !94448 %call = tail call x86_thiscallcc zeroext i1 @"\01?MyMethod@C@@UAE_NXZ"(ptr %1), !dbg !94449 ret i1 %call, !dbg !94450}451 452; Function Attrs: noinline nounwind optnone453define linkonce_odr x86_thiscallcc zeroext i1 @"\01?MyMethod@A@@UAE_NXZ"(ptr %this) unnamed_addr #4 comdat align 2 !dbg !95 {454entry:455 %this.addr = alloca ptr, align 4456 store ptr %this, ptr %this.addr, align 4457 call void @llvm.dbg.declare(metadata ptr %this.addr, metadata !96, metadata !DIExpression()), !dbg !97458 %this1 = load ptr, ptr %this.addr, align 4459 ret i1 true, !dbg !98460}461 462; Function Attrs: noinline nounwind optnone463define linkonce_odr x86_thiscallcc zeroext i1 @"\01?MyMethod@B@@UAE_NXZ"(ptr %this) unnamed_addr #4 comdat align 2 !dbg !99 {464entry:465 %this.addr = alloca ptr, align 4466 store ptr %this, ptr %this.addr, align 4467 call void @llvm.dbg.declare(metadata ptr %this.addr, metadata !100, metadata !DIExpression()), !dbg !101468 %this1 = load ptr, ptr %this.addr, align 4469 ret i1 true, !dbg !102470}471 472attributes #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" "use-soft-float"="false" }473attributes #1 = { nounwind readnone speculatable }474attributes #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" "use-soft-float"="false" }475attributes #3 = { argmemonly nounwind }476attributes #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" "use-soft-float"="false" }477attributes #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" "use-soft-float"="false" }478attributes #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" "use-soft-float"="false" }479attributes #7 = { builtin }480attributes #8 = { nounwind }481 482!llvm.dbg.cu = !{!0}483!llvm.module.flags = !{!3, !4, !5, !6}484!llvm.ident = !{!7}485 486!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)487!1 = !DIFile(filename: "thunk.cpp", directory: "C:\5Cpath\5Cto", checksumkind: CSK_MD5, checksum: "d4b977fc614313c5a4fbdc980b2f4243")488!2 = !{}489!3 = !{i32 1, !"NumRegisterParameters", i32 0}490!4 = !{i32 2, !"CodeView", i32 1}491!5 = !{i32 2, !"Debug Info Version", i32 3}492!6 = !{i32 1, !"wchar_size", i32 2}493!7 = !{!"clang version 7.0.0 (trunk)"}494!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)495!9 = !DISubroutineType(types: !10)496!10 = !{!11}497!11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)498!12 = !DILocalVariable(name: "a", scope: !8, file: !1, line: 10, type: !13)499!13 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !14, size: 32)500!14 = distinct !DICompositeType(tag: DW_TAG_class_type, name: "A", file: !1, line: 1, size: 32, flags: DIFlagTypePassByValue, elements: !15, vtableHolder: !14, identifier: ".?AVA@@")501!15 = !{!16, !17, !19}502!16 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "__vtbl_ptr_type", baseType: null, size: 32)503!17 = !DIDerivedType(tag: DW_TAG_member, name: "_vptr$A", scope: !1, file: !1, baseType: !18, size: 32, flags: DIFlagArtificial)504!18 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !16, size: 32)505!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)506!20 = !DISubroutineType(cc: DW_CC_BORLAND_thiscall, types: !21)507!21 = !{!22, !23}508!22 = !DIBasicType(name: "bool", size: 8, encoding: DW_ATE_boolean)509!23 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !14, size: 32, flags: DIFlagArtificial | DIFlagObjectPointer)510!24 = !DILocation(line: 10, column: 8, scope: !8)511!25 = !DILocation(line: 10, column: 12, scope: !8)512!26 = !DILocation(line: 10, column: 16, scope: !8)513!27 = !DILocalVariable(name: "b", scope: !8, file: !1, line: 11, type: !28)514!28 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !29, size: 32)515!29 = distinct !DICompositeType(tag: DW_TAG_class_type, name: "B", file: !1, line: 2, size: 32, flags: DIFlagTypePassByValue, elements: !30, vtableHolder: !29, identifier: ".?AVB@@")516!30 = !{!16, !31, !32}517!31 = !DIDerivedType(tag: DW_TAG_member, name: "_vptr$B", scope: !1, file: !1, baseType: !18, size: 32, flags: DIFlagArtificial)518!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)519!33 = !DISubroutineType(cc: DW_CC_BORLAND_thiscall, types: !34)520!34 = !{!22, !35}521!35 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !29, size: 32, flags: DIFlagArtificial | DIFlagObjectPointer)522!36 = !DILocation(line: 11, column: 8, scope: !8)523!37 = !DILocation(line: 11, column: 12, scope: !8)524!38 = !DILocation(line: 11, column: 16, scope: !8)525!39 = !DILocalVariable(name: "c", scope: !8, file: !1, line: 12, type: !40)526!40 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !41, size: 32)527!41 = distinct !DICompositeType(tag: DW_TAG_class_type, name: "C", file: !1, line: 3, size: 96, flags: DIFlagTypePassByValue, elements: !42, vtableHolder: !41, identifier: ".?AVC@@")528!42 = !{!43, !44, !45}529!43 = !DIDerivedType(tag: DW_TAG_inheritance, scope: !41, baseType: !14, offset: 4, flags: DIFlagPublic | DIFlagVirtual)530!44 = !DIDerivedType(tag: DW_TAG_inheritance, scope: !41, baseType: !29, offset: 8, flags: DIFlagPublic | DIFlagVirtual)531!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)532!46 = !DISubroutineType(cc: DW_CC_BORLAND_thiscall, types: !47)533!47 = !{!22, !48}534!48 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !41, size: 32, flags: DIFlagArtificial | DIFlagObjectPointer)535!49 = !DILocation(line: 12, column: 8, scope: !8)536!50 = !DILocation(line: 12, column: 12, scope: !8)537!51 = !DILocation(line: 12, column: 16, scope: !8)538!52 = !DILocation(line: 13, column: 5, scope: !8)539!53 = !DILocation(line: 13, column: 8, scope: !8)540!54 = !DILocation(line: 14, column: 5, scope: !8)541!55 = !DILocation(line: 14, column: 8, scope: !8)542!56 = !DILocation(line: 15, column: 5, scope: !8)543!57 = !DILocation(line: 15, column: 8, scope: !8)544!58 = !DILocalVariable(name: "mp", scope: !8, file: !1, line: 16, type: !59)545!59 = !DIDerivedType(tag: DW_TAG_ptr_to_member_type, baseType: !20, size: 32, flags: DIFlagSingleInheritance, extraData: !14)546!60 = !DILocation(line: 16, column: 15, scope: !8)547!61 = !DILocation(line: 17, column: 5, scope: !8)548!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)549!63 = !DISubroutineType(cc: DW_CC_BORLAND_thiscall, types: !64)550!64 = !{null, !48}551!65 = !DISubprogram(name: "C", scope: !41, type: !63, isLocal: false, isDefinition: false, flags: DIFlagPublic | DIFlagArtificial | DIFlagPrototyped, isOptimized: false)552!66 = !DILocalVariable(name: "is_most_derived", arg: 2, scope: !62, type: !11, flags: DIFlagArtificial)553!67 = !DILocation(line: 0, scope: !62)554!68 = !DILocalVariable(name: "this", arg: 1, scope: !62, type: !40, flags: DIFlagArtificial | DIFlagObjectPointer)555!69 = !DILocation(line: 3, column: 7, scope: !62)556!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)557!71 = !DISubroutineType(types: !2)558!72 = !DILocalVariable(name: "this", arg: 1, scope: !70, type: !13, flags: DIFlagArtificial | DIFlagObjectPointer)559!73 = !DILocation(line: 0, scope: !70)560!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)561!75 = !DISubroutineType(cc: DW_CC_BORLAND_thiscall, types: !76)562!76 = !{null, !23}563!77 = !DISubprogram(name: "A", scope: !14, type: !75, isLocal: false, isDefinition: false, flags: DIFlagPublic | DIFlagArtificial | DIFlagPrototyped, isOptimized: false)564!78 = !DILocalVariable(name: "this", arg: 1, scope: !74, type: !13, flags: DIFlagArtificial | DIFlagObjectPointer)565!79 = !DILocation(line: 0, scope: !74)566!80 = !DILocation(line: 1, column: 7, scope: !74)567!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)568!82 = !DISubroutineType(cc: DW_CC_BORLAND_thiscall, types: !83)569!83 = !{null, !35}570!84 = !DISubprogram(name: "B", scope: !29, type: !82, isLocal: false, isDefinition: false, flags: DIFlagPublic | DIFlagArtificial | DIFlagPrototyped, isOptimized: false)571!85 = !DILocalVariable(name: "this", arg: 1, scope: !81, type: !28, flags: DIFlagArtificial | DIFlagObjectPointer)572!86 = !DILocation(line: 0, scope: !81)573!87 = !DILocation(line: 2, column: 7, scope: !81)574!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)575!89 = !DILocalVariable(name: "this", arg: 1, scope: !88, type: !40, flags: DIFlagArtificial | DIFlagObjectPointer)576!90 = !DILocation(line: 0, scope: !88)577!91 = !DILocation(line: 5, column: 31, scope: !88)578!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)579!93 = !DILocalVariable(name: "this", arg: 1, scope: !92, type: !40, flags: DIFlagArtificial | DIFlagObjectPointer)580!94 = !DILocation(line: 0, scope: !92)581!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)582!96 = !DILocalVariable(name: "this", arg: 1, scope: !95, type: !13, flags: DIFlagArtificial | DIFlagObjectPointer)583!97 = !DILocation(line: 0, scope: !95)584!98 = !DILocation(line: 1, column: 45, scope: !95)585!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)586!100 = !DILocalVariable(name: "this", arg: 1, scope: !99, type: !28, flags: DIFlagArtificial | DIFlagObjectPointer)587!101 = !DILocation(line: 0, scope: !99)588!102 = !DILocation(line: 2, column: 45, scope: !99)589