diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h index b3df2252109..b51a5a589f4 100644 --- a/include/llvm/MC/MCContext.h +++ b/include/llvm/MC/MCContext.h @@ -371,7 +371,9 @@ namespace llvm { bool getGenDwarfForAssembly() { return GenDwarfForAssembly; } void setGenDwarfForAssembly(bool Value) { GenDwarfForAssembly = Value; } unsigned getGenDwarfFileNumber() { return GenDwarfFileNumber; } - unsigned nextGenDwarfFileNumber() { return ++GenDwarfFileNumber; } + void setGenDwarfFileNumber(unsigned FileNumber) { + GenDwarfFileNumber = FileNumber; + } const MCSection *getGenDwarfSection() { return GenDwarfSection; } void setGenDwarfSection(const MCSection *Sec) { GenDwarfSection = Sec; } MCSymbol *getGenDwarfSectionStartSym() { return GenDwarfSectionStartSym; } diff --git a/include/llvm/MC/MCDwarf.h b/include/llvm/MC/MCDwarf.h index abd2f7a2d69..3b604506144 100644 --- a/include/llvm/MC/MCDwarf.h +++ b/include/llvm/MC/MCDwarf.h @@ -16,6 +16,7 @@ #define LLVM_MC_MCDWARF_H #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/StringMap.h" #include "llvm/ADT/MapVector.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Dwarf.h" @@ -179,8 +180,9 @@ struct MCDwarfLineTableHeader { MCSymbol *Label; SmallVector MCDwarfDirs; SmallVector MCDwarfFiles; + StringMap SourceIdMap; MCDwarfLineTableHeader() : Label(nullptr) {} - unsigned getFile(StringRef Directory, StringRef FileName, unsigned FileNumber); + unsigned getFile(StringRef Directory, StringRef FileName, unsigned FileNumber = 0); std::pair Emit(MCStreamer *MCOS) const; }; @@ -195,7 +197,7 @@ public: // This emits the Dwarf file and the line tables for a given Compile Unit. const MCSymbol *EmitCU(MCStreamer *MCOS) const; - unsigned getFile(StringRef Directory, StringRef FileName, unsigned FileNumber); + unsigned getFile(StringRef Directory, StringRef FileName, unsigned FileNumber = 0); MCSymbol *getLabel() const { return Header.Label; diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h index 18f0e772ef0..fc7a3b86482 100644 --- a/include/llvm/MC/MCStreamer.h +++ b/include/llvm/MC/MCStreamer.h @@ -628,8 +628,9 @@ public: /// EmitDwarfFileDirective - Associate a filename with a specified logical /// file number. This implements the DWARF2 '.file 4 "foo.c"' assembler /// directive. - virtual bool EmitDwarfFileDirective(unsigned FileNo, StringRef Directory, - StringRef Filename, unsigned CUID = 0); + virtual unsigned EmitDwarfFileDirective(unsigned FileNo, StringRef Directory, + StringRef Filename, + unsigned CUID = 0); /// EmitDwarfLocDirective - This implements the DWARF2 // '.loc fileno lineno ...' assembler directive. diff --git a/lib/MC/MCAsmStreamer.cpp b/lib/MC/MCAsmStreamer.cpp index 75db7a96bbf..b40305d0fc2 100644 --- a/lib/MC/MCAsmStreamer.cpp +++ b/lib/MC/MCAsmStreamer.cpp @@ -197,8 +197,9 @@ public: unsigned char Value = 0) override; void EmitFileDirective(StringRef Filename) override; - bool EmitDwarfFileDirective(unsigned FileNo, StringRef Directory, - StringRef Filename, unsigned CUID = 0) override; + unsigned EmitDwarfFileDirective(unsigned FileNo, StringRef Directory, + StringRef Filename, + unsigned CUID = 0) override; void EmitDwarfLocDirective(unsigned FileNo, unsigned Line, unsigned Column, unsigned Flags, unsigned Isa, unsigned Discriminator, @@ -843,8 +844,10 @@ void MCAsmStreamer::EmitFileDirective(StringRef Filename) { EmitEOL(); } -bool MCAsmStreamer::EmitDwarfFileDirective(unsigned FileNo, StringRef Directory, - StringRef Filename, unsigned CUID) { +unsigned MCAsmStreamer::EmitDwarfFileDirective(unsigned FileNo, + StringRef Directory, + StringRef Filename, + unsigned CUID) { if (!UseDwarfDirectory && !Directory.empty()) { if (sys::path::is_absolute(Filename)) return EmitDwarfFileDirective(FileNo, "", Filename, CUID); diff --git a/lib/MC/MCDwarf.cpp b/lib/MC/MCDwarf.cpp index 181e73dd432..72ecfa6cb45 100644 --- a/lib/MC/MCDwarf.cpp +++ b/lib/MC/MCDwarf.cpp @@ -336,7 +336,18 @@ unsigned MCDwarfLineTable::getFile(StringRef Directory, StringRef FileName, return Header.getFile(Directory, FileName, FileNumber); } -unsigned MCDwarfLineTableHeader::getFile(StringRef Directory, StringRef FileName, unsigned FileNumber) { +unsigned MCDwarfLineTableHeader::getFile(StringRef Directory, + StringRef FileName, + unsigned FileNumber) { + if (FileNumber == 0) { + FileNumber = SourceIdMap.size() + 1; + assert((MCDwarfFiles.empty() || FileNumber == MCDwarfFiles.size()) && + "Don't mix autonumbered and explicit numbered line table usage"); + StringMapEntry &Ent = SourceIdMap.GetOrCreateValue( + (Directory + Twine('\0') + FileName).str(), FileNumber); + if (Ent.getValue() != FileNumber) + return Ent.getValue(); + } // Make space for this FileNumber in the MCDwarfFiles vector if needed. MCDwarfFiles.resize(FileNumber + 1); diff --git a/lib/MC/MCNullStreamer.cpp b/lib/MC/MCNullStreamer.cpp index 181000b249c..894eada57d6 100644 --- a/lib/MC/MCNullStreamer.cpp +++ b/lib/MC/MCNullStreamer.cpp @@ -85,10 +85,10 @@ namespace { unsigned char Value = 0) override { return false; } void EmitFileDirective(StringRef Filename) override {} - bool EmitDwarfFileDirective(unsigned FileNo, StringRef Directory, - StringRef Filename, - unsigned CUID = 0) override { - return false; + unsigned EmitDwarfFileDirective(unsigned FileNo, StringRef Directory, + StringRef Filename, + unsigned CUID = 0) override { + return 0; } void EmitDwarfLocDirective(unsigned FileNo, unsigned Line, unsigned Column, unsigned Flags, diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp index f3cf8f2d1c7..fbbd4365bcb 100644 --- a/lib/MC/MCParser/AsmParser.cpp +++ b/lib/MC/MCParser/AsmParser.cpp @@ -640,9 +640,8 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) { MCSymbol *SectionStartSym = getContext().CreateTempSymbol(); getStreamer().EmitLabel(SectionStartSym); getContext().setGenDwarfSectionStartSym(SectionStartSym); - getStreamer().EmitDwarfFileDirective(getContext().nextGenDwarfFileNumber(), - StringRef(), - getContext().getMainFileName()); + getContext().setGenDwarfFileNumber(getStreamer().EmitDwarfFileDirective( + 0, StringRef(), getContext().getMainFileName())); } // While we have input, parse each statement. @@ -1589,14 +1588,10 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info) { // If we previously parsed a cpp hash file line comment then make sure the // current Dwarf File is for the CppHashFilename if not then emit the // Dwarf File table for it and adjust the line number for the .loc. - const SmallVectorImpl &MCDwarfFiles = - getContext().getMCDwarfFiles(); if (CppHashFilename.size() != 0) { - if (MCDwarfFiles[getContext().getGenDwarfFileNumber()].Name != - CppHashFilename) - getStreamer().EmitDwarfFileDirective( - getContext().nextGenDwarfFileNumber(), StringRef(), - CppHashFilename); + unsigned FileNumber = getStreamer().EmitDwarfFileDirective( + 0, StringRef(), CppHashFilename); + getContext().setGenDwarfFileNumber(FileNumber); // Since SrcMgr.FindLineNumber() is slow and messes up the SourceMgr's // cache with the different Loc from the call above we save the last @@ -2762,7 +2757,8 @@ bool AsmParser::parseDirectiveFile(SMLoc DirectiveLoc) { "input can't have .file dwarf directives when -g is " "used to generate dwarf debug info for assembly code"); - if (getStreamer().EmitDwarfFileDirective(FileNumber, Directory, Filename)) + if (getStreamer().EmitDwarfFileDirective(FileNumber, Directory, Filename) == + 0) Error(FileNumberLoc, "file number already allocated"); } diff --git a/lib/MC/MCStreamer.cpp b/lib/MC/MCStreamer.cpp index 08373895814..ec3b5f9be41 100644 --- a/lib/MC/MCStreamer.cpp +++ b/lib/MC/MCStreamer.cpp @@ -174,10 +174,10 @@ void MCStreamer::EmitZeros(uint64_t NumBytes) { EmitFill(NumBytes, 0); } -bool MCStreamer::EmitDwarfFileDirective(unsigned FileNo, - StringRef Directory, - StringRef Filename, unsigned CUID) { - return getContext().GetDwarfFile(Directory, Filename, FileNo, CUID) == 0; +unsigned MCStreamer::EmitDwarfFileDirective(unsigned FileNo, + StringRef Directory, + StringRef Filename, unsigned CUID) { + return getContext().GetDwarfFile(Directory, Filename, FileNo, CUID); } void MCStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line, diff --git a/test/MC/MachO/gen-dwarf-cpp.s b/test/MC/MachO/gen-dwarf-cpp.s index c32bcbf580f..d5cda27ec58 100644 --- a/test/MC/MachO/gen-dwarf-cpp.s +++ b/test/MC/MachO/gen-dwarf-cpp.s @@ -4,6 +4,7 @@ # 100 "t.s" 1 .globl _bar _bar: + movl $0, %eax # 3 "inc/g.s" movl $0, %eax L1: leave