Index: llvm/include/llvm/IR/DIBuilder.h =================================================================== --- llvm/include/llvm/IR/DIBuilder.h +++ llvm/include/llvm/IR/DIBuilder.h @@ -220,6 +220,23 @@ /// \param SizeInBits Size of the type. DIStringType *createStringType(StringRef Name, uint64_t SizeInBits); + /// Create debugging information entry for Fortran + /// assumed length string type. + /// \param Name Type name. + /// \param StringLength String length expressed as DIVariable *. + /// \param StrLocationExp Optional memory location of the string. + DIStringType *createStringType(StringRef Name, DIVariable *StringLength, + DIExpression *StrLocationExp = nullptr); + + /// Create debugging information entry for Fortran + /// assumed length string type. + /// \param Name Type name. + /// \param StringLengthExp String length expressed in DIExpression form. + /// \param StrLocationExp Optional memory location of the string. + DIStringType *createStringType(StringRef Name, + DIExpression *StringLengthExp, + DIExpression *StrLocationExp = nullptr); + /// Create debugging information entry for a qualified /// type, e.g. 'const int'. /// \param Tag Tag identifing type, e.g. dwarf::TAG_volatile_type Index: llvm/lib/IR/DIBuilder.cpp =================================================================== --- llvm/lib/IR/DIBuilder.cpp +++ llvm/lib/IR/DIBuilder.cpp @@ -293,6 +293,22 @@ SizeInBits, 0); } +DIStringType *DIBuilder::createStringType(StringRef Name, + DIVariable *StringLength, + DIExpression *StrLocationExp) { + assert(!Name.empty() && "Unable to create type without name"); + return DIStringType::get(VMContext, dwarf::DW_TAG_string_type, Name, + StringLength, nullptr, StrLocationExp, 0, 0, 0); +} + +DIStringType *DIBuilder::createStringType(StringRef Name, + DIExpression *StringLengthExp, + DIExpression *StrLocationExp) { + assert(!Name.empty() && "Unable to create type without name"); + return DIStringType::get(VMContext, dwarf::DW_TAG_string_type, Name, nullptr, + StringLengthExp, StrLocationExp, 0, 0, 0); +} + DIDerivedType *DIBuilder::createQualifiedType(unsigned Tag, DIType *FromTy) { return DIDerivedType::get(VMContext, Tag, "", nullptr, 0, nullptr, FromTy, 0, 0, 0, None, DINode::FlagZero); Index: llvm/unittests/IR/DebugInfoTest.cpp =================================================================== --- llvm/unittests/IR/DebugInfoTest.cpp +++ llvm/unittests/IR/DebugInfoTest.cpp @@ -247,6 +247,45 @@ EXPECT_TRUE(isa_and_nonnull(SetType)); } +TEST(DIBuilder, CreateStringType) { + LLVMContext Ctx; + std::unique_ptr M(new Module("MyModule", Ctx)); + DIBuilder DIB(*M); + DIScope *Scope = DISubprogram::getDistinct( + Ctx, nullptr, "", "", nullptr, 0, nullptr, 0, nullptr, 0, 0, + DINode::FlagZero, DISubprogram::SPFlagZero, nullptr); + DIFile *F = DIB.createFile("main.c", "/"); + StringRef StrName = "string"; + DIVariable *StringLen = DIB.createAutoVariable(Scope, StrName, F, 0, nullptr, + false, DINode::FlagZero, 0); + 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); + }; + DIExpression *StringLocationExp = getDIExpression(1); + DIStringType *StringType = + DIB.createStringType(StrName, StringLen, StringLocationExp); + + EXPECT_TRUE(isa_and_nonnull(StringType)); + EXPECT_EQ(StringType->getName(), StrName); + EXPECT_EQ(StringType->getStringLength(), StringLen); + EXPECT_EQ(StringType->getStringLocationExp(), StringLocationExp); + + StringRef StrNameExp = "stringexp"; + DIExpression *StringLengthExp = getDIExpression(2); + DIStringType *StringTypeExp = + DIB.createStringType(StrNameExp, StringLengthExp, StringLocationExp); + + EXPECT_TRUE(isa_and_nonnull(StringTypeExp)); + EXPECT_EQ(StringTypeExp->getName(), StrNameExp); + EXPECT_EQ(StringTypeExp->getStringLocationExp(), StringLocationExp); + EXPECT_EQ(StringTypeExp->getStringLengthExp(), StringLengthExp); +} + TEST(DIBuilder, DIEnumerator) { LLVMContext Ctx; std::unique_ptr M(new Module("MyModule", Ctx));