diff --git a/driver/cl_options.cpp b/driver/cl_options.cpp index d230bc0f12..58d38536a0 100644 --- a/driver/cl_options.cpp +++ b/driver/cl_options.cpp @@ -223,6 +223,32 @@ cl::opt emitDwarfDebugInfo( "gdwarf", cl::ZeroOrMore, cl::desc("Emit DWARF debuginfo (instead of CodeView) for MSVC targets")); +// Prefix map for filenames in DWARF debuginfo +std::map debugPrefixMap; + +struct DwarfPrefixParser : public cl::parser { + explicit DwarfPrefixParser(cl::Option &O) : cl::parser(O) {} + + bool parse(cl::Option &O, llvm::StringRef /*ArgName*/, llvm::StringRef Arg, + std::string & /*Val*/) { + auto [from, to] = Arg.split('='); + if (from.empty() || to.empty()) { + return O.error("invalid debug prefix map: " + Arg); + } + auto fromStr = std::string(from); + if (debugPrefixMap.find(fromStr) != debugPrefixMap.end()) { + return O.error("debug prefix map already contains: " + fromStr); + } + debugPrefixMap[fromStr] = std::string(to); + return false; + } +}; + +static cl::opt fdebugPrefixMap( + "fdebug-prefix-map", cl::ZeroOrMore, + cl::desc("Prefix map for filenames in DWARF debuginfo"), + cl::value_desc("=")); + cl::opt noAsm("noasm", cl::desc("Disallow use of inline assembler"), cl::ZeroOrMore); diff --git a/driver/cl_options.h b/driver/cl_options.h index 01596ccc8e..8d1d6208ff 100644 --- a/driver/cl_options.h +++ b/driver/cl_options.h @@ -20,6 +20,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/Support/CodeGen.h" #include "llvm/Support/CommandLine.h" +#include #include #include @@ -149,4 +150,6 @@ extern cl::opt dynamicCompileTlsWorkaround; #else constexpr bool enableDynamicCompile = false; #endif +// Prefix map for filenames in DWARF debuginfo +extern std::map debugPrefixMap; } diff --git a/gen/dibuilder.cpp b/gen/dibuilder.cpp index 3b5c7470f2..1872e914b5 100644 --- a/gen/dibuilder.cpp +++ b/gen/dibuilder.cpp @@ -218,6 +218,15 @@ void DIBuilder::SetValue(Loc loc, llvm::Value *value, IR->scopebb()); } +std::string DIBuilder::remapDIPath(llvm::StringRef path) { + for (const auto &[from, to] : opts::debugPrefixMap) { + if (path.starts_with(from)) { + return to + path.substr(from.size()).str(); + } + } + return std::string(path); +} + DIFile DIBuilder::CreateFile(const char *filename) { if (!filename) filename = IR->dmodule->srcfile.toChars(); @@ -231,14 +240,14 @@ DIFile DIBuilder::CreateFile(const char *filename) { // ...) if (llvm::sys::path::is_absolute(filename)) { - return DBuilder.createFile(llvm::sys::path::relative_path(filename), - llvm::sys::path::root_path(filename)); + return DBuilder.createFile(remapDIPath(llvm::sys::path::relative_path(filename)), + remapDIPath(llvm::sys::path::root_path(filename))); } llvm::SmallString<128> cwd; llvm::sys::fs::current_path(cwd); - return DBuilder.createFile(filename, cwd); + return DBuilder.createFile(remapDIPath(filename), remapDIPath(cwd)); } DIFile DIBuilder::CreateFile(Loc loc) { diff --git a/gen/dibuilder.h b/gen/dibuilder.h index 01ee7d0477..2d506e38db 100644 --- a/gen/dibuilder.h +++ b/gen/dibuilder.h @@ -163,6 +163,7 @@ class DIBuilder { llvm::SmallVector &elems); void AddStaticMembers(AggregateDeclaration *sd, ldc::DIFile file, llvm::SmallVector &elems); + std::string remapDIPath(llvm::StringRef path); DIFile CreateFile(const char *filename = nullptr); DIFile CreateFile(Loc loc); DIFile CreateFile(Dsymbol *decl);