diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -4886,7 +4886,12 @@ raw data, if they aren't equivalent. This is only supported for array types, particularly to describe Fortran arrays, which have an array descriptor in addition to the array data. Alternatively it can also be DIVariable which -has the address of the actual raw data. +has the address of the actual raw data. The Fortran language supports pointer +arrays which can be attached to actual arrays, this attachement between pointer +and pointee is called association. The optional ``associated`` is a +DIExpression that describes whether the pointer array is currently associated. +The optional ``allocated`` is a DIExpression that describes whether the +allocatable array is currently allocated. For ``DW_TAG_enumeration_type``, the ``elements:`` should be :ref:`enumerator descriptors `, each representing the definition of an enumeration diff --git a/llvm/include/llvm/IR/DebugInfoMetadata.h b/llvm/include/llvm/IR/DebugInfoMetadata.h --- a/llvm/include/llvm/IR/DebugInfoMetadata.h +++ b/llvm/include/llvm/IR/DebugInfoMetadata.h @@ -942,13 +942,14 @@ DINodeArray Elements, unsigned RuntimeLang, DIType *VTableHolder, DITemplateParameterArray TemplateParams, StringRef Identifier, DIDerivedType *Discriminator, Metadata *DataLocation, - StorageType Storage, bool ShouldCreate = true) { + Metadata *Associated, Metadata *Allocated, StorageType Storage, + bool ShouldCreate = true) { return getImpl(Context, Tag, getCanonicalMDString(Context, Name), File, Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements.get(), RuntimeLang, VTableHolder, TemplateParams.get(), getCanonicalMDString(Context, Identifier), Discriminator, - DataLocation, Storage, ShouldCreate); + DataLocation, Associated, Allocated, Storage, ShouldCreate); } static DICompositeType * getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File, @@ -957,15 +958,16 @@ DIFlags Flags, Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder, Metadata *TemplateParams, MDString *Identifier, Metadata *Discriminator, Metadata *DataLocation, - StorageType Storage, bool ShouldCreate = true); + Metadata *Associated, Metadata *Allocated, StorageType Storage, + bool ShouldCreate = true); TempDICompositeType cloneImpl() const { - return getTemporary(getContext(), getTag(), getName(), getFile(), getLine(), - getScope(), getBaseType(), getSizeInBits(), - getAlignInBits(), getOffsetInBits(), getFlags(), - getElements(), getRuntimeLang(), getVTableHolder(), - getTemplateParams(), getIdentifier(), - getDiscriminator(), getRawDataLocation()); + return getTemporary( + getContext(), getTag(), getName(), getFile(), getLine(), getScope(), + getBaseType(), getSizeInBits(), getAlignInBits(), getOffsetInBits(), + getFlags(), getElements(), getRuntimeLang(), getVTableHolder(), + getTemplateParams(), getIdentifier(), getDiscriminator(), + getRawDataLocation(), getRawAssociated(), getRawAllocated()); } public: @@ -977,10 +979,11 @@ DINodeArray Elements, unsigned RuntimeLang, DIType *VTableHolder, DITemplateParameterArray TemplateParams = nullptr, StringRef Identifier = "", DIDerivedType *Discriminator = nullptr, - Metadata *DataLocation = nullptr), + Metadata *DataLocation = nullptr, Metadata *Associated = nullptr, + Metadata *Allocated = nullptr), (Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams, - Identifier, Discriminator, DataLocation)) + Identifier, Discriminator, DataLocation, Associated, Allocated)) DEFINE_MDNODE_GET( DICompositeType, (unsigned Tag, MDString *Name, Metadata *File, unsigned Line, @@ -988,10 +991,11 @@ uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags, Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder, Metadata *TemplateParams = nullptr, MDString *Identifier = nullptr, - Metadata *Discriminator = nullptr, Metadata *DataLocation = nullptr), + Metadata *Discriminator = nullptr, Metadata *DataLocation = nullptr, + Metadata *Associated = nullptr, Metadata *Allocated = nullptr), (Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams, - Identifier, Discriminator, DataLocation)) + Identifier, Discriminator, DataLocation, Associated, Allocated)) TempDICompositeType clone() const { return cloneImpl(); } @@ -1009,7 +1013,7 @@ uint64_t OffsetInBits, DIFlags Flags, Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder, Metadata *TemplateParams, Metadata *Discriminator, - Metadata *DataLocation); + Metadata *DataLocation, Metadata *Associated, Metadata *Allocated); static DICompositeType *getODRTypeIfExists(LLVMContext &Context, MDString &Identifier); @@ -1022,14 +1026,13 @@ /// /// 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, DIFlags Flags, Metadata *Elements, - unsigned RuntimeLang, Metadata *VTableHolder, - Metadata *TemplateParams, Metadata *Discriminator, - Metadata *DataLocation); + 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, + DIFlags Flags, Metadata *Elements, unsigned RuntimeLang, + Metadata *VTableHolder, Metadata *TemplateParams, Metadata *Discriminator, + Metadata *DataLocation, Metadata *Associated, Metadata *Allocated); DIType *getBaseType() const { return cast_or_null(getRawBaseType()); } DINodeArray getElements() const { @@ -1058,6 +1061,20 @@ DIExpression *getDataLocationExp() const { return dyn_cast_or_null(getRawDataLocation()); } + Metadata *getRawAssociated() const { return getOperand(10); } + DIVariable *getAssociated() const { + return dyn_cast_or_null(getRawAssociated()); + } + DIExpression *getAssociatedExp() const { + return dyn_cast_or_null(getRawAssociated()); + } + Metadata *getRawAllocated() const { return getOperand(11); } + DIVariable *getAllocated() const { + return dyn_cast_or_null(getRawAllocated()); + } + DIExpression *getAllocatedExp() const { + return dyn_cast_or_null(getRawAllocated()); + } /// Replace operands. /// diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -4682,7 +4682,9 @@ OPTIONAL(templateParams, MDField, ); \ OPTIONAL(identifier, MDStringField, ); \ OPTIONAL(discriminator, MDField, ); \ - OPTIONAL(dataLocation, MDField, ); + OPTIONAL(dataLocation, MDField, ); \ + OPTIONAL(associated, MDField, ); \ + OPTIONAL(allocated, MDField, ); PARSE_MD_FIELDS(); #undef VISIT_MD_FIELDS @@ -4692,7 +4694,8 @@ Context, *identifier.Val, tag.Val, name.Val, file.Val, line.Val, scope.Val, baseType.Val, size.Val, align.Val, offset.Val, flags.Val, elements.Val, runtimeLang.Val, vtableHolder.Val, templateParams.Val, - discriminator.Val, dataLocation.Val)) { + discriminator.Val, dataLocation.Val, associated.Val, + allocated.Val)) { Result = CT; return false; } @@ -4704,7 +4707,7 @@ (Context, tag.Val, name.Val, file.Val, line.Val, scope.Val, baseType.Val, size.Val, align.Val, offset.Val, flags.Val, elements.Val, runtimeLang.Val, vtableHolder.Val, templateParams.Val, identifier.Val, - discriminator.Val, dataLocation.Val)); + discriminator.Val, dataLocation.Val, associated.Val, allocated.Val)); return false; } diff --git a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp --- a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp +++ b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp @@ -1350,7 +1350,7 @@ break; } case bitc::METADATA_COMPOSITE_TYPE: { - if (Record.size() < 16 || Record.size() > 18) + if (Record.size() < 16 || Record.size() > 20) return error("Invalid record"); // If we have a UUID and this is not a forward declaration, lookup the @@ -1375,6 +1375,8 @@ Metadata *TemplateParams = nullptr; Metadata *Discriminator = nullptr; Metadata *DataLocation = nullptr; + Metadata *Associated = nullptr; + Metadata *Allocated = 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 @@ -1399,13 +1401,18 @@ Discriminator = getMDOrNull(Record[16]); if (Record.size() > 17) DataLocation = getMDOrNull(Record[17]); + if (Record.size() > 19) { + Associated = getMDOrNull(Record[18]); + Allocated = getMDOrNull(Record[19]); + } } DICompositeType *CT = nullptr; if (Identifier) CT = DICompositeType::buildODRType( Context, *Identifier, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, - VTableHolder, TemplateParams, Discriminator, DataLocation); + VTableHolder, TemplateParams, Discriminator, DataLocation, Associated, + Allocated); // Create a node if we didn't get a lazy ODR type. if (!CT) @@ -1413,7 +1420,8 @@ (Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams, - Identifier, Discriminator, DataLocation)); + Identifier, Discriminator, DataLocation, Associated, + Allocated)); if (!IsNotUsedInTypeRef && Identifier) MetadataList.addTypeRef(*Identifier, *cast(CT)); diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -1632,6 +1632,8 @@ Record.push_back(VE.getMetadataOrNullID(N->getRawIdentifier())); Record.push_back(VE.getMetadataOrNullID(N->getDiscriminator())); Record.push_back(VE.getMetadataOrNullID(N->getRawDataLocation())); + Record.push_back(VE.getMetadataOrNullID(N->getRawAssociated())); + Record.push_back(VE.getMetadataOrNullID(N->getRawAllocated())); Stream.EmitRecord(bitc::METADATA_COMPOSITE_TYPE, Record, Abbrev); Record.clear(); diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp --- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -803,6 +803,10 @@ return Result; if (auto *DLVar = Array->getDataLocation()) Result.push_back(DLVar); + if (auto *AsVar = Array->getAssociated()) + Result.push_back(AsVar); + if (auto *AlVar = Array->getAllocated()) + Result.push_back(AlVar); for (auto *El : Array->getElements()) { if (auto *Subrange = dyn_cast(El)) { if (auto Count = Subrange->getCount()) diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp --- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -1445,6 +1445,28 @@ addBlock(Buffer, dwarf::DW_AT_data_location, DwarfExpr.finalize()); } + if (DIVariable *Var = CTy->getAssociated()) { + if (auto *VarDIE = getDIE(Var)) + addDIEEntry(Buffer, dwarf::DW_AT_associated, *VarDIE); + } else if (DIExpression *Expr = CTy->getAssociatedExp()) { + DIELoc *Loc = new (DIEValueAllocator) DIELoc; + DIEDwarfExpression DwarfExpr(*Asm, getCU(), *Loc); + DwarfExpr.setMemoryLocationKind(); + DwarfExpr.addExpression(Expr); + addBlock(Buffer, dwarf::DW_AT_associated, DwarfExpr.finalize()); + } + + if (DIVariable *Var = CTy->getAllocated()) { + if (auto *VarDIE = getDIE(Var)) + addDIEEntry(Buffer, dwarf::DW_AT_allocated, *VarDIE); + } else if (DIExpression *Expr = CTy->getAllocatedExp()) { + DIELoc *Loc = new (DIEValueAllocator) DIELoc; + DIEDwarfExpression DwarfExpr(*Asm, getCU(), *Loc); + DwarfExpr.setMemoryLocationKind(); + DwarfExpr.addExpression(Expr); + addBlock(Buffer, dwarf::DW_AT_allocated, DwarfExpr.finalize()); + } + // Emit the element type. addType(Buffer, CTy->getBaseType()); diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -1962,6 +1962,8 @@ Printer.printString("identifier", N->getIdentifier()); Printer.printMetadata("discriminator", N->getRawDiscriminator()); Printer.printMetadata("dataLocation", N->getRawDataLocation()); + Printer.printMetadata("associated", N->getRawAssociated()); + Printer.printMetadata("allocated", N->getRawAllocated()); Out << ")"; } diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp --- a/llvm/lib/IR/DebugInfoMetadata.cpp +++ b/llvm/lib/IR/DebugInfoMetadata.cpp @@ -493,7 +493,8 @@ uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags, Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder, Metadata *TemplateParams, MDString *Identifier, Metadata *Discriminator, - Metadata *DataLocation, StorageType Storage, bool ShouldCreate) { + Metadata *DataLocation, Metadata *Associated, Metadata *Allocated, + StorageType Storage, bool ShouldCreate) { assert(isCanonical(Name) && "Expected canonical MDString"); // Keep this in sync with buildODRType. @@ -501,10 +502,10 @@ (Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams, Identifier, - Discriminator, DataLocation)); + Discriminator, DataLocation, Associated, Allocated)); Metadata *Ops[] = {File, Scope, Name, BaseType, Elements, VTableHolder, TemplateParams, Identifier, - Discriminator, DataLocation}; + Discriminator, DataLocation, Associated, Allocated}; DEFINE_GETIMPL_STORE(DICompositeType, (Tag, Line, RuntimeLang, SizeInBits, AlignInBits, OffsetInBits, Flags), Ops); @@ -516,7 +517,7 @@ uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags, Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder, Metadata *TemplateParams, Metadata *Discriminator, - Metadata *DataLocation) { + Metadata *DataLocation, Metadata *Associated, Metadata *Allocated) { assert(!Identifier.getString().empty() && "Expected valid identifier"); if (!Context.isODRUniquingDebugTypes()) return nullptr; @@ -526,7 +527,7 @@ Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams, &Identifier, Discriminator, - DataLocation); + DataLocation, Associated, Allocated); // Only mutate CT if it's a forward declaration and the new operands aren't. assert(CT->getRawIdentifier() == &Identifier && "Wrong ODR identifier?"); @@ -538,7 +539,7 @@ Flags); Metadata *Ops[] = {File, Scope, Name, BaseType, Elements, VTableHolder, TemplateParams, &Identifier, - Discriminator, DataLocation}; + Discriminator, DataLocation, Associated, Allocated}; assert((std::end(Ops) - std::begin(Ops)) == (int)CT->getNumOperands() && "Mismatched number of operands"); for (unsigned I = 0, E = CT->getNumOperands(); I != E; ++I) @@ -553,7 +554,7 @@ uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags, Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder, Metadata *TemplateParams, Metadata *Discriminator, - Metadata *DataLocation) { + Metadata *DataLocation, Metadata *Associated, Metadata *Allocated) { assert(!Identifier.getString().empty() && "Expected valid identifier"); if (!Context.isODRUniquingDebugTypes()) return nullptr; @@ -562,7 +563,8 @@ CT = DICompositeType::getDistinct( Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, - TemplateParams, &Identifier, Discriminator, DataLocation); + TemplateParams, &Identifier, Discriminator, DataLocation, Associated, + Allocated); return CT; } diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h --- a/llvm/lib/IR/LLVMContextImpl.h +++ b/llvm/lib/IR/LLVMContextImpl.h @@ -525,6 +525,8 @@ MDString *Identifier; Metadata *Discriminator; Metadata *DataLocation; + Metadata *Associated; + Metadata *Allocated; MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits, @@ -532,13 +534,15 @@ Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder, Metadata *TemplateParams, MDString *Identifier, Metadata *Discriminator, - Metadata *DataLocation) + Metadata *DataLocation, Metadata *Associated, + Metadata *Allocated) : Tag(Tag), Name(Name), File(File), Line(Line), Scope(Scope), BaseType(BaseType), SizeInBits(SizeInBits), OffsetInBits(OffsetInBits), AlignInBits(AlignInBits), Flags(Flags), Elements(Elements), RuntimeLang(RuntimeLang), VTableHolder(VTableHolder), TemplateParams(TemplateParams), Identifier(Identifier), - Discriminator(Discriminator), DataLocation(DataLocation) {} + Discriminator(Discriminator), DataLocation(DataLocation), + Associated(Associated), Allocated(Allocated) {} MDNodeKeyImpl(const DICompositeType *N) : Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()), Line(N->getLine()), Scope(N->getRawScope()), @@ -549,7 +553,8 @@ TemplateParams(N->getRawTemplateParams()), Identifier(N->getRawIdentifier()), Discriminator(N->getRawDiscriminator()), - DataLocation(N->getRawDataLocation()) {} + DataLocation(N->getRawDataLocation()), + Associated(N->getRawAssociated()), Allocated(N->getRawAllocated()) {} bool isKeyOf(const DICompositeType *RHS) const { return Tag == RHS->getTag() && Name == RHS->getRawName() && @@ -564,7 +569,9 @@ TemplateParams == RHS->getRawTemplateParams() && Identifier == RHS->getRawIdentifier() && Discriminator == RHS->getRawDiscriminator() && - DataLocation == RHS->getRawDataLocation(); + DataLocation == RHS->getRawDataLocation() && + Associated == RHS->getRawAssociated() && + Allocated == RHS->getRawAllocated(); } unsigned getHashValue() const { diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -1035,6 +1035,16 @@ AssertDI(N.getTag() == dwarf::DW_TAG_array_type, "dataLocation can only appear in array type"); } + + if (N.getRawAssociated()) { + AssertDI(N.getTag() == dwarf::DW_TAG_array_type, + "associated can only appear in array type"); + } + + if (N.getRawAllocated()) { + AssertDI(N.getTag() == dwarf::DW_TAG_array_type, + "allocated can only appear in array type"); + } } void Verifier::visitDISubroutineType(const DISubroutineType &N) { diff --git a/llvm/test/Bitcode/allocated.ll b/llvm/test/Bitcode/allocated.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Bitcode/allocated.ll @@ -0,0 +1,32 @@ +;; This test checks dataLocation field of DICompositeType + +; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | FileCheck %s + +;; Test whether DW_AT_data_location is generated. +; CHECK: !DICompositeType(tag: DW_TAG_array_type, baseType: !{{[0-9]+}}, size: 32, align: 32, elements: !{{[0-9]+}}, dataLocation: !{{[0-9]+}}, allocated: !{{[0-9]+}}) +; CHECK: !DICompositeType(tag: DW_TAG_array_type, baseType: !{{[0-9]+}}, size: 32, align: 32, elements: !{{[0-9]+}}, dataLocation: !DIExpression(DW_OP_push_object_address, DW_OP_deref), allocated: !DIExpression(DW_OP_push_object_address, DW_OP_deref)) + +; ModuleID = 'allocated.f90' +source_filename = "/dir/allocated.ll" + +!llvm.module.flags = !{!0, !1} +!llvm.dbg.cu = !{!2} + +!0 = !{i32 2, !"Dwarf Version", i32 4} +!1 = !{i32 2, !"Debug Info Version", i32 3} +!2 = distinct !DICompileUnit(language: DW_LANG_Fortran90, file: !3, producer: " F90 Flang - 1.5 2017-05-01", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, retainedTypes: !5, globals: !4, imports: !4) +!3 = !DIFile(filename: "allocated.f90", directory: "/dir") +!4 = !{} +!5 = !{!6, !17} +!6 = !DICompositeType(tag: DW_TAG_array_type, baseType: !7, size: 32, align: 32, elements: !8, dataLocation: !10, allocated: !15) +!7 = !DIBasicType(name: "integer", size: 32, align: 32, encoding: DW_ATE_signed) +!8 = !{!9} +!9 = !DISubrange(count: 19, lowerBound: 2) +!10 = distinct !DILocalVariable(scope: !11, file: !3, type: !14, flags: DIFlagArtificial) +!11 = distinct !DISubprogram(name: "main", scope: !2, file: !3, line: 1, type: !12, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagMainSubprogram, unit: !2) +!12 = !DISubroutineType(cc: DW_CC_program, types: !13) +!13 = !{null} +!14 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !7, size: 32, align: 32) +!15 = distinct !DILocalVariable(scope: !11, file: !3, type: !16, flags: DIFlagArtificial) +!16 = !DIBasicType(name: "logical", size: 32, align: 32, encoding: DW_ATE_signed) +!17 = !DICompositeType(tag: DW_TAG_array_type, baseType: !7, size: 32, align: 32, elements: !8, dataLocation: !DIExpression(DW_OP_push_object_address, DW_OP_deref), allocated: !DIExpression(DW_OP_push_object_address, DW_OP_deref)) diff --git a/llvm/test/Bitcode/associated.ll b/llvm/test/Bitcode/associated.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Bitcode/associated.ll @@ -0,0 +1,32 @@ +;; This test checks dataLocation field of DICompositeType + +; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | FileCheck %s + +;; Test whether DW_AT_data_location is generated. +; CHECK: !DICompositeType(tag: DW_TAG_array_type, baseType: !{{[0-9]+}}, size: 32, align: 32, elements: !{{[0-9]+}}, dataLocation: !{{[0-9]+}}, associated: !{{[0-9]+}}) +; CHECK: !DICompositeType(tag: DW_TAG_array_type, baseType: !{{[0-9]+}}, size: 32, align: 32, elements: !{{[0-9]+}}, dataLocation: !DIExpression(DW_OP_push_object_address, DW_OP_deref), associated: !DIExpression(DW_OP_push_object_address, DW_OP_deref)) + +; ModuleID = 'associated.f90' +source_filename = "/dir/associated.ll" + +!llvm.module.flags = !{!0, !1} +!llvm.dbg.cu = !{!2} + +!0 = !{i32 2, !"Dwarf Version", i32 4} +!1 = !{i32 2, !"Debug Info Version", i32 3} +!2 = distinct !DICompileUnit(language: DW_LANG_Fortran90, file: !3, producer: " F90 Flang - 1.5 2017-05-01", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, retainedTypes: !5, globals: !4, imports: !4) +!3 = !DIFile(filename: "associated.f90", directory: "/dir") +!4 = !{} +!5 = !{!6, !17} +!6 = !DICompositeType(tag: DW_TAG_array_type, baseType: !7, size: 32, align: 32, elements: !8, dataLocation: !10, associated: !15) +!7 = !DIBasicType(name: "integer", size: 32, align: 32, encoding: DW_ATE_signed) +!8 = !{!9} +!9 = !DISubrange(count: 19, lowerBound: 2) +!10 = distinct !DILocalVariable(scope: !11, file: !3, type: !14, flags: DIFlagArtificial) +!11 = distinct !DISubprogram(name: "main", scope: !2, file: !3, line: 1, type: !12, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagMainSubprogram, unit: !2) +!12 = !DISubroutineType(cc: DW_CC_program, types: !13) +!13 = !{null} +!14 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !7, size: 32, align: 32) +!15 = distinct !DILocalVariable(scope: !11, file: !3, type: !16, flags: DIFlagArtificial) +!16 = !DIBasicType(name: "logical", size: 32, align: 32, encoding: DW_ATE_signed) +!17 = !DICompositeType(tag: DW_TAG_array_type, baseType: !7, size: 32, align: 32, elements: !8, dataLocation: !DIExpression(DW_OP_push_object_address, DW_OP_deref), associated: !DIExpression(DW_OP_push_object_address, DW_OP_deref)) diff --git a/llvm/test/DebugInfo/X86/dwarfdump-allocatedExp.ll b/llvm/test/DebugInfo/X86/dwarfdump-allocatedExp.ll new file mode 100644 --- /dev/null +++ b/llvm/test/DebugInfo/X86/dwarfdump-allocatedExp.ll @@ -0,0 +1,56 @@ +; RUN: llc %s -O2 -filetype=obj -o %t.o +; RUN: llvm-dwarfdump %t.o | FileCheck %s + +; Test whether DW_AT_data_location is generated. +; CHECK-LABEL: DW_TAG_array_type +; CHECK: DW_AT_allocated (DW_OP_push_object_address, DW_OP_deref) +; CHECK-NOT: DW_TAG +; CHECK: DW_TAG_subrange_type + +; Test case is hand written with the help of below testcase +;------------------------------ +;program main +;integer, allocatable :: arr(:) +;allocate(arr(2:20)) +;arr(2)=99 +;print *, arr +;end program main +;------------------------------ + +; ModuleID = 'allocated.ll' +source_filename = "allocated.ll" +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +define void @MAIN_() !dbg !5 { +L.entry: + %.Z0640_333 = alloca i32*, align 8 + %"arr$sd1_349" = alloca [16 x i64], align 8 + call void @llvm.dbg.declare(metadata [16 x i64]* %"arr$sd1_349", metadata !8, metadata !DIExpression()), !dbg !13 + call void @llvm.dbg.declare(metadata i32** %.Z0640_333, metadata !14, metadata !DIExpression()), !dbg !13 + ret void, !dbg !16 +} + +; Function Attrs: nounwind readnone speculatable willreturn +declare void @llvm.dbg.declare(metadata, metadata, metadata) + +!llvm.module.flags = !{!0, !1} +!llvm.dbg.cu = !{!2} + +!0 = !{i32 2, !"Dwarf Version", i32 4} +!1 = !{i32 2, !"Debug Info Version", i32 3} +!2 = distinct !DICompileUnit(language: DW_LANG_Fortran90, file: !3, producer: " F90 Flang - 1.5 2017-05-01", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, retainedTypes: !4, globals: !4, imports: !4) +!3 = !DIFile(filename: "allocated.f90", directory: "/dir") +!4 = !{} +!5 = distinct !DISubprogram(name: "main", scope: !2, file: !3, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagMainSubprogram, unit: !2) +!6 = !DISubroutineType(cc: DW_CC_program, types: !7) +!7 = !{null} +!8 = !DILocalVariable(name: "arr", scope: !5, file: !3, type: !9) +!9 = !DICompositeType(tag: DW_TAG_array_type, baseType: !10, size: 32, align: 32, elements: !11, dataLocation: !DIExpression(DW_OP_push_object_address, DW_OP_deref), allocated: !DIExpression(DW_OP_push_object_address, DW_OP_deref)) +!10 = !DIBasicType(name: "integer", size: 32, align: 32, encoding: DW_ATE_signed) +!11 = !{!12} +!12 = !DISubrange(count: 19, lowerBound: 2) +!13 = !DILocation(line: 0, scope: !5) +!14 = distinct !DILocalVariable(scope: !5, file: !3, type: !15, flags: DIFlagArtificial) +!15 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !10, size: 32, align: 32) +!16 = !DILocation(line: 6, column: 1, scope: !5) diff --git a/llvm/test/DebugInfo/X86/dwarfdump-allocatedVar.ll b/llvm/test/DebugInfo/X86/dwarfdump-allocatedVar.ll new file mode 100644 --- /dev/null +++ b/llvm/test/DebugInfo/X86/dwarfdump-allocatedVar.ll @@ -0,0 +1,68 @@ +;; This test checks whether DW_AT_data_location attribute +;; accepts DIVariable + +; RUN: llc -mtriple=x86_64-unknown-linux-gnu %s -filetype=obj -o %t.o +; RUN: llvm-dwarfdump %t.o | FileCheck %s + +;; Test whether DW_AT_data_location is generated. +; CHECK: [[ALCDIE:0x.+]]: DW_TAG_variable +; CHECK: DW_AT_type ({{0x[0-9]+}} "logical") +; CHECK: [[LOCDIE:0x.+]]: DW_TAG_variable +; CHECK: DW_AT_type ({{0x[0-9]+}} "integer*") +; CHECK: DW_AT_artificial (true) +; CHECK: DW_TAG_variable +; CHECK: DW_AT_name ("arr") +; CHECK: DW_TAG_array_type +; CHECK-NEXT: DW_AT_data_location ([[LOCDIE]]) +; CHECK-NEXT: DW_AT_allocated ([[ALCDIE]]) + +;; Test case is hand written with the help of below testcase +;;------------------------------ +;;program main +;;integer, allocatable :: arr(:) +;;allocate(arr(2:20)) +;;arr(2)=99 +;;print *, arr +;;end program main +;;------------------------------ + +; ModuleID = 'allocated.ll' +source_filename = "allocated.ll" +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +define void @MAIN_() !dbg !5 { +L.entry: + %.Z0640_333 = alloca i32*, align 8 + %"arr$sd1_349" = alloca [16 x i64], align 8 + call void @llvm.dbg.declare(metadata [16 x i64]* %"arr$sd1_349", metadata !8, metadata !DIExpression()), !dbg !17 + call void @llvm.dbg.declare(metadata i32** %.Z0640_333, metadata !13, metadata !DIExpression()), !dbg !17 + call void @llvm.dbg.declare(metadata i32** %.Z0640_333, metadata !15, metadata !DIExpression()), !dbg !17 + ret void, !dbg !18 +} + +; Function Attrs: nounwind readnone speculatable willreturn +declare void @llvm.dbg.declare(metadata, metadata, metadata) + +!llvm.module.flags = !{!0, !1} +!llvm.dbg.cu = !{!2} + +!0 = !{i32 2, !"Dwarf Version", i32 4} +!1 = !{i32 2, !"Debug Info Version", i32 3} +!2 = distinct !DICompileUnit(language: DW_LANG_Fortran90, file: !3, producer: " F90 Flang - 1.5 2017-05-01", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, retainedTypes: !4, globals: !4, imports: !4) +!3 = !DIFile(filename: "allocated.f90", directory: "/dir") +!4 = !{} +!5 = distinct !DISubprogram(name: "main", scope: !2, file: !3, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagMainSubprogram, unit: !2) +!6 = !DISubroutineType(cc: DW_CC_program, types: !7) +!7 = !{null} +!8 = !DILocalVariable(name: "arr", scope: !5, file: !3, type: !9) +!9 = !DICompositeType(tag: DW_TAG_array_type, baseType: !10, size: 32, align: 32, elements: !11, dataLocation: !13, allocated: !15) +!10 = !DIBasicType(name: "integer", size: 32, align: 32, encoding: DW_ATE_signed) +!11 = !{!12} +!12 = !DISubrange(count: 19, lowerBound: 2) +!13 = distinct !DILocalVariable(scope: !5, file: !3, type: !14, flags: DIFlagArtificial) +!14 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !10, size: 32, align: 32) +!15 = distinct !DILocalVariable(scope: !5, file: !3, type: !16, flags: DIFlagArtificial) +!16 = !DIBasicType(name: "logical", size: 32, align: 32, encoding: DW_ATE_signed) +!17 = !DILocation(line: 0, scope: !5) +!18 = !DILocation(line: 6, column: 1, scope: !5) diff --git a/llvm/test/DebugInfo/X86/dwarfdump-associatedExp.ll b/llvm/test/DebugInfo/X86/dwarfdump-associatedExp.ll new file mode 100644 --- /dev/null +++ b/llvm/test/DebugInfo/X86/dwarfdump-associatedExp.ll @@ -0,0 +1,56 @@ +; RUN: llc %s -O2 -filetype=obj -o %t.o +; RUN: llvm-dwarfdump %t.o | FileCheck %s + +; Test whether DW_AT_data_location is generated. +; CHECK-LABEL: DW_TAG_array_type +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_associated (DW_OP_push_object_address, DW_OP_deref) +; CHECK: DW_TAG_subrange_type + +; Test case is hand written with the help of below testcase +;------------------------------ +;program main +;integer, pointer :: arr(:) +;allocate(arr(2:20)) +;arr(2)=99 +;print *, arr +;end program main +;------------------------------ + +; ModuleID = 'associated.ll' +source_filename = "associated.ll" +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +define void @MAIN_() !dbg !5 { +L.entry: + %.Z0640_333 = alloca i32*, align 8 + %"arr$sd1_349" = alloca [16 x i64], align 8 + call void @llvm.dbg.declare(metadata [16 x i64]* %"arr$sd1_349", metadata !8, metadata !DIExpression()), !dbg !13 + call void @llvm.dbg.declare(metadata i32** %.Z0640_333, metadata !14, metadata !DIExpression()), !dbg !13 + ret void, !dbg !16 +} + +; Function Attrs: nounwind readnone speculatable willreturn +declare void @llvm.dbg.declare(metadata, metadata, metadata) + +!llvm.module.flags = !{!0, !1} +!llvm.dbg.cu = !{!2} + +!0 = !{i32 2, !"Dwarf Version", i32 4} +!1 = !{i32 2, !"Debug Info Version", i32 3} +!2 = distinct !DICompileUnit(language: DW_LANG_Fortran90, file: !3, producer: " F90 Flang - 1.5 2017-05-01", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, retainedTypes: !4, globals: !4, imports: !4) +!3 = !DIFile(filename: "associated.f90", directory: "/dir") +!4 = !{} +!5 = distinct !DISubprogram(name: "main", scope: !2, file: !3, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagMainSubprogram, unit: !2) +!6 = !DISubroutineType(cc: DW_CC_program, types: !7) +!7 = !{null} +!8 = !DILocalVariable(name: "arr", scope: !5, file: !3, type: !9) +!9 = !DICompositeType(tag: DW_TAG_array_type, baseType: !10, size: 32, align: 32, elements: !11, dataLocation: !DIExpression(DW_OP_push_object_address, DW_OP_deref), associated: !DIExpression(DW_OP_push_object_address, DW_OP_deref)) +!10 = !DIBasicType(name: "integer", size: 32, align: 32, encoding: DW_ATE_signed) +!11 = !{!12} +!12 = !DISubrange(count: 19, lowerBound: 2) +!13 = !DILocation(line: 0, scope: !5) +!14 = distinct !DILocalVariable(scope: !5, file: !3, type: !15, flags: DIFlagArtificial) +!15 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !10, size: 32, align: 32) +!16 = !DILocation(line: 6, column: 1, scope: !5) diff --git a/llvm/test/DebugInfo/X86/dwarfdump-associatedVar.ll b/llvm/test/DebugInfo/X86/dwarfdump-associatedVar.ll new file mode 100644 --- /dev/null +++ b/llvm/test/DebugInfo/X86/dwarfdump-associatedVar.ll @@ -0,0 +1,68 @@ +;; This test checks whether DW_AT_data_location attribute +;; accepts DIVariable + +; RUN: llc -mtriple=x86_64-unknown-linux-gnu %s -filetype=obj -o %t.o +; RUN: llvm-dwarfdump %t.o | FileCheck %s + +;; Test whether DW_AT_data_location is generated. +; CHECK: [[ALCDIE:0x.+]]: DW_TAG_variable +; CHECK: DW_AT_type ({{0x[0-9]+}} "logical") +; CHECK: [[LOCDIE:0x.+]]: DW_TAG_variable +; CHECK: DW_AT_type ({{0x[0-9]+}} "integer*") +; CHECK: DW_AT_artificial (true) +; CHECK: DW_TAG_variable +; CHECK: DW_AT_name ("arr") +; CHECK: DW_TAG_array_type +; CHECK-NEXT: DW_AT_data_location ([[LOCDIE]]) +; CHECK-NEXT: DW_AT_associated ([[ALCDIE]]) + +;; Test case is hand written with the help of below testcase +;;------------------------------ +;;program main +;;integer, pointer :: arr(:) +;;allocate(arr(2:20)) +;;arr(2)=99 +;;print *, arr +;;end program main +;;------------------------------ + +; ModuleID = 'associated.ll' +source_filename = "associated.ll" +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +define void @MAIN_() !dbg !5 { +L.entry: + %.Z0640_333 = alloca i32*, align 8 + %"arr$sd1_349" = alloca [16 x i64], align 8 + call void @llvm.dbg.declare(metadata [16 x i64]* %"arr$sd1_349", metadata !8, metadata !DIExpression()), !dbg !17 + call void @llvm.dbg.declare(metadata i32** %.Z0640_333, metadata !13, metadata !DIExpression()), !dbg !17 + call void @llvm.dbg.declare(metadata i32** %.Z0640_333, metadata !15, metadata !DIExpression()), !dbg !17 + ret void, !dbg !18 +} + +; Function Attrs: nounwind readnone speculatable willreturn +declare void @llvm.dbg.declare(metadata, metadata, metadata) + +!llvm.module.flags = !{!0, !1} +!llvm.dbg.cu = !{!2} + +!0 = !{i32 2, !"Dwarf Version", i32 4} +!1 = !{i32 2, !"Debug Info Version", i32 3} +!2 = distinct !DICompileUnit(language: DW_LANG_Fortran90, file: !3, producer: " F90 Flang - 1.5 2017-05-01", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, retainedTypes: !4, globals: !4, imports: !4) +!3 = !DIFile(filename: "associated.f90", directory: "/dir") +!4 = !{} +!5 = distinct !DISubprogram(name: "main", scope: !2, file: !3, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagMainSubprogram, unit: !2) +!6 = !DISubroutineType(cc: DW_CC_program, types: !7) +!7 = !{null} +!8 = !DILocalVariable(name: "arr", scope: !5, file: !3, type: !9) +!9 = !DICompositeType(tag: DW_TAG_array_type, baseType: !10, size: 32, align: 32, elements: !11, dataLocation: !13, associated: !15) +!10 = !DIBasicType(name: "integer", size: 32, align: 32, encoding: DW_ATE_signed) +!11 = !{!12} +!12 = !DISubrange(count: 19, lowerBound: 2) +!13 = distinct !DILocalVariable(scope: !5, file: !3, type: !14, flags: DIFlagArtificial) +!14 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !10, size: 32, align: 32) +!15 = distinct !DILocalVariable(scope: !5, file: !3, type: !16, flags: DIFlagArtificial) +!16 = !DIBasicType(name: "logical", size: 32, align: 32, encoding: DW_ATE_signed) +!17 = !DILocation(line: 0, scope: !5) +!18 = !DILocation(line: 6, column: 1, scope: !5) diff --git a/llvm/test/Verifier/array_allocated.ll b/llvm/test/Verifier/array_allocated.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Verifier/array_allocated.ll @@ -0,0 +1,6 @@ +; RUN: not llvm-as -disable-output <%s 2>&1 | FileCheck %s + +!named = !{!0} +!0 = !DICompositeType(tag: DW_TAG_structure_type, name: "A", size: 64, allocated: !DIExpression(DW_OP_constu, 6789)) + +; CHECK: allocated can only appear in array type diff --git a/llvm/test/Verifier/array_associated.ll b/llvm/test/Verifier/array_associated.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Verifier/array_associated.ll @@ -0,0 +1,6 @@ +; RUN: not llvm-as -disable-output <%s 2>&1 | FileCheck %s + +!named = !{!0} +!0 = !DICompositeType(tag: DW_TAG_structure_type, name: "A", size: 64, associated: !DIExpression(DW_OP_constu, 6789)) + +; CHECK: associated can only appear in array type diff --git a/llvm/unittests/IR/DebugTypeODRUniquingTest.cpp b/llvm/unittests/IR/DebugTypeODRUniquingTest.cpp --- a/llvm/unittests/IR/DebugTypeODRUniquingTest.cpp +++ b/llvm/unittests/IR/DebugTypeODRUniquingTest.cpp @@ -30,7 +30,7 @@ EXPECT_FALSE(DICompositeType::getODRType( Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, nullptr, nullptr, 0, 0, 0, DINode::FlagZero, nullptr, 0, nullptr, nullptr, nullptr, - nullptr)); + nullptr, nullptr, nullptr)); // Enable the mapping. There still shouldn't be a type. Context.enableDebugTypeODRUniquing(); @@ -40,7 +40,7 @@ auto &CT = *DICompositeType::getODRType( Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, nullptr, nullptr, 0, 0, 0, DINode::FlagZero, nullptr, 0, 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. @@ -48,12 +48,12 @@ EXPECT_EQ(&CT, DICompositeType::getODRType( Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, nullptr, nullptr, 0, 0, 0, DINode::FlagZero, nullptr, 0, - nullptr, nullptr, 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, DINode::FlagZero, nullptr, 0, nullptr, - nullptr, nullptr, nullptr)); + nullptr, nullptr, nullptr, nullptr, nullptr)); // Check that it's discarded with the type map. Context.disableDebugTypeODRUniquing(); @@ -73,34 +73,36 @@ auto &CT = *DICompositeType::buildODRType( Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, nullptr, nullptr, 0, 0, 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_structure_type, nullptr, - nullptr, 0, nullptr, nullptr, 0, 0, 0, DINode::FlagFwdDecl, - nullptr, 0, nullptr, nullptr, nullptr, nullptr)); + EXPECT_EQ(&CT, + DICompositeType::buildODRType( + Context, UUID, dwarf::DW_TAG_structure_type, nullptr, nullptr, + 0, nullptr, nullptr, 0, 0, 0, DINode::FlagFwdDecl, nullptr, 0, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr)); EXPECT_EQ(dwarf::DW_TAG_class_type, CT.getTag()); // Update with a definition. This time we should see a change. - EXPECT_EQ(&CT, DICompositeType::buildODRType( - Context, UUID, dwarf::DW_TAG_structure_type, nullptr, - nullptr, 0, nullptr, nullptr, 0, 0, 0, DINode::FlagZero, - nullptr, 0, nullptr, nullptr, nullptr, nullptr)); + EXPECT_EQ(&CT, + DICompositeType::buildODRType( + Context, UUID, dwarf::DW_TAG_structure_type, nullptr, nullptr, + 0, nullptr, nullptr, 0, 0, 0, DINode::FlagZero, nullptr, 0, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr)); EXPECT_EQ(dwarf::DW_TAG_structure_type, CT.getTag()); // 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, DINode::FlagFwdDecl, nullptr, - 0, nullptr, nullptr, nullptr, nullptr)); + 0, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr)); EXPECT_EQ(dwarf::DW_TAG_structure_type, CT.getTag()); EXPECT_EQ(&CT, DICompositeType::buildODRType( Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, nullptr, nullptr, 0, 0, 0, DINode::FlagZero, nullptr, 0, - nullptr, nullptr, nullptr, nullptr)); + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr)); EXPECT_EQ(dwarf::DW_TAG_structure_type, CT.getTag()); } @@ -112,7 +114,8 @@ MDString &UUID = *MDString::get(Context, "UUID"); auto &CT = *DICompositeType::buildODRType( Context, UUID, 0, nullptr, nullptr, 0, nullptr, nullptr, 0, 0, 0, - DINode::FlagFwdDecl, nullptr, 0, nullptr, nullptr, nullptr, nullptr); + DINode::FlagFwdDecl, nullptr, 0, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr); // Create macros for running through all the fields except Identifier and Flags. #define FOR_EACH_MDFIELD() \ @@ -141,11 +144,12 @@ #undef DO_FOR_FIELD // Replace all the fields with new values that are distinct from each other. - EXPECT_EQ(&CT, DICompositeType::buildODRType( - Context, UUID, Tag, Name, File, Line, Scope, BaseType, - SizeInBits, AlignInBits, OffsetInBits, - DINode::FlagArtificial, Elements, RuntimeLang, - VTableHolder, TemplateParams, nullptr, nullptr)); + EXPECT_EQ(&CT, + DICompositeType::buildODRType( + Context, UUID, Tag, Name, File, Line, Scope, BaseType, + SizeInBits, AlignInBits, OffsetInBits, DINode::FlagArtificial, + Elements, RuntimeLang, VTableHolder, TemplateParams, nullptr, + nullptr, nullptr, nullptr)); // Confirm that all the right fields got updated. #define DO_FOR_FIELD(X) EXPECT_EQ(X, CT.getRaw##X());