From cb4efa0839a421e0573b3ccb586bef6f62f37dbe Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Thu, 23 Oct 2025 16:56:59 -0700 Subject: [PATCH] Add a -debug-module-path frontend option This new option allows the Driver to pass the path to a compilation job's own binary swiftmodule artifact to the frontend. The compiler then stores this path in the debug info, to allow clients like LLDB to unambiguously know which binary Swift module belongs to which compile unit. rdar://163302154 --- include/swift/AST/IRGenOptions.h | 3 +++ include/swift/Option/Options.td | 6 ++++++ lib/Frontend/CompilerInvocation.cpp | 3 +++ lib/IRGen/IRGenDebugInfo.cpp | 10 +++++++--- test/DebugInfo/ebm_module_path.swift | 4 ++++ 5 files changed, 23 insertions(+), 3 deletions(-) create mode 100644 test/DebugInfo/ebm_module_path.swift diff --git a/include/swift/AST/IRGenOptions.h b/include/swift/AST/IRGenOptions.h index e31ac132a0d..226eded7f12 100644 --- a/include/swift/AST/IRGenOptions.h +++ b/include/swift/AST/IRGenOptions.h @@ -270,6 +270,9 @@ class IRGenOptions { public: std::string ModuleName; + /// The path to the main binary swiftmodule for the debug info. + std::string DebugModulePath; + /// The compilation directory for the debug info. std::string DebugCompilationDir; diff --git a/include/swift/Option/Options.td b/include/swift/Option/Options.td index 85a11d114d0..f3cd8bd24ae 100644 --- a/include/swift/Option/Options.td +++ b/include/swift/Option/Options.td @@ -643,6 +643,12 @@ def project_name : Separate<["-"], "project-name">, def module_name_EQ : Joined<["-"], "module-name=">, Flags<[FrontendOption]>, Alias; +def debug_module_path : Separate<["-"], "debug-module-path">, + Flags<[FrontendOption]>, + HelpText<"Path to this module's binary swiftmodule artifact (required by debug info)">; +def debug_module_path_EQ : Joined<["-"], "debug-module-path=">, Flags<[FrontendOption]>, + Alias; + def module_alias : Separate<["-"], "module-alias">, Flags<[FrontendOption, ModuleInterfaceOption]>, MetaVarName<"">, diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 98134b74aeb..ad52fc68a6c 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -3460,6 +3460,9 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args, A->getAsString(Args), A->getValue()); } + if (const Arg *A = Args.getLastArg(options::OPT_debug_module_path)) + Opts.DebugModulePath = A->getValue(); + for (auto A : Args.getAllArgValues(options::OPT_file_prefix_map)) { auto SplitMap = StringRef(A).split('='); Opts.FilePrefixMap.addMapping(SplitMap.first, SplitMap.second); diff --git a/lib/IRGen/IRGenDebugInfo.cpp b/lib/IRGen/IRGenDebugInfo.cpp index aa48bdea6b9..c6e649f0cac 100644 --- a/lib/IRGen/IRGenDebugInfo.cpp +++ b/lib/IRGen/IRGenDebugInfo.cpp @@ -864,7 +864,7 @@ private: llvm::DIModule *getOrCreateModule(const void *Key, llvm::DIScope *Parent, StringRef Name, StringRef IncludePath, uint64_t Signature = ~1ULL, - StringRef ASTFile = StringRef()) { + StringRef ASTFile = {}) { // Look in the cache first. auto Val = DIModuleCache.find(Key); if (Val != DIModuleCache.end()) @@ -2823,8 +2823,12 @@ IRGenDebugInfoImpl::IRGenDebugInfoImpl(const IRGenOptions &Opts, // Create a module for the current compile unit. auto *MDecl = IGM.getSwiftModule(); - llvm::sys::path::remove_filename(SourcePath); - MainModule = getOrCreateModule(MDecl, TheCU, Opts.ModuleName, SourcePath); + StringRef Path = Opts.DebugModulePath; + if (Path.empty()) { + llvm::sys::path::remove_filename(SourcePath); + Path = SourcePath; + } + MainModule = getOrCreateModule(MDecl, TheCU, Opts.ModuleName, Path); DBuilder.createImportedModule(MainFile, MainModule, MainFile, 0); // Macro definitions that were defined by the user with "-Xcc -D" on the diff --git a/test/DebugInfo/ebm_module_path.swift b/test/DebugInfo/ebm_module_path.swift new file mode 100644 index 00000000000..a48a85017b1 --- /dev/null +++ b/test/DebugInfo/ebm_module_path.swift @@ -0,0 +1,4 @@ +// RUN: %target-swift-frontend -primary-file %s -emit-ir -g -module-name=A -debug-module-path %t/MY_MODULE_PATH.swiftmodule -emit-ir -o - | %FileCheck %s + +// CHECK: DIModule(scope: null, name: "A", includePath: "{{.*}}MY_MODULE_PATH.swiftmodule") +