Skip to content

Commit

Permalink
[Driver] Invoke dsymutil after linking when invoked with -g.
Browse files Browse the repository at this point in the history
This matches Clang's behavior, though this implementation does not check
that it's actually on a platform that uses dsymutil.

<rdar://problem/16012971>

Swift SVN r20529
  • Loading branch information
jrose-apple committed Jul 25, 2014
1 parent 706934b commit 69533b5
Show file tree
Hide file tree
Showing 14 changed files with 123 additions and 38 deletions.
14 changes: 13 additions & 1 deletion include/swift/Driver/Action.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,10 @@ class Action {
MergeModuleJob,
REPLJob,
LinkJob,
GenerateDSYMJob,

JobFirst=CompileJob,
JobLast=LinkJob
JobLast=GenerateDSYMJob
};

static const char *getClassName(ActionClass AC);
Expand Down Expand Up @@ -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;
Expand Down
6 changes: 0 additions & 6 deletions include/swift/Driver/Driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions include/swift/Driver/Job.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions include/swift/Driver/Tool.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
7 changes: 7 additions & 0 deletions include/swift/Driver/ToolChain.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 <memory>
Expand All @@ -42,10 +43,13 @@ class ToolChain {
mutable std::unique_ptr<Tool> MergeModule;
mutable std::unique_ptr<Tool> LLDB;
mutable std::unique_ptr<Tool> Linker;
mutable std::unique_ptr<Tool> 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) {}
Expand All @@ -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.
Expand Down
3 changes: 3 additions & 0 deletions lib/Driver/Action.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand All @@ -47,3 +48,5 @@ void MergeModuleJobAction::anchor() {}
void REPLJobAction::anchor() {}

void LinkJobAction::anchor() {}

void GenerateDSYMJobAction::anchor() {}
36 changes: 21 additions & 15 deletions lib/Driver/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 <memory>
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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;
}
}
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -954,6 +961,15 @@ static StringRef getOutputFilename(const JobAction *JA,
}
}

// dSYM actions are never treated as top-level.
if (isa<GenerateDSYMJobAction>(JA)) {
auto linkJob = cast<Command>(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) {
Expand Down Expand Up @@ -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<CommandOutput> Output(new CommandOutput(JA->getType(),
OutputFile,
BaseInput));
Expand Down Expand Up @@ -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
Expand Down
38 changes: 25 additions & 13 deletions lib/Driver/ToolChain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 <typename T>
static Tool *cacheTool(const ToolChain &TC,
const std::unique_ptr<Tool> &tool) {
if (!tool)
const_cast<std::unique_ptr<Tool> &>(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<tools::X>(*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)
Expand All @@ -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<REPLJobAction>(JA).getRequestedMode()) {
case REPLJobAction::Mode::Integrated:
Expand All @@ -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);
}
28 changes: 26 additions & 2 deletions lib/Driver/Tools.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<JobList> Inputs,
std::unique_ptr<CommandOutput> 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<Command>(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) {
Expand Down Expand Up @@ -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);
Expand Down
14 changes: 13 additions & 1 deletion lib/Driver/Tools.h
Original file line number Diff line number Diff line change
Expand Up @@ -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; }

Expand Down Expand Up @@ -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<JobList> Inputs,
std::unique_ptr<CommandOutput> Output,
const ActionList &InputActions,
const llvm::opt::ArgList &Args,
const OutputInfo &OI) const;
};


namespace darwin {

Expand Down
4 changes: 4 additions & 0 deletions test/Driver/actions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
1 change: 1 addition & 0 deletions test/Driver/advanced_output_file_map.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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"}
3 changes: 3 additions & 0 deletions test/Driver/linker.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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
3 changes: 3 additions & 0 deletions test/Driver/temp-files.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,21 @@
// 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
// RUN: echo "{\"%s\": {\"object\": \"%t/main5.o\"}}" > %t.json
// 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
Expand Down

0 comments on commit 69533b5

Please sign in to comment.