Index: llvm/include/llvm/IR/DIBuilder.h =================================================================== --- llvm/include/llvm/IR/DIBuilder.h +++ llvm/include/llvm/IR/DIBuilder.h @@ -237,10 +237,11 @@ /// \param Ty Original type. /// \param BaseTy Base type. Ty is inherits from base. /// \param BaseOffset Base offset. + /// \param VBPtrOffset Virtual base pointer offset. /// \param Flags Flags to describe inheritance attribute, /// e.g. private DIDerivedType *createInheritance(DIType *Ty, DIType *BaseTy, - uint64_t BaseOffset, + uint64_t BaseOffset, uint32_t VBPtrOffset, DINode::DIFlags Flags); /// Create debugging information entry for a member. Index: llvm/include/llvm/IR/DebugInfoMetadata.h =================================================================== --- llvm/include/llvm/IR/DebugInfoMetadata.h +++ llvm/include/llvm/IR/DebugInfoMetadata.h @@ -790,16 +790,21 @@ friend class LLVMContextImpl; friend class MDNode; + /// \brief In inheritance, the pointer offset to virtual bases. + uint32_t VBPtrOffset; + /// \brief The DWARF address space of the memory pointed to or referenced by a /// pointer or reference type respectively. Optional DWARFAddressSpace; DIDerivedType(LLVMContext &C, StorageType Storage, unsigned Tag, unsigned Line, uint64_t SizeInBits, uint32_t AlignInBits, - uint64_t OffsetInBits, Optional DWARFAddressSpace, - DIFlags Flags, ArrayRef Ops) + uint64_t OffsetInBits, uint32_t VBPtrOffset, + Optional DWARFAddressSpace, DIFlags Flags, + ArrayRef Ops) : DIType(C, DIDerivedTypeKind, Storage, Tag, Line, SizeInBits, AlignInBits, OffsetInBits, Flags, Ops), + VBPtrOffset(VBPtrOffset), DWARFAddressSpace(DWARFAddressSpace) {} ~DIDerivedType() = default; @@ -807,19 +812,20 @@ StringRef Name, DIFile *File, unsigned Line, DIScopeRef Scope, DITypeRef BaseType, uint64_t SizeInBits, uint32_t AlignInBits, - uint64_t OffsetInBits, + uint64_t OffsetInBits, uint32_t VBPtrOffset, Optional DWARFAddressSpace, DIFlags Flags, Metadata *ExtraData, StorageType Storage, bool ShouldCreate = true) { return getImpl(Context, Tag, getCanonicalMDString(Context, Name), File, Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits, - DWARFAddressSpace, Flags, ExtraData, Storage, ShouldCreate); + VBPtrOffset, DWARFAddressSpace, Flags, ExtraData, Storage, + ShouldCreate); } static DIDerivedType *getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits, - uint64_t OffsetInBits, + uint64_t OffsetInBits, uint32_t VBPtrOffset, Optional DWARFAddressSpace, DIFlags Flags, Metadata *ExtraData, StorageType Storage, bool ShouldCreate = true); @@ -827,7 +833,7 @@ TempDIDerivedType cloneImpl() const { return getTemporary(getContext(), getTag(), getName(), getFile(), getLine(), getScope(), getBaseType(), getSizeInBits(), - getAlignInBits(), getOffsetInBits(), + getAlignInBits(), getOffsetInBits(), getVBPtrOffset(), getDWARFAddressSpace(), getFlags(), getExtraData()); } @@ -840,7 +846,7 @@ Optional DWARFAddressSpace, DIFlags Flags, Metadata *ExtraData = nullptr), (Tag, Name, File, Line, Scope, BaseType, SizeInBits, - AlignInBits, OffsetInBits, DWARFAddressSpace, Flags, + AlignInBits, OffsetInBits, 0, DWARFAddressSpace, Flags, ExtraData)) DEFINE_MDNODE_GET(DIDerivedType, (unsigned Tag, StringRef Name, DIFile *File, unsigned Line, @@ -849,8 +855,27 @@ Optional DWARFAddressSpace, DIFlags Flags, Metadata *ExtraData = nullptr), (Tag, Name, File, Line, Scope, BaseType, SizeInBits, - AlignInBits, OffsetInBits, DWARFAddressSpace, Flags, + AlignInBits, OffsetInBits, 0, DWARFAddressSpace, Flags, ExtraData)) + DEFINE_MDNODE_GET(DIDerivedType, + (unsigned Tag, MDString *Name, Metadata *File, + unsigned Line, Metadata *Scope, Metadata *BaseType, + uint64_t SizeInBits, uint32_t AlignInBits, + uint64_t OffsetInBits, uint32_t VBPtrOffset, + Optional DWARFAddressSpace, DIFlags Flags, + Metadata *ExtraData = nullptr), + (Tag, Name, File, Line, Scope, BaseType, SizeInBits, + AlignInBits, OffsetInBits, VBPtrOffset, DWARFAddressSpace, + Flags, ExtraData)) + DEFINE_MDNODE_GET(DIDerivedType, + (unsigned Tag, StringRef Name, DIFile *File, unsigned Line, + DIScopeRef Scope, DITypeRef BaseType, uint64_t SizeInBits, + uint32_t AlignInBits, uint64_t OffsetInBits, + uint32_t VBPtrOffset, Optional DWARFAddressSpace, + DIFlags Flags, Metadata *ExtraData = nullptr), + (Tag, Name, File, Line, Scope, BaseType, SizeInBits, + AlignInBits, OffsetInBits, VBPtrOffset, DWARFAddressSpace, + Flags, ExtraData)) TempDIDerivedType clone() const { return cloneImpl(); } @@ -858,6 +883,9 @@ DITypeRef getBaseType() const { return DITypeRef(getRawBaseType()); } Metadata *getRawBaseType() const { return getOperand(3); } + /// \returns In inheritance, the pointer offset to virtual bases. + uint32_t getVBPtrOffset() const { return VBPtrOffset; } + /// \returns The DWARF address space of the memory pointed to or referenced by /// a pointer or reference type respectively. Optional getDWARFAddressSpace() const { return DWARFAddressSpace; } Index: llvm/lib/AsmParser/LLParser.cpp =================================================================== --- llvm/lib/AsmParser/LLParser.cpp +++ llvm/lib/AsmParser/LLParser.cpp @@ -4195,6 +4195,7 @@ OPTIONAL(size, MDUnsignedField, (0, UINT64_MAX)); \ OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX)); \ OPTIONAL(offset, MDUnsignedField, (0, UINT64_MAX)); \ + OPTIONAL(vbpOffset, MDUnsignedField, (0, UINT32_MAX)); \ OPTIONAL(flags, DIFlagField, ); \ OPTIONAL(extraData, MDField, ); \ OPTIONAL(dwarfAddressSpace, MDUnsignedField, (UINT32_MAX, UINT32_MAX)); @@ -4208,8 +4209,8 @@ Result = GET_OR_DISTINCT(DIDerivedType, (Context, tag.Val, name.Val, file.Val, line.Val, scope.Val, baseType.Val, size.Val, align.Val, - offset.Val, DWARFAddressSpace, flags.Val, - extraData.Val)); + offset.Val, vbpOffset.Val, DWARFAddressSpace, + flags.Val, extraData.Val)); return false; } Index: llvm/lib/Bitcode/Reader/MetadataLoader.cpp =================================================================== --- llvm/lib/Bitcode/Reader/MetadataLoader.cpp +++ llvm/lib/Bitcode/Reader/MetadataLoader.cpp @@ -1223,25 +1223,25 @@ break; } case bitc::METADATA_DERIVED_TYPE: { - if (Record.size() < 12 || Record.size() > 13) + if (Record.size() < 13 || Record.size() > 14) return error("Invalid record"); // DWARF address space is encoded as N->getDWARFAddressSpace() + 1. 0 means // that there is no DWARF address space associated with DIDerivedType. Optional DWARFAddressSpace; - if (Record.size() > 12 && Record[12]) - DWARFAddressSpace = Record[12] - 1; + if (Record.size() > 13 && Record[13]) + DWARFAddressSpace = Record[13] - 1; IsDistinct = Record[0]; - DINode::DIFlags Flags = static_cast(Record[10]); + DINode::DIFlags Flags = static_cast(Record[11]); MetadataList.assignValue( GET_OR_DISTINCT(DIDerivedType, (Context, Record[1], getMDString(Record[2]), getMDOrNull(Record[3]), Record[4], getDITypeRefOrNull(Record[5]), getDITypeRefOrNull(Record[6]), Record[7], Record[8], - Record[9], DWARFAddressSpace, Flags, - getDITypeRefOrNull(Record[11]))), + Record[9], Record[10], DWARFAddressSpace, Flags, + getDITypeRefOrNull(Record[12]))), NextMetadataNo); NextMetadataNo++; break; Index: llvm/lib/Bitcode/Writer/BitcodeWriter.cpp =================================================================== --- llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -1502,6 +1502,7 @@ Record.push_back(N->getSizeInBits()); Record.push_back(N->getAlignInBits()); Record.push_back(N->getOffsetInBits()); + Record.push_back(N->getVBPtrOffset()); Record.push_back(N->getFlags()); Record.push_back(VE.getMetadataOrNullID(N->getExtraData())); Index: llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp =================================================================== --- llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp +++ llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp @@ -2099,8 +2099,7 @@ for (const DIDerivedType *I : Info.Inheritance) { if (I->getFlags() & DINode::FlagVirtual) { // Virtual base. - // FIXME: Emit VBPtrOffset when the frontend provides it. - unsigned VBPtrOffset = 0; + unsigned VBPtrOffset = I->getVBPtrOffset(); // FIXME: Despite the accessor name, the offset is really in bytes. unsigned VBTableIndex = I->getOffsetInBits() / 4; auto RecordKind = (I->getFlags() & DINode::FlagIndirectVirtualBase) == DINode::FlagIndirectVirtualBase Index: llvm/lib/IR/AsmWriter.cpp =================================================================== --- llvm/lib/IR/AsmWriter.cpp +++ llvm/lib/IR/AsmWriter.cpp @@ -1716,6 +1716,7 @@ Printer.printInt("size", N->getSizeInBits()); Printer.printInt("align", N->getAlignInBits()); Printer.printInt("offset", N->getOffsetInBits()); + Printer.printInt("vbpOffset", N->getVBPtrOffset()); Printer.printDIFlags("flags", N->getFlags()); Printer.printMetadata("extraData", N->getRawExtraData()); if (const auto &DWARFAddressSpace = N->getDWARFAddressSpace()) Index: llvm/lib/IR/DIBuilder.cpp =================================================================== --- llvm/lib/IR/DIBuilder.cpp +++ llvm/lib/IR/DIBuilder.cpp @@ -313,10 +313,12 @@ DIDerivedType *DIBuilder::createInheritance(DIType *Ty, DIType *BaseTy, uint64_t BaseOffset, + uint32_t VBPtrOffset, DINode::DIFlags Flags) { assert(Ty && "Unable to create inheritance"); return DIDerivedType::get(VMContext, dwarf::DW_TAG_inheritance, "", nullptr, - 0, Ty, BaseTy, 0, 0, BaseOffset, None, Flags); + 0, Ty, BaseTy, 0, 0, BaseOffset, VBPtrOffset, None, + Flags); } DIDerivedType *DIBuilder::createMemberType(DIScope *Scope, StringRef Name, Index: llvm/lib/IR/DebugInfoMetadata.cpp =================================================================== --- llvm/lib/IR/DebugInfoMetadata.cpp +++ llvm/lib/IR/DebugInfoMetadata.cpp @@ -286,18 +286,18 @@ DIDerivedType *DIDerivedType::getImpl( LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits, - uint32_t AlignInBits, uint64_t OffsetInBits, + uint32_t AlignInBits, uint64_t OffsetInBits, uint32_t VBPtrOffset, Optional DWARFAddressSpace, DIFlags Flags, Metadata *ExtraData, StorageType Storage, bool ShouldCreate) { assert(isCanonical(Name) && "Expected canonical MDString"); DEFINE_GETIMPL_LOOKUP(DIDerivedType, (Tag, Name, File, Line, Scope, BaseType, SizeInBits, - AlignInBits, OffsetInBits, DWARFAddressSpace, Flags, - ExtraData)); + AlignInBits, OffsetInBits, VBPtrOffset, + DWARFAddressSpace, Flags, ExtraData)); Metadata *Ops[] = {File, Scope, Name, BaseType, ExtraData}; DEFINE_GETIMPL_STORE( DIDerivedType, (Tag, Line, SizeInBits, AlignInBits, OffsetInBits, - DWARFAddressSpace, Flags), Ops); + VBPtrOffset, DWARFAddressSpace, Flags), Ops); } DICompositeType *DICompositeType::getImpl( Index: llvm/lib/IR/LLVMContextImpl.h =================================================================== --- llvm/lib/IR/LLVMContextImpl.h +++ llvm/lib/IR/LLVMContextImpl.h @@ -406,6 +406,7 @@ Metadata *BaseType; uint64_t SizeInBits; uint64_t OffsetInBits; + uint32_t VBPtrOffset; uint32_t AlignInBits; Optional DWARFAddressSpace; unsigned Flags; @@ -414,17 +415,19 @@ MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, - Optional DWARFAddressSpace, unsigned Flags, - Metadata *ExtraData) + uint32_t VBPtrOffset, Optional DWARFAddressSpace, + unsigned Flags, Metadata *ExtraData) : Tag(Tag), Name(Name), File(File), Line(Line), Scope(Scope), BaseType(BaseType), SizeInBits(SizeInBits), OffsetInBits(OffsetInBits), - AlignInBits(AlignInBits), DWARFAddressSpace(DWARFAddressSpace), - Flags(Flags), ExtraData(ExtraData) {} + VBPtrOffset(VBPtrOffset), AlignInBits(AlignInBits), + DWARFAddressSpace(DWARFAddressSpace), Flags(Flags), + ExtraData(ExtraData) {} MDNodeKeyImpl(const DIDerivedType *N) : Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()), Line(N->getLine()), Scope(N->getRawScope()), BaseType(N->getRawBaseType()), SizeInBits(N->getSizeInBits()), - OffsetInBits(N->getOffsetInBits()), AlignInBits(N->getAlignInBits()), + OffsetInBits(N->getOffsetInBits()), VBPtrOffset(N->getVBPtrOffset()), + AlignInBits(N->getAlignInBits()), DWARFAddressSpace(N->getDWARFAddressSpace()), Flags(N->getFlags()), ExtraData(N->getRawExtraData()) {} @@ -435,6 +438,7 @@ SizeInBits == RHS->getSizeInBits() && AlignInBits == RHS->getAlignInBits() && OffsetInBits == RHS->getOffsetInBits() && + VBPtrOffset == RHS->getVBPtrOffset() && DWARFAddressSpace == RHS->getDWARFAddressSpace() && Flags == RHS->getFlags() && ExtraData == RHS->getRawExtraData(); Index: llvm/test/Bitcode/diglobalvariable-3.8.ll =================================================================== --- llvm/test/Bitcode/diglobalvariable-3.8.ll +++ llvm/test/Bitcode/diglobalvariable-3.8.ll @@ -1,19 +1,19 @@ ; RUN: llvm-dis -o - %s.bc | FileCheck %s !llvm.dbg.cu = !{!0} -!llvm.module.flags = !{!7, !8} +!llvm.module.flags = !{!8, !9} ; CHECK: !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 3.8.1", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, globals: !3) -!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 3.8.1", isOptimized: true, runtimeVersion: 0, emissionKind: 1, enums: !2, globals: !3) +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 3.8.1", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, globals: !3) !1 = !DIFile(filename: "g.c", directory: "/") !2 = !{} ; CHECK: !3 = !{!4} !3 = !{!4} ; CHECK: !4 = {{.*}}!DIGlobalVariableExpression(var: !5, expr: !DIExpression(DW_OP_constu, 42, DW_OP_stack_value)) +!4 = distinct !DIGlobalVariableExpression(var: !5, expr: !DIExpression(DW_OP_constu, 42, DW_OP_stack_value)) ; CHECK: !5 = !DIGlobalVariable(name: "c", scope: !0, file: !1, line: 1, type: !6, isLocal: false, isDefinition: true) -!4 = !DIGlobalVariable(name: "c", scope: !0, file: !1, line: 1, type: !5, isLocal: false, isDefinition: true, variable: i32 42) -!5 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !6) -!6 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed) -!7 = !{i32 2, !"Dwarf Version", i32 2} -!8 = !{i32 2, !"Debug Info Version", i32 3} - +!5 = !DIGlobalVariable(name: "c", scope: !0, file: !1, line: 1, type: !6, isLocal: false, isDefinition: true) +!6 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !7) +!7 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!8 = !{i32 2, !"Dwarf Version", i32 2} +!9 = !{i32 2, !"Debug Info Version", i32 3} Index: llvm/test/Bitcode/dityperefs-3.8.ll =================================================================== --- llvm/test/Bitcode/dityperefs-3.8.ll +++ llvm/test/Bitcode/dityperefs-3.8.ll @@ -28,20 +28,20 @@ !0 = !DIFile(filename: "path/to/file", directory: "/path/to/dir") !1 = !DICompositeType(tag: DW_TAG_structure_type, name: "T1", file: !0, identifier: "T1") -!2 = !DICompositeType(tag: DW_TAG_structure_type, name: "T2", file: !0, scope: !"T1", baseType: !"T1", vtableHolder: !"T1", identifier: "T2") -!3 = !DIDerivedType(tag: DW_TAG_member, name: "M1", file: !0, scope: !"T1", baseType: !"T2") +!2 = !DICompositeType(tag: DW_TAG_structure_type, name: "T2", scope: !1, file: !0, baseType: !1, vtableHolder: !1, identifier: "T2") +!3 = !DIDerivedType(tag: DW_TAG_member, name: "M1", scope: !1, file: !0, baseType: !2) !4 = !DISubroutineType(types: !5) -!5 = !{!"T1", !"T2"} -!6 = !DISubprogram(scope: !"T1", isDefinition: false, containingType: !"T1") -!7 = !DILocalVariable(name: "V1", scope: !6, type: !"T2") -!8 = !DIObjCProperty(name: "P1", type: !"T1") -!9 = !DITemplateTypeParameter(type: !"T1") -!10 = !DIGlobalVariable(name: "G", type: !"T1", isDefinition: false, variable: i32* @G1) -!11 = !DITemplateValueParameter(type: !"T1", value: i32* @G1) -!12 = !DIImportedEntity(tag: DW_TAG_imported_module, name: "T2", scope: !0, entity: !"T1") +!5 = !{!1, !2} +!6 = !DISubprogram(scope: !1, isLocal: false, isDefinition: false, containingType: !1, isOptimized: false) +!7 = !DILocalVariable(name: "V1", scope: !6, type: !2) +!8 = !DIObjCProperty(name: "P1", type: !1) +!9 = !DITemplateTypeParameter(type: !1) +!10 = !DIGlobalVariable(name: "G", scope: null, type: !1, isLocal: false, isDefinition: false) +!11 = !DITemplateValueParameter(type: !1, value: i32* @G1) +!12 = !DIImportedEntity(tag: DW_TAG_imported_module, name: "T2", scope: !0, entity: !1) !13 = !DICompositeType(tag: DW_TAG_structure_type, name: "T3", file: !0, elements: !14, identifier: "T3") !14 = !{!15} -!15 = !DISubprogram(scope: !"T3", isDefinition: false) -!16 = !DIDerivedType(tag: DW_TAG_ptr_to_member_type, baseType: !4, extraData: !"T3") +!15 = !DISubprogram(scope: !13, isLocal: false, isDefinition: false, isOptimized: false) +!16 = !DIDerivedType(tag: DW_TAG_ptr_to_member_type, baseType: !4, extraData: !13) @G1 = global i32 0 Index: llvm/test/DebugInfo/COFF/inheritance.ll =================================================================== --- llvm/test/DebugInfo/COFF/inheritance.ll +++ llvm/test/DebugInfo/COFF/inheritance.ll @@ -3,8 +3,8 @@ ; C++ source to regenerate: ; $ cat t.cpp ; struct A { int a; }; -; struct B : virtual A { int b; }; -; struct C : virtual A { int c; }; +; struct B : virtual A { int b; virtual int get() { return b; } }; +; struct C : virtual A { int c; virtual int get() { return c; } }; ; struct D : B, C { ; virtual void f(); // make vbptr not offset zero ; int d; @@ -12,32 +12,7 @@ ; 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: TypeLeafKind: LF_BCLASS (0x1400) -; CHECK-NEXT: AccessSpecifier: Public (0x3) -; CHECK-NEXT: BaseType: B ({{.*}}) -; CHECK-NEXT: BaseOffset: 0x8 -; CHECK-NEXT: } -; CHECK-NEXT: BaseClass { -; CHECK-NEXT: TypeLeafKind: LF_BCLASS (0x1400) -; CHECK-NEXT: AccessSpecifier: Public (0x3) -; CHECK-NEXT: BaseType: C ({{.*}}) -; CHECK-NEXT: BaseOffset: 0x18 -; CHECK-NEXT: } -; CHECK-NEXT: IndirectVirtualBaseClass { -; CHECK-NEXT: TypeLeafKind: LF_IVBCLASS (0x1402) -; 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 B's field list. +; struct B's field list comes first. ; CHECK: FieldList ({{.*}}) { ; CHECK-NEXT: TypeLeafKind: LF_FIELDLIST (0x1203) ; CHECK-NEXT: VirtualBaseClass { @@ -45,88 +20,178 @@ ; CHECK-NEXT: AccessSpecifier: Public (0x3) ; CHECK-NEXT: BaseType: A ({{.*}}) ; CHECK-NEXT: VBPtrType: const int* ({{.*}}) -; CHECK-NEXT: VBPtrOffset: 0x0 +; CHECK-NEXT: VBPtrOffset: 0x8 ; 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: TypeLeafKind: LF_VBCLASS (0x1401) -; 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: } +; struct A's field list comes next. +; CHECK: FieldList ({{.*}}) +; CHECK-NEXT: TypeLeafKind: LF_FIELDLIST (0x1203) +; CHECK: } + +; struct C's field list comes next. +; CHECK: FieldList ({{.*}}) +; CHECK-NEXT: TypeLeafKind: LF_FIELDLIST (0x1203) +; CHECK-NEXT: VirtualBaseClass { +; CHECK-NEXT: TypeLeafKind: LF_VBCLASS (0x1401) +; CHECK-NEXT: AccessSpecifier: Public (0x3) +; CHECK-NEXT: BaseType: A ({{.*}}) +; CHECK-NEXT: VBPtrType: const int* ({{.*}}) +; CHECK-NEXT: VBPtrOffset: 0x8 +; CHECK-NEXT: VBTableIndex: 0x1 +; CHECK-NEXT: } +; CHECK: } + +; struct D's field list is last. +; CHECK: FieldList ({{.*}}) { +; CHECK-NEXT: TypeLeafKind: LF_FIELDLIST (0x1203) +; CHECK-NEXT: BaseClass { +; CHECK-NEXT: TypeLeafKind: LF_BCLASS (0x1400) +; CHECK-NEXT: AccessSpecifier: Public (0x3) +; CHECK-NEXT: BaseType: B ({{.*}}) +; CHECK-NEXT: BaseOffset: 0x0 +; CHECK-NEXT: } +; CHECK-NEXT: BaseClass { +; CHECK-NEXT: TypeLeafKind: LF_BCLASS (0x1400) +; CHECK-NEXT: AccessSpecifier: Public (0x3) +; CHECK-NEXT: BaseType: C ({{.*}}) +; CHECK-NEXT: BaseOffset: 0x18 +; CHECK-NEXT: } +; CHECK-NEXT: IndirectVirtualBaseClass { +; CHECK-NEXT: TypeLeafKind: LF_IVBCLASS (0x1402) +; CHECK-NEXT: AccessSpecifier: Public (0x3) +; CHECK-NEXT: BaseType: A ({{.*}}) +; CHECK-NEXT: VBPtrType: const int* ({{.*}}) +; CHECK-NEXT: VBPtrOffset: 0x8 +; 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" +target triple = "x86_64-pc-windows-msvc19.12.25835" -%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.D = type { %struct.B.base, %struct.C.base, i32, [4 x i8], %struct.A } +%struct.B.base = type { i32 (...)**, i32*, i32 } +%struct.C.base = type { i32 (...)**, i32*, i32 } %struct.A = type { i32 } +%struct.B = type { i32 (...)**, i32*, i32, [4 x i8], %struct.A } +%struct.C = type { i32 (...)**, i32*, i32, [4 x i8], %struct.A } -$"\01??_8D@@7BB@@@" = comdat any +$"?get@B@@UEAAHXZ" = comdat any -$"\01??_8D@@7BC@@@" = comdat any +$"?get@C@@UEAAHXZ" = comdat any -$"\01??_7D@@6B@" = comdat any +$"??_8D@@7BB@@@" = comdat any -@"\01?d@@3UD@@A" = local_unnamed_addr global %struct.D { i32 (...)** bitcast ([1 x i8*]* @"\01??_7D@@6B@" to i32 (...)**), %struct.B.base { i32* getelementptr inbounds ([2 x i32], [2 x i32]* @"\01??_8D@@7BB@@@", i32 0, i32 0), i32 0 }, %struct.C.base { i32* getelementptr inbounds ([2 x i32], [2 x i32]* @"\01??_8D@@7BC@@@", i32 0, i32 0), i32 0 }, i32 0, [4 x i8] zeroinitializer, %struct.A zeroinitializer }, align 8, !dbg !0 -@"\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@D@@UEAAXXZ" to i8*)], comdat -@llvm.global_ctors = appending global [0 x { i32, void ()*, i8* }] zeroinitializer +$"??_8D@@7BC@@@" = comdat any -declare void @"\01?f@D@@UEAAXXZ"(%struct.D*) unnamed_addr #0 +$"??_7D@@6BB@@@" = comdat any -attributes #0 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "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"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } +$"??_7D@@6BC@@@" = comdat any + +@"?d@@3UD@@A" = dso_local local_unnamed_addr global %struct.D { %struct.B.base { i32 (...)** bitcast ({ [2 x i8*] }* @"??_7D@@6BB@@@" to i32 (...)**), i32* getelementptr inbounds ([2 x i32], [2 x i32]* @"??_8D@@7BB@@@", i32 0, i32 0), i32 0 }, %struct.C.base { i32 (...)** bitcast ({ [1 x i8*] }* @"??_7D@@6BC@@@" to i32 (...)**), i32* getelementptr inbounds ([2 x i32], [2 x i32]* @"??_8D@@7BC@@@", i32 0, i32 0), i32 0 }, i32 0, [4 x i8] zeroinitializer, %struct.A zeroinitializer }, align 8, !dbg !0 +@"??_8D@@7BB@@@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 -8, i32 48], comdat +@"??_8D@@7BC@@@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 -8, i32 24], comdat +@"??_7D@@6BB@@@" = linkonce_odr unnamed_addr constant { [2 x i8*] } { [2 x i8*] [i8* bitcast (i32 (%struct.B*)* @"?get@B@@UEAAHXZ" to i8*), i8* bitcast (void (%struct.D*)* @"?f@D@@UEAAXXZ" to i8*)] }, comdat +@"??_7D@@6BC@@@" = linkonce_odr unnamed_addr constant { [1 x i8*] } { [1 x i8*] [i8* bitcast (i32 (%struct.C*)* @"?get@C@@UEAAHXZ" to i8*)] }, comdat +@llvm.global_ctors = appending global [0 x { i32, void ()*, i8* }] zeroinitializer + +; Function Attrs: nounwind uwtable +define linkonce_odr dso_local i32 @"?get@B@@UEAAHXZ"(%struct.B* %this) unnamed_addr #0 comdat align 2 !dbg !46 { +entry: + call void @llvm.dbg.value(metadata %struct.B* %this, metadata !48, metadata !DIExpression()), !dbg !50 + %b = getelementptr inbounds %struct.B, %struct.B* %this, i64 0, i32 2, !dbg !51 + %0 = load i32, i32* %b, align 8, !dbg !51, !tbaa !52 + ret i32 %0, !dbg !51 +} + +declare dso_local void @"?f@D@@UEAAXXZ"(%struct.D*) unnamed_addr #1 + +; Function Attrs: nounwind uwtable +define linkonce_odr dso_local i32 @"?get@C@@UEAAHXZ"(%struct.C* %this) unnamed_addr #0 comdat align 2 !dbg !57 { +entry: + call void @llvm.dbg.value(metadata %struct.C* %this, metadata !59, metadata !DIExpression()), !dbg !61 + %c = getelementptr inbounds %struct.C, %struct.C* %this, i64 0, i32 2, !dbg !62 + %0 = load i32, i32* %c, align 8, !dbg !62, !tbaa !63 + ret i32 %0, !dbg !62 +} + +; Function Attrs: nounwind readnone speculatable +declare void @llvm.dbg.value(metadata, metadata, metadata) #2 + +attributes #0 = { nounwind uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "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" "no-signed-zeros-fp-math"="false" "no-trapping-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 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "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"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { nounwind readnone speculatable } !llvm.dbg.cu = !{!2} -!llvm.module.flags = !{!32, !33, !34} -!llvm.ident = !{!35} +!llvm.module.flags = !{!41, !42, !43, !44} +!llvm.ident = !{!45} -!0 = distinct !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) -!1 = !DIGlobalVariable(name: "d", linkageName: "\01?d@@3UD@@A", scope: !2, file: !6, line: 8, type: !7, isLocal: false, isDefinition: true) -!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, producer: "clang version 4.0.0 (http://llvm.org/git/clang.git 95626d54d6db7e13087089396a80ebaccc4ffe7c) (http://llvm.org/git/llvm.git 374b6e2fa0b230d13c0fb9ee7af69b2146bfad8a)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5) -!3 = !DIFile(filename: "t.cpp", directory: "D:\5Csrc\5Cllvm\5Cbuild") +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "d", linkageName: "?d@@3UD@@A", scope: !2, file: !3, line: 8, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, producer: "clang version 7.0.0 (trunk)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5) +!3 = !DIFile(filename: "t.cpp", directory: "C:\5CPath\5CTo\5CDirectory", checksumkind: CSK_MD5, checksum: "7477d4db6bf8a461a719bcaab9c6d65e") !4 = !{} !5 = !{!0} -!6 = !DIFile(filename: "t.cpp", directory: "C:\5Cbuild\5Cllvm\5Cbuild") -!7 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "D", file: !6, line: 4, size: 448, elements: !8, vtableHolder: !7, identifier: ".?AUD@@") -!8 = !{!9, !18, !23, !24, !25, !27, !28} -!9 = !DIDerivedType(tag: DW_TAG_inheritance, scope: !7, baseType: !10, offset: 64) -!10 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "B", file: !6, line: 2, size: 192, elements: !11, vtableHolder: !10, identifier: ".?AUB@@") -!11 = !{!12, !17} -!12 = !DIDerivedType(tag: DW_TAG_inheritance, scope: !10, baseType: !13, offset: 4, flags: DIFlagVirtual) -!13 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "A", file: !6, line: 1, size: 32, elements: !14, identifier: ".?AUA@@") -!14 = !{!15} -!15 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !13, file: !6, line: 1, baseType: !16, size: 32) -!16 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) -!17 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !10, file: !6, line: 2, baseType: !16, size: 32, offset: 64) -!18 = !DIDerivedType(tag: DW_TAG_inheritance, scope: !7, baseType: !19, offset: 192) -!19 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "C", file: !6, line: 3, size: 192, elements: !20, vtableHolder: !19, identifier: ".?AUC@@") -!20 = !{!21, !22} -!21 = !DIDerivedType(tag: DW_TAG_inheritance, scope: !19, baseType: !13, offset: 4, flags: DIFlagVirtual) -!22 = !DIDerivedType(tag: DW_TAG_member, name: "c", scope: !19, file: !6, line: 3, baseType: !16, size: 32, offset: 64) -!23 = !DIDerivedType(tag: DW_TAG_inheritance, scope: !7, baseType: !13, offset: 4, flags: DIFlagIndirectVirtualBase) -!24 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "__vtbl_ptr_type", baseType: null, size: 64) -!25 = !DIDerivedType(tag: DW_TAG_member, name: "_vptr$D", scope: !6, file: !6, baseType: !26, size: 64, flags: DIFlagArtificial) -!26 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !24, size: 64) -!27 = !DIDerivedType(tag: DW_TAG_member, name: "d", scope: !7, file: !6, line: 6, baseType: !16, size: 32, offset: 320) -!28 = !DISubprogram(name: "f", linkageName: "\01?f@D@@UEAAXXZ", scope: !7, file: !6, line: 5, type: !29, isLocal: false, isDefinition: false, scopeLine: 5, containingType: !7, virtuality: DW_VIRTUALITY_virtual, virtualIndex: 0, flags: DIFlagPrototyped | DIFlagIntroducedVirtual, isOptimized: true) -!29 = !DISubroutineType(types: !30) -!30 = !{null, !31} -!31 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !7, size: 64, flags: DIFlagArtificial | DIFlagObjectPointer) -!32 = !{i32 2, !"CodeView", i32 1} -!33 = !{i32 2, !"Debug Info Version", i32 3} -!34 = !{i32 1, !"PIC Level", i32 2} -!35 = !{!"clang version 4.0.0 (http://llvm.org/git/clang.git 95626d54d6db7e13087089396a80ebaccc4ffe7c) (http://llvm.org/git/llvm.git 374b6e2fa0b230d13c0fb9ee7af69b2146bfad8a)"} - +!6 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "D", file: !3, line: 4, size: 512, flags: DIFlagTypePassByReference, elements: !7, vtableHolder: !9, identifier: ".?AUD@@") +!7 = !{!8, !24, !34, !35, !36, !37} +!8 = !DIDerivedType(tag: DW_TAG_inheritance, scope: !6, baseType: !9) +!9 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "B", file: !3, line: 2, size: 256, flags: DIFlagTypePassByReference, elements: !10, vtableHolder: !9, identifier: ".?AUB@@") +!10 = !{!11, !16, !17, !19, !20} +!11 = !DIDerivedType(tag: DW_TAG_inheritance, scope: !9, baseType: !12, offset: 4, vbpOffset: 8, flags: DIFlagVirtual) +!12 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "A", file: !3, line: 1, size: 32, flags: DIFlagTypePassByValue, elements: !13, identifier: ".?AUA@@") +!13 = !{!14} +!14 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !12, file: !3, line: 1, baseType: !15, size: 32) +!15 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!16 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "__vtbl_ptr_type", baseType: null, size: 64) +!17 = !DIDerivedType(tag: DW_TAG_member, name: "_vptr$B", scope: !3, file: !3, baseType: !18, size: 64, flags: DIFlagArtificial) +!18 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !16, size: 64) +!19 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !9, file: !3, line: 2, baseType: !15, size: 32, offset: 128) +!20 = !DISubprogram(name: "get", linkageName: "?get@B@@UEAAHXZ", scope: !9, file: !3, line: 2, type: !21, isLocal: false, isDefinition: false, scopeLine: 2, containingType: !9, virtuality: DW_VIRTUALITY_virtual, virtualIndex: 0, flags: DIFlagPrototyped | DIFlagIntroducedVirtual, isOptimized: true) +!21 = !DISubroutineType(types: !22) +!22 = !{!15, !23} +!23 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !9, size: 64, flags: DIFlagArtificial | DIFlagObjectPointer) +!24 = !DIDerivedType(tag: DW_TAG_inheritance, scope: !6, baseType: !25, offset: 192) +!25 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "C", file: !3, line: 3, size: 256, flags: DIFlagTypePassByReference, elements: !26, vtableHolder: !25, identifier: ".?AUC@@") +!26 = !{!27, !16, !28, !29, !30} +!27 = !DIDerivedType(tag: DW_TAG_inheritance, scope: !25, baseType: !12, offset: 4, vbpOffset: 8, flags: DIFlagVirtual) +!28 = !DIDerivedType(tag: DW_TAG_member, name: "_vptr$C", scope: !3, file: !3, baseType: !18, size: 64, flags: DIFlagArtificial) +!29 = !DIDerivedType(tag: DW_TAG_member, name: "c", scope: !25, file: !3, line: 3, baseType: !15, size: 32, offset: 128) +!30 = !DISubprogram(name: "get", linkageName: "?get@C@@UEAAHXZ", scope: !25, file: !3, line: 3, type: !31, isLocal: false, isDefinition: false, scopeLine: 3, containingType: !25, virtuality: DW_VIRTUALITY_virtual, virtualIndex: 0, flags: DIFlagPrototyped | DIFlagIntroducedVirtual, isOptimized: true) +!31 = !DISubroutineType(types: !32) +!32 = !{!15, !33} +!33 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !25, size: 64, flags: DIFlagArtificial | DIFlagObjectPointer) +!34 = !DIDerivedType(tag: DW_TAG_inheritance, scope: !6, baseType: !12, offset: 4, vbpOffset: 8, flags: DIFlagIndirectVirtualBase) +!35 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "__vtbl_ptr_type", baseType: null, size: 128) +!36 = !DIDerivedType(tag: DW_TAG_member, name: "d", scope: !6, file: !3, line: 6, baseType: !15, size: 32, offset: 384) +!37 = !DISubprogram(name: "f", linkageName: "?f@D@@UEAAXXZ", scope: !6, file: !3, line: 5, type: !38, isLocal: false, isDefinition: false, scopeLine: 5, containingType: !6, virtuality: DW_VIRTUALITY_virtual, virtualIndex: 1, flags: DIFlagPrototyped | DIFlagIntroducedVirtual, isOptimized: true) +!38 = !DISubroutineType(types: !39) +!39 = !{null, !40} +!40 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !6, size: 64, flags: DIFlagArtificial | DIFlagObjectPointer) +!41 = !{i32 2, !"CodeView", i32 1} +!42 = !{i32 2, !"Debug Info Version", i32 3} +!43 = !{i32 1, !"wchar_size", i32 2} +!44 = !{i32 7, !"PIC Level", i32 2} +!45 = !{!"clang version 7.0.0 (trunk)"} +!46 = distinct !DISubprogram(name: "get", linkageName: "?get@B@@UEAAHXZ", scope: !9, file: !3, line: 2, type: !21, isLocal: false, isDefinition: true, scopeLine: 2, flags: DIFlagPrototyped, isOptimized: true, unit: !2, declaration: !20, variables: !47) +!47 = !{!48} +!48 = !DILocalVariable(name: "this", arg: 1, scope: !46, type: !49, flags: DIFlagArtificial | DIFlagObjectPointer) +!49 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !9, size: 64) +!50 = !DILocation(line: 0, scope: !46) +!51 = !DILocation(line: 2, scope: !46) +!52 = !{!53, !54, i64 16} +!53 = !{!"?AUB@@", !54, i64 16} +!54 = !{!"int", !55, i64 0} +!55 = !{!"omnipotent char", !56, i64 0} +!56 = !{!"Simple C++ TBAA"} +!57 = distinct !DISubprogram(name: "get", linkageName: "?get@C@@UEAAHXZ", scope: !25, file: !3, line: 3, type: !31, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagPrototyped, isOptimized: true, unit: !2, declaration: !30, variables: !58) +!58 = !{!59} +!59 = !DILocalVariable(name: "this", arg: 1, scope: !57, type: !60, flags: DIFlagArtificial | DIFlagObjectPointer) +!60 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !25, size: 64) +!61 = !DILocation(line: 0, scope: !57) +!62 = !DILocation(line: 3, scope: !57) +!63 = !{!64, !54, i64 16} +!64 = !{!"?AUC@@", !54, i64 16} Index: llvm/tools/clang/lib/CodeGen/CGDebugInfo.cpp =================================================================== --- llvm/tools/clang/lib/CodeGen/CGDebugInfo.cpp +++ llvm/tools/clang/lib/CodeGen/CGDebugInfo.cpp @@ -1535,6 +1535,7 @@ auto *BaseTy = getOrCreateType(BI.getType(), Unit); llvm::DINode::DIFlags BFlags = StartingFlags; uint64_t BaseOffset; + uint32_t VBPtrOffset = 0; if (BI.isVirtual()) { if (CGM.getTarget().getCXXABI().isItaniumFamily()) { @@ -1548,6 +1549,8 @@ // vbase offset offset in Itanium. BaseOffset = 4 * CGM.getMicrosoftVTableContext().getVBTableIndex(RD, Base); + VBPtrOffset = CGM.getContext().getASTRecordLayout(RD).getVBPtrOffset() + .getQuantity(); } BFlags |= llvm::DINode::FlagVirtual; } else @@ -1557,7 +1560,8 @@ BFlags |= getAccessFlag(BI.getAccessSpecifier(), RD); llvm::DIType *DTy = - DBuilder.createInheritance(RecordTy, BaseTy, BaseOffset, BFlags); + DBuilder.createInheritance(RecordTy, BaseTy, BaseOffset, VBPtrOffset, + BFlags); EltTys.push_back(DTy); } } @@ -2191,7 +2195,7 @@ if (!SClassTy) return nullptr; - llvm::DIType *InhTag = DBuilder.createInheritance(RealDecl, SClassTy, 0, + llvm::DIType *InhTag = DBuilder.createInheritance(RealDecl, SClassTy, 0, 0, llvm::DINode::FlagZero); EltTys.push_back(InhTag); } Index: llvm/tools/clang/test/CodeGenCXX/debug-info-ms-vbase.cpp =================================================================== --- llvm/tools/clang/test/CodeGenCXX/debug-info-ms-vbase.cpp +++ llvm/tools/clang/test/CodeGenCXX/debug-info-ms-vbase.cpp @@ -18,7 +18,7 @@ // CHECK: ![[elements]] = !{![[SecondaryVTable_base:[0-9]+]], ![[HasVirtualMethod_base:[0-9]+]], ![[vshape:[0-9]+]]} // CHECK: ![[SecondaryVTable_base]] = !DIDerivedType(tag: DW_TAG_inheritance, scope: ![[HasPrimaryBase]], -// CHECK-SAME: baseType: ![[SecondaryVTable:[0-9]+]], offset: 4, flags: DIFlagVirtual) +// CHECK-SAME: baseType: ![[SecondaryVTable:[0-9]+]], offset: 4, vbpOffset: 4, flags: DIFlagVirtual) // CHECK: ![[SecondaryVTable]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "SecondaryVTable"