diff --git a/clang/lib/Driver/ToolChains/MSVC.cpp b/clang/lib/Driver/ToolChains/MSVC.cpp --- a/clang/lib/Driver/ToolChains/MSVC.cpp +++ b/clang/lib/Driver/ToolChains/MSVC.cpp @@ -269,6 +269,26 @@ AddRunTimeLibs(TC, TC.getDriver(), CmdArgs, Args); } + StringRef Linker = + Args.getLastArgValue(options::OPT_fuse_ld_EQ, CLANG_DEFAULT_LINKER); + if (Linker.empty()) + Linker = "link"; + // We need to translate 'lld' into 'lld-link'. + else if (Linker.equals_insensitive("lld")) + Linker = "lld-link"; + + if (Linker == "lld-link") { + for (Arg *A : Args.filtered(options::OPT_vfsoverlay)) + CmdArgs.push_back( + Args.MakeArgString(std::string("/vfsoverlay:") + A->getValue())); + + if (C.getDriver().isUsingLTO() && + Args.hasFlag(options::OPT_gsplit_dwarf, options::OPT_gno_split_dwarf, + false)) + CmdArgs.push_back(Args.MakeArgString(Twine("/dwodir:") + + Output.getFilename() + "_dwo")); + } + // Add filenames, libraries, and other linker inputs. for (const auto &Input : Inputs) { if (Input.isFilename()) { @@ -301,22 +321,9 @@ std::vector Environment; - // We need to special case some linker paths. In the case of lld, we need to - // translate 'lld' into 'lld-link', and in the case of the regular msvc + // We need to special case some linker paths. in the case of the regular msvc // linker, we need to use a special search algorithm. llvm::SmallString<128> linkPath; - StringRef Linker - = Args.getLastArgValue(options::OPT_fuse_ld_EQ, CLANG_DEFAULT_LINKER); - if (Linker.empty()) - Linker = "link"; - if (Linker.equals_insensitive("lld")) - Linker = "lld-link"; - - if (Linker == "lld-link") - for (Arg *A : Args.filtered(options::OPT_vfsoverlay)) - CmdArgs.push_back( - Args.MakeArgString(std::string("/vfsoverlay:") + A->getValue())); - if (Linker.equals_insensitive("link")) { // If we're using the MSVC linker, it's not sufficient to just use link // from the program PATH, because other environments like GnuWin32 install diff --git a/clang/test/Driver/lto-dwo.c b/clang/test/Driver/lto-dwo.c --- a/clang/test/Driver/lto-dwo.c +++ b/clang/test/Driver/lto-dwo.c @@ -1,6 +1,9 @@ // Confirm that -gsplit-dwarf=DIR is passed to linker // RUN: %clang --target=x86_64-unknown-linux -### %s -flto=thin -gsplit-dwarf -o a.out 2> %t -// RUN: FileCheck -check-prefix=CHECK-LINK-DWO-DIR-DEFAULT < %t %s +// RUN: FileCheck -check-prefix=CHECK-LINK-ELF-DWO-DIR-DEFAULT < %t %s +// RUN: %clang_cl --target=x86_64-unknown-windows-msvc -### -fuse-ld=lld -flto -gsplit-dwarf -o a.out -- %s 2> %t +// RUN: FileCheck -check-prefix=CHECK-LINK-COFF-DWO-DIR-DEFAULT < %t %s // -// CHECK-LINK-DWO-DIR-DEFAULT: "-plugin-opt=dwo_dir=a.out_dwo" +// CHECK-LINK-ELF-DWO-DIR-DEFAULT: "-plugin-opt=dwo_dir=a.out_dwo" +// CHECK-LINK-COFF-DWO-DIR-DEFAULT: "/dwodir:a.out_dwo" diff --git a/lld/COFF/Config.h b/lld/COFF/Config.h --- a/lld/COFF/Config.h +++ b/lld/COFF/Config.h @@ -203,6 +203,9 @@ StringRef manifestUIAccess = "'false'"; StringRef manifestFile; + // used for /dwodir + StringRef dwoDir; + // Used for /aligncomm. std::map alignComm; diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp --- a/lld/COFF/Driver.cpp +++ b/lld/COFF/Driver.cpp @@ -1910,6 +1910,9 @@ fatal("/manifestinput: requires /manifest:embed"); } + // Handle /dwodir + config->dwoDir = args.getLastArgValue(OPT_dwodir); + config->thinLTOEmitImportsFiles = args.hasArg(OPT_thinlto_emit_imports_files); config->thinLTOIndexOnly = args.hasArg(OPT_thinlto_index_only) || args.hasArg(OPT_thinlto_index_only_arg); diff --git a/lld/COFF/LTO.cpp b/lld/COFF/LTO.cpp --- a/lld/COFF/LTO.cpp +++ b/lld/COFF/LTO.cpp @@ -84,6 +84,7 @@ c.DisableVerify = true; #endif c.DiagHandler = diagnosticHandler; + c.DwoDir = ctx.config.dwoDir.str(); c.OptLevel = ctx.config.ltoo; c.CPU = getCPUStr(); c.MAttrs = getMAttrs(); diff --git a/lld/COFF/Options.td b/lld/COFF/Options.td --- a/lld/COFF/Options.td +++ b/lld/COFF/Options.td @@ -42,6 +42,8 @@ def defaultlib : P<"defaultlib", "Add the library to the list of input files">; def delayload : P<"delayload", "Delay loaded DLL name">; def diasdkdir : P<"diasdkdir", "Set the location of the DIA SDK">; +def dwodir : P<"dwodir", + "Directory to store .dwo files when LTO and debug fission are used">; def entry : P<"entry", "Name of entry point symbol">; def errorlimit : P<"errorlimit", "Maximum number of errors to emit before stopping (0 = no limit)">; diff --git a/lld/test/COFF/lto-debug-fission.ll b/lld/test/COFF/lto-debug-fission.ll new file mode 100644 --- /dev/null +++ b/lld/test/COFF/lto-debug-fission.ll @@ -0,0 +1,18 @@ +; REQUIRES: x86 + +; RUN: opt %s -o %t1.o +; RUN: rm -rf %t.dir + +; Test to ensure that -dwodir:$DIR creates .dwo files under $DIR +; RUN: lld-link -dwodir:%t.dir -noentry -dll %t1.o -out:%t.dll +; RUN: llvm-readobj -h %t.dir/0.dwo | FileCheck %s + +; CHECK: Format: COFF-x86-64 + +target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-windows-msvc" + +define void @f() { +entry: + ret void +}