Index: llvm/include/llvm/IR/DebugInfoMetadata.h =================================================================== --- llvm/include/llvm/IR/DebugInfoMetadata.h +++ llvm/include/llvm/IR/DebugInfoMetadata.h @@ -852,42 +852,48 @@ static DIStringType *getImpl(LLVMContext &Context, unsigned Tag, StringRef Name, Metadata *StringLength, - Metadata *StrLenExp, uint64_t SizeInBits, - uint32_t AlignInBits, unsigned Encoding, - StorageType Storage, bool ShouldCreate = true) { + Metadata *StrLenExp, Metadata *StrLocationExp, + uint64_t SizeInBits, uint32_t AlignInBits, + unsigned Encoding, StorageType Storage, + bool ShouldCreate = true) { return getImpl(Context, Tag, getCanonicalMDString(Context, Name), - StringLength, StrLenExp, SizeInBits, AlignInBits, Encoding, - Storage, ShouldCreate); + StringLength, StrLenExp, StrLocationExp, SizeInBits, + AlignInBits, Encoding, Storage, ShouldCreate); } static DIStringType *getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *StringLength, - Metadata *StrLenExp, uint64_t SizeInBits, - uint32_t AlignInBits, unsigned Encoding, - StorageType Storage, bool ShouldCreate = true); + Metadata *StrLenExp, Metadata *StrLocationExp, + uint64_t SizeInBits, uint32_t AlignInBits, + unsigned Encoding, StorageType Storage, + bool ShouldCreate = true); TempDIStringType cloneImpl() const { return getTemporary(getContext(), getTag(), getRawName(), getRawStringLength(), getRawStringLengthExp(), - getSizeInBits(), getAlignInBits(), getEncoding()); + getRawStringLocationExp(), getSizeInBits(), + getAlignInBits(), getEncoding()); } public: DEFINE_MDNODE_GET(DIStringType, (unsigned Tag, StringRef Name, uint64_t SizeInBits, uint32_t AlignInBits), - (Tag, Name, nullptr, nullptr, SizeInBits, AlignInBits, 0)) + (Tag, Name, nullptr, nullptr, nullptr, SizeInBits, + AlignInBits, 0)) DEFINE_MDNODE_GET(DIStringType, (unsigned Tag, MDString *Name, Metadata *StringLength, - Metadata *StringLengthExp, uint64_t SizeInBits, - uint32_t AlignInBits, unsigned Encoding), - (Tag, Name, StringLength, StringLengthExp, SizeInBits, - AlignInBits, Encoding)) + Metadata *StringLengthExp, Metadata *StringLocationExp, + uint64_t SizeInBits, uint32_t AlignInBits, + unsigned Encoding), + (Tag, Name, StringLength, StringLengthExp, + StringLocationExp, SizeInBits, AlignInBits, Encoding)) DEFINE_MDNODE_GET(DIStringType, (unsigned Tag, StringRef Name, Metadata *StringLength, - Metadata *StringLengthExp, uint64_t SizeInBits, - uint32_t AlignInBits, unsigned Encoding), - (Tag, Name, StringLength, StringLengthExp, SizeInBits, - AlignInBits, Encoding)) + Metadata *StringLengthExp, Metadata *StringLocationExp, + uint64_t SizeInBits, uint32_t AlignInBits, + unsigned Encoding), + (Tag, Name, StringLength, StringLengthExp, + StringLocationExp, SizeInBits, AlignInBits, Encoding)) TempDIStringType clone() const { return cloneImpl(); } @@ -903,11 +909,17 @@ return cast_or_null(getRawStringLengthExp()); } + DIExpression *getStringLocationExp() const { + return cast_or_null(getRawStringLocationExp()); + } + unsigned getEncoding() const { return Encoding; } Metadata *getRawStringLength() const { return getOperand(3); } Metadata *getRawStringLengthExp() const { return getOperand(4); } + + Metadata *getRawStringLocationExp() const { return getOperand(5); } }; /// Derived types. Index: llvm/lib/AsmParser/LLParser.cpp =================================================================== --- llvm/lib/AsmParser/LLParser.cpp +++ llvm/lib/AsmParser/LLParser.cpp @@ -4550,16 +4550,17 @@ OPTIONAL(name, MDStringField, ); \ OPTIONAL(stringLength, MDField, ); \ OPTIONAL(stringLengthExpression, MDField, ); \ + OPTIONAL(stringLocationExpression, MDField, ); \ OPTIONAL(size, MDUnsignedField, (0, UINT64_MAX)); \ OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX)); \ OPTIONAL(encoding, DwarfAttEncodingField, ); PARSE_MD_FIELDS(); #undef VISIT_MD_FIELDS - Result = GET_OR_DISTINCT(DIStringType, - (Context, tag.Val, name.Val, stringLength.Val, - stringLengthExpression.Val, size.Val, align.Val, - encoding.Val)); + Result = GET_OR_DISTINCT( + DIStringType, + (Context, tag.Val, name.Val, stringLength.Val, stringLengthExpression.Val, + stringLocationExpression.Val, size.Val, align.Val, encoding.Val)); return false; } Index: llvm/lib/Bitcode/Reader/MetadataLoader.cpp =================================================================== --- llvm/lib/Bitcode/Reader/MetadataLoader.cpp +++ llvm/lib/Bitcode/Reader/MetadataLoader.cpp @@ -1423,7 +1423,7 @@ break; } case bitc::METADATA_STRING_TYPE: { - if (Record.size() != 8) + if (Record.size() != 9) return error("Invalid record"); IsDistinct = Record[0]; @@ -1431,7 +1431,8 @@ GET_OR_DISTINCT(DIStringType, (Context, Record[1], getMDString(Record[2]), getMDOrNull(Record[3]), getMDOrNull(Record[4]), - Record[5], Record[6], Record[7])), + getMDOrNull(Record[5]), Record[6], Record[7], + Record[8])), NextMetadataNo); NextMetadataNo++; break; Index: llvm/lib/Bitcode/Writer/BitcodeWriter.cpp =================================================================== --- llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -1657,6 +1657,7 @@ Record.push_back(VE.getMetadataOrNullID(N->getRawName())); Record.push_back(VE.getMetadataOrNullID(N->getStringLength())); Record.push_back(VE.getMetadataOrNullID(N->getStringLengthExp())); + Record.push_back(VE.getMetadataOrNullID(N->getStringLocationExp())); Record.push_back(N->getSizeInBits()); Record.push_back(N->getAlignInBits()); Record.push_back(N->getEncoding()); Index: llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp =================================================================== --- llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -744,6 +744,16 @@ addUInt(Buffer, dwarf::DW_AT_byte_size, None, Size); } + if (DIExpression *Expr = STy->getStringLocationExp()) { + DIELoc *Loc = new (DIEValueAllocator) DIELoc; + DIEDwarfExpression DwarfExpr(*Asm, getCU(), *Loc); + // This is to describe the memory location of the + // string, so lock it down as such. + DwarfExpr.setMemoryLocationKind(); + DwarfExpr.addExpression(Expr); + addBlock(Buffer, dwarf::DW_AT_data_location, DwarfExpr.finalize()); + } + if (STy->getEncoding()) { // For eventual Unicode support. addUInt(Buffer, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, Index: llvm/lib/IR/AsmWriter.cpp =================================================================== --- llvm/lib/IR/AsmWriter.cpp +++ llvm/lib/IR/AsmWriter.cpp @@ -1986,6 +1986,8 @@ Printer.printString("name", N->getName()); Printer.printMetadata("stringLength", N->getRawStringLength()); Printer.printMetadata("stringLengthExpression", N->getRawStringLengthExp()); + Printer.printMetadata("stringLocationExpression", + N->getRawStringLocationExp()); Printer.printInt("size", N->getSizeInBits()); Printer.printInt("align", N->getAlignInBits()); Printer.printDwarfEnum("encoding", N->getEncoding(), Index: llvm/lib/IR/DebugInfoMetadata.cpp =================================================================== --- llvm/lib/IR/DebugInfoMetadata.cpp +++ llvm/lib/IR/DebugInfoMetadata.cpp @@ -567,13 +567,16 @@ DIStringType *DIStringType::getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *StringLength, Metadata *StringLengthExp, + Metadata *StringLocationExp, uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding, StorageType Storage, bool ShouldCreate) { assert(isCanonical(Name) && "Expected canonical MDString"); - DEFINE_GETIMPL_LOOKUP(DIStringType, (Tag, Name, StringLength, StringLengthExp, - SizeInBits, AlignInBits, Encoding)); - Metadata *Ops[] = {nullptr, nullptr, Name, StringLength, StringLengthExp}; + DEFINE_GETIMPL_LOOKUP(DIStringType, + (Tag, Name, StringLength, StringLengthExp, + StringLocationExp, SizeInBits, AlignInBits, Encoding)); + Metadata *Ops[] = {nullptr, nullptr, Name, + StringLength, StringLengthExp, StringLocationExp}; DEFINE_GETIMPL_STORE(DIStringType, (Tag, SizeInBits, AlignInBits, Encoding), Ops); } Index: llvm/lib/IR/LLVMContextImpl.h =================================================================== --- llvm/lib/IR/LLVMContextImpl.h +++ llvm/lib/IR/LLVMContextImpl.h @@ -428,20 +428,22 @@ MDString *Name; Metadata *StringLength; Metadata *StringLengthExp; + Metadata *StringLocationExp; uint64_t SizeInBits; uint32_t AlignInBits; unsigned Encoding; MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *StringLength, - Metadata *StringLengthExp, uint64_t SizeInBits, - uint32_t AlignInBits, unsigned Encoding) + Metadata *StringLengthExp, Metadata *StringLocationExp, + uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding) : Tag(Tag), Name(Name), StringLength(StringLength), - StringLengthExp(StringLengthExp), SizeInBits(SizeInBits), - AlignInBits(AlignInBits), Encoding(Encoding) {} + StringLengthExp(StringLengthExp), StringLocationExp(StringLocationExp), + SizeInBits(SizeInBits), AlignInBits(AlignInBits), Encoding(Encoding) {} MDNodeKeyImpl(const DIStringType *N) : Tag(N->getTag()), Name(N->getRawName()), StringLength(N->getRawStringLength()), StringLengthExp(N->getRawStringLengthExp()), + StringLocationExp(N->getRawStringLocationExp()), SizeInBits(N->getSizeInBits()), AlignInBits(N->getAlignInBits()), Encoding(N->getEncoding()) {} Index: llvm/test/DebugInfo/X86/distringtype.ll =================================================================== --- llvm/test/DebugInfo/X86/distringtype.ll +++ llvm/test/DebugInfo/X86/distringtype.ll @@ -5,11 +5,16 @@ ;; generates DW_AT_string_length attribute ;; !DIStringType(name: "character(*)", stringLength: !{{[0-9]+}}) ;; !DIStringType(name: "character(*)", stringLengthExpr: !DIExpression(...)) +;; +;; !DIStringType has an optional stringLocationExpr field. This +;; tests also verifies that field gets emitted as DW_AT_data_location +;; in the DIE. ; RUN: llc -filetype=obj %s -o - | llvm-dwarfdump - | FileCheck %s ; CHECK: DW_TAG_string_type ; CHECK: DW_AT_name (".str.DEFERRED") ; CHECK-NEXT: DW_AT_string_length (DW_OP_push_object_address, DW_OP_plus_uconst 0x8) +; CHECK-NEXT: DW_AT_data_location (DW_OP_push_object_address, DW_OP_deref) ; CHECK: DW_TAG_string_type ; CHECK: DW_AT_name ("character(*)!2") ; CHECK-NEXT: DW_AT_string_length @@ -150,7 +155,7 @@ !6 = distinct !DICompileUnit(language: DW_LANG_Fortran95, file: !3, producer: "Intel(R) Fortran 21.0-2142", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !7, globals: !8, splitDebugInlining: false, nameTableKind: None) !7 = !{} !8 = !{!0} -!9 = !DIStringType(name: ".str.DEFERRED", stringLengthExpression: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 8)) +!9 = !DIStringType(name: ".str.DEFERRED", stringLengthExpression: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 8), stringLocationExpression: !DIExpression(DW_OP_push_object_address, DW_OP_deref)) !10 = !{i32 2, !"Debug Info Version", i32 3} !11 = !{i32 2, !"Dwarf Version", i32 4} !12 = !DILocation(line: 1, column: 9, scope: !2) Index: llvm/test/DebugInfo/fortran-string-type.ll =================================================================== --- llvm/test/DebugInfo/fortran-string-type.ll +++ llvm/test/DebugInfo/fortran-string-type.ll @@ -7,7 +7,7 @@ ; CHECK: !DIStringType(name: "character(*)", stringLength: !{{[0-9]+}}, stringLengthExpression: !DIExpression(), size: 32) ; CHECK: !DIStringType(name: "character(10)", size: 80, align: 8) ; CHECK: !DIBasicType(tag: DW_TAG_string_type -; CHECK: !DIStringType(name: ".str.DEFERRED", stringLengthExpression: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 8)) +; CHECK: !DIStringType(name: ".str.DEFERRED", stringLengthExpression: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 8), stringLocationExpression: !DIExpression(DW_OP_push_object_address, DW_OP_deref)) !llvm.module.flags = !{!0, !1} !llvm.dbg.cu = !{!2} @@ -26,4 +26,4 @@ !11 = !DIBasicType(name: "integer*8", size: 64, align: 64, encoding: DW_ATE_signed) !12 = !DIStringType(name: "character(10)", size: 80, align: 8) !13 = !DIBasicType(tag: DW_TAG_string_type, name: "character") -!14 = !DIStringType(name: ".str.DEFERRED", stringLengthExpression: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 8)) +!14 = !DIStringType(name: ".str.DEFERRED", stringLengthExpression: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 8), stringLocationExpression: !DIExpression(DW_OP_push_object_address, DW_OP_deref))