summaryrefslogtreecommitdiffstats
path: root/llvm/lib/MC
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/MC')
-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
5 files changed, 92 insertions, 31 deletions
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