diff options
Diffstat (limited to 'llvm/lib/MC')
| -rw-r--r-- | llvm/lib/MC/MCAsmStreamer.cpp | 10 | ||||
| -rw-r--r-- | llvm/lib/MC/MCContext.cpp | 6 | ||||
| -rw-r--r-- | llvm/lib/MC/MCDwarf.cpp | 51 | ||||
| -rw-r--r-- | llvm/lib/MC/MCParser/AsmParser.cpp | 48 | ||||
| -rw-r--r-- | llvm/lib/MC/MCStreamer.cpp | 8 |
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, |

