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