From 69533b53f705542b8e1ed986a3dfd9a2eb97f15a Mon Sep 17 00:00:00 2001 From: Jordan Rose Date: Fri, 25 Jul 2014 01:31:40 +0000 Subject: [PATCH] [Driver] Invoke dsymutil after linking when invoked with -g. This matches Clang's behavior, though this implementation does not check that it's actually on a platform that uses dsymutil. Swift SVN r20529 --- include/swift/Driver/Action.h | 14 +++++++- include/swift/Driver/Driver.h | 6 ---- include/swift/Driver/Job.h | 2 ++ include/swift/Driver/Tool.h | 2 ++ include/swift/Driver/ToolChain.h | 7 ++++ lib/Driver/Action.cpp | 3 ++ lib/Driver/Driver.cpp | 36 +++++++++++--------- lib/Driver/ToolChain.cpp | 38 ++++++++++++++-------- lib/Driver/Tools.cpp | 28 ++++++++++++++-- lib/Driver/Tools.h | 14 +++++++- test/Driver/actions.swift | 4 +++ test/Driver/advanced_output_file_map.swift | 1 + test/Driver/linker.swift | 3 ++ test/Driver/temp-files.swift | 3 ++ 14 files changed, 123 insertions(+), 38 deletions(-) diff --git a/include/swift/Driver/Action.h b/include/swift/Driver/Action.h index f0b1ed1e391c2..726bc772f5ea3 100644 --- a/include/swift/Driver/Action.h +++ b/include/swift/Driver/Action.h @@ -40,9 +40,10 @@ class Action { MergeModuleJob, REPLJob, LinkJob, + GenerateDSYMJob, JobFirst=CompileJob, - JobLast=LinkJob + JobLast=GenerateDSYMJob }; static const char *getClassName(ActionClass AC); @@ -157,6 +158,17 @@ class MergeModuleJobAction : public JobAction { } }; +class GenerateDSYMJobAction : public JobAction { + virtual void anchor(); +public: + explicit GenerateDSYMJobAction(Action *Input) + : JobAction(Action::GenerateDSYMJob, Input, types::TY_dSYM) {} + + static bool classof(const Action *A) { + return A->getKind() == Action::GenerateDSYMJob; + } +}; + class LinkJobAction : public JobAction { virtual void anchor(); LinkKind Kind; diff --git a/include/swift/Driver/Driver.h b/include/swift/Driver/Driver.h index 0ea714b6e96b8..93b622059cb8d 100644 --- a/include/swift/Driver/Driver.h +++ b/include/swift/Driver/Driver.h @@ -263,12 +263,6 @@ class Driver { /// \param ShowHidden Show hidden options. void printHelp(bool ShowHidden) const; - /// Look up \p Name in the list of program search paths. - /// - /// \param TC The provided tool chain for additional information on - /// directories to search. - std::string getProgramPath(StringRef Name, const ToolChain &TC) const; - private: const ToolChain &getToolChain(const llvm::opt::ArgList &Args, StringRef DarwinArchName = "") const; diff --git a/include/swift/Driver/Job.h b/include/swift/Driver/Job.h index 821f684d8b1b1..eba4eb6dc0f9c 100644 --- a/include/swift/Driver/Job.h +++ b/include/swift/Driver/Job.h @@ -80,6 +80,8 @@ class JobList : public Job { const_iterator begin() const { return Jobs.begin(); } iterator end() { return Jobs.end(); } const_iterator end() const { return Jobs.end(); } + Job *front() const { return Jobs.front(); } + Job *back() const { return Jobs.back(); } static bool classof(const Job *J) { return J->getKind() == JobListClass; diff --git a/include/swift/Driver/Tool.h b/include/swift/Driver/Tool.h index 439b0ebffa16c..8df9fbe0294da 100644 --- a/include/swift/Driver/Tool.h +++ b/include/swift/Driver/Tool.h @@ -50,6 +50,8 @@ class Tool { public: Tool(StringRef Name, StringRef DiagName, const ToolChain &TC) : Name(Name), DiagName(DiagName), TheToolChain(TC) {} + Tool(StringRef Name, const ToolChain &TC) + : Tool(Name, Name, TC) {} virtual ~Tool() = default; diff --git a/include/swift/Driver/ToolChain.h b/include/swift/Driver/ToolChain.h index 74a3927185dd4..62012ce17d816 100644 --- a/include/swift/Driver/ToolChain.h +++ b/include/swift/Driver/ToolChain.h @@ -16,6 +16,7 @@ #include "swift/Basic/LLVM.h" #include "swift/Driver/Action.h" #include "swift/Driver/Types.h" +#include "llvm/Support/Program.h" #include "llvm/ADT/Triple.h" #include @@ -42,10 +43,13 @@ class ToolChain { mutable std::unique_ptr MergeModule; mutable std::unique_ptr LLDB; mutable std::unique_ptr Linker; + mutable std::unique_ptr Dsymutil; + Tool *getSwift() const; Tool *getMergeModule() const; Tool *getLLDB() const; Tool *getLinker() const; + Tool *getDsymutil() const; protected: ToolChain(const Driver &D, const llvm::Triple &T) : D(D), Triple(T) {} @@ -70,6 +74,9 @@ class ToolChain { /// Choose a tool to use to handle the action \p JA. virtual Tool *selectTool(const JobAction &JA) const; + /// Look up \p Name in the list of program search paths. + virtual std::string getProgramPath(StringRef Name) const; + // Platform defaults information /// Return the default langauge type to use for the given extension. diff --git a/lib/Driver/Action.cpp b/lib/Driver/Action.cpp index 895755ac06691..0bc2c376a67fd 100644 --- a/lib/Driver/Action.cpp +++ b/lib/Driver/Action.cpp @@ -31,6 +31,7 @@ const char *Action::getClassName(ActionClass AC) { case MergeModuleJob: return "merge-module"; case REPLJob: return "repl"; case LinkJob: return "link"; + case GenerateDSYMJob: return "generate-dSYM"; } llvm_unreachable("invalid class"); @@ -47,3 +48,5 @@ void MergeModuleJobAction::anchor() {} void REPLJobAction::anchor() {} void LinkJobAction::anchor() {} + +void GenerateDSYMJobAction::anchor() {} diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp index bc6d7b70ed46b..9824e347e1d03 100644 --- a/lib/Driver/Driver.cpp +++ b/lib/Driver/Driver.cpp @@ -46,7 +46,6 @@ #include "llvm/Support/Host.h" #include "llvm/Support/Path.h" #include "llvm/Support/PrettyStackTrace.h" -#include "llvm/Support/Program.h" #include "llvm/Support/raw_ostream.h" #include @@ -796,6 +795,11 @@ void Driver::buildActions(const ToolChain &TC, Actions.push_back(MergeModuleAction.release()); } Actions.push_back(LinkAction); + if (OI.ShouldGenerateDebugInfo) { + Action *dSYMAction = new GenerateDSYMJobAction(LinkAction); + dSYMAction->setOwnsInputs(false); + Actions.push_back(dSYMAction); + } } else if (MergeModuleAction) { Actions.push_back(MergeModuleAction.release()); } else { @@ -855,11 +859,13 @@ void Driver::buildJobs(const ActionList &Actions, const OutputInfo &OI, unsigned NumOutputs = 0; for (const Action *A : Actions) { types::ID Type = A->getType(); - if (Type != types::TY_Nothing && Type != types::TY_SwiftModuleFile) { + if (Type != types::TY_Nothing && Type != types::TY_SwiftModuleFile && + Type != types::TY_dSYM) { // Only increment NumOutputs if this is an output which must have its // path specified using -o. // (Module outputs can be specified using -module-output-path, or will - // be inferred if there are other top-level outputs.) + // be inferred if there are other top-level outputs. dSYM outputs are + // based on the image.) ++NumOutputs; } } @@ -915,6 +921,7 @@ static StringRef getOutputFilename(const JobAction *JA, const llvm::opt::DerivedArgList &Args, bool AtTopLevel, StringRef BaseInput, + const JobList &InputJobs, DiagnosticEngine &Diags, llvm::SmallString<128> &Buffer) { if (JA->getType() == types::TY_Nothing) @@ -954,6 +961,15 @@ static StringRef getOutputFilename(const JobAction *JA, } } + // dSYM actions are never treated as top-level. + if (isa(JA)) { + auto linkJob = cast(InputJobs.front()); + Buffer = linkJob->getOutput().getPrimaryOutputFilename(); + Buffer.push_back('.'); + Buffer.append(types::getTypeTempSuffix(JA->getType())); + return Buffer.str(); + } + // We don't have an output from an Action-specific command line option, // so figure one out using the defaults. if (AtTopLevel) { @@ -1149,7 +1165,8 @@ Job *Driver::buildJobsForAction(const Compilation &C, const Action *A, llvm::SmallString<128> Buf; StringRef OutputFile = getOutputFilename(JA, OI, OutputMap, C.getArgs(), - AtTopLevel, BaseInput, Diags, Buf); + AtTopLevel, BaseInput, *InputJobs, + Diags, Buf); std::unique_ptr Output(new CommandOutput(JA->getType(), OutputFile, BaseInput)); @@ -1409,17 +1426,6 @@ void Driver::printHelp(bool ShowHidden) const { IncludedFlagsBitmask, ExcludedFlagsBitmask); } -std::string Driver::getProgramPath(StringRef Name, const ToolChain &TC) const { - // TODO: perform ToolChain-specific lookup - - std::string P(llvm::sys::FindProgramByName(Name)); - if (!P.empty()) { - return P; - } - - return Name; -} - static void setTargetFromArch(DiagnosticEngine &diags, llvm::Triple &target, StringRef archName) { llvm::Triple::ArchType archValue diff --git a/lib/Driver/ToolChain.cpp b/lib/Driver/ToolChain.cpp index ea8a3b573fd83..f85a9a6a4334f 100644 --- a/lib/Driver/ToolChain.cpp +++ b/lib/Driver/ToolChain.cpp @@ -19,23 +19,23 @@ using namespace swift; using namespace swift::driver; using namespace llvm::opt; -Tool *ToolChain::getSwift() const { - if (!Swift) - Swift.reset(new tools::Swift(*this)); - return Swift.get(); +template +static Tool *cacheTool(const ToolChain &TC, + const std::unique_ptr &tool) { + if (!tool) + const_cast &>(tool).reset(new T(TC)); + return tool.get(); } -Tool *ToolChain::getMergeModule() const { - if (!MergeModule) - MergeModule.reset(new tools::MergeModule(*this)); - return MergeModule.get(); +#define CACHE_TOOL(X) \ +Tool *ToolChain::get##X() const { \ + return cacheTool(*this, X); \ } -Tool *ToolChain::getLLDB() const { - if (!LLDB) - LLDB.reset(new tools::LLDB(*this)); - return LLDB.get(); -} +CACHE_TOOL(Swift) +CACHE_TOOL(MergeModule) +CACHE_TOOL(LLDB) +CACHE_TOOL(Dsymutil) Tool *ToolChain::getLinker() const { if (!Linker) @@ -51,6 +51,8 @@ Tool *ToolChain::selectTool(const JobAction &JA) const { return getMergeModule(); case Action::LinkJob: return getLinker(); + case Action::GenerateDSYMJob: + return getDsymutil(); case Action::REPLJob: switch (cast(JA).getRequestedMode()) { case REPLJobAction::Mode::Integrated: @@ -69,6 +71,16 @@ Tool *ToolChain::selectTool(const JobAction &JA) const { llvm_unreachable("Invalid tool kind."); } +std::string ToolChain::getProgramPath(StringRef Name) const { + // TODO: perform ToolChain-specific lookup + + std::string P = llvm::sys::FindProgramByName(Name); + if (!P.empty()) + return P; + + return Name; +} + types::ID ToolChain::lookupTypeForExtension(StringRef Ext) const { return types::lookupTypeForExtension(Ext); } diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index ceb9355c44fda..2dd4e54acce70 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -498,13 +498,37 @@ Job *LLDB::constructJob(const JobAction &JA, Exec = Path.c_str(); } else { auto &TC = getToolChain(); - Exec = Args.MakeArgString(TC.getDriver().getProgramPath("lldb", TC)); + Exec = Args.MakeArgString(TC.getProgramPath("lldb")); } return new Command(JA, *this, std::move(Inputs), std::move(Output), Exec, Arguments); } +Job *Dsymutil::constructJob(const JobAction &JA, + std::unique_ptr Inputs, + std::unique_ptr Output, + const ActionList &InputActions, + const ArgList &Args, + const OutputInfo &OI) const { + assert(Inputs->size() == 1); + assert(InputActions.empty()); + assert(Output->getPrimaryOutputType() == types::TY_dSYM); + + ArgStringList Arguments; + + auto inputJob = cast(Inputs->front()); + StringRef inputPath = inputJob->getOutput().getPrimaryOutputFilename(); + Arguments.push_back(Args.MakeArgString(inputPath)); + + Arguments.push_back("-o"); + Arguments.push_back(Args.MakeArgString(Output->getPrimaryOutputFilename())); + + std::string Exec = getToolChain().getProgramPath("dsymutil"); + return new Command(JA, *this, std::move(Inputs), std::move(Output), + Args.MakeArgString(Exec), Arguments); +} + /// Darwin Tools llvm::Triple::ArchType darwin::getArchTypeForDarwinArchName(StringRef Arch) { @@ -664,7 +688,7 @@ Job *darwin::Linker::constructJob(const JobAction &JA, Arguments.push_back("-o"); Arguments.push_back(Output->getPrimaryOutputFilename().c_str()); - std::string Exec = D.getProgramPath("ld", getToolChain()); + std::string Exec = getToolChain().getProgramPath("ld"); return new Command(JA, *this, std::move(Inputs), std::move(Output), Args.MakeArgString(Exec), Arguments); diff --git a/lib/Driver/Tools.h b/lib/Driver/Tools.h index 2afb0f9a0fa4a..5852656604dc9 100644 --- a/lib/Driver/Tools.h +++ b/lib/Driver/Tools.h @@ -45,7 +45,7 @@ class LLVM_LIBRARY_VISIBILITY Swift : public Tool { class LLVM_LIBRARY_VISIBILITY MergeModule : public Tool { public: explicit MergeModule(const ToolChain &TC) - : Tool("merge-module", "merge-module", TC) {} + : Tool("merge-module", TC) {} virtual bool hasGoodDiagnostics() const { return true; } @@ -75,6 +75,18 @@ class LLVM_LIBRARY_VISIBILITY LLDB : public Tool { const OutputInfo &OI) const; }; +class LLVM_LIBRARY_VISIBILITY Dsymutil : public Tool { +public: + explicit Dsymutil(const ToolChain &TC) : Tool("dsymutil", TC) {} + + virtual Job *constructJob(const JobAction &JA, + std::unique_ptr Inputs, + std::unique_ptr Output, + const ActionList &InputActions, + const llvm::opt::ArgList &Args, + const OutputInfo &OI) const; +}; + namespace darwin { diff --git a/test/Driver/actions.swift b/test/Driver/actions.swift index b56f79892688b..3edbedc5cfffe 100644 --- a/test/Driver/actions.swift +++ b/test/Driver/actions.swift @@ -38,6 +38,7 @@ // DEBUG: 1: compile, {0}, object // DEBUG: 2: merge-module, {1}, swiftmodule // DEBUG: 3: link, {1, 2}, image +// DEBUG: 4: generate-dSYM, {3}, dSYM // RUN: %swiftc_driver -driver-print-actions -g -c %s 2>&1 | FileCheck %s -check-prefix=DEBUG-OBJECT // DEBUG-OBJECT: 0: input, "{{.*}}actions.swift", swift @@ -49,6 +50,7 @@ // DEBUG-MODULE: 1: compile, {0}, object // DEBUG-MODULE: 2: merge-module, {1}, swiftmodule // DEBUG-MODULE: 3: link, {1, 2}, image +// DEBUG-MODULE: 4: generate-dSYM, {3}, dSYM // RUN: %swiftc_driver -driver-print-actions %S/Inputs/main.swift %S/../Inputs/empty.swift %s -module-name actions 2>&1 | FileCheck %s -check-prefix=MULTI // MULTI: 0: input, "{{.*}}Inputs/main.swift", swift @@ -68,6 +70,7 @@ // DEBUG-MULTI: 5: compile, {4}, object // DEBUG-MULTI: 6: merge-module, {1, 3, 5}, swiftmodule // DEBUG-MULTI: 7: link, {1, 3, 5, 6}, image +// DEBUG-MULTI: 8: generate-dSYM, {7}, dSYM // RUN: touch %t/a.o %t/b.o @@ -84,3 +87,4 @@ // DEBUG-LINK-ONLY: 3: input, "{{.*}}/b.swiftmodule", swiftmodule // DEBUG-LINK-ONLY: 4: merge-module, {0, 1, 2, 3}, swiftmodule // DEBUG-LINK-ONLY: 5: link, {0, 1, 2, 3, 4}, image +// DEBUG-LINK-ONLY: 6: generate-dSYM, {5}, dSYM diff --git a/test/Driver/advanced_output_file_map.swift b/test/Driver/advanced_output_file_map.swift index 2476754610384..f28d0d6b2fb72 100644 --- a/test/Driver/advanced_output_file_map.swift +++ b/test/Driver/advanced_output_file_map.swift @@ -24,3 +24,4 @@ // BINDINGS: # "x86_64-apple-macosx10.9" - "swift", inputs: ["{{.*}}/Inputs/lib.swift"], output: {object: "/build/obj/lib.o", dependencies: "/build/d/lib.d", swiftmodule: "/build/swiftmodule/lib.swiftmodule", swiftdoc: "/build/swiftmodule/lib_x.swiftdoc", diagnostics: "/build/dia/lib.dia"} // BINDINGS: # "x86_64-apple-macosx10.9" - "merge-module", inputs: ["/build/obj/advanced_output_file_map.o", "/build/obj/main.o", "/build/obj/lib.o"], output: {swiftmodule: "/build/OutputFileMap.swiftmodule", swiftdoc: "/build/OutputFileMap.swiftdoc"} // BINDINGS: # "x86_64-apple-macosx10.9" - "darwin::Linker", inputs: ["/build/obj/advanced_output_file_map.o", "/build/obj/main.o", "/build/obj/lib.o", "/build/OutputFileMap.swiftmodule"], output: {image: "/build/advanced_output_file_map.out"} +// BINDINGS: # "x86_64-apple-macosx10.9" - "dsymutil", inputs: ["/build/advanced_output_file_map.out"], output: {dSYM: "/build/advanced_output_file_map.out.dSYM"} diff --git a/test/Driver/linker.swift b/test/Driver/linker.swift index ef09bd6c3f282..2ffb69050de0e 100644 --- a/test/Driver/linker.swift +++ b/test/Driver/linker.swift @@ -46,3 +46,6 @@ // DEBUG-NEXT: bin/ld{{ }} // DEBUG: -add_ast_path {{.*}}/{{[^/]+}}.swiftmodule // DEBUG: -o linker +// DEBUG-NEXT: bin/dsymutil +// DEBUG: linker +// DEBUG: -o linker.dSYM diff --git a/test/Driver/temp-files.swift b/test/Driver/temp-files.swift index 4c9c272f04278..e265605317d43 100644 --- a/test/Driver/temp-files.swift +++ b/test/Driver/temp-files.swift @@ -27,6 +27,7 @@ // RUN: env TMPDIR=%t/tmp/ %swiftc_driver -emit-executable %s -o %t/main4 -emit-module-path %t/main4.swiftmodule -g // RUN: ls %t/main4 // RUN: ls %t/main4.swiftmodule +// RUN: ls %t/main4.dSYM // RUN: ls %t/tmp | FileCheck -check-prefix=OBJECT-ONLY %s // RUN: rm -rf %t && mkdir -p %t/tmp/ && touch %t/tmp/dummy @@ -34,11 +35,13 @@ // RUN: env TMPDIR=%t/tmp/ %swiftc_driver -emit-executable %s -o %t/main5 -output-file-map %t.json -g // RUN: ls %t/main5 // RUN: ls %t/main5.o +// RUN: ls %t/main5.dSYM // RUN: ls %t/tmp | FileCheck -check-prefix=EMPTY %s // RUN: rm -rf %t && mkdir -p %t/tmp/ && touch %t/tmp/dummy // RUN: env TMPDIR=%t/tmp/ %swiftc_driver -emit-executable %s -o %t/main6 -g -save-temps // RUN: ls %t/main6 +// RUN: ls %t/main6.dSYM // RUN: ls %t/tmp | FileCheck -check-prefix=SAVE-TEMPS %s // SAVE-TEMPS-DAG: temp-files-{{.+}}.o