llvm.org GIT mirror llvm / 5e4b515
[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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@325970 91177308-0d34-0410-b5e6-96231b3b80d8 Scott Linder 2 years ago
51 changed file(s) with 589 addition(s) and 229 deletion(s). Raw diff Collapse all Expand all
779779 DWARF
780780 -----
781781
782 Standard DWARF [DWARF]_ Version 2 sections can be generated. These contain
782 Standard DWARF [DWARF]_ Version 5 sections can be generated. These contain
783783 information that maps the code object executable code and data to the source
784784 language constructs. It can be used by tools such as debuggers and profilers.
785785
835835 Source Text
836836 ~~~~~~~~~~~
837837
838 *This section is WIP.*
839
840 .. TODO
841 DWARF extension to include runtime generated source text.
838 Source text for online-compiled programs (e.g. those compiled by the OpenCL
839 runtime) may be embedded into the DWARF v5 line table using the ``clang
840 -gembed-source`` option, described in table :ref:`amdgpu-debug-options`.
841
842 For example:
843
844 ``-gembed-source``
845 Enable the embedded source DWARF v5 extension.
846 ``-gno-embed-source``
847 Disable the embedded source DWARF v5 extension.
848
849 .. table:: AMDGPU Debug Options
850 :name: amdgpu-debug-options
851
852 ==================== ==================================================
853 Debug Flag Description
854 ==================== ==================================================
855 -g[no-]embed-source Enable/disable embedding source text in DWARF
856 debug sections. Useful for environments where
857 source cannot be written to disk, such as
858 when performing online compilation.
859 ==================== ==================================================
860
861 This option enables one extended content types in the DWARF v5 Line Number
862 Program Header, which is used to encode embedded source.
863
864 .. table:: AMDGPU DWARF Line Number Program Header Extended Content Types
865 :name: amdgpu-dwarf-extended-content-types
866
867 ============================ ======================
868 Content Type Form
869 ============================ ======================
870 ``DW_LNCT_LLVM_source`` ``DW_FORM_line_strp``
871 ============================ ======================
872
873 The source field will contain the UTF-8 encoded, null-terminated source text
874 with ``'\n'`` line endings. When the source field is present, consumers can use
875 the embedded source instead of attempting to discover the source on disk. When
876 the source field is absent, consumers can access the file to get the source
877 text.
878
879 The above content type appears in the ``file_name_entry_format`` field of the
880 line table prologue, and its corresponding value appear in the ``file_names``
881 field. The current encoding of the content type is documented in table
882 :ref:`amdgpu-dwarf-extended-content-types-encoding`
883
884 .. table:: AMDGPU DWARF Line Number Program Header Extended Content Types Encoding
885 :name: amdgpu-dwarf-extended-content-types-encoding
886
887 ============================ ====================
888 Content Type Value
889 ============================ ====================
890 ``DW_LNCT_LLVM_source`` 0x2001
891 ============================ ====================
842892
843893 .. _amdgpu-code-conventions:
844894
746746 HANDLE_DW_LNCT(0x03, timestamp)
747747 HANDLE_DW_LNCT(0x04, size)
748748 HANDLE_DW_LNCT(0x05, MD5)
749 // A vendor extension until http://dwarfstd.org/ShowIssue.php?issue=180201.1 is
750 // accepted and incorporated into the next DWARF standard.
751 HANDLE_DW_LNCT(0x2001, LLVM_source)
749752
750753 // DWARF v5 Macro information.
751754 HANDLE_DW_MACRO(0x01, define)
3030 struct DILineInfo {
3131 std::string FileName;
3232 std::string FunctionName;
33 Optional Source;
3334 uint32_t Line = 0;
3435 uint32_t Column = 0;
3536 uint32_t StartLine = 0;
99 #ifndef LLVM_DEBUGINFO_DWARFDEBUGLINE_H
1010 #define LLVM_DEBUGINFO_DWARFDEBUGLINE_H
1111
12 #include "llvm/ADT/Optional.h"
1213 #include "llvm/ADT/StringRef.h"
1314 #include "llvm/DebugInfo/DIContext.h"
1415 #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
3536 uint64_t ModTime = 0;
3637 uint64_t Length = 0;
3738 MD5::MD5Result Checksum;
39 DWARFFormValue Source;
40 };
41
42 /// Tracks which optional content types are present in a DWARF file name
43 /// entry format.
44 struct ContentTypeTracker {
45 ContentTypeTracker() = default;
46
47 /// Whether filename entries provide a modification timestamp.
48 bool HasModTime = false;
49 /// Whether filename entries provide a file size.
50 bool HasLength = false;
51 /// For v5, whether filename entries provide an MD5 checksum.
52 bool HasMD5 = false;
53 /// For v5, whether filename entries provide source text.
54 bool HasSource = false;
55
56 /// Update tracked content types with \p ContentType.
57 void trackContentType(dwarf::LineNumberEntryFormat ContentType);
3858 };
3959
4060 struct Prologue {
6787 uint8_t LineRange;
6888 /// The number assigned to the first special opcode.
6989 uint8_t OpcodeBase;
70 /// For v5, whether filename entries provide an MD5 checksum.
71 bool HasMD5;
90 /// This tracks which optional file format content types are present.
91 ContentTypeTracker ContentTypes;
7292 std::vector StandardOpcodeLengths;
7393 std::vector IncludeDirectories;
7494 std::vector FileNames;
238258 private:
239259 uint32_t findRowInSeq(const DWARFDebugLine::Sequence &Seq,
240260 uint64_t Address) const;
261 Optional getSourceByIndex(uint64_t FileIndex,
262 DILineInfoSpecifier::FileLineInfoKind Kind) const;
241263 };
242264
243265 const LineTable *getLineTable(uint32_t Offset) const;
1717 #include "llvm/ADT/ArrayRef.h"
1818 #include "llvm/ADT/DenseMap.h"
1919 #include "llvm/ADT/MapVector.h"
20 #include "llvm/ADT/None.h"
20 #include "llvm/ADT/Optional.h"
2121 #include "llvm/ADT/SetVector.h"
2222 #include "llvm/ADT/SmallVector.h"
2323 #include "llvm/ADT/StringRef.h"
140140 /// Create a file descriptor to hold debugging information for a file.
141141 /// \param Filename File name.
142142 /// \param Directory Directory.
143 /// \param Checksum Checksum kind (e.g. CSK_MD5, CSK_SHA1, etc.) and value.
143 /// \param Checksum Optional checksum kind (e.g. CSK_MD5, CSK_SHA1, etc.)
144 /// and value.
145 /// \param Source Optional source text.
144146 DIFile *
145147 createFile(StringRef Filename, StringRef Directory,
146 Optional> Checksum = None);
148 Optional> Checksum = None,
149 Optional Source = None);
147150
148151 /// Create debugging information entry for a macro.
149152 /// \param Parent Macro parent (could be nullptr).
454454
455455 inline StringRef getFilename() const;
456456 inline StringRef getDirectory() const;
457 inline Optional getSource() const;
457458
458459 StringRef getName() const;
459460 DIScopeRef getScope() const;
531532
532533 private:
533534 Optional> Checksum;
535 Optional Source;
534536
535537 DIFile(LLVMContext &C, StorageType Storage,
536 Optional> CS,
538 Optional> CS, Optional Src,
537539 ArrayRef Ops)
538540 : DIScope(C, DIFileKind, Storage, dwarf::DW_TAG_file_type, Ops),
539 Checksum(CS) {}
541 Checksum(CS), Source(Src) {}
540542 ~DIFile() = default;
541543
542544 static DIFile *getImpl(LLVMContext &Context, StringRef Filename,
543545 StringRef Directory,
544546 Optional> CS,
547 Optional Source,
545548 StorageType Storage, bool ShouldCreate = true) {
546549 Optional> MDChecksum;
547550 if (CS)
548551 MDChecksum.emplace(CS->Kind, getCanonicalMDString(Context, CS->Value));
549552 return getImpl(Context, getCanonicalMDString(Context, Filename),
550553 getCanonicalMDString(Context, Directory), MDChecksum,
554 Source ? Optional(getCanonicalMDString(Context, *Source)) : None,
551555 Storage, ShouldCreate);
552556 }
553557 static DIFile *getImpl(LLVMContext &Context, MDString *Filename,
554558 MDString *Directory,
555559 Optional> CS,
556 StorageType Storage, bool ShouldCreate = true);
560 Optional Source, StorageType Storage,
561 bool ShouldCreate = true);
557562
558563 TempDIFile cloneImpl() const {
559564 return getTemporary(getContext(), getFilename(), getDirectory(),
560 getChecksum());
565 getChecksum(), getSource());
561566 }
562567
563568 public:
564569 DEFINE_MDNODE_GET(DIFile, (StringRef Filename, StringRef Directory,
565 Optional> CS = None),
566 (Filename, Directory, CS))
570 Optional> CS = None,
571 Optional Source = None),
572 (Filename, Directory, CS, Source))
567573 DEFINE_MDNODE_GET(DIFile, (MDString * Filename, MDString *Directory,
568 Optional> CS = None),
569 (Filename, Directory, CS))
574 Optional> CS = None,
575 Optional Source = None),
576 (Filename, Directory, CS, Source))
570577
571578 TempDIFile clone() const { return cloneImpl(); }
572579
578585 StringRefChecksum.emplace(Checksum->Kind, Checksum->Value->getString());
579586 return StringRefChecksum;
580587 }
588 Optional getSource() const {
589 return Source ? Optional((*Source)->getString()) : None;
590 }
581591
582592 MDString *getRawFilename() const { return getOperandAs(0); }
583593 MDString *getRawDirectory() const { return getOperandAs(1); }
584594 Optional> getRawChecksum() const { return Checksum; }
595 Optional getRawSource() const { return Source; }
585596
586597 static StringRef getChecksumKindAsString(ChecksumKind CSKind);
587598 static Optional getChecksumKind(StringRef CSKindStr);
601612 if (auto *F = getFile())
602613 return F->getDirectory();
603614 return "";
615 }
616
617 Optional DIScope::getSource() const {
618 if (auto *F = getFile())
619 return F->getSource();
620 return None;
604621 }
605622
606623 /// Base class for types.
14071424 DIFile *getFile() const { return getScope()->getFile(); }
14081425 StringRef getFilename() const { return getScope()->getFilename(); }
14091426 StringRef getDirectory() const { return getScope()->getDirectory(); }
1427 Optional getSource() const { return getScope()->getSource(); }
14101428
14111429 /// Get the scope where this is inlined.
14121430 ///
21762194 return "";
21772195 }
21782196
2197 Optional getSource() const {
2198 if (auto *F = getFile())
2199 return F->getSource();
2200 return None;
2201 }
2202
21792203 Metadata *getRawScope() const { return getOperand(0); }
21802204 MDString *getRawName() const { return getOperandAs(1); }
21812205 Metadata *getRawFile() const { return getOperand(2); }
26232647 return "";
26242648 }
26252649
2650 Optional getSource() const {
2651 if (auto *F = getFile())
2652 return F->getSource();
2653 return None;
2654 }
2655
26262656 MDString *getRawName() const { return getOperandAs(0); }
26272657 Metadata *getRawFile() const { return getOperand(1); }
26282658 MDString *getRawGetterName() const { return getOperandAs(2); }
1010 #define LLVM_MC_MCCONTEXT_H
1111
1212 #include "llvm/ADT/DenseMap.h"
13 #include "llvm/ADT/Optional.h"
1314 #include "llvm/ADT/SetVector.h"
1415 #include "llvm/ADT/SmallString.h"
1516 #include "llvm/ADT/SmallVector.h"
495496 /// Creates an entry in the dwarf file and directory tables.
496497 Expected getDwarfFile(StringRef Directory, StringRef FileName,
497498 unsigned FileNumber,
498 MD5::MD5Result *Checksum, unsigned CUID);
499 MD5::MD5Result *Checksum,
500 Optional Source, unsigned CUID);
499501
500502 bool isValidDwarfFileNumber(unsigned FileNumber, unsigned CUID = 0);
501503
1515 #define LLVM_MC_MCDWARF_H
1616
1717 #include "llvm/ADT/MapVector.h"
18 #include "llvm/ADT/Optional.h"
1819 #include "llvm/ADT/SmallVector.h"
1920 #include "llvm/ADT/StringMap.h"
2021 #include "llvm/ADT/StringRef.h"
4748 /// index 0 is not used and not a valid dwarf file number).
4849 struct MCDwarfFile {
4950 // \brief The base name of the file without its directory path.
50 // The StringRef references memory allocated in the MCContext.
5151 std::string Name;
5252
5353 // \brief The index into the list of directory names for this file name.
5656 /// The MD5 checksum, if there is one. Non-owning pointer to data allocated
5757 /// in MCContext.
5858 MD5::MD5Result *Checksum = nullptr;
59
60 /// The source code of the file. Non-owning reference to data allocated in
61 /// MCContext.
62 Optional Source;
5963 };
6064
6165 /// \brief Instances of this class represent the information from a
210214 StringMap SourceIdMap;
211215 StringRef CompilationDir;
212216 bool HasMD5 = false;
217 bool HasSource = false;
213218
214219 MCDwarfLineTableHeader() = default;
215220
216221 Expected tryGetFile(StringRef &Directory, StringRef &FileName,
217222 MD5::MD5Result *Checksum,
223 Optional &Source,
218224 unsigned FileNumber = 0);
219225 std::pair
220226 Emit(MCStreamer *MCOS, MCDwarfLineTableParams Params,
239245 }
240246
241247 unsigned getFile(StringRef Directory, StringRef FileName,
242 MD5::MD5Result *Checksum) {
243 return cantFail(Header.tryGetFile(Directory, FileName, Checksum));
248 MD5::MD5Result *Checksum, Optional Source) {
249 return cantFail(Header.tryGetFile(Directory, FileName, Checksum, Source));
244250 }
245251
246252 void Emit(MCStreamer &MCOS, MCDwarfLineTableParams Params) const;
260266
261267 Expected tryGetFile(StringRef &Directory, StringRef &FileName,
262268 MD5::MD5Result *Checksum,
269 Optional Source,
263270 unsigned FileNumber = 0);
264271 unsigned getFile(StringRef &Directory, StringRef &FileName,
265 MD5::MD5Result *Checksum, unsigned FileNumber = 0) {
266 return cantFail(tryGetFile(Directory, FileName, Checksum, FileNumber));
272 MD5::MD5Result *Checksum, Optional &Source,
273 unsigned FileNumber = 0) {
274 return cantFail(tryGetFile(Directory, FileName, Checksum, Source,
275 FileNumber));
267276 }
268277
269278 MCSymbol *getLabel() const {
1515
1616 #include "llvm/ADT/ArrayRef.h"
1717 #include "llvm/ADT/DenseMap.h"
18 #include "llvm/ADT/Optional.h"
1819 #include "llvm/ADT/SmallVector.h"
1920 #include "llvm/ADT/StringRef.h"
2021 #include "llvm/MC/MCDirectives.h"
755756 unsigned EmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
756757 StringRef Filename,
757758 MD5::MD5Result *Checksum = nullptr,
759 Optional Source = None,
758760 unsigned CUID = 0) {
759761 return cantFail(
760 tryEmitDwarfFileDirective(FileNo, Directory, Filename, Checksum, CUID));
761 }
762
763 /// Associate a filename with a specified logical file number. Returns a
764 /// StringError for any problem, or the file number. This implements the
765 /// DWARF2 '.file 4 "foo.c"' assembler directive.
762 tryEmitDwarfFileDirective(FileNo, Directory, Filename, Checksum,
763 Source, CUID));
764 }
765
766 /// Associate a filename with a specified logical file number.
767 /// Also associate a directory, optional checksum, and optional source
768 /// text with the logical file. This implements the DWARF2
769 /// '.file 4 "dir/foo.c"' assembler directive, and the DWARF5
770 /// '.file 4 "dir/foo.c" md5 "..." source "..."' assembler directive.
766771 virtual Expected tryEmitDwarfFileDirective(
767772 unsigned FileNo, StringRef Directory, StringRef Filename,
768 MD5::MD5Result *Checksum = nullptr, unsigned CUID = 0);
773 MD5::MD5Result *Checksum = nullptr, Optional Source = None,
774 unsigned CUID = 0);
769775
770776 /// \brief This implements the DWARF2 '.loc fileno lineno ...' assembler
771777 /// directive.
42424242 }
42434243
42444244 /// ParseDIFileType:
4245 /// ::= !DIFileType(filename: "path/to/file", directory: "/path/to/dir"
4245 /// ::= !DIFileType(filename: "path/to/file", directory: "/path/to/dir",
42464246 /// checksumkind: CSK_MD5,
4247 /// checksum: "000102030405060708090a0b0c0d0e0f")
4247 /// checksum: "000102030405060708090a0b0c0d0e0f",
4248 /// source: "source file contents")
42484249 bool LLParser::ParseDIFile(MDNode *&Result, bool IsDistinct) {
42494250 // The default constructed value for checksumkind is required, but will never
42504251 // be used, as the parser checks if the field was actually Seen before using
42534254 REQUIRED(filename, MDStringField, ); \
42544255 REQUIRED(directory, MDStringField, ); \
42554256 OPTIONAL(checksumkind, ChecksumKindField, (DIFile::CSK_MD5)); \
4256 OPTIONAL(checksum, MDStringField, );
4257 OPTIONAL(checksum, MDStringField, ); \
4258 OPTIONAL(source, MDStringField, );
42574259 PARSE_MD_FIELDS();
42584260 #undef VISIT_MD_FIELDS
42594261
42634265 else if (checksumkind.Seen || checksum.Seen)
42644266 return Lex.Error("'checksumkind' and 'checksum' must be provided together");
42654267
4268 Optional OptSource;
4269 if (source.Seen)
4270 OptSource = source.Val;
42664271 Result = GET_OR_DISTINCT(DIFile, (Context, filename.Val, directory.Val,
4267 OptChecksum));
4272 OptChecksum, OptSource));
42684273 return false;
42694274 }
42704275
13491349 }
13501350
13511351 case bitc::METADATA_FILE: {
1352 if (Record.size() != 3 && Record.size() != 5)
1352 if (Record.size() != 3 && Record.size() != 5 && Record.size() != 6)
13531353 return error("Invalid record");
13541354
13551355 IsDistinct = Record[0];
13591359 // and the old encoding for CSK_None in the ChecksumKind. The new
13601360 // representation reserves the value 0 in the ChecksumKind to continue to
13611361 // encode None in a backwards-compatible way.
1362 if (Record.size() == 5 && Record[3] && Record[4])
1362 if (Record.size() > 4 && Record[3] && Record[4])
13631363 Checksum.emplace(static_cast(Record[3]),
13641364 getMDString(Record[4]));
13651365 MetadataList.assignValue(
13661366 GET_OR_DISTINCT(
13671367 DIFile,
1368 (Context, getMDString(Record[1]), getMDString(Record[2]),
1369 Checksum)),
1368 (Context, getMDString(Record[1]), getMDString(Record[2]), Checksum,
1369 Record.size() > 5 ? Optional(getMDString(Record[5]))
1370 : None)),
13701371 NextMetadataNo);
13711372 NextMetadataNo++;
13721373 break;
15591559 Record.push_back(0);
15601560 Record.push_back(VE.getMetadataOrNullID(nullptr));
15611561 }
1562 auto Source = N->getRawSource();
1563 if (Source)
1564 Record.push_back(VE.getMetadataOrNullID(*Source));
15621565
15631566 Stream.EmitRecord(bitc::METADATA_FILE, Record, Abbrev);
15641567 Record.clear();
101101 // extend .file to support this.
102102 unsigned CUID = Asm->OutStreamer->hasRawTextSupport() ? 0 : getUniqueID();
103103 if (!File)
104 return Asm->OutStreamer->EmitDwarfFileDirective(0, "", "", nullptr, CUID);
104 return Asm->OutStreamer->EmitDwarfFileDirective(0, "", "", nullptr, None, CUID);
105105 return Asm->OutStreamer->EmitDwarfFileDirective(
106 0, File->getDirectory(), File->getFilename(), getMD5AsBytes(File), CUID);
106 0, File->getDirectory(), File->getFilename(), getMD5AsBytes(File),
107 File->getSource(), CUID);
107108 }
108109
109110 DIE *DwarfCompileUnit::getOrCreateGlobalVariableDIE(
13831383 void DwarfDebug::recordSourceLine(unsigned Line, unsigned Col, const MDNode *S,
13841384 unsigned Flags) {
13851385 StringRef Fn;
1386 unsigned Src = 1;
1386 unsigned FileNo = 1;
13871387 unsigned Discriminator = 0;
13881388 if (auto *Scope = cast_or_null(S)) {
13891389 Fn = Scope->getFilename();
13921392 Discriminator = LBF->getDiscriminator();
13931393
13941394 unsigned CUID = Asm->OutStreamer->getContext().getDwarfCompileUnitID();
1395 Src = static_cast(*InfoHolder.getUnits()[CUID])
1395 FileNo = static_cast(*InfoHolder.getUnits()[CUID])
13961396 .getOrCreateSourceID(Scope->getFile());
13971397 }
1398 Asm->OutStreamer->EmitDwarfLocDirective(Src, Line, Col, Flags, 0,
1398 Asm->OutStreamer->EmitDwarfLocDirective(FileNo, Line, Col, Flags, 0,
13991399 Discriminator, Fn);
14001400 }
14011401
301301 unsigned DwarfTypeUnit::getOrCreateSourceID(const DIFile *File) {
302302 return SplitLineTable
303303 ? SplitLineTable->getFile(File->getDirectory(),
304 File->getFilename(), getMD5AsBytes(File))
304 File->getFilename(),
305 getMD5AsBytes(File),
306 File->getSource())
305307 : getCU().getOrCreateSourceID(File);
306308 }
307309
465465 uint32_t offset = 0;
466466 uint32_t strOffset = 0;
467467 while (const char *s = strData.getCStr(&offset)) {
468 OS << format("0x%8.8x: \"%s\"\n", strOffset, s);
468 OS << format("0x%8.8x: \"", strOffset);
469 OS.write_escaped(s);
470 OS << "\"\n";
469471 strOffset = offset;
470472 }
471473 }
77 //===----------------------------------------------------------------------===//
88
99 #include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
10 #include "llvm/ADT/Optional.h"
1011 #include "llvm/ADT/SmallString.h"
1112 #include "llvm/ADT/SmallVector.h"
1213 #include "llvm/ADT/StringRef.h"
3940
4041 } // end anonmyous namespace
4142
43 void DWARFDebugLine::ContentTypeTracker::trackContentType(
44 dwarf::LineNumberEntryFormat ContentType) {
45 switch (ContentType) {
46 case dwarf::DW_LNCT_timestamp:
47 HasModTime = true;
48 break;
49 case dwarf::DW_LNCT_size:
50 HasLength = true;
51 break;
52 case dwarf::DW_LNCT_MD5:
53 HasMD5 = true;
54 break;
55 case dwarf::DW_LNCT_LLVM_source:
56 HasSource = true;
57 break;
58 default:
59 // We only care about values we consider optional, and new values may be
60 // added in the vendor extension range, so we do not match exhaustively.
61 break;
62 }
63 }
64
4265 DWARFDebugLine::Prologue::Prologue() { clear(); }
4366
4467 void DWARFDebugLine::Prologue::clear() {
4770 MinInstLength = MaxOpsPerInst = DefaultIsStmt = LineBase = LineRange = 0;
4871 OpcodeBase = 0;
4972 FormParams = DWARFFormParams({0, 0, DWARF32});
50 HasMD5 = false;
73 ContentTypes = ContentTypeTracker();
5174 StandardOpcodeLengths.clear();
5275 IncludeDirectories.clear();
5376 FileNames.clear();
84107 }
85108
86109 if (!FileNames.empty()) {
87 if (HasMD5)
88 OS << " Dir MD5 Checksum File Name\n"
89 << " ---- -------------------------------- -----------"
90 "---------------\n";
91 else
92 OS << " Dir Mod Time File Len File Name\n"
93 << " ---- ---------- ---------- -----------"
94 "----------------\n";
95110 // DWARF v5 starts file indexes at 0.
96111 uint32_t FileBase = getVersion() >= 5 ? 0 : 1;
97112 for (uint32_t I = 0; I != FileNames.size(); ++I) {
98113 const FileNameEntry &FileEntry = FileNames[I];
99 OS << format("file_names[%3u] %4" PRIu64 " ", I + FileBase,
100 FileEntry.DirIdx);
101 if (HasMD5)
102 OS << FileEntry.Checksum.digest();
103 else
104 OS << format("0x%8.8" PRIx64 " 0x%8.8" PRIx64, FileEntry.ModTime,
105 FileEntry.Length);
106 OS << ' ';
114 OS << format("file_names[%3u]:\n", I + FileBase);
115 OS << " name: ";
107116 FileEntry.Name.dump(OS, DumpOptions);
108 OS << '\n';
117 OS << '\n'
118 << format(" dir_index: %" PRIu64 "\n", FileEntry.DirIdx);
119 if (ContentTypes.HasMD5)
120 OS << " md5_checksum: " << FileEntry.Checksum.digest() << '\n';
121 if (ContentTypes.HasModTime)
122 OS << format(" mod_time: 0x%8.8" PRIx64 "\n", FileEntry.ModTime);
123 if (ContentTypes.HasLength)
124 OS << format(" length: 0x%8.8" PRIx64 "\n", FileEntry.Length);
125 if (ContentTypes.HasSource) {
126 OS << " source: ";
127 FileEntry.Source.dump(OS, DumpOptions);
128 OS << '\n';
129 }
109130 }
110131 }
111132 }
114135 static void
115136 parseV2DirFileTables(const DWARFDataExtractor &DebugLineData,
116137 uint32_t *OffsetPtr, uint64_t EndPrologueOffset,
138 DWARFDebugLine::ContentTypeTracker &ContentTypes,
117139 std::vector &IncludeDirectories,
118140 std::vector &FileNames) {
119141 while (*OffsetPtr < EndPrologueOffset) {
137159 FileEntry.Length = DebugLineData.getULEB128(OffsetPtr);
138160 FileNames.push_back(FileEntry);
139161 }
162
163 ContentTypes.HasModTime = true;
164 ContentTypes.HasLength = true;
140165 }
141166
142167 // Parse v5 directory/file entry content descriptions.
143168 // Returns the descriptors, or an empty vector if we did not find a path or
144169 // ran off the end of the prologue.
145170 static ContentDescriptors
146 parseV5EntryFormat(const DWARFDataExtractor &DebugLineData, uint32_t *OffsetPtr,
147 uint64_t EndPrologueOffset, bool *HasMD5) {
171 parseV5EntryFormat(const DWARFDataExtractor &DebugLineData, uint32_t
172 *OffsetPtr, uint64_t EndPrologueOffset, DWARFDebugLine::ContentTypeTracker
173 *ContentTypes) {
148174 ContentDescriptors Descriptors;
149175 int FormatCount = DebugLineData.getU8(OffsetPtr);
150176 bool HasPath = false;
157183 Descriptor.Form = dwarf::Form(DebugLineData.getULEB128(OffsetPtr));
158184 if (Descriptor.Type == dwarf::DW_LNCT_path)
159185 HasPath = true;
160 else if (Descriptor.Type == dwarf::DW_LNCT_MD5 && HasMD5)
161 *HasMD5 = true;
186 if (ContentTypes)
187 ContentTypes->trackContentType(Descriptor.Type);
162188 Descriptors.push_back(Descriptor);
163189 }
164190 return HasPath ? Descriptors : ContentDescriptors();
167193 static bool
168194 parseV5DirFileTables(const DWARFDataExtractor &DebugLineData,
169195 uint32_t *OffsetPtr, uint64_t EndPrologueOffset,
170 const DWARFFormParams &FormParams, const DWARFContext &Ctx,
171 const DWARFUnit *U, bool &HasMD5,
196 const DWARFFormParams &FormParams, const DWARFContext
197 &Ctx, const DWARFUnit *U,
198 DWARFDebugLine::ContentTypeTracker &ContentTypes,
172199 std::vector &IncludeDirectories,
173200 std::vector &FileNames) {
174201 // Get the directory entry description.
199226
200227 // Get the file entry description.
201228 ContentDescriptors FileDescriptors =
202 parseV5EntryFormat(DebugLineData, OffsetPtr, EndPrologueOffset, &HasMD5);
229 parseV5EntryFormat(DebugLineData, OffsetPtr, EndPrologueOffset,
230 &ContentTypes);
203231 if (FileDescriptors.empty())
204232 return false;
205233
217245 case DW_LNCT_path:
218246 FileEntry.Name = Value;
219247 break;
248 case DW_LNCT_LLVM_source:
249 FileEntry.Source = Value;
250 break;
220251 case DW_LNCT_directory_index:
221252 FileEntry.DirIdx = Value.getAsUnsignedConstant().getValue();
222253 break;
284315
285316 if (getVersion() >= 5) {
286317 if (!parseV5DirFileTables(DebugLineData, OffsetPtr, EndPrologueOffset,
287 FormParams, Ctx, U, HasMD5, IncludeDirectories,
288 FileNames)) {
318 FormParams, Ctx, U, ContentTypes,
319 IncludeDirectories, FileNames)) {
289320 fprintf(stderr,
290321 "warning: parsing line table prologue at 0x%8.8" PRIx64
291322 " found an invalid directory or file table description at"
294325 }
295326 } else
296327 parseV2DirFileTables(DebugLineData, OffsetPtr, EndPrologueOffset,
297 IncludeDirectories, FileNames);
328 ContentTypes, IncludeDirectories, FileNames);
298329
299330 if (*OffsetPtr != EndPrologueOffset) {
300331 fprintf(stderr,
911942 return FileIndex != 0 && FileIndex <= Prologue.FileNames.size();
912943 }
913944
945 Optional DWARFDebugLine::LineTable::getSourceByIndex(uint64_t FileIndex,
946 FileLineInfoKind Kind) const {
947 if (Kind == FileLineInfoKind::None || !hasFileAtIndex(FileIndex))
948 return None;
949 const FileNameEntry &Entry = Prologue.FileNames[FileIndex - 1];
950 if (Optional source = Entry.Source.getAsCString())
951 return StringRef(*source);
952 return None;
953 }
954
914955 bool DWARFDebugLine::LineTable::getFileNameByIndex(uint64_t FileIndex,
915956 const char *CompDir,
916957 FileLineInfoKind Kind,
9621003 Result.Line = Row.Line;
9631004 Result.Column = Row.Column;
9641005 Result.Discriminator = Row.Discriminator;
1006 Result.Source = getSourceByIndex(Row.File, Kind);
9651007 return true;
9661008 }
17221722 // Print all values for checksum together, or not at all.
17231723 if (N->getChecksum())
17241724 Printer.printChecksum(*N->getChecksum());
1725 Printer.printString("source", N->getSource().getValueOr(StringRef()),
1726 /* ShouldSkipEmpty */ true);
17251727 Out << ")";
17261728 }
17271729
1313 #include "llvm/IR/DIBuilder.h"
1414 #include "llvm/IR/IRBuilder.h"
1515 #include "LLVMContextImpl.h"
16 #include "llvm/ADT/Optional.h"
1617 #include "llvm/ADT/STLExtras.h"
1718 #include "llvm/BinaryFormat/Dwarf.h"
1819 #include "llvm/IR/Constants.h"
203204 }
204205
205206 DIFile *DIBuilder::createFile(StringRef Filename, StringRef Directory,
206 Optional> CS) {
207 return DIFile::get(VMContext, Filename, Directory, CS);
207 Optional> CS,
208 Optional Source) {
209 return DIFile::get(VMContext, Filename, Directory, CS, Source);
208210 }
209211
210212 DIMacro *DIBuilder::createMacro(DIMacroFile *Parent, unsigned LineNumber,
416416 DIFile *DIFile::getImpl(LLVMContext &Context, MDString *Filename,
417417 MDString *Directory,
418418 Optional> CS,
419 StorageType Storage, bool ShouldCreate) {
419 Optional Source, StorageType Storage,
420 bool ShouldCreate) {
420421 assert(isCanonical(Filename) && "Expected canonical MDString");
421422 assert(isCanonical(Directory) && "Expected canonical MDString");
422423 assert((!CS || isCanonical(CS->Value)) && "Expected canonical MDString");
423 DEFINE_GETIMPL_LOOKUP(DIFile, (Filename, Directory, CS));
424 Metadata *Ops[] = {Filename, Directory, CS ? CS->Value : nullptr};
425 DEFINE_GETIMPL_STORE(DIFile, (CS), Ops);
424 assert((!Source || isCanonical(*Source)) && "Expected canonical MDString");
425 DEFINE_GETIMPL_LOOKUP(DIFile, (Filename, Directory, CS, Source));
426 Metadata *Ops[] = {Filename, Directory, CS ? CS->Value : nullptr,
427 Source.getValueOr(nullptr)};
428 DEFINE_GETIMPL_STORE(DIFile, (CS, Source), Ops);
426429 }
427430
428431 DICompileUnit *DICompileUnit::getImpl(
574574 MDString *Filename;
575575 MDString *Directory;
576576 Optional> Checksum;
577 Optional Source;
577578
578579 MDNodeKeyImpl(MDString *Filename, MDString *Directory,
579 Optional> Checksum)
580 : Filename(Filename), Directory(Directory), Checksum(Checksum) {}
580 Optional> Checksum,
581 Optional Source)
582 : Filename(Filename), Directory(Directory), Checksum(Checksum),
583 Source(Source) {}
581584 MDNodeKeyImpl(const DIFile *N)
582585 : Filename(N->getRawFilename()), Directory(N->getRawDirectory()),
583 Checksum(N->getRawChecksum()) {}
586 Checksum(N->getRawChecksum()), Source(N->getRawSource()) {}
584587
585588 bool isKeyOf(const DIFile *RHS) const {
586589 return Filename == RHS->getRawFilename() &&
587590 Directory == RHS->getRawDirectory() &&
588 Checksum == RHS->getRawChecksum();
589 }
590
591 unsigned getHashValue() const {
592 if (Checksum)
593 return hash_combine(Filename, Directory, Checksum->Kind, Checksum->Value);
594 return hash_combine(Filename, Directory);
591 Checksum == RHS->getRawChecksum() &&
592 Source == RHS->getRawSource();
593 }
594
595 unsigned getHashValue() const {
596 return hash_combine(
597 Filename, Directory, Checksum ? Checksum->Kind : 0,
598 Checksum ? Checksum->Value : nullptr, Source.getValueOr(nullptr));
595599 }
596600 };
597601
66 //
77 //===----------------------------------------------------------------------===//
88
9 #include "llvm/ADT/Optional.h"
910 #include "llvm/ADT/STLExtras.h"
1011 #include "llvm/ADT/SmallString.h"
1112 #include "llvm/ADT/StringExtras.h"
214215 StringRef Directory,
215216 StringRef Filename,
216217 MD5::MD5Result *Checksum = 0,
218 Optional Source = None,
217219 unsigned CUID = 0) override;
218220 void EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
219221 unsigned Column, unsigned Flags,
10751077
10761078 Expected MCAsmStreamer::tryEmitDwarfFileDirective(
10771079 unsigned FileNo, StringRef Directory, StringRef Filename,
1078 MD5::MD5Result *Checksum, unsigned CUID) {
1080 MD5::MD5Result *Checksum, Optional Source, unsigned CUID) {
10791081 assert(CUID == 0);
10801082
10811083 MCDwarfLineTable &Table = getContext().getMCDwarfLineTable(CUID);
10821084 unsigned NumFiles = Table.getMCDwarfFiles().size();
10831085 Expected FileNoOrErr =
1084 Table.tryGetFile(Directory, Filename, Checksum, FileNo);
1086 Table.tryGetFile(Directory, Filename, Checksum, Source, FileNo);
10851087 if (!FileNoOrErr)
10861088 return FileNoOrErr.takeError();
10871089 FileNo = FileNoOrErr.get();
11121114 if (Checksum) {
11131115 OS1 << " md5 ";
11141116 PrintQuotedString(Checksum->digest(), OS1);
1117 }
1118 if (Source) {
1119 OS1 << " source ";
1120 PrintQuotedString(*Source, OS1);
11151121 }
11161122 if (MCTargetStreamer *TS = getTargetStreamer()) {
11171123 TS->emitDwarfFileDirective(OS1.str());
77 //===----------------------------------------------------------------------===//
88
99 #include "llvm/MC/MCContext.h"
10 #include "llvm/ADT/Optional.h"
1011 #include "llvm/ADT/SmallString.h"
1112 #include "llvm/ADT/SmallVector.h"
1213 #include "llvm/ADT/StringMap.h"
531532 // Dwarf Management
532533 //===----------------------------------------------------------------------===//
533534
534 /// getDwarfFile - takes a file name an number to place in the dwarf file and
535 /// getDwarfFile - takes a file name and number to place in the dwarf file and
535536 /// directory tables. If the file number has already been allocated it is an
536537 /// error and zero is returned and the client reports the error, else the
537538 /// allocated file number is returned. The file numbers may be in any order.
539540 StringRef FileName,
540541 unsigned FileNumber,
541542 MD5::MD5Result *Checksum,
543 Optional Source,
542544 unsigned CUID) {
543545 MCDwarfLineTable &Table = MCDwarfLineTablesCUMap[CUID];
544 return Table.tryGetFile(Directory, FileName, Checksum, FileNumber);
546 return Table.tryGetFile(Directory, FileName, Checksum, Source, FileNumber);
545547 }
546548
547549 /// isValidDwarfFileNumber - takes a dwarf file number and returns true if it
1010 #include "llvm/ADT/ArrayRef.h"
1111 #include "llvm/ADT/DenseMap.h"
1212 #include "llvm/ADT/Hashing.h"
13 #include "llvm/ADT/None.h"
13 #include "llvm/ADT/Optional.h"
1414 #include "llvm/ADT/STLExtras.h"
1515 #include "llvm/ADT/SmallString.h"
1616 #include "llvm/ADT/SmallVector.h"
372372
373373 // The file format, which is the inline null-terminated filename and a
374374 // directory index. We don't track file size/timestamp so don't emit them
375 // in the v5 table. Emit MD5 checksums if we have them.
376 MCOS->EmitIntValue(HasMD5 ? 3 : 2, 1);
375 // in the v5 table. Emit MD5 checksums and source if we have them.
376 uint64_t Entries = 2;
377 if (HasMD5)
378 Entries += 1;
379 if (HasSource)
380 Entries += 1;
381 MCOS->EmitIntValue(Entries, 1);
377382 MCOS->EmitULEB128IntValue(dwarf::DW_LNCT_path);
378383 MCOS->EmitULEB128IntValue(LineStr ? dwarf::DW_FORM_line_strp
379384 : dwarf::DW_FORM_string);
382387 if (HasMD5) {
383388 MCOS->EmitULEB128IntValue(dwarf::DW_LNCT_MD5);
384389 MCOS->EmitULEB128IntValue(dwarf::DW_FORM_data16);
390 }
391 if (HasSource) {
392 MCOS->EmitULEB128IntValue(dwarf::DW_LNCT_LLVM_source);
393 MCOS->EmitULEB128IntValue(LineStr ? dwarf::DW_FORM_line_strp
394 : dwarf::DW_FORM_string);
385395 }
386396 // Then the list of file names. These start at 1.
387397 MCOS->EmitULEB128IntValue(MCDwarfFiles.size() - 1);
399409 MCOS->EmitBinaryData(
400410 StringRef(reinterpret_cast(Cksum->Bytes.data()),
401411 Cksum->Bytes.size()));
412 }
413 if (HasSource) {
414 if (LineStr)
415 LineStr->emitRef(MCOS, MCDwarfFiles[i].Source.getValueOr(StringRef()));
416 else {
417 MCOS->EmitBytes(
418 MCDwarfFiles[i].Source.getValueOr(StringRef())); // Source and...
419 MCOS->EmitBytes(StringRef("\0", 1)); // its null terminator.
420 }
402421 }
403422 }
404423 }
499518 Expected MCDwarfLineTable::tryGetFile(StringRef &Directory,
500519 StringRef &FileName,
501520 MD5::MD5Result *Checksum,
521 Optional Source,
502522 unsigned FileNumber) {
503 return Header.tryGetFile(Directory, FileName, Checksum, FileNumber);
504 }
505
506 Expected MCDwarfLineTableHeader::tryGetFile(StringRef &Directory,
507 StringRef &FileName,
508 MD5::MD5Result *Checksum,
509 unsigned FileNumber) {
523 return Header.tryGetFile(Directory, FileName, Checksum, Source, FileNumber);
524 }
525
526 Expected
527 MCDwarfLineTableHeader::tryGetFile(StringRef &Directory,
528 StringRef &FileName,
529 MD5::MD5Result *Checksum,
530 Optional &Source,
531 unsigned FileNumber) {
510532 if (Directory == CompilationDir)
511533 Directory = "";
512534 if (FileName.empty()) {
514536 Directory = "";
515537 }
516538 assert(!FileName.empty());
517 // If any files have an MD5 checksum, they all must.
518 if (MCDwarfFiles.empty())
539 // If any files have an MD5 checksum or embedded source, they all must.
540 if (MCDwarfFiles.empty()) {
519541 HasMD5 = (Checksum != nullptr);
542 HasSource = (Source != None);
543 }
520544 if (FileNumber == 0) {
521545 // File numbers start with 1 and/or after any file numbers
522546 // allocated by inline-assembler .file directives.
543567 // If any files have an MD5 checksum, they all must.
544568 if (HasMD5 != (Checksum != nullptr))
545569 return make_error("inconsistent use of MD5 checksums",
570 inconvertibleErrorCode());
571 // If any files have embedded source, they all must.
572 if (HasSource != (Source != None))
573 return make_error("inconsistent use of embedded source",
546574 inconvertibleErrorCode());
547575
548576 if (Directory.empty()) {
581609 File.Checksum = Checksum;
582610 if (Checksum)
583611 HasMD5 = true;
612 File.Source = Source;
613 if (Source)
614 HasSource = true;
584615
585616 // return the allocated FileNumber.
586617 return FileNumber;
32493249
32503250 /// parseDirectiveFile
32513251 /// ::= .file filename
3252 /// ::= .file number [directory] filename [md5 checksum]
3252 /// ::= .file number [directory] filename [md5 checksum] [source source-text]
32533253 bool AsmParser::parseDirectiveFile(SMLoc DirectiveLoc) {
32543254 // FIXME: I'm not sure what this is.
32553255 int64_t FileNumber = -1;
32853285 }
32863286
32873287 std::string Checksum;
3288 if (!parseOptionalToken(AsmToken::EndOfStatement)) {
3288
3289 Optional Source;
3290 bool HasSource = false;
3291 std::string SourceString;
3292
3293 while (!parseOptionalToken(AsmToken::EndOfStatement)) {
32893294 StringRef Keyword;
32903295 if (check(getTok().isNot(AsmToken::Identifier),
32913296 "unexpected token in '.file' directive") ||
3292 parseIdentifier(Keyword) ||
3293 check(Keyword != "md5", "unexpected token in '.file' directive"))
3297 parseIdentifier(Keyword))
32943298 return true;
3295 if (getLexer().is(AsmToken::String) &&
3296 check(FileNumber == -1, "MD5 checksum specified, but no file number"))
3297 return true;
3298 if (check(getTok().isNot(AsmToken::String),
3299 "unexpected token in '.file' directive") ||
3300 parseEscapedString(Checksum) ||
3301 check(Checksum.size() != 32, "invalid MD5 checksum specified") ||
3302 parseToken(AsmToken::EndOfStatement,
3303 "unexpected token in '.file' directive"))
3304 return true;
3299 if (Keyword == "md5") {
3300 if (check(FileNumber == -1,
3301 "MD5 checksum specified, but no file number") ||
3302 check(getTok().isNot(AsmToken::String),
3303 "unexpected token in '.file' directive") ||
3304 parseEscapedString(Checksum) ||
3305 check(Checksum.size() != 32, "invalid MD5 checksum specified"))
3306 return true;
3307 } else if (Keyword == "source") {
3308 HasSource = true;
3309 if (check(FileNumber == -1,
3310 "source specified, but no file number") ||
3311 check(getTok().isNot(AsmToken::String),
3312 "unexpected token in '.file' directive") ||
3313 parseEscapedString(SourceString))
3314 return true;
3315 } else {
3316 return TokError("unexpected token in '.file' directive");
3317 }
33053318 }
33063319
33073320 if (FileNumber == -1)
33153328 CKMem = (MD5::MD5Result *)Ctx.allocate(sizeof(MD5::MD5Result), 1);
33163329 memcpy(&CKMem->Bytes, Checksum.data(), 16);
33173330 }
3331 if (HasSource) {
3332 char *SourceBuf = static_cast(Ctx.allocate(SourceString.size()));
3333 memcpy(SourceBuf, SourceString.data(), SourceString.size());
3334 Source = StringRef(SourceBuf, SourceString.size());
3335 }
33183336 // If there is -g option as well as debug info from directive file,
33193337 // we turn off -g option, directly use the existing debug info instead.
33203338 if (getContext().getGenDwarfForAssembly())
33213339 getContext().setGenDwarfForAssembly(false);
33223340 else {
33233341 Expected FileNumOrErr = getStreamer().tryEmitDwarfFileDirective(
3324 FileNumber, Directory, Filename, CKMem);
3342 FileNumber, Directory, Filename, CKMem, Source);
33253343 if (!FileNumOrErr)
33263344 return Error(DirectiveLoc, toString(FileNumOrErr.takeError()));
33273345 FileNumber = FileNumOrErr.get();
77 //===----------------------------------------------------------------------===//
88
99 #include "llvm/MC/MCStreamer.h"
10 #include "llvm/ADT/Optional.h"
1011 #include "llvm/ADT/SmallString.h"
1112 #include "llvm/ADT/StringRef.h"
1213 #include "llvm/ADT/Twine.h"
190191 Expected
191192 MCStreamer::tryEmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
192193 StringRef Filename,
193 MD5::MD5Result *Checksum, unsigned CUID) {
194 return getContext().getDwarfFile(Directory, Filename, FileNo, Checksum, CUID);
194 MD5::MD5Result *Checksum,
195 Optional Source,
196 unsigned CUID) {
197 return getContext().getDwarfFile(Directory, Filename, FileNo, Checksum,
198 Source, CUID);
195199 }
196200
197201 void MCStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
0 ; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | FileCheck %s
11 ; RUN: verify-uselistorder %s
22
3 ; 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}
4 !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}
3 ; 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}
4 !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}
55
66 ; CHECK: !0 = !DISubrange(count: 3)
77 ; CHECK-NEXT: !1 = !DISubrange(count: 3, lowerBound: 4)
8888 !36 = !DICompositeType(tag: DW_TAG_variant_part, name: "A", scope: !16, size: 64, discriminator: !37)
8989 !37 = !DIDerivedType(tag: DW_TAG_member, scope: !36, baseType: !38, size: 64, align: 64, flags: DIFlagArtificial)
9090 !38 = !DIBasicType(name: "u64", size: 64, encoding: DW_ATE_unsigned)
91
92 ; CHECK-NEXT: !36 = !DIFile(filename: "file", directory: "dir", source: "int source() { }\0A")
93 ; CHECK-NEXT: !37 = !DIFile(filename: "file", directory: "dir", checksumkind: CSK_MD5, checksum: "3a420e2646916a475e68de8d48f779f5", source: "int source() { }\0A")
94 !39 = !DIFile(filename: "file", directory: "dir", source: "int source() { }\0A")
95 !40 = !DIFile(filename: "file", directory: "dir", checksumkind: CSK_MD5, checksum: "3a420e2646916a475e68de8d48f779f5", source: "int source() { }\0A")
5858 !26 = !DILocation(line: 7, column: 17, scope: !2)
5959 !27 = !DILocation(line: 9, column: 9, scope: !2)
6060
61 ; CHECK: file_names[ 1] 0 0x00000000 0x00000000 "testprog.c"
61 ; CHECK: file_names[ 1]:
62 ; CHECK-NEXT: name: "testprog.c"
63 ; CHECK-NEXT: dir_index: 0
6264 ; CHECK: 0x0000000000000000 2
6365 ; CHECK: 0x0000000000000028 7
1515 ; ASM: .file 1 ".{{/|\\\\}}t1.h" md5 "11111111111111111111111111111111"
1616 ; ASM: .file 2 ".{{/|\\\\}}t2.h" md5 "22222222222222222222222222222222"
1717
18 ; OBJ-4: Dir Mod Time File Len File Name
19 ; OBJ-4: file_names[ 1] 1 0x00000000 0x00000000 "t1.h"
20 ; OBJ-4: file_names[ 2] 1 0x00000000 0x00000000 "t2.h"
18 ; OBJ-4: file_names[ 1]:
19 ; OBJ-4-NEXT: name: "t1.h"
20 ; OBJ-4-NEXT: dir_index: 1
21 ; OBJ-4: file_names[ 2]:
22 ; OBJ-4-NEXT: name: "t2.h"
23 ; OBJ-4-NEXT: dir_index: 1
2124
22 ; OBJ-5: Dir MD5 Checksum File Name
23 ; OBJ-5: file_names[ 0] 1 11111111111111111111111111111111 "t1.h"
24 ; OBJ-5: file_names[ 1] 1 22222222222222222222222222222222 "t2.h"
25 ; OBJ-5: file_names[ 0]:
26 ; OBJ-5-NEXT: name: "t1.h"
27 ; OBJ-5-NEXT: dir_index: 1
28 ; OBJ-5-NEXT: md5_checksum: 11111111111111111111111111111111
29 ; OBJ-5: file_names[ 1]:
30 ; OBJ-5-NEXT: name: "t2.h"
31 ; OBJ-5-NEXT: dir_index: 1
32 ; OBJ-5-NEXT: md5_checksum: 22222222222222222222222222222222
2533
2634 ; ModuleID = 't.c'
2735 source_filename = "t.c"
1414 !7 = !{!6}
1515
1616 ; The important part of the following check is that dir = #0.
17 ; Dir Mod Time File Len File Name
18 ; ---- ---------- ---------- ---------------------------
19 ; CHECK: file_names[ 1] 0 0x00000000 0x00000000 "empty.c"
17 ; CHECK: file_names[ 1]:
18 ; CHECK-NEXT: name: "empty.c"
19 ; CHECK-NEXT: dir_index: 0
2020 !5 = !{i32 1, !"Debug Info Version", i32 3}
1212 ; }
1313
1414 ; CHECK-NOT: failed to compute relocation
15 ; CHECK: file_names[ 1] 0 0x00000000 0x00000000 "dwarfdump-relocs.cl"
15 ; CHECK: file_names[ 1]:
16 ; CHECK-NEXT: name: "dwarfdump-relocs.cl"
17 ; CHECK-NEXT: dir_index: 0
1618
1719 declare void @llvm.dbg.declare(metadata, metadata, metadata)
1820
1010 ; CHECK-NEXT: debug_line[{{.*}}]
1111 ; CHECK-NEXT: Line table prologue:
1212 ; CHECK-NOT: include_directories
13 ; CHECK: file_names[ 1] 0 {{.*}} "a.cpp"
13 ; CHECK: file_names[ 1]
14 ; CHECK: name: "a.cpp"
15 ; CHECK-NEXT: dir_index: 0
1416 ; CHECK-NOT: file_names
1517
1618 ; CHECK: debug_line[{{.*}}]
1719 ; CHECK-NEXT: Line table prologue:
1820 ; CHECK-NOT: include_directories
19 ; CHECK: file_names[ 1] 0 {{.*}} "b.cpp"
21 ; CHECK: file_names[ 1]
22 ; CHECK: name: "b.cpp"
23 ; CHECK-NEXT: dir_index: 0
2024 ; CHECK-NOT: file_names
2125
2226 ; However, if a single line table is emitted and shared between CUs, the
2727 ; CHECK-NEXT: DW_MACINFO_end_file
2828
2929 ; CHECK-LABEL: .debug_line contents:
30 ; CHECK: Dir Mod Time File Len File Name
31 ; CHECK: file_names[ 1] {{.*}}debug-macro.cpp
32 ; CHECK: file_names[ 2] {{.*}}debug-macro.h
33 ; CHECK: Dir Mod Time File Len File Name
34 ; CHECK: file_names[ 1] {{.*}}debug-macro1.cpp
30 ; CHECK: file_names[ 1]:
31 ; CHECK: name: "debug-macro.cpp"
32 ; CHECK: file_names[ 2]:
33 ; CHECK: name: "debug-macro.h"
34 ; CHECK: file_names[ 1]:
35 ; CHECK: name: "debug-macro1.cpp"
3536
3637 !llvm.dbg.cu = !{!0, !16, !20}
3738 !llvm.module.flags = !{!13, !14}
143143 # CHECK: include_directories[ 0] = .debug_str[0x00000028] = "Directory5a"
144144 # CHECK: include_directories[ 1] = .debug_str[0x00000034] = "Directory5b"
145145 # CHECK-NOT: include_directories
146 # CHECK: file_names[ 0] 0 0x00000051 0x00000052 "File5a"
147 # CHECK: file_names[ 1] 1 0x00000053 0x00000054 "File5b"
146 # CHECK: file_names[ 0]:
147 # CHECK-NEXT: name: "File5a"
148 # CHECK-NEXT: dir_index: 0
149 # CHECK-NEXT: mod_time: 0x00000051
150 # CHECK-NEXT: length: 0x00000052
151 # CHECK: file_names[ 1]:
152 # CHECK-NEXT: name: "File5b"
153 # CHECK-NEXT: dir_index: 1
154 # CHECK-NEXT: mod_time: 0x00000053
155 # CHECK-NEXT: length: 0x00000054
148156 # CHECK-NOT: file_names
257257 # CHECK: include_directories[ 1] = "Directory4a"
258258 # CHECK: include_directories[ 2] = "Directory4b"
259259 # CHECK-NOT: include_directories
260 # CHECK: file_names[ 1] 1 0x00000041 0x00000042 "File4a"
261 # CHECK: file_names[ 2] 0 0x00000043 0x00000044 "File4b"
260 # CHECK: file_names[ 1]:
261 # CHECK-NEXT: name: "File4a"
262 # CHECK-NEXT: dir_index: 1
263 # CHECK-NEXT: mod_time: 0x00000041
264 # CHECK-NEXT: length: 0x00000042
265 # CHECK: file_names[ 2]:
266 # CHECK-NEXT: name: "File4b"
267 # CHECK-NEXT: dir_index: 0
268 # CHECK-NEXT: mod_time: 0x00000043
269 # CHECK-NEXT: length: 0x00000044
262270 # CHECK-NOT: file_names
263271
264272 # DWARF v5 line-table header.
328336 # CHECK: include_directories[ 0] = .debug_str[0x00000045] = "Directory5a"
329337 # CHECK: include_directories[ 1] = .debug_str[0x00000051] = "Directory5b"
330338 # CHECK-NOT: include_directories
331 # CHECK: MD5 Checksum
332 # CHECK: file_names[ 0] 0 00112233445566778899aabbccddeeff .debug_line_str[0x00000000] = "File5a"
333 # CHECK: file_names[ 1] 1 ffeeddccbbaa99887766554433221100 .debug_line_str[0x00000007] = "File5b"
339 # CHECK: file_names[ 0]:
340 # CHECK-NEXT: name: .debug_line_str[0x00000000] = "File5a"
341 # CHECK-NEXT: dir_index: 0
342 # CHECK-NEXT: md5_checksum: 00112233445566778899aabbccddeeff
343 # CHECK: file_names[ 1]:
344 # CHECK-NEXT: name: .debug_line_str[0x00000007] = "File5b"
345 # CHECK-NEXT: dir_index: 1
346 # CHECK-NEXT: md5_checksum: ffeeddccbbaa99887766554433221100
334347 # CHECK-NOT: file_names
335348
336349 .section .debug_line_str,"MS",@progbits,1
409422 # CHECK: include_directories[ 0] = .debug_str[0x0000003d] = "DWODirectory5a"
410423 # CHECK: include_directories[ 1] = .debug_str[0x0000004c] = "DWODirectory5b"
411424 # CHECK-NOT: include_directories
412 # CHECK: file_names[ 0] 0 0x00000015 0x00000025 "DWOFile5a"
413 # CHECK: file_names[ 1] 1 0x00000035 0x00000045 "DWOFile5b"
425 # CHECK: file_names[ 0]:
426 # CHECK-NEXT: name: "DWOFile5a"
427 # CHECK-NEXT: dir_index: 0
428 # CHECK-NEXT: mod_time: 0x00000015
429 # CHECK-NEXT: length: 0x00000025
430 # CHECK: file_names[ 1]:
431 # CHECK-NEXT: name: "DWOFile5b"
432 # CHECK-NEXT: dir_index: 1
433 # CHECK-NEXT: mod_time: 0x00000035
434 # CHECK-NEXT: length: 0x00000045
414435 # CHECK-NOT: file_names
4646 # PART1-NEXT: version: 4
4747 # PART1-NEXT: prologue_length: 0x00000028
4848 # PART1: include_directories[ 1] = "Directory1"
49 # PART1: file_names[ 1] {{.*}} "File1"
49 # PART1: file_names[ 1]
50 # PART1: name: "File1"
5051
5152 # Second line table.
5253 LH_2_start:
9293 # PART2-NEXT: prologue_length: 0x00000022
9394 # PART2-NOT: prologue:
9495 # PART2: include_directories[ 1] = "Dir2"
95 # PART2: file_names[ 1] {{.*}} "File2"
96 # PART2: file_names[ 1]
97 # PART2: name: "File2"
9698 # PART2-NOT: prologue:
9393 # CHECK: include_directories[ 0] = .debug_str[0x00000000] = "Directory1"
9494 # CHECK: include_directories[ 1] = .debug_str[0x0000000b] = "Directory2"
9595 # CHECK-NOT: include_directories
96 # CHECK: file_names[ 0] 1 0x00000051 0x00000052 .debug_line_str[0x00000000] = "File1"
97 # CHECK: file_names[ 1] 0 0x00000053 0x00000054 .debug_line_str[0x00000006] = "File2"
96 # CHECK: file_names[ 0]:
97 # CHECK-NEXT: name: .debug_line_str[0x00000000] = "File1"
98 # CHECK-NEXT: dir_index: 1
99 # CHECK-NEXT: mod_time: 0x00000051
100 # CHECK-NEXT: length: 0x00000052
101 # CHECK: file_names[ 1]:
102 # CHECK-NEXT: name: .debug_line_str[0x00000006] = "File2"
103 # CHECK-NEXT: dir_index: 0
104 # CHECK-NEXT: mod_time: 0x00000053
105 # CHECK-NEXT: length: 0x00000054
98106 # CHECK-NOT: file_names
99107 # CHECK: 0x0000000000000000 {{.*}} is_stmt end_sequence
121121 ; CHECK-LABEL: .debug_line contents:
122122 ; CHECK: Line table prologue
123123 ; CHECK-NOT: file_names[
124 ; SINGLE: file_names{{.*}} "bar.h"
125 ; CHECK: file_names{{.*}} "bar.cpp"
124 ; SINGLE: file_names[
125 ; SINGLE-NEXT: name: "bar.h"
126 ; CHECK: file_names[
127 ; CHECK-NEXT: name: "bar.cpp"
126128 ; CHECK-NOT: file_names[
127129
128130 ; FISSION: .debug_line.dwo contents:
132134 ; FISSION-NOT: standard_opcode_lengths
133135 ; FISSION-NOT: include_directories
134136 ; FISSION-NOT: file_names[
135 ; FISSION: file_names{{.*}} "bar.h"
136 ; FISSION: file_names{{.*}} "bar.cpp"
137 ; FISSION: file_names[
138 ; FISSION-NEXT: name: "bar.h"
139 ; FISSION: file_names[
140 ; FISSION-NEXT: name: "bar.cpp"
137141 ; FISSION-NOT: file_names[
138142
139143 ; CHECK-LABEL: .debug_str contents:
2626 ; CHECK-NEXT: debug_line[{{.*}}]
2727 ; CHECK-NEXT: Line table prologue:
2828 ; CHECK-NEXT: total_length: 0x00000038
29 ; CHECK: file_names[ 1] 0 0x00000000 0x00000000 "simple.c"
29 ; CHECK: file_names[ 1]:
30 ; CHECK-NEXT: name: "simple.c"
31 ; CHECK-NEXT: dir_index: 0
3032 ; CHECK: debug_line[{{.*}}]
3133 ; CHECK-NEXT: Line table prologue:
3234 ; CHECK-NEXT: total_length: 0x00000039
33 ; CHECK: file_names[ 1] 0 0x00000000 0x00000000 "simple2.c"
35 ; CHECK: file_names[ 1]:
36 ; CHECK-NEXT: name: "simple2.c"
37 ; CHECK-NEXT: dir_index: 0
3438 ; CHECK-NOT: file_names
3539
3640 ; DWARF3: .debug_info contents:
4549 ; DWARF3-NEXT: debug_line[{{.*}}]
4650 ; DWARF3-NEXT: Line table prologue:
4751 ; DWARF3-NEXT: total_length: 0x00000038
48 ; DWARF3: file_names[ 1] 0 0x00000000 0x00000000 "simple.c"
52 ; DWARF3: file_names[ 1]:
53 ; DWARF3-NEXT: name: "simple.c"
54 ; DWARF3-NEXT: dir_index: 0
4955 ; DWARF3: debug_line[{{.*}}]
5056 ; DWARF3-NEXT: Line table prologue:
5157 ; DWARF3-NEXT: total_length: 0x00000039
52 ; DWARF3: file_names[ 1] 0 0x00000000 0x00000000 "simple2.c"
58 ; DWARF3: file_names[ 1]:
59 ; DWARF3-NEXT: name: "simple2.c"
60 ; DWARF3-NEXT: dir_index: 0
5361 ; DWARF3-NOT: file_names
5462
5563 ; PR15408
2121 TEST_MACINFO: DW_MACINFO_end_file
2222
2323 TEST_LINE: .debug_line contents:
24 TEST_LINE: file_names[ 1] 0 0x00000000 0x00000000 "dwarfdump-macro.cc"
25 TEST_LINE: file_names[ 2] 1 0x00000000 0x00000000 "dwarfdump-macro-cmd.h"
26 TEST_LINE: file_names[ 3] 0 0x00000000 0x00000000 "dwarfdump-macro.h"
24 TEST_LINE: file_names[ 1]:
25 TEST_LINE-NEXT: name: "dwarfdump-macro.cc"
26 TEST_LINE-NEXT: dir_index: 0
27 TEST_LINE: file_names[ 2]:
28 TEST_LINE-NEXT: name: "dwarfdump-macro-cmd.h"
29 TEST_LINE-NEXT: dir_index: 1
30 TEST_LINE: file_names[ 3]:
31 TEST_LINE-NEXT: name: "dwarfdump-macro.h"
32 TEST_LINE-NEXT: dir_index: 0
146146 ; DW-LABEL: .debug_line contents:
147147 ; Check that we have the right things in the line table as well.
148148
149 ; DWLW-LABEL: file_names[{{ *}}1]{{.*}} "bar.c"
149 ; DWLW-LABEL: file_names[ 1]:
150 ; DWLW-NEXT: name: "bar.c"
150151 ; DWLW: 2 0 1 0 0 is_stmt prologue_end
151 ; DWLW-LABEL: file_names[{{ *}}1]{{.*}} "foo.c"
152 ; DWLW-LABEL: file_names[ 1]:
153 ; DWLW-NEXT: name: "foo.c"
152154 ; DWLW: 52 0 1 0 0 is_stmt prologue_end
153155 ; DWLW-NOT: prologue_end
154156
155 ; DWWL-LABEL: file_names[{{ *}}1]{{.*}} "foo.c"
157 ; DWWL-LABEL: file_names[ 1]:
158 ; DWWL-NEXT: name: "foo.c"
156159 ; DWWL: 52 0 1 0 0 is_stmt prologue_end
157 ; DWWL-LABEL: file_names[{{ *}}1]{{.*}} "bar.c"
160 ; DWWL-LABEL: file_names[ 1]:
161 ; DWWL-NEXT: name: "bar.c"
158162 ; DWWL: 2 0 1 0 0 is_stmt prologue_end
159163 ; DWWL-NOT: prologue_end
5454 // DWARF-DL: version: [[DWVER]]
5555 // DWARF-DL-5: address_size: 4
5656 // DWARF-DL-5: include_directories[ 0] = ""
57 // DWARF-DL: file_names[ [[DWFILE]]] {{.*}} ""
57 // DWARF-DL: file_names[ [[DWFILE]]]:
58 // DWARF-DL: name: ""
5859 // DWARF-DL: 0x0000000000000000 17 0 1 0 0 is_stmt
5960 // DWARF-DL-NEXT: 0x0000000000000004 17 0 1 0 0 is_stmt end_sequence
6061 // DWARF-DL-NEXT: 0x0000000000000000 21 0 1 0 0 is_stmt
1212 # CHECK: include_directories[ 1] = .debug_line_str[0x[[DIR1:[0-9a-f]+]]] = "dir1"
1313 # CHECK: include_directories[ 2] = .debug_line_str[0x[[DIR2:[0-9a-f]+]]] = "dir2"
1414 # CHECK-NOT: include_directories
15 # CHECK: Dir MD5 Checksum File Name
16 # CHECK: file_names[ 0] 1 00112233445566778899aabbccddeeff .debug_line_str[0x[[FILE1:[0-9a-f]+]]] = "foo"
17 # CHECK: file_names[ 1] 2 ffeeddccbbaa99887766554433221100 .debug_line_str[0x[[FILE2:[0-9a-f]+]]] = "bar"
15 # CHECK: file_names[ 0]:
16 # CHECK-NEXT: name: .debug_line_str[0x[[FILE1:[0-9a-f]+]]] = "foo"
17 # CHECK-NEXT: dir_index: 1
18 # CHECK-NEXT: md5_checksum: 00112233445566778899aabbccddeeff
19 # CHECK: file_names[ 1]:
20 # CHECK-NEXT: name: .debug_line_str[0x[[FILE2:[0-9a-f]+]]] = "bar"
21 # CHECK-NEXT: dir_index: 2
22 # CHECK-NEXT: md5_checksum: ffeeddccbbaa99887766554433221100
1823
1924 # CHECK: .debug_line_str contents:
2025 # CHECK-NEXT: 0x[[DIR0]]: ""
1515 // We check that the source name "t.s" is picked up
1616 // CHECK: include_directories[ 1] = "{{.*(/|\\\\)}}test{{(/|\\\\)}}MC{{(/|\\\\)}}MachO"
1717 // CHECK: include_directories[ 2] = "inc"
18 // CHECK: Dir Mod Time File Len File Name
19 // CHECK: ---- ---------- ---------- ---------------------------
20 // CHECK: file_names[ 1] 1 0x00000000 0x00000000 "gen-dwarf-cpp.s"
21 // CHECK: file_names[ 2] 0 0x00000000 0x00000000 "t.s"
22 // CHECK: file_names[ 3] 2 0x00000000 0x00000000 "g.s"
18 // CHECK: file_names[ 1]:
19 // CHECK-NEXT: name: "gen-dwarf-cpp.s"
20 // CHECK-NEXT: dir_index: 1
21 // CHECK: file_names[ 2]:
22 // CHECK-NEXT: name: "t.s"
23 // CHECK-NEXT: dir_index: 0
24 // CHECK: file_names[ 3]:
25 // CHECK-NEXT: name: "g.s"
26 // CHECK-NEXT: dir_index: 2
2327 // CHECK-NOT: file_names
2428
2529 // We check that the source line number 100 is picked up before the "movl"
1010 // rdar://12637628
1111
1212 // We check that the source name "foo.S" is picked up
13 // CHECK: Dir Mod Time File Len File Name
14 // CHECK: ---- ---------- ---------- ---------------------------
15 // CHECK: file_names[ 1] 1 0x00000000 0x00000000 "gen-dwarf-macro-cpp.s"
16 // CHECK: file_names[ 2] 0 0x00000000 0x00000000 "foo.S"
13 // CHECK: file_names[ 1]:
14 // CHECK-NEXT: name: "gen-dwarf-macro-cpp.s"
15 // CHECK-NEXT: dir_index: 1
16 // CHECK: file_names[ 2]:
17 // CHECK-NEXT: name: "foo.S"
18 // CHECK-NEXT: dir_index: 0
108108 // CHECK: standard_opcode_lengths[DW_LNS_set_epilogue_begin] = 0
109109 // CHECK: standard_opcode_lengths[DW_LNS_set_isa] = 1
110110 // We don't check include_directories as it has a temp path
111 // CHECK: Dir Mod Time File Len File Name
112 // CHECK: ---- ---------- ---------- ---------------------------
113 // CHECK: file_names[ 1] 1 0x00000000 0x00000000 "gen-dwarf.s"
111 // CHECK: file_names[ 1]:
112 // CHECK-NEXT: name: "gen-dwarf.s"
113 // CHECK-NEXT: dir_index: 1
114114
115115 // CHECK: Address Line Column File ISA Discriminator Flags
116116 // CHECK: ------------------ ------ ------ ------ --- ------------- -------------
152152 CHECK-NEXT:[0x0000000100000f90, 0x0000000100000fa9)
153153
154154 CHECK: .debug_line contents:
155 CHECK: Dir Mod Time File Len File Name
156 CHECK-NEXT: ---- ---------- ---------- ---------------------------
157 CHECK-NEXT: file_names[ 1] 0 0x00000000 0x00000000 "basic1.c"
155 CHECK: file_names[ 1]:
156 CHECK-NEXT: name: "basic1.c"
157 CHECK-NEXT: dir_index: 0
158158 CHECK: Address Line Column File ISA Discriminator Flags
159159 CHECK-NEXT: ------------------ ------ ------ ------ --- ------------- -------------
160160 CHECK-NEXT: 0x0000000100000ea0 23 0 1 0 0 is_stmt
161161 CHECK-NEXT: 0x0000000100000eb6 24 0 1 0 0 is_stmt prologue_end
162162 CHECK-NEXT: 0x0000000100000ec4 24 0 1 0 0 is_stmt end_sequence
163163
164 CHECK: Dir Mod Time File Len File Name
165 CHECK-NEXT: ---- ---------- ---------- ---------------------------
166 CHECK-NEXT: file_names[ 1] 0 0x00000000 0x00000000 "basic2.c"
164 CHECK: file_names[ 1]:
165 CHECK-NEXT: name: "basic2.c"
166 CHECK-NEXT: dir_index: 0
167167 CHECK: Address Line Column File ISA Discriminator Flags
168168 CHECK-NEXT: ------------------ ------ ------ ------ --- ------------- -------------
169169 CHECK-NEXT: 0x0000000100000ed0 19 0 1 0 0 is_stmt
173173 CHECK-NEXT: 0x0000000100000f24 15 0 1 0 0 is_stmt prologue_end
174174 CHECK-NEXT: 0x0000000100000f37 15 0 1 0 0 is_stmt end_sequence
175175
176 CHECK: Dir Mod Time File Len File Name
177 CHECK-NEXT: ---- ---------- ---------- ---------------------------
178 CHECK-NEXT: file_names[ 1] 0 0x00000000 0x00000000 "basic3.c"
176 CHECK: file_names[ 1]:
177 CHECK-NEXT: name: "basic3.c"
178 CHECK-NEXT: dir_index: 0
179179 CHECK: Address Line Column File ISA Discriminator Flags
180180 CHECK-NEXT: ------------------ ------ ------ ------ --- ------------- -------------
181181 CHECK-NEXT: 0x0000000100000f40 16 0 1 0 0 is_stmt
137137 CHECK-NEXT: [0x0000000100000f90, 0x0000000100000fb4)
138138
139139 CHECK: .debug_line contents:
140 CHECK: Dir Mod Time File Len File Name
141 CHECK-NEXT: ---- ---------- ---------- ---------------------------
142 CHECK-NEXT: file_names[ 1] 0 0x00000000 0x00000000 "basic1.c"
140 CHECK: file_names[ 1]:
141 CHECK-NEXT: name: "basic1.c"
142 CHECK-NEXT: dir_index: 0
143143 CHECK: Address Line Column File ISA Discriminator Flags
144144 CHECK-NEXT: ------------------ ------ ------ ------ --- ------------- -------------
145145 CHECK-NEXT: 0x0000000100000f40 26 0 1 0 0 is_stmt
147147 CHECK-NEXT: 0x0000000100000f49 27 3 1 0 0
148148 CHECK-NEXT: 0x0000000100000f4b 27 3 1 0 0 end_sequence
149149
150 CHECK: Dir Mod Time File Len File Name
151 CHECK-NEXT: ---- ---------- ---------- ---------------------------
152 CHECK-NEXT: file_names[ 1] 0 0x00000000 0x00000000 "basic2.c"
150 CHECK: file_names[ 1]:
151 CHECK-NEXT: name: "basic2.c"
152 CHECK-NEXT: dir_index: 0
153153 CHECK: Address Line Column File ISA Discriminator Flags
154154 CHECK-NEXT: ------------------ ------ ------ ------ --- ------------- -------------
155155 CHECK-NEXT: 0x0000000100000f50 19 0 1 0 0 is_stmt
163163 CHECK-NEXT: 0x0000000100000f85 20 3 1 0 0
164164 CHECK-NEXT: 0x0000000100000f87 20 3 1 0 0 end_sequence
165165
166 CHECK: Dir Mod Time File Len File Name
167 CHECK-NEXT: ---- ---------- ---------- ---------------------------
168 CHECK-NEXT: file_names[ 1] 0 0x00000000 0x00000000 "basic3.c"
166 CHECK: file_names[ 1]:
167 CHECK-NEXT: name: "basic3.c"
168 CHECK-NEXT: dir_index: 0
169169 CHECK: Address Line Column File ISA Discriminator Flags
170170 CHECK-NEXT: ------------------ ------ ------ ------ --- ------------- -------------
171171 CHECK-NEXT: 0x0000000100000f90 16 0 1 0 0 is_stmt
149149
150150
151151 CHECK: .debug_line contents
152 CHECK: Dir Mod Time File Len File Name
153 CHECK-NEXT: ---- ---------- ---------- ---------------------------
154 CHECK-NEXT: file_names[ 1] 0 0x00000000 0x00000000 "basic1.c"
152 CHECK: file_names[ 1]:
153 CHECK-NEXT: name: "basic1.c"
154 CHECK-NEXT: dir_index: 0
155155 CHECK: 0x0000000100000f40 23 0 1 0 0 is_stmt
156156 CHECK: 0x0000000100000f44 24 0 1 0 0 is_stmt prologue_end
157157 CHECK: 0x0000000100000f4b 24 0 1 0 0 is_stmt end_sequence
158158
159 CHECK: Dir Mod Time File Len File Name
160 CHECK-NEXT: ---- ---------- ---------- ---------------------------
161 CHECK-NEXT: file_names[ 1] 0 0x00000000 0x00000000 "basic2.c"
159 CHECK: file_names[ 1]:
160 CHECK-NEXT: name: "basic2.c"
161 CHECK-NEXT: dir_index: 0
162162 CHECK: 0x0000000100000f50 19 0 1 0 0 is_stmt
163163 CHECK: 0x0000000100000f54 20 0 1 0 0 is_stmt prologue_end
164164 CHECK: 0x0000000100000f63 15 0 1 0 0 is_stmt
165165 CHECK: 0x0000000100000f72 20 0 1 0 0 is_stmt
166166 CHECK: 0x0000000100000f89 20 0 1 0 0 is_stmt end_sequence
167167
168 CHECK: Dir Mod Time File Len File Name
169 CHECK-NEXT: ---- ---------- ---------- ---------------------------
170 CHECK-NEXT: file_names[ 1] 0 0x00000000 0x00000000 "basic3.c"
168 CHECK: file_names[ 1]:
169 CHECK-NEXT: name: "basic3.c"
170 CHECK-NEXT: dir_index: 0
171171 CHECK: 0x0000000100000f90 16 0 1 0 0 is_stmt
172172 CHECK: 0x0000000100000f94 12 0 1 0 0 is_stmt prologue_end
173173 CHECK: 0x0000000100000f9a 17 0 1 0 0 is_stmt
407407 std::unordered_map> LineCache;
408408
409409 private:
410 bool cacheSource(const std::string& File);
410 bool cacheSource(const DILineInfo& LineInfoFile);
411411
412412 public:
413413 SourcePrinter() = default;
422422 StringRef Delimiter = "; ");
423423 };
424424
425 bool SourcePrinter::cacheSource(const std::string& File) {
426 auto BufferOrError = MemoryBuffer::getFile(File);
427 if (!BufferOrError)
428 return false;
425 bool SourcePrinter::cacheSource(const DILineInfo &LineInfo) {
426 std::unique_ptr Buffer;
427 if (LineInfo.Source) {
428 Buffer = MemoryBuffer::getMemBuffer(*LineInfo.Source);
429 } else {
430 auto BufferOrError = MemoryBuffer::getFile(LineInfo.FileName);
431 if (!BufferOrError)
432 return false;
433 Buffer = std::move(*BufferOrError);
434 }
429435 // Chomp the file to get lines
430 size_t BufferSize = (*BufferOrError)->getBufferSize();
431 const char *BufferStart = (*BufferOrError)->getBufferStart();
436 size_t BufferSize = Buffer->getBufferSize();
437 const char *BufferStart = Buffer->getBufferStart();
432438 for (const char *Start = BufferStart, *End = BufferStart;
433439 End < BufferStart + BufferSize; End++)
434440 if (*End == '\n' || End == BufferStart + BufferSize - 1 ||
435441 (*End == '\r' && *(End + 1) == '\n')) {
436 LineCache[File].push_back(StringRef(Start, End - Start));
442 LineCache[LineInfo.FileName].push_back(StringRef(Start, End - Start));
437443 if (*End == '\r')
438444 End++;
439445 Start = End + 1;
440446 }
441 SourceCache[File] = std::move(*BufferOrError);
447 SourceCache[LineInfo.FileName] = std::move(Buffer);
442448 return true;
443449 }
444450
462468 OS << Delimiter << LineInfo.FileName << ":" << LineInfo.Line << "\n";
463469 if (PrintSource) {
464470 if (SourceCache.find(LineInfo.FileName) == SourceCache.end())
465 if (!cacheSource(LineInfo.FileName))
471 if (!cacheSource(LineInfo))
466472 return;
467473 auto FileBuffer = SourceCache.find(LineInfo.FileName);
468474 if (FileBuffer != SourceCache.end()) {
14491449 DIFile::ChecksumKind CSKind = DIFile::ChecksumKind::CSK_MD5;
14501450 StringRef ChecksumString = "000102030405060708090a0b0c0d0e0f";
14511451 DIFile::ChecksumInfo Checksum(CSKind, ChecksumString);
1452 auto *N = DIFile::get(Context, Filename, Directory, Checksum);
1452 StringRef Source = "source";
1453 auto *N = DIFile::get(Context, Filename, Directory, Checksum, Source);
14531454
14541455 EXPECT_EQ(dwarf::DW_TAG_file_type, N->getTag());
14551456 EXPECT_EQ(Filename, N->getFilename());
14561457 EXPECT_EQ(Directory, N->getDirectory());
14571458 EXPECT_EQ(Checksum, N->getChecksum());
1458 EXPECT_EQ(N, DIFile::get(Context, Filename, Directory, Checksum));
1459
1460 EXPECT_NE(N, DIFile::get(Context, "other", Directory, Checksum));
1461 EXPECT_NE(N, DIFile::get(Context, Filename, "other", Checksum));
1459 EXPECT_EQ(Source, N->getSource());
1460 EXPECT_EQ(N, DIFile::get(Context, Filename, Directory, Checksum, Source));
1461
1462 EXPECT_NE(N, DIFile::get(Context, "other", Directory, Checksum, Source));
1463 EXPECT_NE(N, DIFile::get(Context, Filename, "other", Checksum, Source));
14621464 DIFile::ChecksumInfo OtherChecksum(DIFile::ChecksumKind::CSK_SHA1, ChecksumString);
14631465 EXPECT_NE(
14641466 N, DIFile::get(Context, Filename, Directory, OtherChecksum));
1467 StringRef OtherSource = "other";
1468 EXPECT_NE(N, DIFile::get(Context, Filename, Directory, Checksum, OtherSource));
1469 EXPECT_NE(N, DIFile::get(Context, Filename, Directory, Checksum));
14651470 EXPECT_NE(N, DIFile::get(Context, Filename, Directory));
14661471
14671472 TempDIFile Temp = N->clone();