diff --git a/llvm/include/llvm/IR/DIBuilder.h b/llvm/include/llvm/IR/DIBuilder.h index 046890d0c7e1f..cb1150c269a1d 100644 --- a/llvm/include/llvm/IR/DIBuilder.h +++ b/llvm/include/llvm/IR/DIBuilder.h @@ -488,6 +488,8 @@ namespace llvm { /// \param Elements Struct elements. /// \param RunTimeLang Optional parameter, Objective-C runtime version. /// \param UniqueIdentifier A unique identifier for the struct. + /// \param Specification The type that this type completes. This is used by + /// Swift to represent generic types. /// \param NumExtraInhabitants The number of extra inhabitants of the type. /// An extra inhabitant is a bit pattern that does not represent a valid /// value for instances of a given type. This is used by the Swift language. @@ -496,7 +498,7 @@ namespace llvm { uint64_t SizeInBits, uint32_t AlignInBits, DINode::DIFlags Flags, DIType *DerivedFrom, DINodeArray Elements, unsigned RunTimeLang = 0, DIType *VTableHolder = nullptr, StringRef UniqueIdentifier = "", - uint32_t NumExtraInhabitants = 0); + DIType *Specification = nullptr, uint32_t NumExtraInhabitants = 0); /// Create debugging information entry for an union. /// \param Scope Scope in which this union is defined. diff --git a/llvm/include/llvm/IR/DebugInfoMetadata.h b/llvm/include/llvm/IR/DebugInfoMetadata.h index 5c8394e45c9d7..c770955be76da 100644 --- a/llvm/include/llvm/IR/DebugInfoMetadata.h +++ b/llvm/include/llvm/IR/DebugInfoMetadata.h @@ -1201,7 +1201,7 @@ class DICompositeType : public DIType { static DICompositeType * getImpl(LLVMContext &Context, unsigned Tag, StringRef Name, Metadata *File, unsigned Line, DIScope *Scope, DIType *BaseType, uint64_t SizeInBits, - uint32_t AlignInBits, uint64_t OffsetInBits, + uint32_t AlignInBits, uint64_t OffsetInBits, DIType *Specification, uint32_t NumExtraInhabitants, DIFlags Flags, DINodeArray Elements, unsigned RuntimeLang, DIType *VTableHolder, DITemplateParameterArray TemplateParams, StringRef Identifier, @@ -1215,7 +1215,7 @@ class DICompositeType : public DIType { TemplateParams.get(), getCanonicalMDString(Context, Identifier), Discriminator, DataLocation, Associated, Allocated, Rank, Annotations.get(), - NumExtraInhabitants, Storage, ShouldCreate); + Specification, NumExtraInhabitants, Storage, ShouldCreate); } static DICompositeType * getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File, @@ -1225,8 +1225,9 @@ class DICompositeType : public DIType { Metadata *VTableHolder, Metadata *TemplateParams, MDString *Identifier, Metadata *Discriminator, Metadata *DataLocation, Metadata *Associated, Metadata *Allocated, Metadata *Rank, - Metadata *Annotations, uint32_t NumExtraInhabitants, - StorageType Storage, bool ShouldCreate = true); + Metadata *Annotations, Metadata *Specification, + uint32_t NumExtraInhabitants, StorageType Storage, + bool ShouldCreate = true); TempDICompositeType cloneImpl() const { return getTemporary( @@ -1235,7 +1236,8 @@ class DICompositeType : public DIType { getFlags(), getElements(), getRuntimeLang(), getVTableHolder(), getTemplateParams(), getIdentifier(), getDiscriminator(), getRawDataLocation(), getRawAssociated(), getRawAllocated(), - getRawRank(), getAnnotations(), getNumExtraInhabitants()); + getRawRank(), getAnnotations(), getSpecification(), + getNumExtraInhabitants()); } public: @@ -1249,11 +1251,12 @@ class DICompositeType : public DIType { StringRef Identifier = "", DIDerivedType *Discriminator = nullptr, Metadata *DataLocation = nullptr, Metadata *Associated = nullptr, Metadata *Allocated = nullptr, Metadata *Rank = nullptr, - DINodeArray Annotations = nullptr, uint32_t NumExtraInhabitants = 0), + DINodeArray Annotations = nullptr, DIType *Specification = nullptr, + uint32_t NumExtraInhabitants = 0), (Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, - OffsetInBits, NumExtraInhabitants, Flags, Elements, RuntimeLang, - VTableHolder, TemplateParams, Identifier, Discriminator, DataLocation, - Associated, Allocated, Rank, Annotations)) + OffsetInBits, Specification, NumExtraInhabitants, Flags, Elements, + RuntimeLang, VTableHolder, TemplateParams, Identifier, Discriminator, + DataLocation, Associated, Allocated, Rank, Annotations)) DEFINE_MDNODE_GET( DICompositeType, (unsigned Tag, MDString *Name, Metadata *File, unsigned Line, @@ -1264,11 +1267,11 @@ class DICompositeType : public DIType { Metadata *Discriminator = nullptr, Metadata *DataLocation = nullptr, Metadata *Associated = nullptr, Metadata *Allocated = nullptr, Metadata *Rank = nullptr, Metadata *Annotations = nullptr, - uint32_t NumExtraInhabitants = 0), + Metadata *Specification = nullptr, uint32_t NumExtraInhabitants = 0), (Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams, Identifier, Discriminator, DataLocation, Associated, Allocated, Rank, - Annotations, NumExtraInhabitants)) + Annotations, Specification, NumExtraInhabitants)) TempDICompositeType clone() const { return cloneImpl(); } @@ -1283,8 +1286,9 @@ class DICompositeType : public DIType { getODRType(LLVMContext &Context, MDString &Identifier, unsigned Tag, MDString *Name, Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits, - uint64_t OffsetInBits, uint32_t NumExtraInhabitants, DIFlags Flags, - Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder, + uint64_t OffsetInBits, Metadata *Specification, + uint32_t NumExtraInhabitants, DIFlags Flags, Metadata *Elements, + unsigned RuntimeLang, Metadata *VTableHolder, Metadata *TemplateParams, Metadata *Discriminator, Metadata *DataLocation, Metadata *Associated, Metadata *Allocated, Metadata *Rank, Metadata *Annotations); @@ -1300,14 +1304,16 @@ class DICompositeType : public DIType { /// /// If not \a LLVMContext::isODRUniquingDebugTypes(), this function returns /// nullptr. - static DICompositeType *buildODRType( - LLVMContext &Context, MDString &Identifier, unsigned Tag, MDString *Name, - Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType, - uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, - uint32_t NumExtraInhabitants, DIFlags Flags, Metadata *Elements, - unsigned RuntimeLang, Metadata *VTableHolder, Metadata *TemplateParams, - Metadata *Discriminator, Metadata *DataLocation, Metadata *Associated, - Metadata *Allocated, Metadata *Rank, Metadata *Annotations); + static DICompositeType * + buildODRType(LLVMContext &Context, MDString &Identifier, unsigned Tag, + MDString *Name, Metadata *File, unsigned Line, Metadata *Scope, + Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits, + uint64_t OffsetInBits, Metadata *Specification, + uint32_t NumExtraInhabitants, DIFlags Flags, Metadata *Elements, + unsigned RuntimeLang, Metadata *VTableHolder, + Metadata *TemplateParams, Metadata *Discriminator, + Metadata *DataLocation, Metadata *Associated, + Metadata *Allocated, Metadata *Rank, Metadata *Annotations); DIType *getBaseType() const { return cast_or_null(getRawBaseType()); } DINodeArray getElements() const { @@ -1367,6 +1373,10 @@ class DICompositeType : public DIType { return cast_or_null(getRawAnnotations()); } + Metadata *getRawSpecification() const { return getOperand(14); } + DIType *getSpecification() const { + return cast_or_null(getRawSpecification()); + } /// Replace operands. /// /// If this \a isUniqued() and not \a isResolved(), on a uniquing collision diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index dd1baabc7e9ac..b8a8df71d4de2 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -5437,7 +5437,8 @@ bool LLParser::parseDICompositeType(MDNode *&Result, bool IsDistinct) { OPTIONAL(allocated, MDField, ); \ OPTIONAL(rank, MDSignedOrMDField, ); \ OPTIONAL(annotations, MDField, ); \ - OPTIONAL(num_extra_inhabitants, MDUnsignedField, (0, UINT32_MAX)); + OPTIONAL(num_extra_inhabitants, MDUnsignedField, (0, UINT32_MAX)); \ + OPTIONAL(specification, MDField, ); PARSE_MD_FIELDS(); #undef VISIT_MD_FIELDS @@ -5453,10 +5454,10 @@ bool LLParser::parseDICompositeType(MDNode *&Result, bool IsDistinct) { if (auto *CT = DICompositeType::buildODRType( Context, *identifier.Val, tag.Val, name.Val, file.Val, line.Val, scope.Val, baseType.Val, size.Val, align.Val, offset.Val, - num_extra_inhabitants.Val, flags.Val, elements.Val, runtimeLang.Val, - vtableHolder.Val, templateParams.Val, discriminator.Val, - dataLocation.Val, associated.Val, allocated.Val, Rank, - annotations.Val)) { + specification.Val, num_extra_inhabitants.Val, flags.Val, + elements.Val, runtimeLang.Val, vtableHolder.Val, templateParams.Val, + discriminator.Val, dataLocation.Val, associated.Val, allocated.Val, + Rank, annotations.Val)) { Result = CT; return false; } @@ -5469,7 +5470,7 @@ bool LLParser::parseDICompositeType(MDNode *&Result, bool IsDistinct) { size.Val, align.Val, offset.Val, flags.Val, elements.Val, runtimeLang.Val, vtableHolder.Val, templateParams.Val, identifier.Val, discriminator.Val, dataLocation.Val, associated.Val, allocated.Val, Rank, - annotations.Val, num_extra_inhabitants.Val)); + annotations.Val, specification.Val, num_extra_inhabitants.Val)); return false; } diff --git a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp index 8ca46a4ce821a..1caa8480efc51 100644 --- a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp +++ b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp @@ -1600,7 +1600,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( break; } case bitc::METADATA_COMPOSITE_TYPE: { - if (Record.size() < 16 || Record.size() > 23) + if (Record.size() < 16 || Record.size() > 24) return error("Invalid record"); // If we have a UUID and this is not a forward declaration, lookup the @@ -1630,6 +1630,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( Metadata *Allocated = nullptr; Metadata *Rank = nullptr; Metadata *Annotations = nullptr; + Metadata *Specification = nullptr; auto *Identifier = getMDString(Record[15]); // If this module is being parsed so that it can be ThinLTO imported // into another module, composite types only need to be imported as @@ -1678,14 +1679,18 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( if (Record.size() > 21) { Annotations = getMDOrNull(Record[21]); } + if (Record.size() > 23) { + Specification = getMDOrNull(Record[23]); + } } DICompositeType *CT = nullptr; if (Identifier) CT = DICompositeType::buildODRType( Context, *Identifier, Tag, Name, File, Line, Scope, BaseType, - SizeInBits, AlignInBits, OffsetInBits, NumExtraInhabitants, Flags, - Elements, RuntimeLang, VTableHolder, TemplateParams, Discriminator, - DataLocation, Associated, Allocated, Rank, Annotations); + SizeInBits, AlignInBits, OffsetInBits, Specification, + NumExtraInhabitants, Flags, Elements, RuntimeLang, VTableHolder, + TemplateParams, Discriminator, DataLocation, Associated, Allocated, + Rank, Annotations); // Create a node if we didn't get a lazy ODR type. if (!CT) @@ -1694,7 +1699,8 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( SizeInBits, AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams, Identifier, Discriminator, DataLocation, Associated, - Allocated, Rank, Annotations, NumExtraInhabitants)); + Allocated, Rank, Annotations, Specification, + NumExtraInhabitants)); if (!IsNotUsedInTypeRef && Identifier) MetadataList.addTypeRef(*Identifier, *cast(CT)); diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index de01750857bba..cd6541c258199 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -1947,6 +1947,7 @@ void ModuleBitcodeWriter::writeDICompositeType( Record.push_back(VE.getMetadataOrNullID(N->getRawRank())); Record.push_back(VE.getMetadataOrNullID(N->getAnnotations().get())); Record.push_back(N->getNumExtraInhabitants()); + Record.push_back(VE.getMetadataOrNullID(N->getRawSpecification())); Stream.EmitRecord(bitc::METADATA_COMPOSITE_TYPE, Record, Abbrev); Record.clear(); diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp index c6d9fcfb0b76c..316e05ba12392 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -1043,6 +1043,11 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, const DICompositeType *CTy) { addUInt(Buffer, dwarf::DW_AT_calling_convention, dwarf::DW_FORM_data1, CC); } + + if (auto *SpecifiedFrom = CTy->getSpecification()) + addDIEEntry(Buffer, dwarf::DW_AT_specification, + *getOrCreateContextDIE(SpecifiedFrom)); + break; } default: diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp index 3c1cb76622bbb..f6a5bc10ff3b2 100644 --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -2235,6 +2235,8 @@ static void writeDICompositeType(raw_ostream &Out, const DICompositeType *N, else Printer.printMetadata("rank", N->getRawRank(), /*ShouldSkipNull */ true); Printer.printMetadata("annotations", N->getRawAnnotations()); + if (auto *Specification = N->getRawSpecification()) + Printer.printMetadata("specification", Specification); Out << ")"; } diff --git a/llvm/lib/IR/DIBuilder.cpp b/llvm/lib/IR/DIBuilder.cpp index 3d8e12e95b774..3af397bfc9ad1 100644 --- a/llvm/lib/IR/DIBuilder.cpp +++ b/llvm/lib/IR/DIBuilder.cpp @@ -521,13 +521,13 @@ DICompositeType *DIBuilder::createStructType( DIScope *Context, StringRef Name, DIFile *File, unsigned LineNumber, uint64_t SizeInBits, uint32_t AlignInBits, DINode::DIFlags Flags, DIType *DerivedFrom, DINodeArray Elements, unsigned RunTimeLang, - DIType *VTableHolder, StringRef UniqueIdentifier, + DIType *VTableHolder, StringRef UniqueIdentifier, DIType *Specification, uint32_t NumExtraInhabitants) { auto *R = DICompositeType::get( VMContext, dwarf::DW_TAG_structure_type, Name, File, LineNumber, getNonCompileUnitScope(Context), DerivedFrom, SizeInBits, AlignInBits, 0, Flags, Elements, RunTimeLang, VTableHolder, nullptr, UniqueIdentifier, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, Specification, NumExtraInhabitants); trackIfUnresolved(R); return R; diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp index f7268a5140628..915cdd301f2c7 100644 --- a/llvm/lib/IR/DebugInfoMetadata.cpp +++ b/llvm/lib/IR/DebugInfoMetadata.cpp @@ -770,21 +770,21 @@ DICompositeType *DICompositeType::getImpl( Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder, Metadata *TemplateParams, MDString *Identifier, Metadata *Discriminator, Metadata *DataLocation, Metadata *Associated, Metadata *Allocated, - Metadata *Rank, Metadata *Annotations, uint32_t NumExtraInhabitants, - StorageType Storage, bool ShouldCreate) { + Metadata *Rank, Metadata *Annotations, Metadata *Specification, + uint32_t NumExtraInhabitants, StorageType Storage, bool ShouldCreate) { assert(isCanonical(Name) && "Expected canonical MDString"); // Keep this in sync with buildODRType. - DEFINE_GETIMPL_LOOKUP(DICompositeType, - (Tag, Name, File, Line, Scope, BaseType, SizeInBits, - AlignInBits, OffsetInBits, Flags, Elements, - RuntimeLang, VTableHolder, TemplateParams, Identifier, - Discriminator, DataLocation, Associated, Allocated, - Rank, Annotations, NumExtraInhabitants)); + DEFINE_GETIMPL_LOOKUP( + DICompositeType, + (Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, + OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams, + Identifier, Discriminator, DataLocation, Associated, Allocated, Rank, + Annotations, Specification, NumExtraInhabitants)); Metadata *Ops[] = {File, Scope, Name, BaseType, Elements, VTableHolder, TemplateParams, Identifier, Discriminator, DataLocation, Associated, Allocated, - Rank, Annotations}; + Rank, Annotations, Specification}; DEFINE_GETIMPL_STORE(DICompositeType, (Tag, Line, RuntimeLang, SizeInBits, AlignInBits, OffsetInBits, NumExtraInhabitants, Flags), @@ -795,10 +795,11 @@ DICompositeType *DICompositeType::buildODRType( LLVMContext &Context, MDString &Identifier, unsigned Tag, MDString *Name, Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, - uint32_t NumExtraInhabitants, DIFlags Flags, Metadata *Elements, - unsigned RuntimeLang, Metadata *VTableHolder, Metadata *TemplateParams, - Metadata *Discriminator, Metadata *DataLocation, Metadata *Associated, - Metadata *Allocated, Metadata *Rank, Metadata *Annotations) { + Metadata *Specification, uint32_t NumExtraInhabitants, DIFlags Flags, + Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder, + Metadata *TemplateParams, Metadata *Discriminator, Metadata *DataLocation, + Metadata *Associated, Metadata *Allocated, Metadata *Rank, + Metadata *Annotations) { assert(!Identifier.getString().empty() && "Expected valid identifier"); if (!Context.isODRUniquingDebugTypes()) return nullptr; @@ -809,8 +810,7 @@ DICompositeType *DICompositeType::buildODRType( AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams, &Identifier, Discriminator, DataLocation, Associated, Allocated, Rank, Annotations, - NumExtraInhabitants); - + Specification, NumExtraInhabitants); if (CT->getTag() != Tag) return nullptr; @@ -825,7 +825,7 @@ DICompositeType *DICompositeType::buildODRType( Metadata *Ops[] = {File, Scope, Name, BaseType, Elements, VTableHolder, TemplateParams, &Identifier, Discriminator, DataLocation, Associated, Allocated, - Rank, Annotations}; + Rank, Annotations, Specification}; assert((std::end(Ops) - std::begin(Ops)) == (int)CT->getNumOperands() && "Mismatched number of operands"); for (unsigned I = 0, E = CT->getNumOperands(); I != E; ++I) @@ -838,10 +838,11 @@ DICompositeType *DICompositeType::getODRType( LLVMContext &Context, MDString &Identifier, unsigned Tag, MDString *Name, Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, - uint32_t NumExtraInhabitants, DIFlags Flags, Metadata *Elements, - unsigned RuntimeLang, Metadata *VTableHolder, Metadata *TemplateParams, - Metadata *Discriminator, Metadata *DataLocation, Metadata *Associated, - Metadata *Allocated, Metadata *Rank, Metadata *Annotations) { + Metadata *Specification, uint32_t NumExtraInhabitants, DIFlags Flags, + Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder, + Metadata *TemplateParams, Metadata *Discriminator, Metadata *DataLocation, + Metadata *Associated, Metadata *Allocated, Metadata *Rank, + Metadata *Annotations) { assert(!Identifier.getString().empty() && "Expected valid identifier"); if (!Context.isODRUniquingDebugTypes()) return nullptr; @@ -851,7 +852,7 @@ DICompositeType *DICompositeType::getODRType( Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams, &Identifier, Discriminator, DataLocation, Associated, - Allocated, Rank, Annotations, NumExtraInhabitants); + Allocated, Rank, Annotations, Specification, NumExtraInhabitants); } else { if (CT->getTag() != Tag) return nullptr; diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h index 1912b1a6b7f3d..69d90c58964f0 100644 --- a/llvm/lib/IR/LLVMContextImpl.h +++ b/llvm/lib/IR/LLVMContextImpl.h @@ -655,6 +655,7 @@ template <> struct MDNodeKeyImpl { Metadata *Allocated; Metadata *Rank; Metadata *Annotations; + Metadata *Specification; uint32_t NumExtraInhabitants; MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *File, unsigned Line, @@ -665,7 +666,7 @@ template <> struct MDNodeKeyImpl { MDString *Identifier, Metadata *Discriminator, Metadata *DataLocation, Metadata *Associated, Metadata *Allocated, Metadata *Rank, Metadata *Annotations, - uint32_t NumExtraInhabitants) + Metadata *Specification, uint32_t NumExtraInhabitants) : Tag(Tag), Name(Name), File(File), Line(Line), Scope(Scope), BaseType(BaseType), SizeInBits(SizeInBits), OffsetInBits(OffsetInBits), AlignInBits(AlignInBits), Flags(Flags), Elements(Elements), @@ -673,7 +674,8 @@ template <> struct MDNodeKeyImpl { TemplateParams(TemplateParams), Identifier(Identifier), Discriminator(Discriminator), DataLocation(DataLocation), Associated(Associated), Allocated(Allocated), Rank(Rank), - Annotations(Annotations), NumExtraInhabitants(NumExtraInhabitants) {} + Annotations(Annotations), Specification(Specification), + NumExtraInhabitants(NumExtraInhabitants) {} MDNodeKeyImpl(const DICompositeType *N) : Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()), Line(N->getLine()), Scope(N->getRawScope()), @@ -687,6 +689,7 @@ template <> struct MDNodeKeyImpl { DataLocation(N->getRawDataLocation()), Associated(N->getRawAssociated()), Allocated(N->getRawAllocated()), Rank(N->getRawRank()), Annotations(N->getRawAnnotations()), + Specification(N->getSpecification()), NumExtraInhabitants(N->getNumExtraInhabitants()) {} bool isKeyOf(const DICompositeType *RHS) const { @@ -706,6 +709,7 @@ template <> struct MDNodeKeyImpl { Associated == RHS->getRawAssociated() && Allocated == RHS->getRawAllocated() && Rank == RHS->getRawRank() && Annotations == RHS->getRawAnnotations() && + Specification == RHS->getSpecification() && NumExtraInhabitants == RHS->getNumExtraInhabitants(); } diff --git a/llvm/test/Assembler/debug-info.ll b/llvm/test/Assembler/debug-info.ll index 7faaf50496def..09282b2114c8f 100644 --- a/llvm/test/Assembler/debug-info.ll +++ b/llvm/test/Assembler/debug-info.ll @@ -1,8 +1,8 @@ ; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | FileCheck %s ; RUN: verify-uselistorder %s -; CHECK: !named = !{!0, !0, !1, !2, !3, !4, !5, !6, !7, !8, !8, !9, !10, !11, !12, !13, !14, !15, !16, !17, !18, !19, !20, !21, !22, !23, !24, !25, !26, !27, !27, !28, !29, !30, !31, !32, !33, !34, !35, !36, !37, !38, !39, !40, !41, !42, !43, !44, !45} -!named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10, !11, !12, !13, !14, !15, !16, !17, !18, !19, !20, !21, !22, !23, !24, !25, !26, !27, !28, !29, !30, !31, !32, !33, !34, !35, !36, !37, !38, !39, !40, !41, !42, !43, !44, !45, !46, !47, !48} +; CHECK: !named = !{!0, !0, !1, !2, !3, !4, !5, !6, !7, !8, !8, !9, !10, !11, !12, !13, !14, !15, !16, !17, !18, !19, !20, !21, !22, !23, !24, !25, !26, !27, !27, !28, !29, !30, !31, !32, !33, !34, !35, !36, !37, !38, !39, !40, !41, !42, !43, !44, !45, !46, !47} +!named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10, !11, !12, !13, !14, !15, !16, !17, !18, !19, !20, !21, !22, !23, !24, !25, !26, !27, !28, !29, !30, !31, !32, !33, !34, !35, !36, !37, !38, !39, !40, !41, !42, !43, !44, !45, !46, !47, !48, !49, !50} ; CHECK: !0 = !DISubrange(count: 3, lowerBound: 0) ; CHECK-NEXT: !1 = !DISubrange(count: 3, lowerBound: 4) @@ -117,3 +117,8 @@ ;CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "ExtraInhabitantCompositeType", file: !10, size: 64, num_extra_inhabitants: 66, identifier: "MangledExtraInhabitantCompositeType") !48 = !DICompositeType(tag: DW_TAG_structure_type, name: "ExtraInhabitantCompositeType", file: !12, size: 64, num_extra_inhabitants: 66, identifier: "MangledExtraInhabitantCompositeType") + +!49 = !DICompositeType(tag: DW_TAG_structure_type, name: "BaseType", file: !12, size: 64, identifier: "BaseType") + +; CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "SpecificationType", file: !10, size: 64, identifier: "SpecificationType", specification: !46) +!50 = !DICompositeType(tag: DW_TAG_structure_type, name: "SpecificationType", file: !12, size: 64, identifier: "SpecificationType", specification: !49) diff --git a/llvm/test/DebugInfo/AArch64/specification.ll b/llvm/test/DebugInfo/AArch64/specification.ll new file mode 100644 index 0000000000000..7fd6ef59e1e27 --- /dev/null +++ b/llvm/test/DebugInfo/AArch64/specification.ll @@ -0,0 +1,31 @@ +; RUN: llc %s -filetype=obj -mtriple arm64e-apple-darwin -o - \ +; RUN: | llvm-dwarfdump - | FileCheck %s + +; CHECK: DW_TAG_structure_type +; CHECK: DW_AT_specification ({{.*}} "BaseType") +; CHECK: DW_AT_name ("SpecificationType") +; CHECK: DW_AT_byte_size (0x08) + +; CHECK: DW_TAG_structure_type +; CHECK: DW_AT_name ("BaseType") +; CHECK: DW_AT_byte_size (0x08) + +target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128" + +@p = common global i8* null, align 8, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!6, !7} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "p", scope: !2, file: !3, line: 1, type: !11, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, emissionKind: FullDebug, globals: !5) +!3 = !DIFile(filename: "/tmp/p.c", directory: "/") +!4 = !{} +!5 = !{!0} +!6 = !{i32 2, !"Dwarf Version", i32 4} +!7 = !{i32 2, !"Debug Info Version", i32 3} + +!10 = !DICompositeType(tag: DW_TAG_structure_type, name: "BaseType", file: !3, size: 64, identifier: "BaseType") + +!11 = !DICompositeType(tag: DW_TAG_structure_type, name: "SpecificationType", file: !3, size: 64, identifier: "SpecificationType", specification: !10) diff --git a/llvm/unittests/IR/DebugTypeODRUniquingTest.cpp b/llvm/unittests/IR/DebugTypeODRUniquingTest.cpp index e9f8146df7574..7180b8183c50a 100644 --- a/llvm/unittests/IR/DebugTypeODRUniquingTest.cpp +++ b/llvm/unittests/IR/DebugTypeODRUniquingTest.cpp @@ -30,8 +30,8 @@ TEST(DebugTypeODRUniquingTest, getODRType) { // Without a type map, this should return null. EXPECT_FALSE(DICompositeType::getODRType( Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, nullptr, - nullptr, 0, 0, 0, 0, DINode::FlagZero, nullptr, 0, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr)); + nullptr, 0, 0, 0, nullptr, 0, DINode::FlagZero, nullptr, 0, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr)); // Enable the mapping. There still shouldn't be a type. Context.enableDebugTypeODRUniquing(); @@ -40,23 +40,23 @@ TEST(DebugTypeODRUniquingTest, getODRType) { // Create some ODR-uniqued type. auto &CT = *DICompositeType::getODRType( Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, nullptr, - nullptr, 0, 0, 0, 0, DINode::FlagZero, nullptr, 0, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr); + nullptr, 0, 0, 0, nullptr, 0, DINode::FlagZero, nullptr, 0, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr); EXPECT_EQ(UUID.getString(), CT.getIdentifier()); // Check that we get it back, even if we change a field. EXPECT_EQ(&CT, DICompositeType::getODRTypeIfExists(Context, UUID)); EXPECT_EQ(&CT, DICompositeType::getODRType( Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, - 0, nullptr, nullptr, 0, 0, 0, 0, DINode::FlagZero, nullptr, - 0, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr)); + 0, nullptr, nullptr, 0, 0, 0, nullptr, 0, DINode::FlagZero, + nullptr, 0, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr)); EXPECT_EQ(&CT, DICompositeType::getODRType( Context, UUID, dwarf::DW_TAG_class_type, MDString::get(Context, "name"), nullptr, 0, nullptr, nullptr, 0, - 0, 0, 0, DINode::FlagZero, nullptr, 0, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr)); + 0, 0, nullptr, 0, DINode::FlagZero, nullptr, 0, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr)); // Check that it's discarded with the type map. Context.disableDebugTypeODRUniquing(); @@ -75,43 +75,43 @@ TEST(DebugTypeODRUniquingTest, buildODRType) { MDString &UUID = *MDString::get(Context, "Type"); auto &CT = *DICompositeType::buildODRType( Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, nullptr, - nullptr, 0, 0, 0, 0, DINode::FlagFwdDecl, nullptr, 0, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr); + nullptr, 0, 0, 0, nullptr, 0, DINode::FlagFwdDecl, nullptr, 0, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr); EXPECT_EQ(&CT, DICompositeType::getODRTypeIfExists(Context, UUID)); EXPECT_EQ(dwarf::DW_TAG_class_type, CT.getTag()); // Update with another forward decl. This should be a no-op. EXPECT_EQ(&CT, DICompositeType::buildODRType( Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, - 0, nullptr, nullptr, 0, 0, 0, 0, DINode::FlagFwdDecl, - nullptr, 0, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr)); + 0, nullptr, nullptr, 0, 0, 0, nullptr, 0, + DINode::FlagFwdDecl, nullptr, 0, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr)); EXPECT_FALSE(DICompositeType::buildODRType( Context, UUID, dwarf::DW_TAG_structure_type, nullptr, nullptr, 0, nullptr, - nullptr, 0, 0, 0, 0, DINode::FlagFwdDecl, nullptr, 0, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr)); + nullptr, 0, 0, 0, nullptr, 0, DINode::FlagFwdDecl, nullptr, 0, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr)); // Update with a definition. This time we should see a change. EXPECT_EQ(&CT, DICompositeType::buildODRType( Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, - 0, nullptr, nullptr, 0, 0, 0, 0, DINode::FlagZero, nullptr, - 0, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr)); + 0, nullptr, nullptr, 0, 0, 0, nullptr, 0, DINode::FlagZero, + nullptr, 0, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr)); EXPECT_FALSE(CT.isForwardDecl()); // Further updates should be ignored. EXPECT_EQ(&CT, DICompositeType::buildODRType( Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, - 0, nullptr, nullptr, 0, 0, 0, 0, DINode::FlagFwdDecl, - nullptr, 0, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr)); + 0, nullptr, nullptr, 0, 0, 0, nullptr, 0, + DINode::FlagFwdDecl, nullptr, 0, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr)); EXPECT_FALSE(CT.isForwardDecl()); EXPECT_EQ(&CT, DICompositeType::buildODRType( Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, - 111u, nullptr, nullptr, 0, 0, 0, 0, DINode::FlagZero, - nullptr, 0, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr)); + 111u, nullptr, nullptr, 0, 0, 0, nullptr, 0, + DINode::FlagZero, nullptr, 0, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr)); EXPECT_NE(111u, CT.getLine()); } @@ -122,8 +122,8 @@ TEST(DebugTypeODRUniquingTest, buildODRTypeFields) { // Build an ODR type that's a forward decl with no other fields set. MDString &UUID = *MDString::get(Context, "UUID"); auto &CT = *DICompositeType::buildODRType( - Context, UUID, 0, nullptr, nullptr, 0, nullptr, nullptr, 0, 0, 0, 0, - DINode::FlagFwdDecl, nullptr, 0, nullptr, nullptr, nullptr, nullptr, + Context, UUID, 0, nullptr, nullptr, 0, nullptr, nullptr, 0, 0, 0, nullptr, + 0, DINode::FlagFwdDecl, nullptr, 0, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr); // Create macros for running through all the fields except Identifier and Flags. @@ -155,10 +155,10 @@ TEST(DebugTypeODRUniquingTest, buildODRTypeFields) { // Replace all the fields with new values that are distinct from each other. EXPECT_EQ(&CT, DICompositeType::buildODRType( Context, UUID, 0, Name, File, Line, Scope, BaseType, - SizeInBits, AlignInBits, OffsetInBits, NumExtraInhabitants, - DINode::FlagArtificial, Elements, RuntimeLang, - VTableHolder, TemplateParams, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr)); + SizeInBits, AlignInBits, OffsetInBits, nullptr, + NumExtraInhabitants, DINode::FlagArtificial, Elements, + RuntimeLang, VTableHolder, TemplateParams, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr)); // Confirm that all the right fields got updated. #define DO_FOR_FIELD(X) EXPECT_EQ(X, CT.getRaw##X());