[llvm] r273688 - [codeview] Emit base class information from DW_TAG_inheritance nodes

David Blaikie via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 8 13:59:49 PDT 2016


On Fri, Jun 24, 2016 at 9:24 AM, Reid Kleckner via llvm-commits <
llvm-commits at lists.llvm.org> wrote:

> Author: rnk
> Date: Fri Jun 24 11:24:24 2016
> New Revision: 273688
>
> URL: http://llvm.org/viewvc/llvm-project?rev=273688&view=rev
> Log:
> [codeview] Emit base class information from DW_TAG_inheritance nodes
>
> There are two remaining issues here:
> 1. No vbptr information
> 2. Need to mention indirect virtual bases
>
> Getting indirect virtual bases is just a matter of adding an "indirect"
> flag, emitting them in the frontend, and ignoring them when appropriate
> for DWARF.
>

I was chatting about some different but related scenarios with Adrian today
- and I'd be a little concerned about adding extra types to the debug info
in all cases, as types can sometimes lead to substantial chunks of debug
info that it'd be unfortunate to build and then throw away. (perhaps doubly
so in LTO builds where that info then needs to be written to files,
potentially shipped around, etc)

If you can always emit these types as declarations, it might not be so bad.


>
> All virtual bases use the same artificial vbptr field, so I think the
> vbptr offset will be best represented by an implicit __vbptr$ClassName
> member similar to our existing __vptr$ member.
>
> Added:
>     llvm/trunk/test/DebugInfo/COFF/inheritance.ll
> Modified:
>     llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
>     llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.h
>     llvm/trunk/test/DebugInfo/COFF/types-data-members.ll
>
> Modified: llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp?rev=273688&r1=273687&r2=273688&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp (original)
> +++ llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp Fri Jun 24
> 11:24:24 2016
> @@ -1319,6 +1319,9 @@ struct llvm::ClassInfo {
>    // MethodName -> MethodsList
>    typedef MapVector<MDString *, MethodsList> MethodsMap;
>
> +  /// Base classes.
> +  std::vector<const DIDerivedType *> Inheritance;
> +
>    /// Direct members.
>    MemberList Members;
>    // Direct overloaded methods gathered by name.
> @@ -1366,10 +1369,10 @@ ClassInfo CodeViewDebug::collectClassInf
>      if (auto *SP = dyn_cast<DISubprogram>(Element)) {
>        Info.Methods[SP->getRawName()].push_back(SP);
>      } else if (auto *DDTy = dyn_cast<DIDerivedType>(Element)) {
> -      if (DDTy->getTag() == dwarf::DW_TAG_member)
> +      if (DDTy->getTag() == dwarf::DW_TAG_member) {
>          collectMemberInfo(Info, DDTy);
> -      else if (DDTy->getTag() == dwarf::DW_TAG_inheritance) {
> -        // FIXME: collect class info from inheritance.
> +      } else if (DDTy->getTag() == dwarf::DW_TAG_inheritance) {
> +        Info.Inheritance.push_back(DDTy);
>        } else if (DDTy->getTag() == dwarf::DW_TAG_friend) {
>          // Ignore friend members. It appears that MSVC emitted info about
>          // friends in the past, but modern versions do not.
> @@ -1474,6 +1477,27 @@ CodeViewDebug::lowerRecordFieldList(cons
>    ClassInfo Info = collectClassInfo(Ty);
>    FieldListRecordBuilder Fields;
>
> +  // Create base classes.
> +  for (const DIDerivedType *I : Info.Inheritance) {
> +    if (I->getFlags() & DINode::FlagVirtual) {
> +      // Virtual base.
> +      // FIXME: Emit VBPtrOffset when the frontend provides it.
> +      unsigned VBPtrOffset = 0;
> +      // FIXME: Despite the accessor name, the offset is really in bytes.
> +      unsigned VBTableIndex = I->getOffsetInBits() / 4;
> +      Fields.writeVirtualBaseClass(VirtualBaseClassRecord(
> +          translateAccessFlags(Ty->getTag(), I->getFlags()),
> +          getTypeIndex(I->getBaseType()), getVBPTypeIndex(), VBPtrOffset,
> +          VBTableIndex));
> +    } else {
> +      assert(I->getOffsetInBits() % 8 == 0 &&
> +             "bases must be on byte boundaries");
> +      Fields.writeBaseClass(BaseClassRecord(
> +          translateAccessFlags(Ty->getTag(), I->getFlags()),
> +          getTypeIndex(I->getBaseType()), I->getOffsetInBits() / 8));
> +    }
> +  }
> +
>    // Create members.
>    for (ClassInfo::MemberInfo &MemberInfo : Info.Members) {
>      const DIDerivedType *Member = MemberInfo.MemberTypeNode;
> @@ -1532,6 +1556,24 @@ CodeViewDebug::lowerRecordFieldList(cons
>    return std::make_tuple(FieldTI, TypeIndex(), MemberCount);
>  }
>
> +TypeIndex CodeViewDebug::getVBPTypeIndex() {
> +  if (!VBPType.getIndex()) {
> +    // Make a 'const int *' type.
> +    ModifierRecord MR(TypeIndex::Int32(), ModifierOptions::Const);
> +    TypeIndex ModifiedTI = TypeTable.writeModifier(MR);
> +
> +    PointerKind PK = getPointerSizeInBytes() == 8 ? PointerKind::Near64
> +                                                  : PointerKind::Near32;
> +    PointerMode PM = PointerMode::Pointer;
> +    PointerOptions PO = PointerOptions::None;
> +    PointerRecord PR(ModifiedTI, PK, PM, PO, getPointerSizeInBytes());
> +
> +    VBPType = TypeTable.writePointer(PR);
> +  }
> +
> +  return VBPType;
> +}
> +
>  struct CodeViewDebug::TypeLoweringScope {
>    TypeLoweringScope(CodeViewDebug &CVD) : CVD(CVD) {
> ++CVD.TypeEmissionLevel; }
>    ~TypeLoweringScope() {
>
> Modified: llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.h?rev=273688&r1=273687&r2=273688&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.h (original)
> +++ llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.h Fri Jun 24 11:24:24
> 2016
> @@ -157,6 +157,8 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDe
>    /// Number of type lowering frames active on the stack.
>    unsigned TypeEmissionLevel = 0;
>
> +  codeview::TypeIndex VBPType;
> +
>    const DISubprogram *CurrentSubprogram = nullptr;
>
>    // The UDTs we have seen while processing types; each entry is a pair
> of type
> @@ -230,6 +232,8 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDe
>
>    codeview::TypeIndex getScopeIndex(const DIScope *Scope);
>
> +  codeview::TypeIndex getVBPTypeIndex();
> +
>    void addToUDTs(const DIType *Ty, codeview::TypeIndex TI);
>
>    codeview::TypeIndex lowerType(const DIType *Ty, const DIType *ClassTy);
>
> Added: llvm/trunk/test/DebugInfo/COFF/inheritance.ll
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/COFF/inheritance.ll?rev=273688&view=auto
>
> ==============================================================================
> --- llvm/trunk/test/DebugInfo/COFF/inheritance.ll (added)
> +++ llvm/trunk/test/DebugInfo/COFF/inheritance.ll Fri Jun 24 11:24:24 2016
> @@ -0,0 +1,296 @@
> +; RUN: llc < %s -filetype=obj -o - | llvm-readobj - -codeview | FileCheck
> %s
> +
> +; C++ source to regenerate:
> +; $ cat t.cpp
> +; struct A { int a; };
> +; struct B : virtual A { int b; };
> +; struct C : virtual A { int c; };
> +; struct D : B, C {
> +;   virtual void f(); // make vbptr not offset zero
> +;   int d;
> +; };
> +; D d;
> +; $ clang -fno-rtti -g -gcodeview t.cpp -emit-llvm -S -o t.ll -O1
> +
> +; D's field list comes first.
> +; CHECK:        FieldList ({{.*}}) {
> +; CHECK-NEXT:     TypeLeafKind: LF_FIELDLIST (0x1203)
> +; CHECK-NEXT:     BaseClass {
> +; CHECK-NEXT:       AccessSpecifier: Public (0x3)
> +; CHECK-NEXT:       BaseType: B ({{.*}})
> +; CHECK-NEXT:       BaseOffset: 0x8
> +; CHECK-NEXT:     }
> +; CHECK-NEXT:     BaseClass {
> +; CHECK-NEXT:       AccessSpecifier: Public (0x3)
> +; CHECK-NEXT:       BaseType: C ({{.*}})
> +; CHECK-NEXT:       BaseOffset: 0x18
> +; CHECK-NEXT:     }
> +; CHECK:        }
> +
> +; Then B's field list.
> +; CHECK:        FieldList ({{.*}}) {
> +; CHECK-NEXT:     TypeLeafKind: LF_FIELDLIST (0x1203)
> +; CHECK-NEXT:     VirtualBaseClass {
> +; CHECK-NEXT:       AccessSpecifier: Public (0x3)
> +; CHECK-NEXT:       BaseType: A ({{.*}})
> +; CHECK-NEXT:       VBPtrType: const int* ({{.*}})
> +; CHECK-NEXT:       VBPtrOffset: 0x0
> +; CHECK-NEXT:       VBTableIndex: 0x1
> +; CHECK-NEXT:     }
> +; CHECK:        }
> +
> +; Then C's field list.
> +; CHECK:        FieldList ({{.*}}) {
> +; CHECK-NEXT:     TypeLeafKind: LF_FIELDLIST (0x1203)
> +; CHECK-NEXT:     VirtualBaseClass {
> +; CHECK-NEXT:       AccessSpecifier: Public (0x3)
> +; CHECK-NEXT:       BaseType: A ({{.*}})
> +; CHECK-NEXT:       VBPtrType: const int* ({{.*}})
> +; CHECK-NEXT:       VBPtrOffset: 0x0
> +; CHECK-NEXT:       VBTableIndex: 0x1
> +; CHECK-NEXT:     }
> +; CHECK:        }
> +
> +; ModuleID = 't.cpp'
> +source_filename = "t.cpp"
> +target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
> +target triple = "x86_64-pc-windows-msvc19.0.23918"
> +
> +%struct.D = type { i32 (...)**, %struct.B.base, %struct.C.base, i32, [4 x
> i8], %struct.A }
> +%struct.B.base = type { i32*, i32 }
> +%struct.C.base = type { i32*, i32 }
> +%struct.A = type { i32 }
> +%struct.B = type { i32*, i32, [4 x i8], %struct.A }
> +%struct.C = type { i32*, i32, [4 x i8], %struct.A }
> +
> +$"\01??0D@@QEAA at XZ" = comdat any
> +
> +$"\01??0B@@QEAA at XZ" = comdat any
> +
> +$"\01??0C@@QEAA at XZ" = comdat any
> +
> +$"\01??_8D@@7BB@@@" = comdat any
> +
> +$"\01??_8D@@7BC@@@" = comdat any
> +
> +$"\01??_7D@@6B@" = comdat any
> +
> +$"\01??_8B@@7B@" = comdat any
> +
> +$"\01??_8C@@7B@" = comdat any
> +
> +@"\01?d@@3UD@@A" = global %struct.D zeroinitializer, align 8
> +@"\01??_8D@@7BB@@@" = linkonce_odr unnamed_addr constant [2 x i32] [i32
> 0, i32 40], comdat
> +@"\01??_8D@@7BC@@@" = linkonce_odr unnamed_addr constant [2 x i32] [i32
> 0, i32 24], comdat
> +@"\01??_7D@@6B@" = linkonce_odr unnamed_addr constant [1 x i8*] [i8*
> bitcast (void (%struct.D*)* @"\01?f at D@@UEAAXXZ" to i8*)], comdat
> +@"\01??_8B@@7B@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 0,
> i32 16], comdat
> +@"\01??_8C@@7B@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 0,
> i32 16], comdat
> + at llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{
> i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__sub_I_t.cpp, i8* null
> }]
> +
> +; Function Attrs: uwtable
> +define internal void @"\01??__Ed@@YAXXZ"() #0 !dbg !37 {
> +entry:
> +  %call = call %struct.D* @"\01??0D@@QEAA at XZ"(%struct.D* @"\01?d@@3UD@@A",
> i32 1) #4, !dbg !40
> +  ret void, !dbg !40
> +}
> +
> +; Function Attrs: inlinehint nounwind uwtable
> +define linkonce_odr %struct.D* @"\01??0D@@QEAA at XZ"(%struct.D* returned
> %this, i32 %is_most_derived) unnamed_addr #1 comdat align 2 !dbg !41 {
> +entry:
> +  %retval = alloca %struct.D*, align 8
> +  %is_most_derived.addr = alloca i32, align 4
> +  %this.addr = alloca %struct.D*, align 8
> +  store i32 %is_most_derived, i32* %is_most_derived.addr, align 4
> +  call void @llvm.dbg.declare(metadata i32* %is_most_derived.addr,
> metadata !43, metadata !44), !dbg !45
> +  store %struct.D* %this, %struct.D** %this.addr, align 8
> +  call void @llvm.dbg.declare(metadata %struct.D** %this.addr, metadata
> !46, metadata !44), !dbg !45
> +  %this1 = load %struct.D*, %struct.D** %this.addr, align 8
> +  store %struct.D* %this1, %struct.D** %retval, align 8
> +  %is_most_derived2 = load i32, i32* %is_most_derived.addr, align 4
> +  %is_complete_object = icmp ne i32 %is_most_derived2, 0, !dbg !48
> +  br i1 %is_complete_object, label %ctor.init_vbases, label
> %ctor.skip_vbases, !dbg !48
> +
> +ctor.init_vbases:                                 ; preds = %entry
> +  %this.int8 = bitcast %struct.D* %this1 to i8*, !dbg !48
> +  %0 = getelementptr inbounds i8, i8* %this.int8, i64 8, !dbg !48
> +  %vbptr.D = bitcast i8* %0 to i32**, !dbg !48
> +  store i32* getelementptr inbounds ([2 x i32], [2 x i32]* @"\01??_8D@
> @7BB@@@", i32 0, i32 0), i32** %vbptr.D, align 8, !dbg !48
> +  %1 = getelementptr inbounds i8, i8* %this.int8, i64 24, !dbg !48
> +  %vbptr.C = bitcast i8* %1 to i32**, !dbg !48
> +  store i32* getelementptr inbounds ([2 x i32], [2 x i32]* @"\01??_8D@
> @7BC@@@", i32 0, i32 0), i32** %vbptr.C, align 8, !dbg !48
> +  %2 = bitcast %struct.D* %this1 to i8*, !dbg !48
> +  %3 = getelementptr inbounds i8, i8* %2, i64 48, !dbg !48
> +  %4 = bitcast i8* %3 to %struct.A*, !dbg !48
> +  br label %ctor.skip_vbases, !dbg !48
> +
> +ctor.skip_vbases:                                 ; preds =
> %ctor.init_vbases, %entry
> +  %5 = bitcast %struct.D* %this1 to i8*, !dbg !48
> +  %6 = getelementptr inbounds i8, i8* %5, i64 8, !dbg !48
> +  %7 = bitcast i8* %6 to %struct.B*, !dbg !48
> +  %call = call %struct.B* @"\01??0B@@QEAA at XZ"(%struct.B* %7, i32 0) #4,
> !dbg !48
> +  %8 = bitcast %struct.D* %this1 to i8*, !dbg !48
> +  %9 = getelementptr inbounds i8, i8* %8, i64 24, !dbg !48
> +  %10 = bitcast i8* %9 to %struct.C*, !dbg !48
> +  %call3 = call %struct.C* @"\01??0C@@QEAA at XZ"(%struct.C* %10, i32 0)
> #4, !dbg !48
> +  %11 = bitcast %struct.D* %this1 to i32 (...)***, !dbg !48
> +  store i32 (...)** bitcast ([1 x i8*]* @"\01??_7D@@6B@" to i32
> (...)**), i32 (...)*** %11, align 8, !dbg !48
> +  %12 = load %struct.D*, %struct.D** %retval, align 8, !dbg !48
> +  ret %struct.D* %12, !dbg !48
> +}
> +
> +; Function Attrs: nounwind readnone
> +declare void @llvm.dbg.declare(metadata, metadata, metadata) #2
> +
> +; Function Attrs: inlinehint nounwind uwtable
> +define linkonce_odr %struct.B* @"\01??0B@@QEAA at XZ"(%struct.B* returned
> %this, i32 %is_most_derived) unnamed_addr #1 comdat align 2 !dbg !49 {
> +entry:
> +  %retval = alloca %struct.B*, align 8
> +  %is_most_derived.addr = alloca i32, align 4
> +  %this.addr = alloca %struct.B*, align 8
> +  store i32 %is_most_derived, i32* %is_most_derived.addr, align 4
> +  call void @llvm.dbg.declare(metadata i32* %is_most_derived.addr,
> metadata !54, metadata !44), !dbg !55
> +  store %struct.B* %this, %struct.B** %this.addr, align 8
> +  call void @llvm.dbg.declare(metadata %struct.B** %this.addr, metadata
> !56, metadata !44), !dbg !55
> +  %this1 = load %struct.B*, %struct.B** %this.addr, align 8
> +  store %struct.B* %this1, %struct.B** %retval, align 8
> +  %is_most_derived2 = load i32, i32* %is_most_derived.addr, align 4
> +  %is_complete_object = icmp ne i32 %is_most_derived2, 0, !dbg !58
> +  br i1 %is_complete_object, label %ctor.init_vbases, label
> %ctor.skip_vbases, !dbg !58
> +
> +ctor.init_vbases:                                 ; preds = %entry
> +  %this.int8 = bitcast %struct.B* %this1 to i8*, !dbg !58
> +  %0 = getelementptr inbounds i8, i8* %this.int8, i64 0, !dbg !58
> +  %vbptr.B = bitcast i8* %0 to i32**, !dbg !58
> +  store i32* getelementptr inbounds ([2 x i32], [2 x i32]* @"\01??_8B@
> @7B@", i32 0, i32 0), i32** %vbptr.B, align 8, !dbg !58
> +  %1 = bitcast %struct.B* %this1 to i8*, !dbg !58
> +  %2 = getelementptr inbounds i8, i8* %1, i64 16, !dbg !58
> +  %3 = bitcast i8* %2 to %struct.A*, !dbg !58
> +  br label %ctor.skip_vbases, !dbg !58
> +
> +ctor.skip_vbases:                                 ; preds =
> %ctor.init_vbases, %entry
> +  %4 = load %struct.B*, %struct.B** %retval, align 8, !dbg !58
> +  ret %struct.B* %4, !dbg !58
> +}
> +
> +; Function Attrs: inlinehint nounwind uwtable
> +define linkonce_odr %struct.C* @"\01??0C@@QEAA at XZ"(%struct.C* returned
> %this, i32 %is_most_derived) unnamed_addr #1 comdat align 2 !dbg !59 {
> +entry:
> +  %retval = alloca %struct.C*, align 8
> +  %is_most_derived.addr = alloca i32, align 4
> +  %this.addr = alloca %struct.C*, align 8
> +  store i32 %is_most_derived, i32* %is_most_derived.addr, align 4
> +  call void @llvm.dbg.declare(metadata i32* %is_most_derived.addr,
> metadata !64, metadata !44), !dbg !65
> +  store %struct.C* %this, %struct.C** %this.addr, align 8
> +  call void @llvm.dbg.declare(metadata %struct.C** %this.addr, metadata
> !66, metadata !44), !dbg !65
> +  %this1 = load %struct.C*, %struct.C** %this.addr, align 8
> +  store %struct.C* %this1, %struct.C** %retval, align 8
> +  %is_most_derived2 = load i32, i32* %is_most_derived.addr, align 4
> +  %is_complete_object = icmp ne i32 %is_most_derived2, 0, !dbg !68
> +  br i1 %is_complete_object, label %ctor.init_vbases, label
> %ctor.skip_vbases, !dbg !68
> +
> +ctor.init_vbases:                                 ; preds = %entry
> +  %this.int8 = bitcast %struct.C* %this1 to i8*, !dbg !68
> +  %0 = getelementptr inbounds i8, i8* %this.int8, i64 0, !dbg !68
> +  %vbptr.C = bitcast i8* %0 to i32**, !dbg !68
> +  store i32* getelementptr inbounds ([2 x i32], [2 x i32]* @"\01??_8C@
> @7B@", i32 0, i32 0), i32** %vbptr.C, align 8, !dbg !68
> +  %1 = bitcast %struct.C* %this1 to i8*, !dbg !68
> +  %2 = getelementptr inbounds i8, i8* %1, i64 16, !dbg !68
> +  %3 = bitcast i8* %2 to %struct.A*, !dbg !68
> +  br label %ctor.skip_vbases, !dbg !68
> +
> +ctor.skip_vbases:                                 ; preds =
> %ctor.init_vbases, %entry
> +  %4 = load %struct.C*, %struct.C** %retval, align 8, !dbg !68
> +  ret %struct.C* %4, !dbg !68
> +}
> +
> +declare void @"\01?f at D@@UEAAXXZ"(%struct.D*) unnamed_addr #3
> +
> +; Function Attrs: uwtable
> +define internal void @_GLOBAL__sub_I_t.cpp() #0 !dbg !69 {
> +entry:
> +  call void @"\01??__Ed@@YAXXZ"(), !dbg !71
> +  ret void
> +}
> +
> +attributes #0 = { uwtable "disable-tail-calls"="false"
> "less-precise-fpmad"="false" "no-frame-pointer-elim"="false"
> "no-infs-fp-math"="false" "no-jump-tables"="false"
> "no-nans-fp-math"="false" "stack-protector-buffer-size"="8"
> "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87"
> "unsafe-fp-math"="false" "use-soft-float"="false" }
> +attributes #1 = { inlinehint nounwind uwtable
> "disable-tail-calls"="false" "less-precise-fpmad"="false"
> "no-frame-pointer-elim"="false" "no-infs-fp-math"="false"
> "no-jump-tables"="false" "no-nans-fp-math"="false"
> "stack-protector-buffer-size"="8" "target-cpu"="x86-64"
> "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false"
> "use-soft-float"="false" }
> +attributes #2 = { nounwind readnone }
> +attributes #3 = { "disable-tail-calls"="false"
> "less-precise-fpmad"="false" "no-frame-pointer-elim"="false"
> "no-infs-fp-math"="false" "no-nans-fp-math"="false"
> "stack-protector-buffer-size"="8" "target-cpu"="x86-64"
> "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false"
> "use-soft-float"="false" }
> +attributes #4 = { nounwind }
> +
> +!llvm.dbg.cu = !{!0}
> +!llvm.module.flags = !{!33, !34, !35}
> +!llvm.ident = !{!36}
> +
> +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1,
> producer: "clang version 3.9.0 ", isOptimized: false, runtimeVersion: 0,
> emissionKind: FullDebug, enums: !2, globals: !3)
> +!1 = !DIFile(filename: "t.cpp", directory: "D:\5Csrc\5Cllvm\5Cbuild")
> +!2 = !{}
> +!3 = !{!4}
> +!4 = distinct !DIGlobalVariable(name: "d", linkageName: "\01?d@@3UD@@A",
> scope: !0, file: !1, line: 9, type: !5, isLocal: false, isDefinition: true,
> variable: %struct.D* @"\01?d@@3UD@@A")
> +!5 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "D",
> file: !1, line: 4, size: 448, align: 64, elements: !6, vtableHolder: !5,
> identifier: ".?AUD@@")
> +!6 = !{!7, !21, !27, !28, !29}
> +!7 = !DIDerivedType(tag: DW_TAG_inheritance, scope: !5, baseType: !8,
> offset: 64)
> +!8 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "B",
> file: !1, line: 2, size: 192, align: 64, elements: !9, vtableHolder: !8,
> identifier: ".?AUB@@")
> +!9 = !{!10, !15, !20}
> +!10 = !DIDerivedType(tag: DW_TAG_inheritance, scope: !8, baseType: !11,
> offset: 4, flags: DIFlagVirtual)
> +!11 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "A",
> file: !1, line: 1, size: 32, align: 32, elements: !12, identifier: ".?AUA@
> @")
> +!12 = !{!13}
> +!13 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !11, file: !1,
> line: 1, baseType: !14, size: 32, align: 32)
> +!14 = !DIBasicType(name: "int", size: 32, align: 32, encoding:
> DW_ATE_signed)
> +!15 = !DIDerivedType(tag: DW_TAG_member, name: "_vptr$B", scope: !1,
> file: !1, baseType: !16, size: 64, flags: DIFlagArtificial)
> +!16 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !17, size: 64)
> +!17 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "__vtbl_ptr_type",
> baseType: !18, size: 64)
> +!18 = !DISubroutineType(types: !19)
> +!19 = !{!14}
> +!20 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !8, file: !1,
> line: 2, baseType: !14, size: 32, align: 32, offset: 64)
> +!21 = !DIDerivedType(tag: DW_TAG_inheritance, scope: !5, baseType: !22,
> offset: 192)
> +!22 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "C",
> file: !1, line: 3, size: 192, align: 64, elements: !23, vtableHolder: !22,
> identifier: ".?AUC@@")
> +!23 = !{!24, !25, !26}
> +!24 = !DIDerivedType(tag: DW_TAG_inheritance, scope: !22, baseType: !11,
> offset: 4, flags: DIFlagVirtual)
> +!25 = !DIDerivedType(tag: DW_TAG_member, name: "_vptr$C", scope: !1,
> file: !1, baseType: !16, size: 64, flags: DIFlagArtificial)
> +!26 = !DIDerivedType(tag: DW_TAG_member, name: "c", scope: !22, file: !1,
> line: 3, baseType: !14, size: 32, align: 32, offset: 64)
> +!27 = !DIDerivedType(tag: DW_TAG_member, name: "_vptr$D", scope: !1,
> file: !1, baseType: !16, size: 64, flags: DIFlagArtificial)
> +!28 = !DIDerivedType(tag: DW_TAG_member, name: "d", scope: !5, file: !1,
> line: 6, baseType: !14, size: 32, align: 32, offset: 320)
> +!29 = !DISubprogram(name: "f", linkageName: "\01?f at D@@UEAAXXZ", scope:
> !5, file: !1, line: 5, type: !30, isLocal: false, isDefinition: false,
> scopeLine: 5, containingType: !5, virtuality: DW_VIRTUALITY_virtual,
> virtualIndex: 0, flags: DIFlagPrototyped | DIFlagIntroducedVirtual,
> isOptimized: false)
> +!30 = !DISubroutineType(types: !31)
> +!31 = !{null, !32}
> +!32 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !5, size: 64,
> align: 64, flags: DIFlagArtificial | DIFlagObjectPointer)
> +!33 = !{i32 2, !"CodeView", i32 1}
> +!34 = !{i32 2, !"Debug Info Version", i32 3}
> +!35 = !{i32 1, !"PIC Level", i32 2}
> +!36 = !{!"clang version 3.9.0 "}
> +!37 = distinct !DISubprogram(name: "??__Ed@@YAXXZ", scope: !1, file: !1,
> line: 9, type: !38, isLocal: true, isDefinition: true, scopeLine: 9, flags:
> DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2)
> +!38 = !DISubroutineType(types: !39)
> +!39 = !{null}
> +!40 = !DILocation(line: 9, column: 3, scope: !37)
> +!41 = distinct !DISubprogram(name: "D", linkageName: "\01??0D@@QEAA at XZ",
> scope: !5, file: !1, line: 4, type: !30, isLocal: false, isDefinition:
> true, scopeLine: 4, flags: DIFlagArtificial | DIFlagPrototyped,
> isOptimized: false, unit: !0, declaration: !42, variables: !2)
> +!42 = !DISubprogram(name: "D", scope: !5, type: !30, isLocal: false,
> isDefinition: false, flags: DIFlagArtificial | DIFlagPrototyped,
> isOptimized: false)
> +!43 = !DILocalVariable(name: "is_most_derived", arg: 2, scope: !41, type:
> !14, flags: DIFlagArtificial)
> +!44 = !DIExpression()
> +!45 = !DILocation(line: 0, scope: !41)
> +!46 = !DILocalVariable(name: "this", arg: 1, scope: !41, type: !47,
> flags: DIFlagArtificial | DIFlagObjectPointer)
> +!47 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !5, size: 64,
> align: 64)
> +!48 = !DILocation(line: 4, column: 8, scope: !41)
> +!49 = distinct !DISubprogram(name: "B", linkageName: "\01??0B@@QEAA at XZ",
> scope: !8, file: !1, line: 2, type: !50, isLocal: false, isDefinition:
> true, scopeLine: 2, flags: DIFlagArtificial | DIFlagPrototyped,
> isOptimized: false, unit: !0, declaration: !53, variables: !2)
> +!50 = !DISubroutineType(types: !51)
> +!51 = !{null, !52}
> +!52 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !8, size: 64,
> align: 64, flags: DIFlagArtificial | DIFlagObjectPointer)
> +!53 = !DISubprogram(name: "B", scope: !8, type: !50, isLocal: false,
> isDefinition: false, flags: DIFlagArtificial | DIFlagPrototyped,
> isOptimized: false)
> +!54 = !DILocalVariable(name: "is_most_derived", arg: 2, scope: !49, type:
> !14, flags: DIFlagArtificial)
> +!55 = !DILocation(line: 0, scope: !49)
> +!56 = !DILocalVariable(name: "this", arg: 1, scope: !49, type: !57,
> flags: DIFlagArtificial | DIFlagObjectPointer)
> +!57 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !8, size: 64,
> align: 64)
> +!58 = !DILocation(line: 2, column: 8, scope: !49)
> +!59 = distinct !DISubprogram(name: "C", linkageName: "\01??0C@@QEAA at XZ",
> scope: !22, file: !1, line: 3, type: !60, isLocal: false, isDefinition:
> true, scopeLine: 3, flags: DIFlagArtificial | DIFlagPrototyped,
> isOptimized: false, unit: !0, declaration: !63, variables: !2)
> +!60 = !DISubroutineType(types: !61)
> +!61 = !{null, !62}
> +!62 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !22, size: 64,
> align: 64, flags: DIFlagArtificial | DIFlagObjectPointer)
> +!63 = !DISubprogram(name: "C", scope: !22, type: !60, isLocal: false,
> isDefinition: false, flags: DIFlagArtificial | DIFlagPrototyped,
> isOptimized: false)
> +!64 = !DILocalVariable(name: "is_most_derived", arg: 2, scope: !59, type:
> !14, flags: DIFlagArtificial)
> +!65 = !DILocation(line: 0, scope: !59)
> +!66 = !DILocalVariable(name: "this", arg: 1, scope: !59, type: !67,
> flags: DIFlagArtificial | DIFlagObjectPointer)
> +!67 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !22, size: 64,
> align: 64)
> +!68 = !DILocation(line: 3, column: 8, scope: !59)
> +!69 = distinct !DISubprogram(linkageName: "_GLOBAL__sub_I_t.cpp", scope:
> !1, file: !1, type: !70, isLocal: true, isDefinition: true, flags:
> DIFlagArtificial, isOptimized: false, unit: !0, variables: !2)
> +!70 = !DISubroutineType(types: !2)
> +!71 = !DILocation(line: 0, scope: !69)
>
> Modified: llvm/trunk/test/DebugInfo/COFF/types-data-members.ll
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/COFF/types-data-members.ll?rev=273688&r1=273687&r2=273688&view=diff
>
> ==============================================================================
> --- llvm/trunk/test/DebugInfo/COFF/types-data-members.ll (original)
> +++ llvm/trunk/test/DebugInfo/COFF/types-data-members.ll Fri Jun 24
> 11:24:24 2016
> @@ -243,7 +243,19 @@
>  ; CHECK:     Name: DerivedClass
>  ; CHECK:     LinkageName: .?AUDerivedClass@@
>  ; CHECK:   }
> -; CHECK:   Procedure (0x1012) {
> +; CHECK:   Pointer (0x1012) {
> +; CHECK:     TypeLeafKind: LF_POINTER (0x1002)
> +; CHECK:     PointeeType: const int (0x1004)
> +; CHECK:     PointerAttributes: 0x1000C
> +; CHECK:     PtrType: Near64 (0xC)
> +; CHECK:     PtrMode: Pointer (0x0)
> +; CHECK:     IsFlat: 0
> +; CHECK:     IsConst: 0
> +; CHECK:     IsVolatile: 0
> +; CHECK:     IsUnaligned: 0
> +; CHECK:     SizeOf: 8
> +; CHECK:   }
> +; CHECK:   Procedure (0x1013) {
>  ; CHECK:     TypeLeafKind: LF_PROCEDURE (0x1008)
>  ; CHECK:     ReturnType: int (0x74)
>  ; CHECK:     CallingConvention: NearC (0x0)
> @@ -252,9 +264,9 @@
>  ; CHECK:     NumParameters: 0
>  ; CHECK:     ArgListType: () (0x1000)
>  ; CHECK:   }
> -; CHECK:   Pointer (0x1013) {
> +; CHECK:   Pointer (0x1014) {
>  ; CHECK:     TypeLeafKind: LF_POINTER (0x1002)
> -; CHECK:     PointeeType: int () (0x1012)
> +; CHECK:     PointeeType: int () (0x1013)
>  ; CHECK:     PointerAttributes: 0x1000C
>  ; CHECK:     PtrType: Near64 (0xC)
>  ; CHECK:     PtrMode: Pointer (0x0)
> @@ -264,9 +276,9 @@
>  ; CHECK:     IsUnaligned: 0
>  ; CHECK:     SizeOf: 8
>  ; CHECK:   }
> -; CHECK:   Pointer (0x1014) {
> +; CHECK:   Pointer (0x1015) {
>  ; CHECK:     TypeLeafKind: LF_POINTER (0x1002)
> -; CHECK:     PointeeType: int ()* (0x1013)
> +; CHECK:     PointeeType: int ()* (0x1014)
>  ; CHECK:     PointerAttributes: 0x1000C
>  ; CHECK:     PtrType: Near64 (0xC)
>  ; CHECK:     PtrMode: Pointer (0x0)
> @@ -276,11 +288,23 @@
>  ; CHECK:     IsUnaligned: 0
>  ; CHECK:     SizeOf: 8
>  ; CHECK:   }
> -; CHECK:   FieldList (0x1015) {
> +; CHECK:   FieldList (0x1016) {
>  ; CHECK:     TypeLeafKind: LF_FIELDLIST (0x1203)
> +; CHECK:     BaseClass {
> +; CHECK:       AccessSpecifier: Public (0x3)
> +; CHECK:       BaseType: Struct (0x1003)
> +; CHECK:       BaseOffset: 0x0
> +; CHECK:     }
> +; CHECK:     VirtualBaseClass {
> +; CHECK:       AccessSpecifier: Public (0x3)
> +; CHECK:       BaseType: Class (0x100D)
> +; CHECK:       VBPtrType: const int* (0x1012)
> +; CHECK:       VBPtrOffset: 0x0
> +; CHECK:       VBTableIndex: 0x1
> +; CHECK:     }
>  ; CHECK:     DataMember {
>  ; CHECK:       AccessSpecifier: Public (0x3)
> -; CHECK:       Type: int ()** (0x1014)
> +; CHECK:       Type: int ()** (0x1015)
>  ; CHECK:       FieldOffset: 0x0
>  ; CHECK:       Name: _vptr$DerivedClass
>  ; CHECK:     }
> @@ -291,26 +315,26 @@
>  ; CHECK:       Name: d
>  ; CHECK:     }
>  ; CHECK:   }
> -; CHECK:   Struct (0x1016) {
> +; CHECK:   Struct (0x1017) {
>  ; CHECK:     TypeLeafKind: LF_STRUCTURE (0x1505)
>  ; CHECK:     MemberCount: 2
>  ; CHECK:     Properties [ (0x200)
>  ; CHECK:       HasUniqueName (0x200)
>  ; CHECK:     ]
> -; CHECK:     FieldList: <field list> (0x1015)
> +; CHECK:     FieldList: <field list> (0x1016)
>  ; CHECK:     DerivedFrom: 0x0
>  ; CHECK:     VShape: 0x0
>  ; CHECK:     SizeOf: 48
>  ; CHECK:     Name: DerivedClass
>  ; CHECK:     LinkageName: .?AUDerivedClass@@
>  ; CHECK:   }
> -; CHECK:   UdtSourceLine (0x1017) {
> +; CHECK:   UdtSourceLine (0x1018) {
>  ; CHECK:     TypeLeafKind: LF_UDT_SRC_LINE (0x1606)
> -; CHECK:     UDT: DerivedClass (0x1016)
> +; CHECK:     UDT: DerivedClass (0x1017)
>  ; CHECK:     SourceFile: D:\src\llvm\build\t.cpp (0x1007)
>  ; CHECK:     LineNumber: 20
>  ; CHECK:   }
> -; CHECK:   Struct (0x1018) {
> +; CHECK:   Struct (0x1019) {
>  ; CHECK:     TypeLeafKind: LF_STRUCTURE (0x1505)
>  ; CHECK:     MemberCount: 0
>  ; CHECK:     Properties [ (0x280)
> @@ -324,7 +348,7 @@
>  ; CHECK:     Name: Class::Nested
>  ; CHECK:     LinkageName: .?AUNested at Class@@
>  ; CHECK:   }
> -; CHECK:   FieldList (0x1019) {
> +; CHECK:   FieldList (0x101A) {
>  ; CHECK:     TypeLeafKind: LF_FIELDLIST (0x1203)
>  ; CHECK:     DataMember {
>  ; CHECK:       AccessSpecifier: Public (0x3)
> @@ -333,26 +357,26 @@
>  ; CHECK:       Name: n
>  ; CHECK:     }
>  ; CHECK:   }
> -; CHECK:   Struct (0x101A) {
> +; CHECK:   Struct (0x101B) {
>  ; CHECK:     TypeLeafKind: LF_STRUCTURE (0x1505)
>  ; CHECK:     MemberCount: 1
>  ; CHECK:     Properties [ (0x200)
>  ; CHECK:       HasUniqueName (0x200)
>  ; CHECK:     ]
> -; CHECK:     FieldList: <field list> (0x1019)
> +; CHECK:     FieldList: <field list> (0x101A)
>  ; CHECK:     DerivedFrom: 0x0
>  ; CHECK:     VShape: 0x0
>  ; CHECK:     SizeOf: 4
>  ; CHECK:     Name: Class::Nested
>  ; CHECK:     LinkageName: .?AUNested at Class@@
>  ; CHECK:   }
> -; CHECK:   UdtSourceLine (0x101B) {
> +; CHECK:   UdtSourceLine (0x101C) {
>  ; CHECK:     TypeLeafKind: LF_UDT_SRC_LINE (0x1606)
> -; CHECK:     UDT: Class::Nested (0x101A)
> +; CHECK:     UDT: Class::Nested (0x101B)
>  ; CHECK:     SourceFile: D:\src\llvm\build\t.cpp (0x1007)
>  ; CHECK:     LineNumber: 23
>  ; CHECK:   }
> -; CHECK:   Pointer (0x101C) {
> +; CHECK:   Pointer (0x101D) {
>  ; CHECK:     TypeLeafKind: LF_POINTER (0x1002)
>  ; CHECK:     PointeeType: DerivedClass (0x1011)
>  ; CHECK:     PointerAttributes: 0x1000C
> @@ -364,11 +388,11 @@
>  ; CHECK:     IsUnaligned: 0
>  ; CHECK:     SizeOf: 8
>  ; CHECK:   }
> -; CHECK:   MemberFunction (0x101D) {
> +; CHECK:   MemberFunction (0x101E) {
>  ; CHECK:     TypeLeafKind: LF_MFUNCTION (0x1009)
>  ; CHECK:     ReturnType: void (0x3)
>  ; CHECK:     ClassType: DerivedClass (0x1011)
> -; CHECK:     ThisType: DerivedClass* (0x101C)
> +; CHECK:     ThisType: DerivedClass* (0x101D)
>  ; CHECK:     CallingConvention: NearC (0x0)
>  ; CHECK:     FunctionOptions [ (0x0)
>  ; CHECK:     ]
> @@ -376,10 +400,10 @@
>  ; CHECK:     ArgListType: () (0x1000)
>  ; CHECK:     ThisAdjustment: 0
>  ; CHECK:   }
> -; CHECK:   MemberFuncId (0x101E) {
> +; CHECK:   MemberFuncId (0x101F) {
>  ; CHECK:     TypeLeafKind: LF_MFUNC_ID (0x1602)
>  ; CHECK:     ClassType: DerivedClass (0x1011)
> -; CHECK:     FunctionType: void DerivedClass::() (0x101D)
> +; CHECK:     FunctionType: void DerivedClass::() (0x101E)
>  ; CHECK:     Name: DerivedClass::DerivedClass
>  ; CHECK:   }
>  ; CHECK: ]
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160708/509d54f4/attachment.html>


More information about the llvm-commits mailing list