summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/AsmParser/LLParser.cpp13
-rw-r--r--llvm/lib/Bitcode/Reader/MetadataLoader.cpp9
-rw-r--r--llvm/lib/Bitcode/Writer/BitcodeWriter.cpp3
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp5
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp6
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp4
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFContext.cpp4
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp98
-rw-r--r--llvm/lib/IR/AsmWriter.cpp2
-rw-r--r--llvm/lib/IR/DIBuilder.cpp6
-rw-r--r--llvm/lib/IR/DebugInfoMetadata.cpp11
-rw-r--r--llvm/lib/IR/LLVMContextImpl.h18
-rw-r--r--llvm/lib/MC/MCAsmStreamer.cpp10
-rw-r--r--llvm/lib/MC/MCContext.cpp6
-rw-r--r--llvm/lib/MC/MCDwarf.cpp51
-rw-r--r--llvm/lib/MC/MCParser/AsmParser.cpp48
-rw-r--r--llvm/lib/MC/MCStreamer.cpp8
17 files changed, 215 insertions, 87 deletions
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index d5714ea1885..42c579878c1 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<MDString *> 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 0931192cd18..efaee21a8d8 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<DIFile::ChecksumKind>(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<MDString *>(getMDString(Record[5]))
+ : None)),
NextMetadataNo);
NextMetadataNo++;
break;
diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
index 832f494bc77..0738b907be3 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 dcc3e55a52e..0b2a0469f8c 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 99ed096d132..6b50fb94d0e 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<DIScope>(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<DwarfCompileUnit &>(*InfoHolder.getUnits()[CUID])
+ FileNo = static_cast<DwarfCompileUnit &>(*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 d7d5298d673..377e557f637 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 ef097265e04..de7ef662afb 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 8986af26c03..56e7af24af5 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<ContentDescriptor, 4>;
} // 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<DWARFFormValue> &IncludeDirectories,
std::vector<DWARFDebugLine::FileNameEntry> &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<DWARFFormValue> &IncludeDirectories,
std::vector<DWARFDebugLine::FileNameEntry> &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<StringRef> 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<const char *> 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 5a02cf39c1b..ae24040a600 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 8cb95d2871d..3e5ecdc2091 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<DIFile::ChecksumInfo<StringRef>> CS) {
- return DIFile::get(VMContext, Filename, Directory, CS);
+ Optional<DIFile::ChecksumInfo<StringRef>> CS,
+ Optional<StringRef> 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 82f04a65618..c1a9f3f6929 100644
--- a/llvm/lib/IR/DebugInfoMetadata.cpp
+++ b/llvm/lib/IR/DebugInfoMetadata.cpp
@@ -417,13 +417,16 @@ Optional<DIFile::ChecksumKind> DIFile::getChecksumKind(StringRef CSKindStr) {
DIFile *DIFile::getImpl(LLVMContext &Context, MDString *Filename,
MDString *Directory,
Optional<DIFile::ChecksumInfo<MDString *>> CS,
- StorageType Storage, bool ShouldCreate) {
+ Optional<MDString *> 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 313b7e16bec..1f2956d54ed 100644
--- a/llvm/lib/IR/LLVMContextImpl.h
+++ b/llvm/lib/IR/LLVMContextImpl.h
@@ -575,24 +575,28 @@ template <> struct MDNodeKeyImpl<DIFile> {
MDString *Filename;
MDString *Directory;
Optional<DIFile::ChecksumInfo<MDString *>> Checksum;
+ Optional<MDString *> Source;
MDNodeKeyImpl(MDString *Filename, MDString *Directory,
- Optional<DIFile::ChecksumInfo<MDString *>> Checksum)
- : Filename(Filename), Directory(Directory), Checksum(Checksum) {}
+ Optional<DIFile::ChecksumInfo<MDString *>> Checksum,
+ Optional<MDString *> 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 7ea5b7677b8..f254cb50b60 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<StringRef> 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<unsigned> MCAsmStreamer::tryEmitDwarfFileDirective(
unsigned FileNo, StringRef Directory, StringRef Filename,
- MD5::MD5Result *Checksum, unsigned CUID) {
+ MD5::MD5Result *Checksum, Optional<StringRef> Source, unsigned CUID) {
assert(CUID == 0);
MCDwarfLineTable &Table = getContext().getMCDwarfLineTable(CUID);
unsigned NumFiles = Table.getMCDwarfFiles().size();
Expected<unsigned> 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<unsigned> 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 ea995288b28..69c10f535e5 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<unsigned> MCContext::getDwarfFile(StringRef Directory,
StringRef FileName,
unsigned FileNumber,
MD5::MD5Result *Checksum,
+ Optional<StringRef> 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 1f0fa78bffc..685b46a606d 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<const char *>(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<unsigned> MCDwarfLineTable::tryGetFile(StringRef &Directory,
StringRef &FileName,
MD5::MD5Result *Checksum,
+ Optional<StringRef> Source,
unsigned FileNumber) {
- return Header.tryGetFile(Directory, FileName, Checksum, FileNumber);
+ return Header.tryGetFile(Directory, FileName, Checksum, Source, FileNumber);
}
-Expected<unsigned> MCDwarfLineTableHeader::tryGetFile(StringRef &Directory,
- StringRef &FileName,
- MD5::MD5Result *Checksum,
- unsigned FileNumber) {
+Expected<unsigned>
+MCDwarfLineTableHeader::tryGetFile(StringRef &Directory,
+ StringRef &FileName,
+ MD5::MD5Result *Checksum,
+ Optional<StringRef> &Source,
+ unsigned FileNumber) {
if (Directory == CompilationDir)
Directory = "";
if (FileName.empty()) {
@@ -515,9 +537,11 @@ Expected<unsigned> 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<unsigned> MCDwarfLineTableHeader::tryGetFile(StringRef &Directory,
if (HasMD5 != (Checksum != nullptr))
return make_error<StringError>("inconsistent use of MD5 checksums",
inconvertibleErrorCode());
+ // If any files have embedded source, they all must.
+ if (HasSource != (Source != None))
+ return make_error<StringError>("inconsistent use of embedded source",
+ inconvertibleErrorCode());
if (Directory.empty()) {
// Separate the directory part from the basename of the FileName.
@@ -582,6 +610,9 @@ Expected<unsigned> 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 8ede318e0e1..76eef5e3725 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<StringRef> 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<char *>(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<unsigned> 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 ab6fd9c7bb0..bf27a0abfda 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<unsigned>
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<StringRef> Source,
+ unsigned CUID) {
+ return getContext().getDwarfFile(Directory, Filename, FileNo, Checksum,
+ Source, CUID);
}
void MCStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
OpenPOWER on IntegriCloud