diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h index 0da75cbda4d..e92d3b9e710 100644 --- a/include/llvm/MC/MCContext.h +++ b/include/llvm/MC/MCContext.h @@ -97,6 +97,9 @@ namespace llvm { /// The compilation directory to use for DW_AT_comp_dir. std::string CompilationDir; + /// The main file name if passed in explicitly. + std::string MainFileName; + /// The dwarf file and directory tables from the dwarf .file directive. std::vector MCDwarfFiles; std::vector MCDwarfDirs; @@ -261,6 +264,14 @@ namespace llvm { /// Override the default (CWD) compilation directory. void setCompilationDir(StringRef S) { CompilationDir = S.str(); } + /// \brief Get the main file name for use in error messages and debug + /// info. This can be set to ensure we've got the correct file name + /// after preprocessing or for -save-temps. + const std::string &getMainFileName() const { return MainFileName; } + + /// \brief Set the main file name and override the default. + void setMainFileName(StringRef S) { MainFileName = S.str(); } + /// GetDwarfFile - creates an entry in the dwarf file and directory tables. unsigned GetDwarfFile(StringRef Directory, StringRef FileName, unsigned FileNumber); diff --git a/include/llvm/Support/SourceMgr.h b/include/llvm/Support/SourceMgr.h index bc832e0c9e5..aaee3447554 100644 --- a/include/llvm/Support/SourceMgr.h +++ b/include/llvm/Support/SourceMgr.h @@ -95,6 +95,10 @@ public: return Buffers[i].Buffer; } + unsigned getNumBuffers() const { + return Buffers.size(); + } + SMLoc getParentIncludeLoc(unsigned i) const { assert(i < Buffers.size() && "Invalid Buffer ID!"); return Buffers[i].IncludeLoc; diff --git a/lib/MC/MCContext.cpp b/lib/MC/MCContext.cpp index 29727ac8a6a..d206dd9f504 100644 --- a/lib/MC/MCContext.cpp +++ b/lib/MC/MCContext.cpp @@ -21,6 +21,7 @@ #include "llvm/MC/MCSymbol.h" #include "llvm/Support/ELF.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Signals.h" #include "llvm/Support/SourceMgr.h" using namespace llvm; @@ -48,6 +49,11 @@ MCContext::MCContext(const MCAsmInfo &mai, const MCRegisterInfo &mri, SecureLogFile = getenv("AS_SECURE_LOG_FILE"); SecureLog = 0; SecureLogUsed = false; + + if (SrcMgr && SrcMgr->getNumBuffers() > 0) + MainFileName = SrcMgr->getMemoryBuffer(0)->getBufferIdentifier(); + else + MainFileName = ""; } MCContext::~MCContext() { diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp index e1a1f89f423..85d31872a73 100644 --- a/lib/MC/MCParser/AsmParser.cpp +++ b/lib/MC/MCParser/AsmParser.cpp @@ -613,7 +613,8 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) { getStreamer().EmitLabel(SectionStartSym); getContext().setGenDwarfSectionStartSym(SectionStartSym); getStreamer().EmitDwarfFileDirective(getContext().nextGenDwarfFileNumber(), - StringRef(), SrcMgr.getMemoryBuffer(CurBuffer)->getBufferIdentifier()); + StringRef(), + getContext().getMainFileName()); } // While we have input, parse each statement. diff --git a/test/DebugInfo/X86/lit.local.cfg b/test/DebugInfo/X86/lit.local.cfg index 0d694da8df5..60d66eae495 100644 --- a/test/DebugInfo/X86/lit.local.cfg +++ b/test/DebugInfo/X86/lit.local.cfg @@ -1,4 +1,4 @@ -config.suffixes = ['.ll'] +config.suffixes = ['.ll', '.s'] targets = set(config.root.targets_to_build.split()) if not 'X86' in targets: diff --git a/test/DebugInfo/X86/main-file-name.s b/test/DebugInfo/X86/main-file-name.s new file mode 100644 index 00000000000..6817c9e3a7f --- /dev/null +++ b/test/DebugInfo/X86/main-file-name.s @@ -0,0 +1,17 @@ +// RUN: llvm-mc -triple x86_64-unknown-linux-gnu -filetype obj -main-file-name foo.S -g -o %t %s +// RUN: llvm-dwarfdump %t | FileCheck %s + +// CHECK: DW_TAG_compile_unit [1] +// CHECK-NOT: DW_TAG_ +// CHECK: DW_AT_name [DW_FORM_string] ("foo.S") + + +# 1 "foo.S" +# 1 "" 1 +# 1 "foo.S" 2 + +foo: + nop + nop + nop + diff --git a/tools/llvm-mc/llvm-mc.cpp b/tools/llvm-mc/llvm-mc.cpp index c12a93d1716..930f528668f 100644 --- a/tools/llvm-mc/llvm-mc.cpp +++ b/tools/llvm-mc/llvm-mc.cpp @@ -161,6 +161,10 @@ static cl::opt DebugCompilationDir("fdebug-compilation-dir", cl::desc("Specifies the debug info's compilation dir")); +static cl::opt +MainFileName("main-file-name", + cl::desc("Specifies the name we should consider the input file")); + enum ActionType { AC_AsLex, AC_Assemble, @@ -397,6 +401,8 @@ int main(int argc, char **argv) { Ctx.setDwarfDebugFlags(StringRef(DwarfDebugFlags)); if (!DebugCompilationDir.empty()) Ctx.setCompilationDir(DebugCompilationDir); + if (!MainFileName.empty()) + Ctx.setMainFileName(MainFileName); // Package up features to be passed to target/subtarget std::string FeaturesStr;