Skip to content

Commit de2ecbb

Browse files
committed
[Driver] Remove the notion of Tools, turn ToolChain into an Action visitor.
The "Tool" abstraction wasn't buying us enough to deserve the added complexity. Now a ToolChain turns Actions into Jobs, and every helper tool is searched for relative to Swift first. Much simpler. Swift SVN r31563
1 parent 4090107 commit de2ecbb

25 files changed

+1169
-1452
lines changed

include/swift/Driver/Job.h

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ namespace driver {
3333
class Action;
3434
class InputAction;
3535
class Job;
36-
class Tool;
3736

3837
class CommandOutput {
3938
types::ID PrimaryOutputType;
@@ -89,12 +88,9 @@ class Job {
8988
};
9089

9190
private:
92-
/// The action which caused the creation of this Job.
93-
const Action &Source;
94-
95-
/// The tool which created this Job, and the conditions under which it must
96-
/// be run.
97-
llvm::PointerIntPair<const Tool *, 2, Condition> CreatorAndCondition;
91+
/// The action which caused the creation of this Job, and the conditions
92+
/// under which it must be run.
93+
llvm::PointerIntPair<const Action *, 2, Condition> SourceAndCondition;
9894

9995
/// The list of other Jobs which are inputs to this Job.
10096
SmallVector<const Job *, 4> Inputs;
@@ -113,17 +109,16 @@ class Job {
113109
llvm::sys::TimeValue InputModTime = llvm::sys::TimeValue::MaxTime();
114110

115111
public:
116-
Job(const Action &Source, const Tool &Creator,
112+
Job(const Action &Source,
117113
SmallVectorImpl<const Job *> &&Inputs,
118114
std::unique_ptr<CommandOutput> Output,
119115
const char *Executable,
120116
llvm::opt::ArgStringList Arguments)
121-
: Source(Source), CreatorAndCondition(&Creator, Condition::Always),
117+
: SourceAndCondition(&Source, Condition::Always),
122118
Inputs(std::move(Inputs)), Output(std::move(Output)),
123119
Executable(Executable), Arguments(std::move(Arguments)) {}
124120

125-
const Action &getSource() const { return Source; }
126-
const Tool &getCreator() const { return *CreatorAndCondition.getPointer(); }
121+
const Action &getSource() const { return *SourceAndCondition.getPointer(); }
127122

128123
const char *getExecutable() const { return Executable; }
129124
const llvm::opt::ArgStringList &getArguments() const { return Arguments; }
@@ -132,10 +127,10 @@ class Job {
132127
const CommandOutput &getOutput() const { return *Output; }
133128

134129
Condition getCondition() const {
135-
return CreatorAndCondition.getInt();
130+
return SourceAndCondition.getInt();
136131
}
137132
void setCondition(Condition Cond) {
138-
CreatorAndCondition.setInt(Cond);
133+
SourceAndCondition.setInt(Cond);
139134
}
140135

141136
void setInputModTime(llvm::sys::TimeValue time) {

include/swift/Driver/Tool.h

Lines changed: 0 additions & 95 deletions
This file was deleted.

include/swift/Driver/ToolChain.h

Lines changed: 77 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -13,67 +13,109 @@
1313
#ifndef SWIFT_DRIVER_TOOLCHAIN_H
1414
#define SWIFT_DRIVER_TOOLCHAIN_H
1515

16-
#include "swift/Basic/LLVM.h"
1716
#include "swift/Driver/Action.h"
1817
#include "swift/Driver/Types.h"
19-
#include "llvm/Support/Program.h"
18+
#include "swift/Basic/LLVM.h"
19+
#include "llvm/Option/Option.h"
2020
#include "llvm/ADT/Triple.h"
2121

2222
#include <memory>
2323

24-
namespace llvm {
25-
namespace opt {
26-
class ArgList;
27-
class DerivedArgList;
28-
class InputArgList;
29-
}
30-
}
31-
3224
namespace swift {
3325
namespace driver {
26+
class CommandOutput;
3427
class Compilation;
3528
class Driver;
36-
class Tool;
37-
29+
class Job;
30+
class OutputInfo;
31+
32+
/// A ToolChain is responsible for turning abstract Actions into concrete,
33+
/// runnable Jobs.
34+
///
35+
/// The primary purpose of a ToolChain is built around the
36+
/// \c constructInvocation family of methods. This is a set of callbacks
37+
/// following the Visitor pattern for the various JobAction subclasses, which
38+
/// returns an executable name and arguments for the Job to be run. The base
39+
/// ToolChain knows how to perform most operations, but some (like linking)
40+
/// require platform-specific knowledge, provided in subclasses.
3841
class ToolChain {
3942
const Driver &D;
4043
const llvm::Triple Triple;
41-
42-
mutable std::unique_ptr<Tool> Swift;
43-
mutable std::unique_ptr<Tool> MergeModule;
44-
mutable std::unique_ptr<Tool> LLDB;
45-
mutable std::unique_ptr<Tool> Linker;
46-
mutable std::unique_ptr<Tool> Dsymutil;
47-
mutable std::unique_ptr<Tool> AutolinkExtract;
48-
49-
Tool *getSwift() const;
50-
Tool *getMergeModule() const;
51-
Tool *getLLDB() const;
52-
Tool *getLinker() const;
53-
Tool *getDsymutil() const;
54-
Tool *getAutolinkExtract() const;
44+
mutable llvm::StringMap<std::string> ProgramLookupCache;
5545

5646
protected:
5747
ToolChain(const Driver &D, const llvm::Triple &T) : D(D), Triple(T) {}
5848

59-
virtual std::unique_ptr<Tool> buildLinker() const = 0;
49+
/// A special name used to identify the Swift executable itself.
50+
constexpr static const char * const SWIFT_EXECUTABLE_NAME = "swift";
51+
52+
/// Packs together the supplementary information about the job being created.
53+
struct JobContext {
54+
ArrayRef<const Job *> Inputs;
55+
const CommandOutput &Output;
56+
ArrayRef<const Action *> InputActions;
57+
const llvm::opt::ArgList &Args;
58+
const OutputInfo &OI;
59+
};
60+
61+
virtual std::pair<const char *, llvm::opt::ArgStringList>
62+
constructInvocation(const CompileJobAction &job,
63+
const JobContext &context) const;
64+
virtual std::pair<const char *, llvm::opt::ArgStringList>
65+
constructInvocation(const BackendJobAction &job,
66+
const JobContext &context) const;
67+
virtual std::pair<const char *, llvm::opt::ArgStringList>
68+
constructInvocation(const MergeModuleJobAction &job,
69+
const JobContext &context) const;
70+
71+
virtual std::pair<const char *, llvm::opt::ArgStringList>
72+
constructInvocation(const REPLJobAction &job,
73+
const JobContext &context) const;
74+
75+
virtual std::pair<const char *, llvm::opt::ArgStringList>
76+
constructInvocation(const GenerateDSYMJobAction &job,
77+
const JobContext &context) const;
78+
virtual std::pair<const char *, llvm::opt::ArgStringList>
79+
constructInvocation(const AutolinkExtractJobAction &job,
80+
const JobContext &context) const;
81+
virtual std::pair<const char *, llvm::opt::ArgStringList>
82+
constructInvocation(const LinkJobAction &job,
83+
const JobContext &context) const;
84+
85+
/// Searches for the given executable in appropriate paths relative to the
86+
/// Swift binary.
87+
///
88+
/// This method caches its results.
89+
///
90+
/// \sa findProgramRelativeToSwiftImpl
91+
std::string findProgramRelativeToSwift(StringRef name) const;
92+
93+
/// An override point for platform-specific subclasses to customize how to
94+
/// do relative searches for programs.
95+
///
96+
/// This method is invoked by findProgramRelativeToSwift().
97+
virtual std::string findProgramRelativeToSwiftImpl(StringRef name) const;
6098

6199
public:
62100
virtual ~ToolChain() = default;
63101

64-
// Accessors
65-
66102
const Driver &getDriver() const { return D; }
67103
const llvm::Triple &getTriple() const { return Triple; }
68104

69-
/// Choose a tool to use to handle the action \p JA.
70-
virtual Tool *selectTool(const JobAction &JA) const;
105+
/// Construct a Job for the action \p JA, taking the given information into
106+
/// account.
107+
///
108+
/// This method dispatches to the various \c constructInvocation methods,
109+
/// which may be overridden by platform-specific subclasses.
110+
std::unique_ptr<Job> constructJob(const JobAction &JA,
111+
SmallVectorImpl<const Job *> &&inputs,
112+
std::unique_ptr<CommandOutput> output,
113+
const ActionList &inputActions,
114+
const llvm::opt::ArgList &args,
115+
const OutputInfo &OI) const;
71116

72117
/// Look up \p Name in the list of program search paths.
73-
virtual std::string getProgramPath(StringRef Name) const;
74-
75-
// Platform defaults information
76-
118+
///
77119
/// Return the default langauge type to use for the given extension.
78120
virtual types::ID lookupTypeForExtension(StringRef Ext) const;
79121
};

include/swift/Driver/Util.h

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,17 +30,6 @@ namespace driver {
3030
DynamicLibrary
3131
};
3232

33-
/// Searches for an executable relative to the compiler itself.
34-
///
35-
/// This first looks next to the compiler binary, then checks to see if the
36-
/// compiler is in an Xcode toolchain and looks in the bin directory outside
37-
/// the toolchain.
38-
///
39-
/// \returns The path to the executable being searched for, or an empty string
40-
/// if it cannot be found.
41-
std::string findRelativeExecutable(StringRef compilerPath,
42-
StringRef executableName);
43-
4433
} // end namespace driver
4534
} // end namespace swift
4635

include/swift/Option/Options.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ def driver_print_actions : Flag<["-"], "driver-print-actions">,
7272
def driver_print_output_file_map : Flag<["-"], "driver-print-output-file-map">,
7373
InternalDebugOpt, HelpText<"Dump the contents of the output file map">;
7474
def driver_print_bindings : Flag<["-"], "driver-print-bindings">,
75-
InternalDebugOpt, HelpText<"Dump list of bindings">;
75+
InternalDebugOpt, HelpText<"Dump list of job inputs and outputs">;
7676
def driver_print_jobs : Flag<["-"], "driver-print-jobs">, InternalDebugOpt,
7777
HelpText<"Dump list of jobs to execute">;
7878
def _HASH_HASH_HASH : Flag<["-"], "###">, Alias<driver_print_jobs>;

lib/Driver/CMakeLists.txt

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,9 @@ set(swiftDriver_sources
77
Job.cpp
88
OutputFileMap.cpp
99
ParseableOutput.cpp
10-
Tool.cpp
11-
Tools.cpp
1210
ToolChain.cpp
1311
ToolChains.cpp
1412
Types.cpp
15-
Util.cpp
1613
)
1714

1815
add_swift_library(swiftDriver

lib/Driver/Compilation.cpp

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
#include "swift/Driver/Driver.h"
2424
#include "swift/Driver/Job.h"
2525
#include "swift/Driver/ParseableOutput.h"
26-
#include "swift/Driver/Tool.h"
2726
#include "llvm/ADT/DenseSet.h"
2827
#include "llvm/ADT/StringExtras.h"
2928
#include "llvm/ADT/TinyPtrVector.h"
@@ -338,7 +337,7 @@ int Compilation::performJobsImpl() {
338337
}
339338
}
340339

341-
int Result = 0;
340+
int Result = EXIT_SUCCESS;
342341

343342
// Set up a callback which will be called immediately after a task has
344343
// started. This callback may be used to provide output indicating that the
@@ -374,21 +373,23 @@ int Compilation::performJobsImpl() {
374373
llvm::errs() << Output;
375374
}
376375

377-
if (ReturnCode != 0) {
376+
if (ReturnCode != EXIT_SUCCESS) {
378377
// The task failed, so return true without performing any further
379378
// dependency analysis.
380379

381380
// Store this task's ReturnCode as our Result if we haven't stored
382381
// anything yet.
383-
if (Result == 0)
382+
if (Result == EXIT_SUCCESS)
384383
Result = ReturnCode;
385384

386-
if (!FinishedCmd->getCreator().hasGoodDiagnostics() || ReturnCode != 1)
385+
if (!isa<CompileJobAction>(FinishedCmd->getSource()) ||
386+
ReturnCode != EXIT_FAILURE) {
387387
Diags.diagnose(SourceLoc(), diag::error_command_failed,
388-
FinishedCmd->getCreator().getNameForDiagnostics(),
388+
FinishedCmd->getSource().getClassName(),
389389
ReturnCode);
390+
}
390391

391-
return ContinueBuildingAfterErrors ?
392+
return ContinueBuildingAfterErrors ?
392393
TaskFinishedResponse::ContinueExecution :
393394
TaskFinishedResponse::StopExecution;
394395
}
@@ -455,7 +456,7 @@ int Compilation::performJobsImpl() {
455456
ErrorMsg);
456457

457458
Diags.diagnose(SourceLoc(), diag::error_command_signalled,
458-
SignalledCmd->getCreator().getNameForDiagnostics());
459+
SignalledCmd->getSource().getClassName());
459460

460461
// Since the task signalled, so unconditionally set result to -2.
461462
Result = -2;

0 commit comments

Comments
 (0)