Index: llvm/include/llvm/IR/DIBuilder.h =================================================================== --- llvm/include/llvm/IR/DIBuilder.h +++ llvm/include/llvm/IR/DIBuilder.h @@ -494,8 +494,24 @@ /// \param AlignInBits Alignment. /// \param Ty Element type. /// \param Subscripts Subscripts. - DICompositeType *createArrayType(uint64_t Size, uint32_t AlignInBits, - DIType *Ty, DINodeArray Subscripts); + /// \param DataLocation The location of the raw data of a descriptor-based + /// Fortran array, either a DIExpression* or + /// a DIVariable*. + /// \param Associated The associated attribute of a descriptor-based + /// Fortran array, either a DIExpression* or + /// a DIVariable*. + /// \param Allocated The allocated attribute of a descriptor-based + /// Fortran array, either a DIExpression* or + /// a DIVariable*. + /// \param Rank The rank attribute of a descriptor-based + /// Fortran array, either a DIExpression* or + /// a DIVariable*. + DICompositeType *createArrayType( + uint64_t Size, uint32_t AlignInBits, DIType *Ty, DINodeArray Subscripts, + PointerUnion DataLocation = nullptr, + PointerUnion Associated = nullptr, + PointerUnion Allocated = nullptr, + PointerUnion Rank = nullptr); /// Create debugging information entry for a vector type. /// \param Size Array size. Index: llvm/lib/IR/DIBuilder.cpp =================================================================== --- llvm/lib/IR/DIBuilder.cpp +++ llvm/lib/IR/DIBuilder.cpp @@ -525,12 +525,24 @@ return CTy; } -DICompositeType *DIBuilder::createArrayType(uint64_t Size, - uint32_t AlignInBits, DIType *Ty, - DINodeArray Subscripts) { - auto *R = DICompositeType::get(VMContext, dwarf::DW_TAG_array_type, "", - nullptr, 0, nullptr, Ty, Size, AlignInBits, 0, - DINode::FlagZero, Subscripts, 0, nullptr); +DICompositeType *DIBuilder::createArrayType( + uint64_t Size, uint32_t AlignInBits, DIType *Ty, DINodeArray Subscripts, + PointerUnion DL, + PointerUnion AS, + PointerUnion AL, + PointerUnion RK) { + auto *R = DICompositeType::get( + VMContext, dwarf::DW_TAG_array_type, "", nullptr, 0, + nullptr, Ty, Size, AlignInBits, 0, DINode::FlagZero, + Subscripts, 0, nullptr, nullptr, "", nullptr, + DL.is() ? (Metadata *)DL.get() + : (Metadata *)DL.get(), + AS.is() ? (Metadata *)AS.get() + : (Metadata *)AS.get(), + AL.is() ? (Metadata *)AL.get() + : (Metadata *)AL.get(), + RK.is() ? (Metadata *)RK.get() + : (Metadata *)RK.get()); trackIfUnresolved(R); return R; } Index: llvm/unittests/IR/DebugInfoTest.cpp =================================================================== --- llvm/unittests/IR/DebugInfoTest.cpp +++ llvm/unittests/IR/DebugInfoTest.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "llvm/IR/DebugInfo.h" +#include "llvm/IR/DIBuilder.h" #include "llvm/AsmParser/Parser.h" #include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/IntrinsicInst.h" @@ -185,4 +186,47 @@ EXPECT_TRUE(isa(DVIs[0]->getValue())); } +TEST(DIBuilder, CreateFortranArrayTypeWithAttributes) { + LLVMContext Ctx; + std::unique_ptr M(new Module("MyModule", Ctx)); + DIBuilder DIB(*M); + + DISubrange *Subrange = DIB.getOrCreateSubrange(1,1); + SmallVector Subranges; + Subranges.push_back(Subrange); + DINodeArray Subscripts = DIB.getOrCreateArray(Subranges); + + auto getDIExpression = [&DIB](int offset) { + SmallVector ops; + ops.push_back(llvm::dwarf::DW_OP_push_object_address); + DIExpression::appendOffset(ops, offset); + ops.push_back(llvm::dwarf::DW_OP_deref); + + return DIB.createExpression(ops); + }; + + DIFile *F = DIB.createFile("main.c", "/"); + DICompileUnit *CU = DIB.createCompileUnit( + dwarf::DW_LANG_C, DIB.createFile("main.c", "/"), "llvm-c", true, "", 0); + + DIVariable *DataLocation = + DIB.createTempGlobalVariableFwdDecl(CU, "dl", "_dl", F, 1, nullptr, true); + DIExpression *Associated = getDIExpression(1); + DIExpression *Allocated = getDIExpression(2); + DIExpression *Rank = DIB.createConstantValueExpression(3); + + DICompositeType *ArrayType = DIB.createArrayType(0, 0, nullptr, Subscripts, + DataLocation, Associated, + Allocated, Rank); + + EXPECT_TRUE(isa_and_nonnull(ArrayType)); + EXPECT_EQ(ArrayType->getRawDataLocation(), DataLocation); + EXPECT_EQ(ArrayType->getRawAssociated(), Associated); + EXPECT_EQ(ArrayType->getRawAllocated(), Allocated); + EXPECT_EQ(ArrayType->getRawRank(), Rank); + + // Avoid memory leak. + DIVariable::deleteTemporary(DataLocation); +} + } // end namespace