forked from swiftlang/swift
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathToolChain.cpp
149 lines (134 loc) · 5.35 KB
/
ToolChain.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
//===--- ToolChain.cpp - Collections of tools for one platform ------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
/// \file This file defines the base implementation of the ToolChain class.
/// The platform-specific subclasses are implemented in ToolChains.cpp.
/// For organizational purposes, the platform-independent logic for
/// constructing job invocations is also located in ToolChains.cpp.
//
//===----------------------------------------------------------------------===//
#include "swift/Driver/ToolChain.h"
#include "swift/Driver/Compilation.h"
#include "swift/Driver/Driver.h"
#include "swift/Driver/Job.h"
#include "llvm/Option/ArgList.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Program.h"
#include "llvm/ADT/STLExtras.h"
using namespace swift;
using namespace swift::driver;
using namespace llvm::opt;
ToolChain::JobContext::JobContext(Compilation &C,
ArrayRef<const Job *> Inputs,
ArrayRef<const Action *> InputActions,
const CommandOutput &Output,
const OutputInfo &OI)
: C(C), Inputs(Inputs), InputActions(InputActions), Output(Output),
OI(OI), Args(C.getArgs()) {}
ArrayRef<InputPair> ToolChain::JobContext::getTopLevelInputFiles() const {
return C.getInputFiles();
}
const char *ToolChain::JobContext::getAllSourcesPath() const {
return C.getAllSourcesPath();
}
const char *
ToolChain::JobContext::getTemporaryFilePath(const llvm::Twine &name,
StringRef suffix) const {
SmallString<128> buffer;
std::error_code EC =
llvm::sys::fs::createTemporaryFile(name, suffix, buffer);
if (EC) {
// FIXME: This should not take down the entire process.
llvm::report_fatal_error("unable to create temporary file for filelist");
}
C.addTemporaryFile(buffer.str());
// We can't just reference the data in the TemporaryFiles vector because
// that could theoretically get copied to a new address.
return C.getArgs().MakeArgString(buffer.str());
}
std::unique_ptr<Job>
ToolChain::constructJob(const JobAction &JA,
Compilation &C,
SmallVectorImpl<const Job *> &&inputs,
const ActionList &inputActions,
std::unique_ptr<CommandOutput> output,
const OutputInfo &OI) const {
JobContext context{C, inputs, inputActions, *output, OI};
auto invocationInfo = [&]() -> InvocationInfo {
switch (JA.getKind()) {
#define CASE(K) case Action::K: \
return constructInvocation(cast<K##Action>(JA), context);
CASE(CompileJob)
CASE(InterpretJob)
CASE(BackendJob)
CASE(MergeModuleJob)
CASE(ModuleWrapJob)
CASE(LinkJob)
CASE(GenerateDSYMJob)
CASE(AutolinkExtractJob)
CASE(REPLJob)
#undef CASE
case Action::Input:
llvm_unreachable("not a JobAction");
}
// Work around MSVC warning: not all control paths return a value
llvm_unreachable("All switch cases are covered");
}();
// Special-case the Swift frontend.
const char *executablePath = nullptr;
if (StringRef(SWIFT_EXECUTABLE_NAME) == invocationInfo.ExecutableName) {
executablePath = getDriver().getSwiftProgramPath().c_str();
} else {
std::string relativePath =
findProgramRelativeToSwift(invocationInfo.ExecutableName);
if (!relativePath.empty()) {
executablePath = C.getArgs().MakeArgString(relativePath);
} else {
auto systemPath =
llvm::sys::findProgramByName(invocationInfo.ExecutableName);
if (systemPath) {
executablePath = C.getArgs().MakeArgString(systemPath.get());
} else {
// For debugging purposes.
executablePath = invocationInfo.ExecutableName;
}
}
}
return llvm::make_unique<Job>(JA, std::move(inputs), std::move(output),
executablePath,
std::move(invocationInfo.Arguments),
std::move(invocationInfo.ExtraEnvironment),
std::move(invocationInfo.FilelistInfo));
}
std::string
ToolChain::findProgramRelativeToSwift(StringRef executableName) const {
auto insertionResult =
ProgramLookupCache.insert(std::make_pair(executableName, ""));
if (insertionResult.second) {
std::string path = findProgramRelativeToSwiftImpl(executableName);
insertionResult.first->setValue(std::move(path));
}
return insertionResult.first->getValue();
}
std::string
ToolChain::findProgramRelativeToSwiftImpl(StringRef executableName) const {
StringRef swiftPath = getDriver().getSwiftProgramPath();
StringRef swiftBinDir = llvm::sys::path::parent_path(swiftPath);
auto result = llvm::sys::findProgramByName(executableName, {swiftBinDir});
if (result)
return result.get();
return {};
}
types::ID ToolChain::lookupTypeForExtension(StringRef Ext) const {
return types::lookupTypeForExtension(Ext);
}