diff --git a/llvm/include/llvm/MC/MCAsmInfo.h b/llvm/include/llvm/MC/MCAsmInfo.h --- a/llvm/include/llvm/MC/MCAsmInfo.h +++ b/llvm/include/llvm/MC/MCAsmInfo.h @@ -390,6 +390,10 @@ /// for ELF targets. Defaults to true. bool HasSingleParameterDotFile = true; + /// True if the target has a four strings .file directive, strings seperated + /// by comma. Defaults to false. + bool HasFourStringsDotFile = false; + /// True if the target has a .ident directive, this is true for ELF targets. /// Defaults to false. bool HasIdentDirective = false; @@ -729,6 +733,7 @@ bool hasFunctionAlignment() const { return HasFunctionAlignment; } bool hasDotTypeDotSizeDirective() const { return HasDotTypeDotSizeDirective; } bool hasSingleParameterDotFile() const { return HasSingleParameterDotFile; } + bool hasFourStringsDotFile() const { return HasFourStringsDotFile; } bool hasIdentDirective() const { return HasIdentDirective; } bool hasNoDeadStrip() const { return HasNoDeadStrip; } bool hasAltEntry() const { return HasAltEntry; } diff --git a/llvm/include/llvm/MC/MCObjectStreamer.h b/llvm/include/llvm/MC/MCObjectStreamer.h --- a/llvm/include/llvm/MC/MCObjectStreamer.h +++ b/llvm/include/llvm/MC/MCObjectStreamer.h @@ -184,6 +184,8 @@ void emitNops(int64_t NumBytes, int64_t ControlledNopLength, SMLoc Loc) override; void emitFileDirective(StringRef Filename) override; + void emitFileDirective(StringRef Filename, StringRef CompilerVerion, + StringRef TimeStamp, StringRef Description) override; void emitAddrsig() override; void emitAddrsigSym(const MCSymbol *Sym) override; diff --git a/llvm/include/llvm/MC/MCStreamer.h b/llvm/include/llvm/MC/MCStreamer.h --- a/llvm/include/llvm/MC/MCStreamer.h +++ b/llvm/include/llvm/MC/MCStreamer.h @@ -854,6 +854,10 @@ /// "foo.c"' assembler directive. virtual void emitFileDirective(StringRef Filename); + /// Emit ".file assembler diretive with additioal info. + virtual void emitFileDirective(StringRef Filename, StringRef CompilerVerion, + StringRef TimeStamp, StringRef Description); + /// Emit the "identifiers" directive. This implements the /// '.ident "version foo"' assembler directive. virtual void emitIdent(StringRef IdentString) {} diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -59,6 +59,7 @@ #include "llvm/CodeGen/TargetLowering.h" #include "llvm/CodeGen/TargetOpcodes.h" #include "llvm/CodeGen/TargetRegisterInfo.h" +#include "llvm/Config/config.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/Comdat.h" #include "llvm/IR/Constant.h" @@ -297,11 +298,24 @@ // don't, this at least helps the user find where a global came from. if (MAI->hasSingleParameterDotFile()) { // .file "foo.c" + + SmallString<128> FileName; if (MAI->hasBasenameOnlyForFileDirective()) - OutStreamer->emitFileDirective( - llvm::sys::path::filename(M.getSourceFileName())); + FileName = llvm::sys::path::filename(M.getSourceFileName()); else - OutStreamer->emitFileDirective(M.getSourceFileName()); + FileName = M.getSourceFileName(); + if (MAI->hasFourStringsDotFile()) { +#ifdef PACKAGE_VENDOR + const char VerStr[] = + PACKAGE_VENDOR " " PACKAGE_NAME " version " PACKAGE_VERSION; +#else + const char VerStr[] = PACKAGE_NAME " version " PACKAGE_VERSION; +#endif + // TODO: Add timestamp and description. + OutStreamer->emitFileDirective(FileName, VerStr, "", ""); + } else { + OutStreamer->emitFileDirective(FileName); + } } GCModuleInfo *MI = getAnalysisIfAvailable(); diff --git a/llvm/lib/MC/MCAsmInfoXCOFF.cpp b/llvm/lib/MC/MCAsmInfoXCOFF.cpp --- a/llvm/lib/MC/MCAsmInfoXCOFF.cpp +++ b/llvm/lib/MC/MCAsmInfoXCOFF.cpp @@ -22,6 +22,7 @@ IsLittleEndian = false; HasVisibilityOnlyWithLinkage = true; HasBasenameOnlyForFileDirective = false; + HasFourStringsDotFile = true; // For XCOFF, string constant consists of any number of characters enclosed in // "" (double quotation marks). diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp --- a/llvm/lib/MC/MCAsmStreamer.cpp +++ b/llvm/lib/MC/MCAsmStreamer.cpp @@ -253,6 +253,8 @@ SMLoc Loc) override; void emitFileDirective(StringRef Filename) override; + void emitFileDirective(StringRef Filename, StringRef CompilerVerion, + StringRef TimeStamp, StringRef Description) override; Expected tryEmitDwarfFileDirective(unsigned FileNo, StringRef Directory, StringRef Filename, @@ -1450,6 +1452,28 @@ EmitEOL(); } +void MCAsmStreamer::emitFileDirective(StringRef Filename, + StringRef CompilerVerion, + StringRef TimeStamp, + StringRef Description) { + assert(MAI->hasFourStringsDotFile()); + OS << "\t.file\t"; + PrintQuotedString(Filename, OS); + OS << ","; + if (!CompilerVerion.empty()) { + PrintQuotedString(CompilerVerion, OS); + } + if (!TimeStamp.empty()) { + OS << ","; + PrintQuotedString(TimeStamp, OS); + } + if (!Description.empty()) { + OS << ","; + PrintQuotedString(Description, OS); + } + EmitEOL(); +} + void MCAsmStreamer::printDwarfFileDirective( unsigned FileNo, StringRef Directory, StringRef Filename, Optional Checksum, Optional Source, diff --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp --- a/llvm/lib/MC/MCObjectStreamer.cpp +++ b/llvm/lib/MC/MCObjectStreamer.cpp @@ -848,6 +848,14 @@ getAssembler().addFileName(Filename); } +void MCObjectStreamer::emitFileDirective(StringRef Filename, + StringRef CompilerVerion, + StringRef TimeStamp, + StringRef Description) { + getAssembler().addFileName(Filename); + // TODO: add additional info to integrated assembler. +} + void MCObjectStreamer::emitAddrsig() { getAssembler().getWriter().emitAddrsigSection(); } diff --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp --- a/llvm/lib/MC/MCStreamer.cpp +++ b/llvm/lib/MC/MCStreamer.cpp @@ -1147,6 +1147,9 @@ llvm_unreachable("this directive only supported on COFF targets"); } void MCStreamer::emitFileDirective(StringRef Filename) {} +void MCStreamer::emitFileDirective(StringRef Filename, StringRef CompilerVerion, + StringRef TimeStamp, StringRef Description) { +} void MCStreamer::EmitCOFFSymbolStorageClass(int StorageClass) { llvm_unreachable("this directive only supported on COFF targets"); } diff --git a/llvm/test/CodeGen/PowerPC/aix-filename-absolute-path.ll b/llvm/test/CodeGen/PowerPC/aix-filename-absolute-path.ll --- a/llvm/test/CodeGen/PowerPC/aix-filename-absolute-path.ll +++ b/llvm/test/CodeGen/PowerPC/aix-filename-absolute-path.ll @@ -4,5 +4,6 @@ ; RUN: | FileCheck %s ; CHECK: .file "/absolute/path/to/file" +; CHECK-SAME: ,{{.*version}} source_filename = "/absolute/path/to/file" diff --git a/llvm/test/CodeGen/PowerPC/aix-filename-relative-path.ll b/llvm/test/CodeGen/PowerPC/aix-filename-relative-path.ll --- a/llvm/test/CodeGen/PowerPC/aix-filename-relative-path.ll +++ b/llvm/test/CodeGen/PowerPC/aix-filename-relative-path.ll @@ -4,5 +4,6 @@ ; RUN: | FileCheck %s ; CHECK: .file "../relative/path/to/file" +; CHECK-SAME: ,{{.*version}} source_filename = "../relative/path/to/file" diff --git a/llvm/test/CodeGen/PowerPC/aix-filename-special-character-double-quotation.ll b/llvm/test/CodeGen/PowerPC/aix-filename-special-character-double-quotation.ll --- a/llvm/test/CodeGen/PowerPC/aix-filename-special-character-double-quotation.ll +++ b/llvm/test/CodeGen/PowerPC/aix-filename-special-character-double-quotation.ll @@ -4,5 +4,6 @@ ; RUN: | FileCheck %s ; CHECK: .file "1""2.c" +; CHECK-SAME: ,{{.*version}} source_filename = "1\222.c" diff --git a/llvm/test/CodeGen/PowerPC/aix-filename-special-character-single-quotation.ll b/llvm/test/CodeGen/PowerPC/aix-filename-special-character-single-quotation.ll --- a/llvm/test/CodeGen/PowerPC/aix-filename-special-character-single-quotation.ll +++ b/llvm/test/CodeGen/PowerPC/aix-filename-special-character-single-quotation.ll @@ -4,5 +4,6 @@ ; RUN: | FileCheck %s ; CHECK: .file "1'2.c" +; CHECK-SAME: ,{{.*version}} source_filename = "1'2.c"