From 16c7bdaf3245d23b9b441144f5efb610e2044927 Mon Sep 17 00:00:00 2001 From: Scott Linder Date: Fri, 23 Feb 2018 23:01:06 +0000 Subject: [PATCH] [DebugInfo] Support DWARF v5 source code embedding extension In DWARF v5 the Line Number Program Header is extensible, allowing values with new content types. In this extension a content type is added, DW_LNCT_LLVM_source, which contains the embedded source code of the file. Add new optional attribute for !DIFile IR metadata called source which contains source text. Use this to output the source to the DWARF line table of code objects. Analogously extend METADATA_FILE in Bitcode and .file directive in ASM to support optional source. Teach llvm-dwarfdump and llvm-objdump about the new values. Update the output format of llvm-dwarfdump to make room for the new attribute on file_names entries, and support embedded sources for the -source option in llvm-objdump. Differential Revision: https://reviews.llvm.org/D42765 llvm-svn: 325970 --- llvm/docs/AMDGPUUsage.rst | 58 ++++++++++++- llvm/include/llvm/BinaryFormat/Dwarf.def | 3 + llvm/include/llvm/DebugInfo/DIContext.h | 1 + llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h | 26 +++++- llvm/include/llvm/IR/DIBuilder.h | 9 +- llvm/include/llvm/IR/DebugInfoMetadata.h | 46 ++++++++-- llvm/include/llvm/MC/MCContext.h | 4 +- llvm/include/llvm/MC/MCDwarf.h | 19 +++-- llvm/include/llvm/MC/MCStreamer.h | 16 ++-- llvm/lib/AsmParser/LLParser.cpp | 13 ++- llvm/lib/Bitcode/Reader/MetadataLoader.cpp | 9 +- llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 3 + llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp | 5 +- llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 6 +- llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp | 4 +- llvm/lib/DebugInfo/DWARF/DWARFContext.cpp | 4 +- llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp | 98 +++++++++++++++------- llvm/lib/IR/AsmWriter.cpp | 2 + llvm/lib/IR/DIBuilder.cpp | 6 +- llvm/lib/IR/DebugInfoMetadata.cpp | 11 ++- llvm/lib/IR/LLVMContextImpl.h | 18 ++-- llvm/lib/MC/MCAsmStreamer.cpp | 10 ++- llvm/lib/MC/MCContext.cpp | 6 +- llvm/lib/MC/MCDwarf.cpp | 51 ++++++++--- llvm/lib/MC/MCParser/AsmParser.cpp | 48 +++++++---- llvm/lib/MC/MCStreamer.cpp | 8 +- llvm/test/Assembler/debug-info.ll | 9 +- llvm/test/CodeGen/BPF/dwarfdump.ll | 4 +- llvm/test/CodeGen/Generic/dwarf-md5.ll | 22 +++-- llvm/test/CodeGen/X86/dwarf-comp-dir.ll | 6 +- llvm/test/DebugInfo/AMDGPU/dwarfdump-relocs.ll | 4 +- llvm/test/DebugInfo/Generic/lto-comp-dir.ll | 8 +- llvm/test/DebugInfo/X86/debug-macro.ll | 11 +-- llvm/test/DebugInfo/X86/dwarfdump-header-64.s | 12 ++- llvm/test/DebugInfo/X86/dwarfdump-header.s | 35 ++++++-- llvm/test/DebugInfo/X86/dwarfdump-line-dwo.s | 6 +- llvm/test/DebugInfo/X86/dwarfdump-line-only.s | 12 ++- llvm/test/DebugInfo/X86/generate-odr-hash.ll | 12 ++- .../X86/stmt-list-multiple-compile-units.ll | 16 +++- llvm/test/DebugInfo/debugmacinfo.test | 12 ++- llvm/test/Linker/subprogram-linkonce-weak.ll | 12 ++- llvm/test/MC/ARM/dwarf-asm-multiple-sections.s | 3 +- llvm/test/MC/ELF/debug-md5.s | 11 ++- llvm/test/MC/MachO/gen-dwarf-cpp.s | 14 ++-- llvm/test/MC/MachO/gen-dwarf-macro-cpp.s | 10 ++- llvm/test/MC/MachO/gen-dwarf.s | 6 +- .../test/tools/dsymutil/X86/basic-linking-x86.test | 18 ++-- .../dsymutil/X86/basic-lto-dw4-linking-x86.test | 18 ++-- .../tools/dsymutil/X86/basic-lto-linking-x86.test | 18 ++-- llvm/tools/llvm-objdump/llvm-objdump.cpp | 26 +++--- llvm/unittests/IR/MetadataTest.cpp | 13 ++- 51 files changed, 581 insertions(+), 221 deletions(-) diff --git a/llvm/docs/AMDGPUUsage.rst b/llvm/docs/AMDGPUUsage.rst index d416b84..aafd922 100644 --- a/llvm/docs/AMDGPUUsage.rst +++ b/llvm/docs/AMDGPUUsage.rst @@ -780,7 +780,7 @@ The following relocation types are supported: DWARF ----- -Standard DWARF [DWARF]_ Version 2 sections can be generated. These contain +Standard DWARF [DWARF]_ Version 5 sections can be generated. These contain information that maps the code object executable code and data to the source language constructs. It can be used by tools such as debuggers and profilers. @@ -836,10 +836,60 @@ Register Mapping Source Text ~~~~~~~~~~~ -*This section is WIP.* +Source text for online-compiled programs (e.g. those compiled by the OpenCL +runtime) may be embedded into the DWARF v5 line table using the ``clang +-gembed-source`` option, described in table :ref:`amdgpu-debug-options`. -.. TODO - DWARF extension to include runtime generated source text. +For example: + +``-gembed-source`` + Enable the embedded source DWARF v5 extension. +``-gno-embed-source`` + Disable the embedded source DWARF v5 extension. + + .. table:: AMDGPU Debug Options + :name: amdgpu-debug-options + + ==================== ================================================== + Debug Flag Description + ==================== ================================================== + -g[no-]embed-source Enable/disable embedding source text in DWARF + debug sections. Useful for environments where + source cannot be written to disk, such as + when performing online compilation. + ==================== ================================================== + +This option enables one extended content types in the DWARF v5 Line Number +Program Header, which is used to encode embedded source. + + .. table:: AMDGPU DWARF Line Number Program Header Extended Content Types + :name: amdgpu-dwarf-extended-content-types + + ============================ ====================== + Content Type Form + ============================ ====================== + ``DW_LNCT_LLVM_source`` ``DW_FORM_line_strp`` + ============================ ====================== + +The source field will contain the UTF-8 encoded, null-terminated source text +with ``'\n'`` line endings. When the source field is present, consumers can use +the embedded source instead of attempting to discover the source on disk. When +the source field is absent, consumers can access the file to get the source +text. + +The above content type appears in the ``file_name_entry_format`` field of the +line table prologue, and its corresponding value appear in the ``file_names`` +field. The current encoding of the content type is documented in table +:ref:`amdgpu-dwarf-extended-content-types-encoding` + + .. table:: AMDGPU DWARF Line Number Program Header Extended Content Types Encoding + :name: amdgpu-dwarf-extended-content-types-encoding + + ============================ ==================== + Content Type Value + ============================ ==================== + ``DW_LNCT_LLVM_source`` 0x2001 + ============================ ==================== .. _amdgpu-code-conventions: diff --git a/llvm/include/llvm/BinaryFormat/Dwarf.def b/llvm/include/llvm/BinaryFormat/Dwarf.def index 11b81a4..69def07 100644 --- a/llvm/include/llvm/BinaryFormat/Dwarf.def +++ b/llvm/include/llvm/BinaryFormat/Dwarf.def @@ -747,6 +747,9 @@ HANDLE_DW_LNCT(0x02, directory_index) HANDLE_DW_LNCT(0x03, timestamp) HANDLE_DW_LNCT(0x04, size) HANDLE_DW_LNCT(0x05, MD5) +// A vendor extension until http://dwarfstd.org/ShowIssue.php?issue=180201.1 is +// accepted and incorporated into the next DWARF standard. +HANDLE_DW_LNCT(0x2001, LLVM_source) // DWARF v5 Macro information. HANDLE_DW_MACRO(0x01, define) diff --git a/llvm/include/llvm/DebugInfo/DIContext.h b/llvm/include/llvm/DebugInfo/DIContext.h index abace93..751bbe3 100644 --- a/llvm/include/llvm/DebugInfo/DIContext.h +++ b/llvm/include/llvm/DebugInfo/DIContext.h @@ -31,6 +31,7 @@ namespace llvm { struct DILineInfo { std::string FileName; std::string FunctionName; + Optional Source; uint32_t Line = 0; uint32_t Column = 0; uint32_t StartLine = 0; diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h index 182afcd..54b86d6 100644 --- a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h +++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h @@ -10,6 +10,7 @@ #ifndef LLVM_DEBUGINFO_DWARFDEBUGLINE_H #define LLVM_DEBUGINFO_DWARFDEBUGLINE_H +#include "llvm/ADT/Optional.h" #include "llvm/ADT/StringRef.h" #include "llvm/DebugInfo/DIContext.h" #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h" @@ -36,6 +37,25 @@ public: uint64_t ModTime = 0; uint64_t Length = 0; MD5::MD5Result Checksum; + DWARFFormValue Source; + }; + + /// Tracks which optional content types are present in a DWARF file name + /// entry format. + struct ContentTypeTracker { + ContentTypeTracker() = default; + + /// Whether filename entries provide a modification timestamp. + bool HasModTime = false; + /// Whether filename entries provide a file size. + bool HasLength = false; + /// For v5, whether filename entries provide an MD5 checksum. + bool HasMD5 = false; + /// For v5, whether filename entries provide source text. + bool HasSource = false; + + /// Update tracked content types with \p ContentType. + void trackContentType(dwarf::LineNumberEntryFormat ContentType); }; struct Prologue { @@ -68,8 +88,8 @@ public: uint8_t LineRange; /// The number assigned to the first special opcode. uint8_t OpcodeBase; - /// For v5, whether filename entries provide an MD5 checksum. - bool HasMD5; + /// This tracks which optional file format content types are present. + ContentTypeTracker ContentTypes; std::vector StandardOpcodeLengths; std::vector IncludeDirectories; std::vector FileNames; @@ -239,6 +259,8 @@ public: private: uint32_t findRowInSeq(const DWARFDebugLine::Sequence &Seq, uint64_t Address) const; + Optional getSourceByIndex(uint64_t FileIndex, + DILineInfoSpecifier::FileLineInfoKind Kind) const; }; const LineTable *getLineTable(uint32_t Offset) const; diff --git a/llvm/include/llvm/IR/DIBuilder.h b/llvm/include/llvm/IR/DIBuilder.h index 9a24e4f..aa8a8ec 100644 --- a/llvm/include/llvm/IR/DIBuilder.h +++ b/llvm/include/llvm/IR/DIBuilder.h @@ -18,7 +18,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/MapVector.h" -#include "llvm/ADT/None.h" +#include "llvm/ADT/Optional.h" #include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" @@ -141,10 +141,13 @@ namespace llvm { /// Create a file descriptor to hold debugging information for a file. /// \param Filename File name. /// \param Directory Directory. - /// \param Checksum Checksum kind (e.g. CSK_MD5, CSK_SHA1, etc.) and value. + /// \param Checksum Optional checksum kind (e.g. CSK_MD5, CSK_SHA1, etc.) + /// and value. + /// \param Source Optional source text. DIFile * createFile(StringRef Filename, StringRef Directory, - Optional> Checksum = None); + Optional> Checksum = None, + Optional Source = None); /// Create debugging information entry for a macro. /// \param Parent Macro parent (could be nullptr). diff --git a/llvm/include/llvm/IR/DebugInfoMetadata.h b/llvm/include/llvm/IR/DebugInfoMetadata.h index c405b4c..232a7d6 100644 --- a/llvm/include/llvm/IR/DebugInfoMetadata.h +++ b/llvm/include/llvm/IR/DebugInfoMetadata.h @@ -455,6 +455,7 @@ public: inline StringRef getFilename() const; inline StringRef getDirectory() const; + inline Optional getSource() const; StringRef getName() const; DIScopeRef getScope() const; @@ -532,42 +533,48 @@ public: private: Optional> Checksum; + Optional Source; DIFile(LLVMContext &C, StorageType Storage, - Optional> CS, + Optional> CS, Optional Src, ArrayRef Ops) : DIScope(C, DIFileKind, Storage, dwarf::DW_TAG_file_type, Ops), - Checksum(CS) {} + Checksum(CS), Source(Src) {} ~DIFile() = default; static DIFile *getImpl(LLVMContext &Context, StringRef Filename, StringRef Directory, Optional> CS, + Optional Source, StorageType Storage, bool ShouldCreate = true) { Optional> MDChecksum; if (CS) MDChecksum.emplace(CS->Kind, getCanonicalMDString(Context, CS->Value)); return getImpl(Context, getCanonicalMDString(Context, Filename), getCanonicalMDString(Context, Directory), MDChecksum, + Source ? Optional(getCanonicalMDString(Context, *Source)) : None, Storage, ShouldCreate); } static DIFile *getImpl(LLVMContext &Context, MDString *Filename, MDString *Directory, Optional> CS, - StorageType Storage, bool ShouldCreate = true); + Optional Source, StorageType Storage, + bool ShouldCreate = true); TempDIFile cloneImpl() const { return getTemporary(getContext(), getFilename(), getDirectory(), - getChecksum()); + getChecksum(), getSource()); } public: DEFINE_MDNODE_GET(DIFile, (StringRef Filename, StringRef Directory, - Optional> CS = None), - (Filename, Directory, CS)) + Optional> CS = None, + Optional Source = None), + (Filename, Directory, CS, Source)) DEFINE_MDNODE_GET(DIFile, (MDString * Filename, MDString *Directory, - Optional> CS = None), - (Filename, Directory, CS)) + Optional> CS = None, + Optional Source = None), + (Filename, Directory, CS, Source)) TempDIFile clone() const { return cloneImpl(); } @@ -579,10 +586,14 @@ public: StringRefChecksum.emplace(Checksum->Kind, Checksum->Value->getString()); return StringRefChecksum; } + Optional getSource() const { + return Source ? Optional((*Source)->getString()) : None; + } MDString *getRawFilename() const { return getOperandAs(0); } MDString *getRawDirectory() const { return getOperandAs(1); } Optional> getRawChecksum() const { return Checksum; } + Optional getRawSource() const { return Source; } static StringRef getChecksumKindAsString(ChecksumKind CSKind); static Optional getChecksumKind(StringRef CSKindStr); @@ -604,6 +615,12 @@ StringRef DIScope::getDirectory() const { return ""; } +Optional DIScope::getSource() const { + if (auto *F = getFile()) + return F->getSource(); + return None; +} + /// Base class for types. /// /// TODO: Remove the hardcoded name and context, since many types don't use @@ -1408,6 +1425,7 @@ public: DIFile *getFile() const { return getScope()->getFile(); } StringRef getFilename() const { return getScope()->getFilename(); } StringRef getDirectory() const { return getScope()->getDirectory(); } + Optional getSource() const { return getScope()->getSource(); } /// Get the scope where this is inlined. /// @@ -2177,6 +2195,12 @@ public: return ""; } + Optional getSource() const { + if (auto *F = getFile()) + return F->getSource(); + return None; + } + Metadata *getRawScope() const { return getOperand(0); } MDString *getRawName() const { return getOperandAs(1); } Metadata *getRawFile() const { return getOperand(2); } @@ -2624,6 +2648,12 @@ public: return ""; } + Optional getSource() const { + if (auto *F = getFile()) + return F->getSource(); + return None; + } + MDString *getRawName() const { return getOperandAs(0); } Metadata *getRawFile() const { return getOperand(1); } MDString *getRawGetterName() const { return getOperandAs(2); } diff --git a/llvm/include/llvm/MC/MCContext.h b/llvm/include/llvm/MC/MCContext.h index 7044ebb..c4abef1 100644 --- a/llvm/include/llvm/MC/MCContext.h +++ b/llvm/include/llvm/MC/MCContext.h @@ -11,6 +11,7 @@ #define LLVM_MC_MCCONTEXT_H #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/Optional.h" #include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" @@ -496,7 +497,8 @@ namespace llvm { /// Creates an entry in the dwarf file and directory tables. Expected getDwarfFile(StringRef Directory, StringRef FileName, unsigned FileNumber, - MD5::MD5Result *Checksum, unsigned CUID); + MD5::MD5Result *Checksum, + Optional Source, unsigned CUID); bool isValidDwarfFileNumber(unsigned FileNumber, unsigned CUID = 0); diff --git a/llvm/include/llvm/MC/MCDwarf.h b/llvm/include/llvm/MC/MCDwarf.h index d39743e..c90a076 100644 --- a/llvm/include/llvm/MC/MCDwarf.h +++ b/llvm/include/llvm/MC/MCDwarf.h @@ -16,6 +16,7 @@ #define LLVM_MC_MCDWARF_H #include "llvm/ADT/MapVector.h" +#include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" @@ -48,7 +49,6 @@ class SourceMgr; /// index 0 is not used and not a valid dwarf file number). struct MCDwarfFile { // \brief The base name of the file without its directory path. - // The StringRef references memory allocated in the MCContext. std::string Name; // \brief The index into the list of directory names for this file name. @@ -57,6 +57,10 @@ struct MCDwarfFile { /// The MD5 checksum, if there is one. Non-owning pointer to data allocated /// in MCContext. MD5::MD5Result *Checksum = nullptr; + + /// The source code of the file. Non-owning reference to data allocated in + /// MCContext. + Optional Source; }; /// \brief Instances of this class represent the information from a @@ -211,11 +215,13 @@ struct MCDwarfLineTableHeader { StringMap SourceIdMap; StringRef CompilationDir; bool HasMD5 = false; + bool HasSource = false; MCDwarfLineTableHeader() = default; Expected tryGetFile(StringRef &Directory, StringRef &FileName, MD5::MD5Result *Checksum, + Optional &Source, unsigned FileNumber = 0); std::pair Emit(MCStreamer *MCOS, MCDwarfLineTableParams Params, @@ -240,8 +246,8 @@ public: } unsigned getFile(StringRef Directory, StringRef FileName, - MD5::MD5Result *Checksum) { - return cantFail(Header.tryGetFile(Directory, FileName, Checksum)); + MD5::MD5Result *Checksum, Optional Source) { + return cantFail(Header.tryGetFile(Directory, FileName, Checksum, Source)); } void Emit(MCStreamer &MCOS, MCDwarfLineTableParams Params) const; @@ -261,10 +267,13 @@ public: Expected tryGetFile(StringRef &Directory, StringRef &FileName, MD5::MD5Result *Checksum, + Optional Source, unsigned FileNumber = 0); unsigned getFile(StringRef &Directory, StringRef &FileName, - MD5::MD5Result *Checksum, unsigned FileNumber = 0) { - return cantFail(tryGetFile(Directory, FileName, Checksum, FileNumber)); + MD5::MD5Result *Checksum, Optional &Source, + unsigned FileNumber = 0) { + return cantFail(tryGetFile(Directory, FileName, Checksum, Source, + FileNumber)); } MCSymbol *getLabel() const { diff --git a/llvm/include/llvm/MC/MCStreamer.h b/llvm/include/llvm/MC/MCStreamer.h index 3adad15..8f0230d 100644 --- a/llvm/include/llvm/MC/MCStreamer.h +++ b/llvm/include/llvm/MC/MCStreamer.h @@ -16,6 +16,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/MC/MCDirectives.h" @@ -756,17 +757,22 @@ public: unsigned EmitDwarfFileDirective(unsigned FileNo, StringRef Directory, StringRef Filename, MD5::MD5Result *Checksum = nullptr, + Optional Source = None, unsigned CUID = 0) { return cantFail( - tryEmitDwarfFileDirective(FileNo, Directory, Filename, Checksum, CUID)); + tryEmitDwarfFileDirective(FileNo, Directory, Filename, Checksum, + Source, CUID)); } - /// Associate a filename with a specified logical file number. Returns a - /// StringError for any problem, or the file number. This implements the - /// DWARF2 '.file 4 "foo.c"' assembler directive. + /// Associate a filename with a specified logical file number. + /// Also associate a directory, optional checksum, and optional source + /// text with the logical file. This implements the DWARF2 + /// '.file 4 "dir/foo.c"' assembler directive, and the DWARF5 + /// '.file 4 "dir/foo.c" md5 "..." source "..."' assembler directive. virtual Expected tryEmitDwarfFileDirective( unsigned FileNo, StringRef Directory, StringRef Filename, - MD5::MD5Result *Checksum = nullptr, unsigned CUID = 0); + MD5::MD5Result *Checksum = nullptr, Optional Source = None, + unsigned CUID = 0); /// \brief This implements the DWARF2 '.loc fileno lineno ...' assembler /// directive. diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index d5714ea..42c5798 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -4243,9 +4243,10 @@ bool LLParser::ParseDISubroutineType(MDNode *&Result, bool IsDistinct) { } /// ParseDIFileType: -/// ::= !DIFileType(filename: "path/to/file", directory: "/path/to/dir" +/// ::= !DIFileType(filename: "path/to/file", directory: "/path/to/dir", /// checksumkind: CSK_MD5, -/// checksum: "000102030405060708090a0b0c0d0e0f") +/// checksum: "000102030405060708090a0b0c0d0e0f", +/// source: "source file contents") bool LLParser::ParseDIFile(MDNode *&Result, bool IsDistinct) { // The default constructed value for checksumkind is required, but will never // be used, as the parser checks if the field was actually Seen before using @@ -4254,7 +4255,8 @@ bool LLParser::ParseDIFile(MDNode *&Result, bool IsDistinct) { REQUIRED(filename, MDStringField, ); \ REQUIRED(directory, MDStringField, ); \ OPTIONAL(checksumkind, ChecksumKindField, (DIFile::CSK_MD5)); \ - OPTIONAL(checksum, MDStringField, ); + OPTIONAL(checksum, MDStringField, ); \ + OPTIONAL(source, MDStringField, ); PARSE_MD_FIELDS(); #undef VISIT_MD_FIELDS @@ -4264,8 +4266,11 @@ bool LLParser::ParseDIFile(MDNode *&Result, bool IsDistinct) { else if (checksumkind.Seen || checksum.Seen) return Lex.Error("'checksumkind' and 'checksum' must be provided together"); + Optional OptSource; + if (source.Seen) + OptSource = source.Val; Result = GET_OR_DISTINCT(DIFile, (Context, filename.Val, directory.Val, - OptChecksum)); + OptChecksum, OptSource)); return false; } diff --git a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp index 0931192..efaee21 100644 --- a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp +++ b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp @@ -1350,7 +1350,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( } case bitc::METADATA_FILE: { - if (Record.size() != 3 && Record.size() != 5) + if (Record.size() != 3 && Record.size() != 5 && Record.size() != 6) return error("Invalid record"); IsDistinct = Record[0]; @@ -1360,14 +1360,15 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( // and the old encoding for CSK_None in the ChecksumKind. The new // representation reserves the value 0 in the ChecksumKind to continue to // encode None in a backwards-compatible way. - if (Record.size() == 5 && Record[3] && Record[4]) + if (Record.size() > 4 && Record[3] && Record[4]) Checksum.emplace(static_cast(Record[3]), getMDString(Record[4])); MetadataList.assignValue( GET_OR_DISTINCT( DIFile, - (Context, getMDString(Record[1]), getMDString(Record[2]), - Checksum)), + (Context, getMDString(Record[1]), getMDString(Record[2]), Checksum, + Record.size() > 5 ? Optional(getMDString(Record[5])) + : None)), NextMetadataNo); NextMetadataNo++; break; diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index 832f494..0738b90 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -1560,6 +1560,9 @@ void ModuleBitcodeWriter::writeDIFile(const DIFile *N, Record.push_back(0); Record.push_back(VE.getMetadataOrNullID(nullptr)); } + auto Source = N->getRawSource(); + if (Source) + Record.push_back(VE.getMetadataOrNullID(*Source)); Stream.EmitRecord(bitc::METADATA_FILE, Record, Abbrev); Record.clear(); diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp index dcc3e55..0b2a046 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -102,9 +102,10 @@ unsigned DwarfCompileUnit::getOrCreateSourceID(const DIFile *File) { // extend .file to support this. unsigned CUID = Asm->OutStreamer->hasRawTextSupport() ? 0 : getUniqueID(); if (!File) - return Asm->OutStreamer->EmitDwarfFileDirective(0, "", "", nullptr, CUID); + return Asm->OutStreamer->EmitDwarfFileDirective(0, "", "", nullptr, None, CUID); return Asm->OutStreamer->EmitDwarfFileDirective( - 0, File->getDirectory(), File->getFilename(), getMD5AsBytes(File), CUID); + 0, File->getDirectory(), File->getFilename(), getMD5AsBytes(File), + File->getSource(), CUID); } DIE *DwarfCompileUnit::getOrCreateGlobalVariableDIE( diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 99ed096..6b50fb9 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -1384,7 +1384,7 @@ void DwarfDebug::endFunctionImpl(const MachineFunction *MF) { void DwarfDebug::recordSourceLine(unsigned Line, unsigned Col, const MDNode *S, unsigned Flags) { StringRef Fn; - unsigned Src = 1; + unsigned FileNo = 1; unsigned Discriminator = 0; if (auto *Scope = cast_or_null(S)) { Fn = Scope->getFilename(); @@ -1393,10 +1393,10 @@ void DwarfDebug::recordSourceLine(unsigned Line, unsigned Col, const MDNode *S, Discriminator = LBF->getDiscriminator(); unsigned CUID = Asm->OutStreamer->getContext().getDwarfCompileUnitID(); - Src = static_cast(*InfoHolder.getUnits()[CUID]) + FileNo = static_cast(*InfoHolder.getUnits()[CUID]) .getOrCreateSourceID(Scope->getFile()); } - Asm->OutStreamer->EmitDwarfLocDirective(Src, Line, Col, Flags, 0, + Asm->OutStreamer->EmitDwarfLocDirective(FileNo, Line, Col, Flags, 0, Discriminator, Fn); } diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp index d7d5298..377e557 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -302,7 +302,9 @@ MD5::MD5Result *DwarfUnit::getMD5AsBytes(const DIFile *File) { unsigned DwarfTypeUnit::getOrCreateSourceID(const DIFile *File) { return SplitLineTable ? SplitLineTable->getFile(File->getDirectory(), - File->getFilename(), getMD5AsBytes(File)) + File->getFilename(), + getMD5AsBytes(File), + File->getSource()) : getCU().getOrCreateSourceID(File); } diff --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp index ef09726..de7ef66 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp @@ -466,7 +466,9 @@ void DWARFContext::dump( uint32_t offset = 0; uint32_t strOffset = 0; while (const char *s = strData.getCStr(&offset)) { - OS << format("0x%8.8x: \"%s\"\n", strOffset, s); + OS << format("0x%8.8x: \"", strOffset); + OS.write_escaped(s); + OS << "\"\n"; strOffset = offset; } } diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp index 8986af2..56e7af2 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// #include "llvm/DebugInfo/DWARF/DWARFDebugLine.h" +#include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" @@ -40,6 +41,28 @@ using ContentDescriptors = SmallVector; } // end anonmyous namespace +void DWARFDebugLine::ContentTypeTracker::trackContentType( + dwarf::LineNumberEntryFormat ContentType) { + switch (ContentType) { + case dwarf::DW_LNCT_timestamp: + HasModTime = true; + break; + case dwarf::DW_LNCT_size: + HasLength = true; + break; + case dwarf::DW_LNCT_MD5: + HasMD5 = true; + break; + case dwarf::DW_LNCT_LLVM_source: + HasSource = true; + break; + default: + // We only care about values we consider optional, and new values may be + // added in the vendor extension range, so we do not match exhaustively. + break; + } +} + DWARFDebugLine::Prologue::Prologue() { clear(); } void DWARFDebugLine::Prologue::clear() { @@ -48,7 +71,7 @@ void DWARFDebugLine::Prologue::clear() { MinInstLength = MaxOpsPerInst = DefaultIsStmt = LineBase = LineRange = 0; OpcodeBase = 0; FormParams = DWARFFormParams({0, 0, DWARF32}); - HasMD5 = false; + ContentTypes = ContentTypeTracker(); StandardOpcodeLengths.clear(); IncludeDirectories.clear(); FileNames.clear(); @@ -85,28 +108,26 @@ void DWARFDebugLine::Prologue::dump(raw_ostream &OS, } if (!FileNames.empty()) { - if (HasMD5) - OS << " Dir MD5 Checksum File Name\n" - << " ---- -------------------------------- -----------" - "---------------\n"; - else - OS << " Dir Mod Time File Len File Name\n" - << " ---- ---------- ---------- -----------" - "----------------\n"; // DWARF v5 starts file indexes at 0. uint32_t FileBase = getVersion() >= 5 ? 0 : 1; for (uint32_t I = 0; I != FileNames.size(); ++I) { const FileNameEntry &FileEntry = FileNames[I]; - OS << format("file_names[%3u] %4" PRIu64 " ", I + FileBase, - FileEntry.DirIdx); - if (HasMD5) - OS << FileEntry.Checksum.digest(); - else - OS << format("0x%8.8" PRIx64 " 0x%8.8" PRIx64, FileEntry.ModTime, - FileEntry.Length); - OS << ' '; + OS << format("file_names[%3u]:\n", I + FileBase); + OS << " name: "; FileEntry.Name.dump(OS, DumpOptions); - OS << '\n'; + OS << '\n' + << format(" dir_index: %" PRIu64 "\n", FileEntry.DirIdx); + if (ContentTypes.HasMD5) + OS << " md5_checksum: " << FileEntry.Checksum.digest() << '\n'; + if (ContentTypes.HasModTime) + OS << format(" mod_time: 0x%8.8" PRIx64 "\n", FileEntry.ModTime); + if (ContentTypes.HasLength) + OS << format(" length: 0x%8.8" PRIx64 "\n", FileEntry.Length); + if (ContentTypes.HasSource) { + OS << " source: "; + FileEntry.Source.dump(OS, DumpOptions); + OS << '\n'; + } } } } @@ -115,6 +136,7 @@ void DWARFDebugLine::Prologue::dump(raw_ostream &OS, static void parseV2DirFileTables(const DWARFDataExtractor &DebugLineData, uint32_t *OffsetPtr, uint64_t EndPrologueOffset, + DWARFDebugLine::ContentTypeTracker &ContentTypes, std::vector &IncludeDirectories, std::vector &FileNames) { while (*OffsetPtr < EndPrologueOffset) { @@ -138,14 +160,18 @@ parseV2DirFileTables(const DWARFDataExtractor &DebugLineData, FileEntry.Length = DebugLineData.getULEB128(OffsetPtr); FileNames.push_back(FileEntry); } + + ContentTypes.HasModTime = true; + ContentTypes.HasLength = true; } // Parse v5 directory/file entry content descriptions. // Returns the descriptors, or an empty vector if we did not find a path or // ran off the end of the prologue. static ContentDescriptors -parseV5EntryFormat(const DWARFDataExtractor &DebugLineData, uint32_t *OffsetPtr, - uint64_t EndPrologueOffset, bool *HasMD5) { +parseV5EntryFormat(const DWARFDataExtractor &DebugLineData, uint32_t + *OffsetPtr, uint64_t EndPrologueOffset, DWARFDebugLine::ContentTypeTracker + *ContentTypes) { ContentDescriptors Descriptors; int FormatCount = DebugLineData.getU8(OffsetPtr); bool HasPath = false; @@ -158,8 +184,8 @@ parseV5EntryFormat(const DWARFDataExtractor &DebugLineData, uint32_t *OffsetPtr, Descriptor.Form = dwarf::Form(DebugLineData.getULEB128(OffsetPtr)); if (Descriptor.Type == dwarf::DW_LNCT_path) HasPath = true; - else if (Descriptor.Type == dwarf::DW_LNCT_MD5 && HasMD5) - *HasMD5 = true; + if (ContentTypes) + ContentTypes->trackContentType(Descriptor.Type); Descriptors.push_back(Descriptor); } return HasPath ? Descriptors : ContentDescriptors(); @@ -168,8 +194,9 @@ parseV5EntryFormat(const DWARFDataExtractor &DebugLineData, uint32_t *OffsetPtr, static bool parseV5DirFileTables(const DWARFDataExtractor &DebugLineData, uint32_t *OffsetPtr, uint64_t EndPrologueOffset, - const DWARFFormParams &FormParams, const DWARFContext &Ctx, - const DWARFUnit *U, bool &HasMD5, + const DWARFFormParams &FormParams, const DWARFContext + &Ctx, const DWARFUnit *U, + DWARFDebugLine::ContentTypeTracker &ContentTypes, std::vector &IncludeDirectories, std::vector &FileNames) { // Get the directory entry description. @@ -200,7 +227,8 @@ parseV5DirFileTables(const DWARFDataExtractor &DebugLineData, // Get the file entry description. ContentDescriptors FileDescriptors = - parseV5EntryFormat(DebugLineData, OffsetPtr, EndPrologueOffset, &HasMD5); + parseV5EntryFormat(DebugLineData, OffsetPtr, EndPrologueOffset, + &ContentTypes); if (FileDescriptors.empty()) return false; @@ -218,6 +246,9 @@ parseV5DirFileTables(const DWARFDataExtractor &DebugLineData, case DW_LNCT_path: FileEntry.Name = Value; break; + case DW_LNCT_LLVM_source: + FileEntry.Source = Value; + break; case DW_LNCT_directory_index: FileEntry.DirIdx = Value.getAsUnsignedConstant().getValue(); break; @@ -285,8 +316,8 @@ bool DWARFDebugLine::Prologue::parse(const DWARFDataExtractor &DebugLineData, if (getVersion() >= 5) { if (!parseV5DirFileTables(DebugLineData, OffsetPtr, EndPrologueOffset, - FormParams, Ctx, U, HasMD5, IncludeDirectories, - FileNames)) { + FormParams, Ctx, U, ContentTypes, + IncludeDirectories, FileNames)) { fprintf(stderr, "warning: parsing line table prologue at 0x%8.8" PRIx64 " found an invalid directory or file table description at" @@ -295,7 +326,7 @@ bool DWARFDebugLine::Prologue::parse(const DWARFDataExtractor &DebugLineData, } } else parseV2DirFileTables(DebugLineData, OffsetPtr, EndPrologueOffset, - IncludeDirectories, FileNames); + ContentTypes, IncludeDirectories, FileNames); if (*OffsetPtr != EndPrologueOffset) { fprintf(stderr, @@ -912,6 +943,16 @@ bool DWARFDebugLine::LineTable::hasFileAtIndex(uint64_t FileIndex) const { return FileIndex != 0 && FileIndex <= Prologue.FileNames.size(); } +Optional DWARFDebugLine::LineTable::getSourceByIndex(uint64_t FileIndex, + FileLineInfoKind Kind) const { + if (Kind == FileLineInfoKind::None || !hasFileAtIndex(FileIndex)) + return None; + const FileNameEntry &Entry = Prologue.FileNames[FileIndex - 1]; + if (Optional source = Entry.Source.getAsCString()) + return StringRef(*source); + return None; +} + bool DWARFDebugLine::LineTable::getFileNameByIndex(uint64_t FileIndex, const char *CompDir, FileLineInfoKind Kind, @@ -963,5 +1004,6 @@ bool DWARFDebugLine::LineTable::getFileLineInfoForAddress( Result.Line = Row.Line; Result.Column = Row.Column; Result.Discriminator = Row.Discriminator; + Result.Source = getSourceByIndex(Row.File, Kind); return true; } diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp index 5a02cf3..ae24040 100644 --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -1723,6 +1723,8 @@ static void writeDIFile(raw_ostream &Out, const DIFile *N, TypePrinting *, // Print all values for checksum together, or not at all. if (N->getChecksum()) Printer.printChecksum(*N->getChecksum()); + Printer.printString("source", N->getSource().getValueOr(StringRef()), + /* ShouldSkipEmpty */ true); Out << ")"; } diff --git a/llvm/lib/IR/DIBuilder.cpp b/llvm/lib/IR/DIBuilder.cpp index 8cb95d2..3e5ecdc 100644 --- a/llvm/lib/IR/DIBuilder.cpp +++ b/llvm/lib/IR/DIBuilder.cpp @@ -14,6 +14,7 @@ #include "llvm/IR/DIBuilder.h" #include "llvm/IR/IRBuilder.h" #include "LLVMContextImpl.h" +#include "llvm/ADT/Optional.h" #include "llvm/ADT/STLExtras.h" #include "llvm/BinaryFormat/Dwarf.h" #include "llvm/IR/Constants.h" @@ -204,8 +205,9 @@ DIImportedEntity *DIBuilder::createImportedDeclaration(DIScope *Context, } DIFile *DIBuilder::createFile(StringRef Filename, StringRef Directory, - Optional> CS) { - return DIFile::get(VMContext, Filename, Directory, CS); + Optional> CS, + Optional Source) { + return DIFile::get(VMContext, Filename, Directory, CS, Source); } DIMacro *DIBuilder::createMacro(DIMacroFile *Parent, unsigned LineNumber, diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp index 82f04a6..c1a9f3f 100644 --- a/llvm/lib/IR/DebugInfoMetadata.cpp +++ b/llvm/lib/IR/DebugInfoMetadata.cpp @@ -417,13 +417,16 @@ Optional DIFile::getChecksumKind(StringRef CSKindStr) { DIFile *DIFile::getImpl(LLVMContext &Context, MDString *Filename, MDString *Directory, Optional> CS, - StorageType Storage, bool ShouldCreate) { + Optional Source, StorageType Storage, + bool ShouldCreate) { assert(isCanonical(Filename) && "Expected canonical MDString"); assert(isCanonical(Directory) && "Expected canonical MDString"); assert((!CS || isCanonical(CS->Value)) && "Expected canonical MDString"); - DEFINE_GETIMPL_LOOKUP(DIFile, (Filename, Directory, CS)); - Metadata *Ops[] = {Filename, Directory, CS ? CS->Value : nullptr}; - DEFINE_GETIMPL_STORE(DIFile, (CS), Ops); + assert((!Source || isCanonical(*Source)) && "Expected canonical MDString"); + DEFINE_GETIMPL_LOOKUP(DIFile, (Filename, Directory, CS, Source)); + Metadata *Ops[] = {Filename, Directory, CS ? CS->Value : nullptr, + Source.getValueOr(nullptr)}; + DEFINE_GETIMPL_STORE(DIFile, (CS, Source), Ops); } DICompileUnit *DICompileUnit::getImpl( diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h index 313b7e1..1f2956d 100644 --- a/llvm/lib/IR/LLVMContextImpl.h +++ b/llvm/lib/IR/LLVMContextImpl.h @@ -575,24 +575,28 @@ template <> struct MDNodeKeyImpl { MDString *Filename; MDString *Directory; Optional> Checksum; + Optional Source; MDNodeKeyImpl(MDString *Filename, MDString *Directory, - Optional> Checksum) - : Filename(Filename), Directory(Directory), Checksum(Checksum) {} + Optional> Checksum, + Optional Source) + : Filename(Filename), Directory(Directory), Checksum(Checksum), + Source(Source) {} MDNodeKeyImpl(const DIFile *N) : Filename(N->getRawFilename()), Directory(N->getRawDirectory()), - Checksum(N->getRawChecksum()) {} + Checksum(N->getRawChecksum()), Source(N->getRawSource()) {} bool isKeyOf(const DIFile *RHS) const { return Filename == RHS->getRawFilename() && Directory == RHS->getRawDirectory() && - Checksum == RHS->getRawChecksum(); + Checksum == RHS->getRawChecksum() && + Source == RHS->getRawSource(); } unsigned getHashValue() const { - if (Checksum) - return hash_combine(Filename, Directory, Checksum->Kind, Checksum->Value); - return hash_combine(Filename, Directory); + return hash_combine( + Filename, Directory, Checksum ? Checksum->Kind : 0, + Checksum ? Checksum->Value : nullptr, Source.getValueOr(nullptr)); } }; diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp index 7ea5b76..f254cb5 100644 --- a/llvm/lib/MC/MCAsmStreamer.cpp +++ b/llvm/lib/MC/MCAsmStreamer.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include "llvm/ADT/Optional.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringExtras.h" @@ -215,6 +216,7 @@ public: StringRef Directory, StringRef Filename, MD5::MD5Result *Checksum = 0, + Optional Source = None, unsigned CUID = 0) override; void EmitDwarfLocDirective(unsigned FileNo, unsigned Line, unsigned Column, unsigned Flags, @@ -1076,13 +1078,13 @@ void MCAsmStreamer::EmitFileDirective(StringRef Filename) { Expected MCAsmStreamer::tryEmitDwarfFileDirective( unsigned FileNo, StringRef Directory, StringRef Filename, - MD5::MD5Result *Checksum, unsigned CUID) { + MD5::MD5Result *Checksum, Optional Source, unsigned CUID) { assert(CUID == 0); MCDwarfLineTable &Table = getContext().getMCDwarfLineTable(CUID); unsigned NumFiles = Table.getMCDwarfFiles().size(); Expected FileNoOrErr = - Table.tryGetFile(Directory, Filename, Checksum, FileNo); + Table.tryGetFile(Directory, Filename, Checksum, Source, FileNo); if (!FileNoOrErr) return FileNoOrErr.takeError(); FileNo = FileNoOrErr.get(); @@ -1114,6 +1116,10 @@ Expected MCAsmStreamer::tryEmitDwarfFileDirective( OS1 << " md5 "; PrintQuotedString(Checksum->digest(), OS1); } + if (Source) { + OS1 << " source "; + PrintQuotedString(*Source, OS1); + } if (MCTargetStreamer *TS = getTargetStreamer()) { TS->emitDwarfFileDirective(OS1.str()); } else { diff --git a/llvm/lib/MC/MCContext.cpp b/llvm/lib/MC/MCContext.cpp index ea99528..69c10f5 100644 --- a/llvm/lib/MC/MCContext.cpp +++ b/llvm/lib/MC/MCContext.cpp @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// #include "llvm/MC/MCContext.h" +#include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" @@ -532,7 +533,7 @@ MCSubtargetInfo &MCContext::getSubtargetCopy(const MCSubtargetInfo &STI) { // Dwarf Management //===----------------------------------------------------------------------===// -/// getDwarfFile - takes a file name an number to place in the dwarf file and +/// getDwarfFile - takes a file name and number to place in the dwarf file and /// directory tables. If the file number has already been allocated it is an /// error and zero is returned and the client reports the error, else the /// allocated file number is returned. The file numbers may be in any order. @@ -540,9 +541,10 @@ Expected MCContext::getDwarfFile(StringRef Directory, StringRef FileName, unsigned FileNumber, MD5::MD5Result *Checksum, + Optional Source, unsigned CUID) { MCDwarfLineTable &Table = MCDwarfLineTablesCUMap[CUID]; - return Table.tryGetFile(Directory, FileName, Checksum, FileNumber); + return Table.tryGetFile(Directory, FileName, Checksum, Source, FileNumber); } /// isValidDwarfFileNumber - takes a dwarf file number and returns true if it diff --git a/llvm/lib/MC/MCDwarf.cpp b/llvm/lib/MC/MCDwarf.cpp index 1f0fa78..685b46a 100644 --- a/llvm/lib/MC/MCDwarf.cpp +++ b/llvm/lib/MC/MCDwarf.cpp @@ -11,7 +11,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/Hashing.h" -#include "llvm/ADT/None.h" +#include "llvm/ADT/Optional.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" @@ -373,8 +373,13 @@ void MCDwarfLineTableHeader::emitV5FileDirTables( // The file format, which is the inline null-terminated filename and a // directory index. We don't track file size/timestamp so don't emit them - // in the v5 table. Emit MD5 checksums if we have them. - MCOS->EmitIntValue(HasMD5 ? 3 : 2, 1); + // in the v5 table. Emit MD5 checksums and source if we have them. + uint64_t Entries = 2; + if (HasMD5) + Entries += 1; + if (HasSource) + Entries += 1; + MCOS->EmitIntValue(Entries, 1); MCOS->EmitULEB128IntValue(dwarf::DW_LNCT_path); MCOS->EmitULEB128IntValue(LineStr ? dwarf::DW_FORM_line_strp : dwarf::DW_FORM_string); @@ -384,6 +389,11 @@ void MCDwarfLineTableHeader::emitV5FileDirTables( MCOS->EmitULEB128IntValue(dwarf::DW_LNCT_MD5); MCOS->EmitULEB128IntValue(dwarf::DW_FORM_data16); } + if (HasSource) { + MCOS->EmitULEB128IntValue(dwarf::DW_LNCT_LLVM_source); + MCOS->EmitULEB128IntValue(LineStr ? dwarf::DW_FORM_line_strp + : dwarf::DW_FORM_string); + } // Then the list of file names. These start at 1. MCOS->EmitULEB128IntValue(MCDwarfFiles.size() - 1); for (unsigned i = 1; i < MCDwarfFiles.size(); ++i) { @@ -401,6 +411,15 @@ void MCDwarfLineTableHeader::emitV5FileDirTables( StringRef(reinterpret_cast(Cksum->Bytes.data()), Cksum->Bytes.size())); } + if (HasSource) { + if (LineStr) + LineStr->emitRef(MCOS, MCDwarfFiles[i].Source.getValueOr(StringRef())); + else { + MCOS->EmitBytes( + MCDwarfFiles[i].Source.getValueOr(StringRef())); // Source and... + MCOS->EmitBytes(StringRef("\0", 1)); // its null terminator. + } + } } } @@ -500,14 +519,17 @@ void MCDwarfLineTable::EmitCU(MCObjectStreamer *MCOS, Expected MCDwarfLineTable::tryGetFile(StringRef &Directory, StringRef &FileName, MD5::MD5Result *Checksum, + Optional Source, unsigned FileNumber) { - return Header.tryGetFile(Directory, FileName, Checksum, FileNumber); + return Header.tryGetFile(Directory, FileName, Checksum, Source, FileNumber); } -Expected MCDwarfLineTableHeader::tryGetFile(StringRef &Directory, - StringRef &FileName, - MD5::MD5Result *Checksum, - unsigned FileNumber) { +Expected +MCDwarfLineTableHeader::tryGetFile(StringRef &Directory, + StringRef &FileName, + MD5::MD5Result *Checksum, + Optional &Source, + unsigned FileNumber) { if (Directory == CompilationDir) Directory = ""; if (FileName.empty()) { @@ -515,9 +537,11 @@ Expected MCDwarfLineTableHeader::tryGetFile(StringRef &Directory, Directory = ""; } assert(!FileName.empty()); - // If any files have an MD5 checksum, they all must. - if (MCDwarfFiles.empty()) + // If any files have an MD5 checksum or embedded source, they all must. + if (MCDwarfFiles.empty()) { HasMD5 = (Checksum != nullptr); + HasSource = (Source != None); + } if (FileNumber == 0) { // File numbers start with 1 and/or after any file numbers // allocated by inline-assembler .file directives. @@ -545,6 +569,10 @@ Expected MCDwarfLineTableHeader::tryGetFile(StringRef &Directory, if (HasMD5 != (Checksum != nullptr)) return make_error("inconsistent use of MD5 checksums", inconvertibleErrorCode()); + // If any files have embedded source, they all must. + if (HasSource != (Source != None)) + return make_error("inconsistent use of embedded source", + inconvertibleErrorCode()); if (Directory.empty()) { // Separate the directory part from the basename of the FileName. @@ -582,6 +610,9 @@ Expected MCDwarfLineTableHeader::tryGetFile(StringRef &Directory, File.Checksum = Checksum; if (Checksum) HasMD5 = true; + File.Source = Source; + if (Source) + HasSource = true; // return the allocated FileNumber. return FileNumber; diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp index 8ede318..76eef5e 100644 --- a/llvm/lib/MC/MCParser/AsmParser.cpp +++ b/llvm/lib/MC/MCParser/AsmParser.cpp @@ -3250,7 +3250,7 @@ bool AsmParser::parseDirectiveAlign(bool IsPow2, unsigned ValueSize) { /// parseDirectiveFile /// ::= .file filename -/// ::= .file number [directory] filename [md5 checksum] +/// ::= .file number [directory] filename [md5 checksum] [source source-text] bool AsmParser::parseDirectiveFile(SMLoc DirectiveLoc) { // FIXME: I'm not sure what this is. int64_t FileNumber = -1; @@ -3286,23 +3286,36 @@ bool AsmParser::parseDirectiveFile(SMLoc DirectiveLoc) { } std::string Checksum; - if (!parseOptionalToken(AsmToken::EndOfStatement)) { + + Optional Source; + bool HasSource = false; + std::string SourceString; + + while (!parseOptionalToken(AsmToken::EndOfStatement)) { StringRef Keyword; if (check(getTok().isNot(AsmToken::Identifier), "unexpected token in '.file' directive") || - parseIdentifier(Keyword) || - check(Keyword != "md5", "unexpected token in '.file' directive")) - return true; - if (getLexer().is(AsmToken::String) && - check(FileNumber == -1, "MD5 checksum specified, but no file number")) - return true; - if (check(getTok().isNot(AsmToken::String), - "unexpected token in '.file' directive") || - parseEscapedString(Checksum) || - check(Checksum.size() != 32, "invalid MD5 checksum specified") || - parseToken(AsmToken::EndOfStatement, - "unexpected token in '.file' directive")) + parseIdentifier(Keyword)) return true; + if (Keyword == "md5") { + if (check(FileNumber == -1, + "MD5 checksum specified, but no file number") || + check(getTok().isNot(AsmToken::String), + "unexpected token in '.file' directive") || + parseEscapedString(Checksum) || + check(Checksum.size() != 32, "invalid MD5 checksum specified")) + return true; + } else if (Keyword == "source") { + HasSource = true; + if (check(FileNumber == -1, + "source specified, but no file number") || + check(getTok().isNot(AsmToken::String), + "unexpected token in '.file' directive") || + parseEscapedString(SourceString)) + return true; + } else { + return TokError("unexpected token in '.file' directive"); + } } if (FileNumber == -1) @@ -3316,13 +3329,18 @@ bool AsmParser::parseDirectiveFile(SMLoc DirectiveLoc) { CKMem = (MD5::MD5Result *)Ctx.allocate(sizeof(MD5::MD5Result), 1); memcpy(&CKMem->Bytes, Checksum.data(), 16); } + if (HasSource) { + char *SourceBuf = static_cast(Ctx.allocate(SourceString.size())); + memcpy(SourceBuf, SourceString.data(), SourceString.size()); + Source = StringRef(SourceBuf, SourceString.size()); + } // If there is -g option as well as debug info from directive file, // we turn off -g option, directly use the existing debug info instead. if (getContext().getGenDwarfForAssembly()) getContext().setGenDwarfForAssembly(false); else { Expected FileNumOrErr = getStreamer().tryEmitDwarfFileDirective( - FileNumber, Directory, Filename, CKMem); + FileNumber, Directory, Filename, CKMem, Source); if (!FileNumOrErr) return Error(DirectiveLoc, toString(FileNumOrErr.takeError())); FileNumber = FileNumOrErr.get(); diff --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp index ab6fd9c..bf27a0a 100644 --- a/llvm/lib/MC/MCStreamer.cpp +++ b/llvm/lib/MC/MCStreamer.cpp @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// #include "llvm/MC/MCStreamer.h" +#include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Twine.h" @@ -191,8 +192,11 @@ void MCStreamer::EmitZeros(uint64_t NumBytes) { Expected MCStreamer::tryEmitDwarfFileDirective(unsigned FileNo, StringRef Directory, StringRef Filename, - MD5::MD5Result *Checksum, unsigned CUID) { - return getContext().getDwarfFile(Directory, Filename, FileNo, Checksum, CUID); + MD5::MD5Result *Checksum, + Optional Source, + unsigned CUID) { + return getContext().getDwarfFile(Directory, Filename, FileNo, Checksum, + Source, CUID); } void MCStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line, diff --git a/llvm/test/Assembler/debug-info.ll b/llvm/test/Assembler/debug-info.ll index ed1206f..5dfb8cd 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} -!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} +; 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} +!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} ; CHECK: !0 = !DISubrange(count: 3) ; CHECK-NEXT: !1 = !DISubrange(count: 3, lowerBound: 4) @@ -89,3 +89,8 @@ !36 = !DICompositeType(tag: DW_TAG_variant_part, name: "A", scope: !16, size: 64, discriminator: !37) !37 = !DIDerivedType(tag: DW_TAG_member, scope: !36, baseType: !38, size: 64, align: 64, flags: DIFlagArtificial) !38 = !DIBasicType(name: "u64", size: 64, encoding: DW_ATE_unsigned) + +; CHECK-NEXT: !36 = !DIFile(filename: "file", directory: "dir", source: "int source() { }\0A") +; CHECK-NEXT: !37 = !DIFile(filename: "file", directory: "dir", checksumkind: CSK_MD5, checksum: "3a420e2646916a475e68de8d48f779f5", source: "int source() { }\0A") +!39 = !DIFile(filename: "file", directory: "dir", source: "int source() { }\0A") +!40 = !DIFile(filename: "file", directory: "dir", checksumkind: CSK_MD5, checksum: "3a420e2646916a475e68de8d48f779f5", source: "int source() { }\0A") diff --git a/llvm/test/CodeGen/BPF/dwarfdump.ll b/llvm/test/CodeGen/BPF/dwarfdump.ll index c7cd886..f079751 100644 --- a/llvm/test/CodeGen/BPF/dwarfdump.ll +++ b/llvm/test/CodeGen/BPF/dwarfdump.ll @@ -59,6 +59,8 @@ attributes #1 = { nounwind readnone } !26 = !DILocation(line: 7, column: 17, scope: !2) !27 = !DILocation(line: 9, column: 9, scope: !2) -; CHECK: file_names[ 1] 0 0x00000000 0x00000000 "testprog.c" +; CHECK: file_names[ 1]: +; CHECK-NEXT: name: "testprog.c" +; CHECK-NEXT: dir_index: 0 ; CHECK: 0x0000000000000000 2 ; CHECK: 0x0000000000000028 7 diff --git a/llvm/test/CodeGen/Generic/dwarf-md5.ll b/llvm/test/CodeGen/Generic/dwarf-md5.ll index 001a67e..b997720 100644 --- a/llvm/test/CodeGen/Generic/dwarf-md5.ll +++ b/llvm/test/CodeGen/Generic/dwarf-md5.ll @@ -16,13 +16,21 @@ ; ASM: .file 1 ".{{/|\\\\}}t1.h" md5 "11111111111111111111111111111111" ; ASM: .file 2 ".{{/|\\\\}}t2.h" md5 "22222222222222222222222222222222" -; OBJ-4: Dir Mod Time File Len File Name -; OBJ-4: file_names[ 1] 1 0x00000000 0x00000000 "t1.h" -; OBJ-4: file_names[ 2] 1 0x00000000 0x00000000 "t2.h" - -; OBJ-5: Dir MD5 Checksum File Name -; OBJ-5: file_names[ 0] 1 11111111111111111111111111111111 "t1.h" -; OBJ-5: file_names[ 1] 1 22222222222222222222222222222222 "t2.h" +; OBJ-4: file_names[ 1]: +; OBJ-4-NEXT: name: "t1.h" +; OBJ-4-NEXT: dir_index: 1 +; OBJ-4: file_names[ 2]: +; OBJ-4-NEXT: name: "t2.h" +; OBJ-4-NEXT: dir_index: 1 + +; OBJ-5: file_names[ 0]: +; OBJ-5-NEXT: name: "t1.h" +; OBJ-5-NEXT: dir_index: 1 +; OBJ-5-NEXT: md5_checksum: 11111111111111111111111111111111 +; OBJ-5: file_names[ 1]: +; OBJ-5-NEXT: name: "t2.h" +; OBJ-5-NEXT: dir_index: 1 +; OBJ-5-NEXT: md5_checksum: 22222222222222222222222222222222 ; ModuleID = 't.c' source_filename = "t.c" diff --git a/llvm/test/CodeGen/X86/dwarf-comp-dir.ll b/llvm/test/CodeGen/X86/dwarf-comp-dir.ll index 8d9f7c0..f308b89 100644 --- a/llvm/test/CodeGen/X86/dwarf-comp-dir.ll +++ b/llvm/test/CodeGen/X86/dwarf-comp-dir.ll @@ -15,7 +15,7 @@ target triple = "x86_64-unknown-linux-gnu" !7 = !{!6} ; The important part of the following check is that dir = #0. -; Dir Mod Time File Len File Name -; ---- ---------- ---------- --------------------------- -; CHECK: file_names[ 1] 0 0x00000000 0x00000000 "empty.c" +; CHECK: file_names[ 1]: +; CHECK-NEXT: name: "empty.c" +; CHECK-NEXT: dir_index: 0 !5 = !{i32 1, !"Debug Info Version", i32 3} diff --git a/llvm/test/DebugInfo/AMDGPU/dwarfdump-relocs.ll b/llvm/test/DebugInfo/AMDGPU/dwarfdump-relocs.ll index c6715cd..3a1da6b 100644 --- a/llvm/test/DebugInfo/AMDGPU/dwarfdump-relocs.ll +++ b/llvm/test/DebugInfo/AMDGPU/dwarfdump-relocs.ll @@ -13,7 +13,9 @@ ; } ; CHECK-NOT: failed to compute relocation -; CHECK: file_names[ 1] 0 0x00000000 0x00000000 "dwarfdump-relocs.cl" +; CHECK: file_names[ 1]: +; CHECK-NEXT: name: "dwarfdump-relocs.cl" +; CHECK-NEXT: dir_index: 0 declare void @llvm.dbg.declare(metadata, metadata, metadata) diff --git a/llvm/test/DebugInfo/Generic/lto-comp-dir.ll b/llvm/test/DebugInfo/Generic/lto-comp-dir.ll index b6d1bf4..3c3e8f8 100644 --- a/llvm/test/DebugInfo/Generic/lto-comp-dir.ll +++ b/llvm/test/DebugInfo/Generic/lto-comp-dir.ll @@ -11,13 +11,17 @@ ; CHECK-NEXT: debug_line[{{.*}}] ; CHECK-NEXT: Line table prologue: ; CHECK-NOT: include_directories -; CHECK: file_names[ 1] 0 {{.*}} "a.cpp" +; CHECK: file_names[ 1] +; CHECK: name: "a.cpp" +; CHECK-NEXT: dir_index: 0 ; CHECK-NOT: file_names ; CHECK: debug_line[{{.*}}] ; CHECK-NEXT: Line table prologue: ; CHECK-NOT: include_directories -; CHECK: file_names[ 1] 0 {{.*}} "b.cpp" +; CHECK: file_names[ 1] +; CHECK: name: "b.cpp" +; CHECK-NEXT: dir_index: 0 ; CHECK-NOT: file_names ; However, if a single line table is emitted and shared between CUs, the diff --git a/llvm/test/DebugInfo/X86/debug-macro.ll b/llvm/test/DebugInfo/X86/debug-macro.ll index 6a8e6c0..e286b8a 100644 --- a/llvm/test/DebugInfo/X86/debug-macro.ll +++ b/llvm/test/DebugInfo/X86/debug-macro.ll @@ -28,11 +28,12 @@ ; CHECK-NEXT: DW_MACINFO_end_file ; CHECK-LABEL: .debug_line contents: -; CHECK: Dir Mod Time File Len File Name -; CHECK: file_names[ 1] {{.*}}debug-macro.cpp -; CHECK: file_names[ 2] {{.*}}debug-macro.h -; CHECK: Dir Mod Time File Len File Name -; CHECK: file_names[ 1] {{.*}}debug-macro1.cpp +; CHECK: file_names[ 1]: +; CHECK: name: "debug-macro.cpp" +; CHECK: file_names[ 2]: +; CHECK: name: "debug-macro.h" +; CHECK: file_names[ 1]: +; CHECK: name: "debug-macro1.cpp" !llvm.dbg.cu = !{!0, !16, !20} !llvm.module.flags = !{!13, !14} diff --git a/llvm/test/DebugInfo/X86/dwarfdump-header-64.s b/llvm/test/DebugInfo/X86/dwarfdump-header-64.s index b0be6f3..9c0e310 100644 --- a/llvm/test/DebugInfo/X86/dwarfdump-header-64.s +++ b/llvm/test/DebugInfo/X86/dwarfdump-header-64.s @@ -144,6 +144,14 @@ LH_5_end: # CHECK: include_directories[ 0] = .debug_str[0x00000028] = "Directory5a" # CHECK: include_directories[ 1] = .debug_str[0x00000034] = "Directory5b" # CHECK-NOT: include_directories -# CHECK: file_names[ 0] 0 0x00000051 0x00000052 "File5a" -# CHECK: file_names[ 1] 1 0x00000053 0x00000054 "File5b" +# CHECK: file_names[ 0]: +# CHECK-NEXT: name: "File5a" +# CHECK-NEXT: dir_index: 0 +# CHECK-NEXT: mod_time: 0x00000051 +# CHECK-NEXT: length: 0x00000052 +# CHECK: file_names[ 1]: +# CHECK-NEXT: name: "File5b" +# CHECK-NEXT: dir_index: 1 +# CHECK-NEXT: mod_time: 0x00000053 +# CHECK-NEXT: length: 0x00000054 # CHECK-NOT: file_names diff --git a/llvm/test/DebugInfo/X86/dwarfdump-header.s b/llvm/test/DebugInfo/X86/dwarfdump-header.s index 8717894..702c991 100644 --- a/llvm/test/DebugInfo/X86/dwarfdump-header.s +++ b/llvm/test/DebugInfo/X86/dwarfdump-header.s @@ -258,8 +258,16 @@ LH_4_end: # CHECK: include_directories[ 1] = "Directory4a" # CHECK: include_directories[ 2] = "Directory4b" # CHECK-NOT: include_directories -# CHECK: file_names[ 1] 1 0x00000041 0x00000042 "File4a" -# CHECK: file_names[ 2] 0 0x00000043 0x00000044 "File4b" +# CHECK: file_names[ 1]: +# CHECK-NEXT: name: "File4a" +# CHECK-NEXT: dir_index: 1 +# CHECK-NEXT: mod_time: 0x00000041 +# CHECK-NEXT: length: 0x00000042 +# CHECK: file_names[ 2]: +# CHECK-NEXT: name: "File4b" +# CHECK-NEXT: dir_index: 0 +# CHECK-NEXT: mod_time: 0x00000043 +# CHECK-NEXT: length: 0x00000044 # CHECK-NOT: file_names # DWARF v5 line-table header. @@ -329,9 +337,14 @@ LH_5_end: # CHECK: include_directories[ 0] = .debug_str[0x00000045] = "Directory5a" # CHECK: include_directories[ 1] = .debug_str[0x00000051] = "Directory5b" # CHECK-NOT: include_directories -# CHECK: MD5 Checksum -# CHECK: file_names[ 0] 0 00112233445566778899aabbccddeeff .debug_line_str[0x00000000] = "File5a" -# CHECK: file_names[ 1] 1 ffeeddccbbaa99887766554433221100 .debug_line_str[0x00000007] = "File5b" +# CHECK: file_names[ 0]: +# CHECK-NEXT: name: .debug_line_str[0x00000000] = "File5a" +# CHECK-NEXT: dir_index: 0 +# CHECK-NEXT: md5_checksum: 00112233445566778899aabbccddeeff +# CHECK: file_names[ 1]: +# CHECK-NEXT: name: .debug_line_str[0x00000007] = "File5b" +# CHECK-NEXT: dir_index: 1 +# CHECK-NEXT: md5_checksum: ffeeddccbbaa99887766554433221100 # CHECK-NOT: file_names .section .debug_line_str,"MS",@progbits,1 @@ -410,6 +423,14 @@ dwo_LH_5_end: # CHECK: include_directories[ 0] = .debug_str[0x0000003d] = "DWODirectory5a" # CHECK: include_directories[ 1] = .debug_str[0x0000004c] = "DWODirectory5b" # CHECK-NOT: include_directories -# CHECK: file_names[ 0] 0 0x00000015 0x00000025 "DWOFile5a" -# CHECK: file_names[ 1] 1 0x00000035 0x00000045 "DWOFile5b" +# CHECK: file_names[ 0]: +# CHECK-NEXT: name: "DWOFile5a" +# CHECK-NEXT: dir_index: 0 +# CHECK-NEXT: mod_time: 0x00000015 +# CHECK-NEXT: length: 0x00000025 +# CHECK: file_names[ 1]: +# CHECK-NEXT: name: "DWOFile5b" +# CHECK-NEXT: dir_index: 1 +# CHECK-NEXT: mod_time: 0x00000035 +# CHECK-NEXT: length: 0x00000045 # CHECK-NOT: file_names diff --git a/llvm/test/DebugInfo/X86/dwarfdump-line-dwo.s b/llvm/test/DebugInfo/X86/dwarfdump-line-dwo.s index 14a6bb6..fcce561 100644 --- a/llvm/test/DebugInfo/X86/dwarfdump-line-dwo.s +++ b/llvm/test/DebugInfo/X86/dwarfdump-line-dwo.s @@ -47,7 +47,8 @@ LH_1_end: # PART1-NEXT: version: 4 # PART1-NEXT: prologue_length: 0x00000028 # PART1: include_directories[ 1] = "Directory1" -# PART1: file_names[ 1] {{.*}} "File1" +# PART1: file_names[ 1] +# PART1: name: "File1" # Second line table. LH_2_start: @@ -93,5 +94,6 @@ LH_2_end: # PART2-NEXT: prologue_length: 0x00000022 # PART2-NOT: prologue: # PART2: include_directories[ 1] = "Dir2" -# PART2: file_names[ 1] {{.*}} "File2" +# PART2: file_names[ 1] +# PART2: name: "File2" # PART2-NOT: prologue: diff --git a/llvm/test/DebugInfo/X86/dwarfdump-line-only.s b/llvm/test/DebugInfo/X86/dwarfdump-line-only.s index 4cd7fb9..e6074c3 100644 --- a/llvm/test/DebugInfo/X86/dwarfdump-line-only.s +++ b/llvm/test/DebugInfo/X86/dwarfdump-line-only.s @@ -94,7 +94,15 @@ ls_F2: .asciz "File2" # CHECK: include_directories[ 0] = .debug_str[0x00000000] = "Directory1" # CHECK: include_directories[ 1] = .debug_str[0x0000000b] = "Directory2" # CHECK-NOT: include_directories -# CHECK: file_names[ 0] 1 0x00000051 0x00000052 .debug_line_str[0x00000000] = "File1" -# CHECK: file_names[ 1] 0 0x00000053 0x00000054 .debug_line_str[0x00000006] = "File2" +# CHECK: file_names[ 0]: +# CHECK-NEXT: name: .debug_line_str[0x00000000] = "File1" +# CHECK-NEXT: dir_index: 1 +# CHECK-NEXT: mod_time: 0x00000051 +# CHECK-NEXT: length: 0x00000052 +# CHECK: file_names[ 1]: +# CHECK-NEXT: name: .debug_line_str[0x00000006] = "File2" +# CHECK-NEXT: dir_index: 0 +# CHECK-NEXT: mod_time: 0x00000053 +# CHECK-NEXT: length: 0x00000054 # CHECK-NOT: file_names # CHECK: 0x0000000000000000 {{.*}} is_stmt end_sequence diff --git a/llvm/test/DebugInfo/X86/generate-odr-hash.ll b/llvm/test/DebugInfo/X86/generate-odr-hash.ll index c73a6de..24d7ffa 100644 --- a/llvm/test/DebugInfo/X86/generate-odr-hash.ll +++ b/llvm/test/DebugInfo/X86/generate-odr-hash.ll @@ -122,8 +122,10 @@ ; CHECK-LABEL: .debug_line contents: ; CHECK: Line table prologue ; CHECK-NOT: file_names[ -; SINGLE: file_names{{.*}} "bar.h" -; CHECK: file_names{{.*}} "bar.cpp" +; SINGLE: file_names[ +; SINGLE-NEXT: name: "bar.h" +; CHECK: file_names[ +; CHECK-NEXT: name: "bar.cpp" ; CHECK-NOT: file_names[ ; FISSION: .debug_line.dwo contents: @@ -133,8 +135,10 @@ ; FISSION-NOT: standard_opcode_lengths ; FISSION-NOT: include_directories ; FISSION-NOT: file_names[ -; FISSION: file_names{{.*}} "bar.h" -; FISSION: file_names{{.*}} "bar.cpp" +; FISSION: file_names[ +; FISSION-NEXT: name: "bar.h" +; FISSION: file_names[ +; FISSION-NEXT: name: "bar.cpp" ; FISSION-NOT: file_names[ ; CHECK-LABEL: .debug_str contents: diff --git a/llvm/test/DebugInfo/X86/stmt-list-multiple-compile-units.ll b/llvm/test/DebugInfo/X86/stmt-list-multiple-compile-units.ll index f3c0527..24a886e 100644 --- a/llvm/test/DebugInfo/X86/stmt-list-multiple-compile-units.ll +++ b/llvm/test/DebugInfo/X86/stmt-list-multiple-compile-units.ll @@ -27,11 +27,15 @@ ; CHECK-NEXT: debug_line[{{.*}}] ; CHECK-NEXT: Line table prologue: ; CHECK-NEXT: total_length: 0x00000038 -; CHECK: file_names[ 1] 0 0x00000000 0x00000000 "simple.c" +; CHECK: file_names[ 1]: +; CHECK-NEXT: name: "simple.c" +; CHECK-NEXT: dir_index: 0 ; CHECK: debug_line[{{.*}}] ; CHECK-NEXT: Line table prologue: ; CHECK-NEXT: total_length: 0x00000039 -; CHECK: file_names[ 1] 0 0x00000000 0x00000000 "simple2.c" +; CHECK: file_names[ 1]: +; CHECK-NEXT: name: "simple2.c" +; CHECK-NEXT: dir_index: 0 ; CHECK-NOT: file_names ; DWARF3: .debug_info contents: @@ -46,11 +50,15 @@ ; DWARF3-NEXT: debug_line[{{.*}}] ; DWARF3-NEXT: Line table prologue: ; DWARF3-NEXT: total_length: 0x00000038 -; DWARF3: file_names[ 1] 0 0x00000000 0x00000000 "simple.c" +; DWARF3: file_names[ 1]: +; DWARF3-NEXT: name: "simple.c" +; DWARF3-NEXT: dir_index: 0 ; DWARF3: debug_line[{{.*}}] ; DWARF3-NEXT: Line table prologue: ; DWARF3-NEXT: total_length: 0x00000039 -; DWARF3: file_names[ 1] 0 0x00000000 0x00000000 "simple2.c" +; DWARF3: file_names[ 1]: +; DWARF3-NEXT: name: "simple2.c" +; DWARF3-NEXT: dir_index: 0 ; DWARF3-NOT: file_names ; PR15408 diff --git a/llvm/test/DebugInfo/debugmacinfo.test b/llvm/test/DebugInfo/debugmacinfo.test index b417e1b..57c5a2b 100644 --- a/llvm/test/DebugInfo/debugmacinfo.test +++ b/llvm/test/DebugInfo/debugmacinfo.test @@ -22,6 +22,12 @@ TEST_MACINFO: DW_MACINFO_define - lineno: 3 macro: M2(x,y) ((x)+(y)* Value2) TEST_MACINFO: DW_MACINFO_end_file TEST_LINE: .debug_line contents: -TEST_LINE: file_names[ 1] 0 0x00000000 0x00000000 "dwarfdump-macro.cc" -TEST_LINE: file_names[ 2] 1 0x00000000 0x00000000 "dwarfdump-macro-cmd.h" -TEST_LINE: file_names[ 3] 0 0x00000000 0x00000000 "dwarfdump-macro.h" +TEST_LINE: file_names[ 1]: +TEST_LINE-NEXT: name: "dwarfdump-macro.cc" +TEST_LINE-NEXT: dir_index: 0 +TEST_LINE: file_names[ 2]: +TEST_LINE-NEXT: name: "dwarfdump-macro-cmd.h" +TEST_LINE-NEXT: dir_index: 1 +TEST_LINE: file_names[ 3]: +TEST_LINE-NEXT: name: "dwarfdump-macro.h" +TEST_LINE-NEXT: dir_index: 0 diff --git a/llvm/test/Linker/subprogram-linkonce-weak.ll b/llvm/test/Linker/subprogram-linkonce-weak.ll index b35c6f0..25052b2 100644 --- a/llvm/test/Linker/subprogram-linkonce-weak.ll +++ b/llvm/test/Linker/subprogram-linkonce-weak.ll @@ -147,14 +147,18 @@ entry: ; DW-LABEL: .debug_line contents: ; Check that we have the right things in the line table as well. -; DWLW-LABEL: file_names[{{ *}}1]{{.*}} "bar.c" +; DWLW-LABEL: file_names[ 1]: +; DWLW-NEXT: name: "bar.c" ; DWLW: 2 0 1 0 0 is_stmt prologue_end -; DWLW-LABEL: file_names[{{ *}}1]{{.*}} "foo.c" +; DWLW-LABEL: file_names[ 1]: +; DWLW-NEXT: name: "foo.c" ; DWLW: 52 0 1 0 0 is_stmt prologue_end ; DWLW-NOT: prologue_end -; DWWL-LABEL: file_names[{{ *}}1]{{.*}} "foo.c" +; DWWL-LABEL: file_names[ 1]: +; DWWL-NEXT: name: "foo.c" ; DWWL: 52 0 1 0 0 is_stmt prologue_end -; DWWL-LABEL: file_names[{{ *}}1]{{.*}} "bar.c" +; DWWL-LABEL: file_names[ 1]: +; DWWL-NEXT: name: "bar.c" ; DWWL: 2 0 1 0 0 is_stmt prologue_end ; DWWL-NOT: prologue_end diff --git a/llvm/test/MC/ARM/dwarf-asm-multiple-sections.s b/llvm/test/MC/ARM/dwarf-asm-multiple-sections.s index 4d8c7d2..4c099ac 100644 --- a/llvm/test/MC/ARM/dwarf-asm-multiple-sections.s +++ b/llvm/test/MC/ARM/dwarf-asm-multiple-sections.s @@ -55,7 +55,8 @@ b: // DWARF-DL: version: [[DWVER]] // DWARF-DL-5: address_size: 4 // DWARF-DL-5: include_directories[ 0] = "" -// DWARF-DL: file_names[ [[DWFILE]]] {{.*}} "" +// DWARF-DL: file_names[ [[DWFILE]]]: +// DWARF-DL: name: "" // DWARF-DL: 0x0000000000000000 17 0 1 0 0 is_stmt // DWARF-DL-NEXT: 0x0000000000000004 17 0 1 0 0 is_stmt end_sequence // DWARF-DL-NEXT: 0x0000000000000000 21 0 1 0 0 is_stmt diff --git a/llvm/test/MC/ELF/debug-md5.s b/llvm/test/MC/ELF/debug-md5.s index 1a228ea..f8f3bc1 100644 --- a/llvm/test/MC/ELF/debug-md5.s +++ b/llvm/test/MC/ELF/debug-md5.s @@ -13,9 +13,14 @@ # CHECK: include_directories[ 1] = .debug_line_str[0x[[DIR1:[0-9a-f]+]]] = "dir1" # CHECK: include_directories[ 2] = .debug_line_str[0x[[DIR2:[0-9a-f]+]]] = "dir2" # CHECK-NOT: include_directories -# CHECK: Dir MD5 Checksum File Name -# CHECK: file_names[ 0] 1 00112233445566778899aabbccddeeff .debug_line_str[0x[[FILE1:[0-9a-f]+]]] = "foo" -# CHECK: file_names[ 1] 2 ffeeddccbbaa99887766554433221100 .debug_line_str[0x[[FILE2:[0-9a-f]+]]] = "bar" +# CHECK: file_names[ 0]: +# CHECK-NEXT: name: .debug_line_str[0x[[FILE1:[0-9a-f]+]]] = "foo" +# CHECK-NEXT: dir_index: 1 +# CHECK-NEXT: md5_checksum: 00112233445566778899aabbccddeeff +# CHECK: file_names[ 1]: +# CHECK-NEXT: name: .debug_line_str[0x[[FILE2:[0-9a-f]+]]] = "bar" +# CHECK-NEXT: dir_index: 2 +# CHECK-NEXT: md5_checksum: ffeeddccbbaa99887766554433221100 # CHECK: .debug_line_str contents: # CHECK-NEXT: 0x[[DIR0]]: "" diff --git a/llvm/test/MC/MachO/gen-dwarf-cpp.s b/llvm/test/MC/MachO/gen-dwarf-cpp.s index ad07bf6..3cb26ce 100644 --- a/llvm/test/MC/MachO/gen-dwarf-cpp.s +++ b/llvm/test/MC/MachO/gen-dwarf-cpp.s @@ -16,11 +16,15 @@ L1: leave // We check that the source name "t.s" is picked up // CHECK: include_directories[ 1] = "{{.*(/|\\\\)}}test{{(/|\\\\)}}MC{{(/|\\\\)}}MachO" // CHECK: include_directories[ 2] = "inc" -// CHECK: Dir Mod Time File Len File Name -// CHECK: ---- ---------- ---------- --------------------------- -// CHECK: file_names[ 1] 1 0x00000000 0x00000000 "gen-dwarf-cpp.s" -// CHECK: file_names[ 2] 0 0x00000000 0x00000000 "t.s" -// CHECK: file_names[ 3] 2 0x00000000 0x00000000 "g.s" +// CHECK: file_names[ 1]: +// CHECK-NEXT: name: "gen-dwarf-cpp.s" +// CHECK-NEXT: dir_index: 1 +// CHECK: file_names[ 2]: +// CHECK-NEXT: name: "t.s" +// CHECK-NEXT: dir_index: 0 +// CHECK: file_names[ 3]: +// CHECK-NEXT: name: "g.s" +// CHECK-NEXT: dir_index: 2 // CHECK-NOT: file_names // We check that the source line number 100 is picked up before the "movl" diff --git a/llvm/test/MC/MachO/gen-dwarf-macro-cpp.s b/llvm/test/MC/MachO/gen-dwarf-macro-cpp.s index 9fc8571..de40bbd 100644 --- a/llvm/test/MC/MachO/gen-dwarf-macro-cpp.s +++ b/llvm/test/MC/MachO/gen-dwarf-macro-cpp.s @@ -11,7 +11,9 @@ // rdar://12637628 // We check that the source name "foo.S" is picked up -// CHECK: Dir Mod Time File Len File Name -// CHECK: ---- ---------- ---------- --------------------------- -// CHECK: file_names[ 1] 1 0x00000000 0x00000000 "gen-dwarf-macro-cpp.s" -// CHECK: file_names[ 2] 0 0x00000000 0x00000000 "foo.S" +// CHECK: file_names[ 1]: +// CHECK-NEXT: name: "gen-dwarf-macro-cpp.s" +// CHECK-NEXT: dir_index: 1 +// CHECK: file_names[ 2]: +// CHECK-NEXT: name: "foo.S" +// CHECK-NEXT: dir_index: 0 diff --git a/llvm/test/MC/MachO/gen-dwarf.s b/llvm/test/MC/MachO/gen-dwarf.s index f398517..f567f79 100644 --- a/llvm/test/MC/MachO/gen-dwarf.s +++ b/llvm/test/MC/MachO/gen-dwarf.s @@ -109,9 +109,9 @@ _x: .long 1 // CHECK: standard_opcode_lengths[DW_LNS_set_epilogue_begin] = 0 // CHECK: standard_opcode_lengths[DW_LNS_set_isa] = 1 // We don't check include_directories as it has a temp path -// CHECK: Dir Mod Time File Len File Name -// CHECK: ---- ---------- ---------- --------------------------- -// CHECK: file_names[ 1] 1 0x00000000 0x00000000 "gen-dwarf.s" +// CHECK: file_names[ 1]: +// CHECK-NEXT: name: "gen-dwarf.s" +// CHECK-NEXT: dir_index: 1 // CHECK: Address Line Column File ISA Discriminator Flags // CHECK: ------------------ ------ ------ ------ --- ------------- ------------- diff --git a/llvm/test/tools/dsymutil/X86/basic-linking-x86.test b/llvm/test/tools/dsymutil/X86/basic-linking-x86.test index d9b0ee9..d0827aa 100644 --- a/llvm/test/tools/dsymutil/X86/basic-linking-x86.test +++ b/llvm/test/tools/dsymutil/X86/basic-linking-x86.test @@ -153,18 +153,18 @@ CHECK-NEXT:[0x0000000100000f40, 0x0000000100000f84) CHECK-NEXT:[0x0000000100000f90, 0x0000000100000fa9) CHECK: .debug_line contents: -CHECK: Dir Mod Time File Len File Name -CHECK-NEXT: ---- ---------- ---------- --------------------------- -CHECK-NEXT: file_names[ 1] 0 0x00000000 0x00000000 "basic1.c" +CHECK: file_names[ 1]: +CHECK-NEXT: name: "basic1.c" +CHECK-NEXT: dir_index: 0 CHECK: Address Line Column File ISA Discriminator Flags CHECK-NEXT: ------------------ ------ ------ ------ --- ------------- ------------- CHECK-NEXT: 0x0000000100000ea0 23 0 1 0 0 is_stmt CHECK-NEXT: 0x0000000100000eb6 24 0 1 0 0 is_stmt prologue_end CHECK-NEXT: 0x0000000100000ec4 24 0 1 0 0 is_stmt end_sequence -CHECK: Dir Mod Time File Len File Name -CHECK-NEXT: ---- ---------- ---------- --------------------------- -CHECK-NEXT: file_names[ 1] 0 0x00000000 0x00000000 "basic2.c" +CHECK: file_names[ 1]: +CHECK-NEXT: name: "basic2.c" +CHECK-NEXT: dir_index: 0 CHECK: Address Line Column File ISA Discriminator Flags CHECK-NEXT: ------------------ ------ ------ ------ --- ------------- ------------- CHECK-NEXT: 0x0000000100000ed0 19 0 1 0 0 is_stmt @@ -174,9 +174,9 @@ CHECK-NEXT: 0x0000000100000f20 14 0 1 0 0 is_stmt CHECK-NEXT: 0x0000000100000f24 15 0 1 0 0 is_stmt prologue_end CHECK-NEXT: 0x0000000100000f37 15 0 1 0 0 is_stmt end_sequence -CHECK: Dir Mod Time File Len File Name -CHECK-NEXT: ---- ---------- ---------- --------------------------- -CHECK-NEXT: file_names[ 1] 0 0x00000000 0x00000000 "basic3.c" +CHECK: file_names[ 1]: +CHECK-NEXT: name: "basic3.c" +CHECK-NEXT: dir_index: 0 CHECK: Address Line Column File ISA Discriminator Flags CHECK-NEXT: ------------------ ------ ------ ------ --- ------------- ------------- CHECK-NEXT: 0x0000000100000f40 16 0 1 0 0 is_stmt diff --git a/llvm/test/tools/dsymutil/X86/basic-lto-dw4-linking-x86.test b/llvm/test/tools/dsymutil/X86/basic-lto-dw4-linking-x86.test index 4bdaf69..2ab2cdd 100644 --- a/llvm/test/tools/dsymutil/X86/basic-lto-dw4-linking-x86.test +++ b/llvm/test/tools/dsymutil/X86/basic-lto-dw4-linking-x86.test @@ -138,9 +138,9 @@ CHECK-NEXT: Address Range Header: length = 0x0000002c, version = 0x0002, cu_offs CHECK-NEXT: [0x0000000100000f90, 0x0000000100000fb4) CHECK: .debug_line contents: -CHECK: Dir Mod Time File Len File Name -CHECK-NEXT: ---- ---------- ---------- --------------------------- -CHECK-NEXT: file_names[ 1] 0 0x00000000 0x00000000 "basic1.c" +CHECK: file_names[ 1]: +CHECK-NEXT: name: "basic1.c" +CHECK-NEXT: dir_index: 0 CHECK: Address Line Column File ISA Discriminator Flags CHECK-NEXT: ------------------ ------ ------ ------ --- ------------- ------------- CHECK-NEXT: 0x0000000100000f40 26 0 1 0 0 is_stmt @@ -148,9 +148,9 @@ CHECK-NEXT: 0x0000000100000f44 27 10 1 0 0 is_stmt p CHECK-NEXT: 0x0000000100000f49 27 3 1 0 0 CHECK-NEXT: 0x0000000100000f4b 27 3 1 0 0 end_sequence -CHECK: Dir Mod Time File Len File Name -CHECK-NEXT: ---- ---------- ---------- --------------------------- -CHECK-NEXT: file_names[ 1] 0 0x00000000 0x00000000 "basic2.c" +CHECK: file_names[ 1]: +CHECK-NEXT: name: "basic2.c" +CHECK-NEXT: dir_index: 0 CHECK: Address Line Column File ISA Discriminator Flags CHECK-NEXT: ------------------ ------ ------ ------ --- ------------- ------------- CHECK-NEXT: 0x0000000100000f50 19 0 1 0 0 is_stmt @@ -164,9 +164,9 @@ CHECK-NEXT: 0x0000000100000f83 20 31 1 0 0 CHECK-NEXT: 0x0000000100000f85 20 3 1 0 0 CHECK-NEXT: 0x0000000100000f87 20 3 1 0 0 end_sequence -CHECK: Dir Mod Time File Len File Name -CHECK-NEXT: ---- ---------- ---------- --------------------------- -CHECK-NEXT: file_names[ 1] 0 0x00000000 0x00000000 "basic3.c" +CHECK: file_names[ 1]: +CHECK-NEXT: name: "basic3.c" +CHECK-NEXT: dir_index: 0 CHECK: Address Line Column File ISA Discriminator Flags CHECK-NEXT: ------------------ ------ ------ ------ --- ------------- ------------- CHECK-NEXT: 0x0000000100000f90 16 0 1 0 0 is_stmt diff --git a/llvm/test/tools/dsymutil/X86/basic-lto-linking-x86.test b/llvm/test/tools/dsymutil/X86/basic-lto-linking-x86.test index 931f8e0..7f6716d 100644 --- a/llvm/test/tools/dsymutil/X86/basic-lto-linking-x86.test +++ b/llvm/test/tools/dsymutil/X86/basic-lto-linking-x86.test @@ -150,25 +150,25 @@ CHECK-NEXT: [0x0000000100000f90, 0x0000000100000fb4) CHECK: .debug_line contents -CHECK: Dir Mod Time File Len File Name -CHECK-NEXT: ---- ---------- ---------- --------------------------- -CHECK-NEXT: file_names[ 1] 0 0x00000000 0x00000000 "basic1.c" +CHECK: file_names[ 1]: +CHECK-NEXT: name: "basic1.c" +CHECK-NEXT: dir_index: 0 CHECK: 0x0000000100000f40 23 0 1 0 0 is_stmt CHECK: 0x0000000100000f44 24 0 1 0 0 is_stmt prologue_end CHECK: 0x0000000100000f4b 24 0 1 0 0 is_stmt end_sequence -CHECK: Dir Mod Time File Len File Name -CHECK-NEXT: ---- ---------- ---------- --------------------------- -CHECK-NEXT: file_names[ 1] 0 0x00000000 0x00000000 "basic2.c" +CHECK: file_names[ 1]: +CHECK-NEXT: name: "basic2.c" +CHECK-NEXT: dir_index: 0 CHECK: 0x0000000100000f50 19 0 1 0 0 is_stmt CHECK: 0x0000000100000f54 20 0 1 0 0 is_stmt prologue_end CHECK: 0x0000000100000f63 15 0 1 0 0 is_stmt CHECK: 0x0000000100000f72 20 0 1 0 0 is_stmt CHECK: 0x0000000100000f89 20 0 1 0 0 is_stmt end_sequence -CHECK: Dir Mod Time File Len File Name -CHECK-NEXT: ---- ---------- ---------- --------------------------- -CHECK-NEXT: file_names[ 1] 0 0x00000000 0x00000000 "basic3.c" +CHECK: file_names[ 1]: +CHECK-NEXT: name: "basic3.c" +CHECK-NEXT: dir_index: 0 CHECK: 0x0000000100000f90 16 0 1 0 0 is_stmt CHECK: 0x0000000100000f94 12 0 1 0 0 is_stmt prologue_end CHECK: 0x0000000100000f9a 17 0 1 0 0 is_stmt diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp index 9d44ee4..3be2c42 100644 --- a/llvm/tools/llvm-objdump/llvm-objdump.cpp +++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp @@ -408,7 +408,7 @@ protected: std::unordered_map> LineCache; private: - bool cacheSource(const std::string& File); + bool cacheSource(const DILineInfo& LineInfoFile); public: SourcePrinter() = default; @@ -423,23 +423,29 @@ public: StringRef Delimiter = "; "); }; -bool SourcePrinter::cacheSource(const std::string& File) { - auto BufferOrError = MemoryBuffer::getFile(File); - if (!BufferOrError) - return false; +bool SourcePrinter::cacheSource(const DILineInfo &LineInfo) { + std::unique_ptr Buffer; + if (LineInfo.Source) { + Buffer = MemoryBuffer::getMemBuffer(*LineInfo.Source); + } else { + auto BufferOrError = MemoryBuffer::getFile(LineInfo.FileName); + if (!BufferOrError) + return false; + Buffer = std::move(*BufferOrError); + } // Chomp the file to get lines - size_t BufferSize = (*BufferOrError)->getBufferSize(); - const char *BufferStart = (*BufferOrError)->getBufferStart(); + size_t BufferSize = Buffer->getBufferSize(); + const char *BufferStart = Buffer->getBufferStart(); for (const char *Start = BufferStart, *End = BufferStart; End < BufferStart + BufferSize; End++) if (*End == '\n' || End == BufferStart + BufferSize - 1 || (*End == '\r' && *(End + 1) == '\n')) { - LineCache[File].push_back(StringRef(Start, End - Start)); + LineCache[LineInfo.FileName].push_back(StringRef(Start, End - Start)); if (*End == '\r') End++; Start = End + 1; } - SourceCache[File] = std::move(*BufferOrError); + SourceCache[LineInfo.FileName] = std::move(Buffer); return true; } @@ -463,7 +469,7 @@ void SourcePrinter::printSourceLine(raw_ostream &OS, uint64_t Address, OS << Delimiter << LineInfo.FileName << ":" << LineInfo.Line << "\n"; if (PrintSource) { if (SourceCache.find(LineInfo.FileName) == SourceCache.end()) - if (!cacheSource(LineInfo.FileName)) + if (!cacheSource(LineInfo)) return; auto FileBuffer = SourceCache.find(LineInfo.FileName); if (FileBuffer != SourceCache.end()) { diff --git a/llvm/unittests/IR/MetadataTest.cpp b/llvm/unittests/IR/MetadataTest.cpp index a039b1e..c400ddc 100644 --- a/llvm/unittests/IR/MetadataTest.cpp +++ b/llvm/unittests/IR/MetadataTest.cpp @@ -1450,19 +1450,24 @@ TEST_F(DIFileTest, get) { DIFile::ChecksumKind CSKind = DIFile::ChecksumKind::CSK_MD5; StringRef ChecksumString = "000102030405060708090a0b0c0d0e0f"; DIFile::ChecksumInfo Checksum(CSKind, ChecksumString); - auto *N = DIFile::get(Context, Filename, Directory, Checksum); + StringRef Source = "source"; + auto *N = DIFile::get(Context, Filename, Directory, Checksum, Source); EXPECT_EQ(dwarf::DW_TAG_file_type, N->getTag()); EXPECT_EQ(Filename, N->getFilename()); EXPECT_EQ(Directory, N->getDirectory()); EXPECT_EQ(Checksum, N->getChecksum()); - EXPECT_EQ(N, DIFile::get(Context, Filename, Directory, Checksum)); + EXPECT_EQ(Source, N->getSource()); + EXPECT_EQ(N, DIFile::get(Context, Filename, Directory, Checksum, Source)); - EXPECT_NE(N, DIFile::get(Context, "other", Directory, Checksum)); - EXPECT_NE(N, DIFile::get(Context, Filename, "other", Checksum)); + EXPECT_NE(N, DIFile::get(Context, "other", Directory, Checksum, Source)); + EXPECT_NE(N, DIFile::get(Context, Filename, "other", Checksum, Source)); DIFile::ChecksumInfo OtherChecksum(DIFile::ChecksumKind::CSK_SHA1, ChecksumString); EXPECT_NE( N, DIFile::get(Context, Filename, Directory, OtherChecksum)); + StringRef OtherSource = "other"; + EXPECT_NE(N, DIFile::get(Context, Filename, Directory, Checksum, OtherSource)); + EXPECT_NE(N, DIFile::get(Context, Filename, Directory, Checksum)); EXPECT_NE(N, DIFile::get(Context, Filename, Directory)); TempDIFile Temp = N->clone(); -- 2.7.4