1*67e74705SXin Li //===-- driver.cpp - Clang GCC-Compatible Driver --------------------------===//
2*67e74705SXin Li //
3*67e74705SXin Li // The LLVM Compiler Infrastructure
4*67e74705SXin Li //
5*67e74705SXin Li // This file is distributed under the University of Illinois Open Source
6*67e74705SXin Li // License. See LICENSE.TXT for details.
7*67e74705SXin Li //
8*67e74705SXin Li //===----------------------------------------------------------------------===//
9*67e74705SXin Li //
10*67e74705SXin Li // This is the entry point to the clang driver; it is a thin wrapper
11*67e74705SXin Li // for functionality in the Driver clang library.
12*67e74705SXin Li //
13*67e74705SXin Li //===----------------------------------------------------------------------===//
14*67e74705SXin Li
15*67e74705SXin Li #include "clang/Basic/CharInfo.h"
16*67e74705SXin Li #include "clang/Basic/DiagnosticOptions.h"
17*67e74705SXin Li #include "clang/Driver/Compilation.h"
18*67e74705SXin Li #include "clang/Driver/Driver.h"
19*67e74705SXin Li #include "clang/Driver/DriverDiagnostic.h"
20*67e74705SXin Li #include "clang/Driver/Options.h"
21*67e74705SXin Li #include "clang/Driver/ToolChain.h"
22*67e74705SXin Li #include "clang/Frontend/ChainedDiagnosticConsumer.h"
23*67e74705SXin Li #include "clang/Frontend/CompilerInvocation.h"
24*67e74705SXin Li #include "clang/Frontend/SerializedDiagnosticPrinter.h"
25*67e74705SXin Li #include "clang/Frontend/TextDiagnosticPrinter.h"
26*67e74705SXin Li #include "clang/Frontend/Utils.h"
27*67e74705SXin Li #include "llvm/ADT/ArrayRef.h"
28*67e74705SXin Li #include "llvm/ADT/STLExtras.h"
29*67e74705SXin Li #include "llvm/ADT/SmallString.h"
30*67e74705SXin Li #include "llvm/ADT/SmallVector.h"
31*67e74705SXin Li #include "llvm/Config/llvm-config.h"
32*67e74705SXin Li #include "llvm/Option/ArgList.h"
33*67e74705SXin Li #include "llvm/Option/OptTable.h"
34*67e74705SXin Li #include "llvm/Option/Option.h"
35*67e74705SXin Li #include "llvm/Support/CommandLine.h"
36*67e74705SXin Li #include "llvm/Support/ErrorHandling.h"
37*67e74705SXin Li #include "llvm/Support/FileSystem.h"
38*67e74705SXin Li #include "llvm/Support/Host.h"
39*67e74705SXin Li #include "llvm/Support/ManagedStatic.h"
40*67e74705SXin Li #include "llvm/Support/MemoryBuffer.h"
41*67e74705SXin Li #include "llvm/Support/Path.h"
42*67e74705SXin Li #include "llvm/Support/PrettyStackTrace.h"
43*67e74705SXin Li #include "llvm/Support/Process.h"
44*67e74705SXin Li #include "llvm/Support/Program.h"
45*67e74705SXin Li #include "llvm/Support/Regex.h"
46*67e74705SXin Li #include "llvm/Support/Signals.h"
47*67e74705SXin Li #include "llvm/Support/StringSaver.h"
48*67e74705SXin Li #include "llvm/Support/TargetSelect.h"
49*67e74705SXin Li #include "llvm/Support/Timer.h"
50*67e74705SXin Li #include "llvm/Support/raw_ostream.h"
51*67e74705SXin Li #include <memory>
52*67e74705SXin Li #include <system_error>
53*67e74705SXin Li using namespace clang;
54*67e74705SXin Li using namespace clang::driver;
55*67e74705SXin Li using namespace llvm::opt;
56*67e74705SXin Li
GetExecutablePath(const char * Argv0,bool CanonicalPrefixes)57*67e74705SXin Li std::string GetExecutablePath(const char *Argv0, bool CanonicalPrefixes) {
58*67e74705SXin Li if (!CanonicalPrefixes)
59*67e74705SXin Li return Argv0;
60*67e74705SXin Li
61*67e74705SXin Li // This just needs to be some symbol in the binary; C++ doesn't
62*67e74705SXin Li // allow taking the address of ::main however.
63*67e74705SXin Li void *P = (void*) (intptr_t) GetExecutablePath;
64*67e74705SXin Li return llvm::sys::fs::getMainExecutable(Argv0, P);
65*67e74705SXin Li }
66*67e74705SXin Li
GetStableCStr(std::set<std::string> & SavedStrings,StringRef S)67*67e74705SXin Li static const char *GetStableCStr(std::set<std::string> &SavedStrings,
68*67e74705SXin Li StringRef S) {
69*67e74705SXin Li return SavedStrings.insert(S).first->c_str();
70*67e74705SXin Li }
71*67e74705SXin Li
72*67e74705SXin Li /// ApplyQAOverride - Apply a list of edits to the input argument lists.
73*67e74705SXin Li ///
74*67e74705SXin Li /// The input string is a space separate list of edits to perform,
75*67e74705SXin Li /// they are applied in order to the input argument lists. Edits
76*67e74705SXin Li /// should be one of the following forms:
77*67e74705SXin Li ///
78*67e74705SXin Li /// '#': Silence information about the changes to the command line arguments.
79*67e74705SXin Li ///
80*67e74705SXin Li /// '^': Add FOO as a new argument at the beginning of the command line.
81*67e74705SXin Li ///
82*67e74705SXin Li /// '+': Add FOO as a new argument at the end of the command line.
83*67e74705SXin Li ///
84*67e74705SXin Li /// 's/XXX/YYY/': Substitute the regular expression XXX with YYY in the command
85*67e74705SXin Li /// line.
86*67e74705SXin Li ///
87*67e74705SXin Li /// 'xOPTION': Removes all instances of the literal argument OPTION.
88*67e74705SXin Li ///
89*67e74705SXin Li /// 'XOPTION': Removes all instances of the literal argument OPTION,
90*67e74705SXin Li /// and the following argument.
91*67e74705SXin Li ///
92*67e74705SXin Li /// 'Ox': Removes all flags matching 'O' or 'O[sz0-9]' and adds 'Ox'
93*67e74705SXin Li /// at the end of the command line.
94*67e74705SXin Li ///
95*67e74705SXin Li /// \param OS - The stream to write edit information to.
96*67e74705SXin Li /// \param Args - The vector of command line arguments.
97*67e74705SXin Li /// \param Edit - The override command to perform.
98*67e74705SXin Li /// \param SavedStrings - Set to use for storing string representations.
ApplyOneQAOverride(raw_ostream & OS,SmallVectorImpl<const char * > & Args,StringRef Edit,std::set<std::string> & SavedStrings)99*67e74705SXin Li static void ApplyOneQAOverride(raw_ostream &OS,
100*67e74705SXin Li SmallVectorImpl<const char*> &Args,
101*67e74705SXin Li StringRef Edit,
102*67e74705SXin Li std::set<std::string> &SavedStrings) {
103*67e74705SXin Li // This does not need to be efficient.
104*67e74705SXin Li
105*67e74705SXin Li if (Edit[0] == '^') {
106*67e74705SXin Li const char *Str =
107*67e74705SXin Li GetStableCStr(SavedStrings, Edit.substr(1));
108*67e74705SXin Li OS << "### Adding argument " << Str << " at beginning\n";
109*67e74705SXin Li Args.insert(Args.begin() + 1, Str);
110*67e74705SXin Li } else if (Edit[0] == '+') {
111*67e74705SXin Li const char *Str =
112*67e74705SXin Li GetStableCStr(SavedStrings, Edit.substr(1));
113*67e74705SXin Li OS << "### Adding argument " << Str << " at end\n";
114*67e74705SXin Li Args.push_back(Str);
115*67e74705SXin Li } else if (Edit[0] == 's' && Edit[1] == '/' && Edit.endswith("/") &&
116*67e74705SXin Li Edit.slice(2, Edit.size()-1).find('/') != StringRef::npos) {
117*67e74705SXin Li StringRef MatchPattern = Edit.substr(2).split('/').first;
118*67e74705SXin Li StringRef ReplPattern = Edit.substr(2).split('/').second;
119*67e74705SXin Li ReplPattern = ReplPattern.slice(0, ReplPattern.size()-1);
120*67e74705SXin Li
121*67e74705SXin Li for (unsigned i = 1, e = Args.size(); i != e; ++i) {
122*67e74705SXin Li // Ignore end-of-line response file markers
123*67e74705SXin Li if (Args[i] == nullptr)
124*67e74705SXin Li continue;
125*67e74705SXin Li std::string Repl = llvm::Regex(MatchPattern).sub(ReplPattern, Args[i]);
126*67e74705SXin Li
127*67e74705SXin Li if (Repl != Args[i]) {
128*67e74705SXin Li OS << "### Replacing '" << Args[i] << "' with '" << Repl << "'\n";
129*67e74705SXin Li Args[i] = GetStableCStr(SavedStrings, Repl);
130*67e74705SXin Li }
131*67e74705SXin Li }
132*67e74705SXin Li } else if (Edit[0] == 'x' || Edit[0] == 'X') {
133*67e74705SXin Li auto Option = Edit.substr(1);
134*67e74705SXin Li for (unsigned i = 1; i < Args.size();) {
135*67e74705SXin Li if (Option == Args[i]) {
136*67e74705SXin Li OS << "### Deleting argument " << Args[i] << '\n';
137*67e74705SXin Li Args.erase(Args.begin() + i);
138*67e74705SXin Li if (Edit[0] == 'X') {
139*67e74705SXin Li if (i < Args.size()) {
140*67e74705SXin Li OS << "### Deleting argument " << Args[i] << '\n';
141*67e74705SXin Li Args.erase(Args.begin() + i);
142*67e74705SXin Li } else
143*67e74705SXin Li OS << "### Invalid X edit, end of command line!\n";
144*67e74705SXin Li }
145*67e74705SXin Li } else
146*67e74705SXin Li ++i;
147*67e74705SXin Li }
148*67e74705SXin Li } else if (Edit[0] == 'O') {
149*67e74705SXin Li for (unsigned i = 1; i < Args.size();) {
150*67e74705SXin Li const char *A = Args[i];
151*67e74705SXin Li // Ignore end-of-line response file markers
152*67e74705SXin Li if (A == nullptr)
153*67e74705SXin Li continue;
154*67e74705SXin Li if (A[0] == '-' && A[1] == 'O' &&
155*67e74705SXin Li (A[2] == '\0' ||
156*67e74705SXin Li (A[3] == '\0' && (A[2] == 's' || A[2] == 'z' ||
157*67e74705SXin Li ('0' <= A[2] && A[2] <= '9'))))) {
158*67e74705SXin Li OS << "### Deleting argument " << Args[i] << '\n';
159*67e74705SXin Li Args.erase(Args.begin() + i);
160*67e74705SXin Li } else
161*67e74705SXin Li ++i;
162*67e74705SXin Li }
163*67e74705SXin Li OS << "### Adding argument " << Edit << " at end\n";
164*67e74705SXin Li Args.push_back(GetStableCStr(SavedStrings, '-' + Edit.str()));
165*67e74705SXin Li } else {
166*67e74705SXin Li OS << "### Unrecognized edit: " << Edit << "\n";
167*67e74705SXin Li }
168*67e74705SXin Li }
169*67e74705SXin Li
170*67e74705SXin Li /// ApplyQAOverride - Apply a comma separate list of edits to the
171*67e74705SXin Li /// input argument lists. See ApplyOneQAOverride.
ApplyQAOverride(SmallVectorImpl<const char * > & Args,const char * OverrideStr,std::set<std::string> & SavedStrings)172*67e74705SXin Li static void ApplyQAOverride(SmallVectorImpl<const char*> &Args,
173*67e74705SXin Li const char *OverrideStr,
174*67e74705SXin Li std::set<std::string> &SavedStrings) {
175*67e74705SXin Li raw_ostream *OS = &llvm::errs();
176*67e74705SXin Li
177*67e74705SXin Li if (OverrideStr[0] == '#') {
178*67e74705SXin Li ++OverrideStr;
179*67e74705SXin Li OS = &llvm::nulls();
180*67e74705SXin Li }
181*67e74705SXin Li
182*67e74705SXin Li *OS << "### CCC_OVERRIDE_OPTIONS: " << OverrideStr << "\n";
183*67e74705SXin Li
184*67e74705SXin Li // This does not need to be efficient.
185*67e74705SXin Li
186*67e74705SXin Li const char *S = OverrideStr;
187*67e74705SXin Li while (*S) {
188*67e74705SXin Li const char *End = ::strchr(S, ' ');
189*67e74705SXin Li if (!End)
190*67e74705SXin Li End = S + strlen(S);
191*67e74705SXin Li if (End != S)
192*67e74705SXin Li ApplyOneQAOverride(*OS, Args, std::string(S, End), SavedStrings);
193*67e74705SXin Li S = End;
194*67e74705SXin Li if (*S != '\0')
195*67e74705SXin Li ++S;
196*67e74705SXin Li }
197*67e74705SXin Li }
198*67e74705SXin Li
199*67e74705SXin Li extern int cc1_main(ArrayRef<const char *> Argv, const char *Argv0,
200*67e74705SXin Li void *MainAddr);
201*67e74705SXin Li extern int cc1as_main(ArrayRef<const char *> Argv, const char *Argv0,
202*67e74705SXin Li void *MainAddr);
203*67e74705SXin Li
insertTargetAndModeArgs(StringRef Target,StringRef Mode,SmallVectorImpl<const char * > & ArgVector,std::set<std::string> & SavedStrings)204*67e74705SXin Li static void insertTargetAndModeArgs(StringRef Target, StringRef Mode,
205*67e74705SXin Li SmallVectorImpl<const char *> &ArgVector,
206*67e74705SXin Li std::set<std::string> &SavedStrings) {
207*67e74705SXin Li if (!Mode.empty()) {
208*67e74705SXin Li // Add the mode flag to the arguments.
209*67e74705SXin Li auto it = ArgVector.begin();
210*67e74705SXin Li if (it != ArgVector.end())
211*67e74705SXin Li ++it;
212*67e74705SXin Li ArgVector.insert(it, GetStableCStr(SavedStrings, Mode));
213*67e74705SXin Li }
214*67e74705SXin Li
215*67e74705SXin Li if (!Target.empty()) {
216*67e74705SXin Li auto it = ArgVector.begin();
217*67e74705SXin Li if (it != ArgVector.end())
218*67e74705SXin Li ++it;
219*67e74705SXin Li const char *arr[] = {"-target", GetStableCStr(SavedStrings, Target)};
220*67e74705SXin Li ArgVector.insert(it, std::begin(arr), std::end(arr));
221*67e74705SXin Li }
222*67e74705SXin Li }
223*67e74705SXin Li
getCLEnvVarOptions(std::string & EnvValue,llvm::StringSaver & Saver,SmallVectorImpl<const char * > & Opts)224*67e74705SXin Li static void getCLEnvVarOptions(std::string &EnvValue, llvm::StringSaver &Saver,
225*67e74705SXin Li SmallVectorImpl<const char *> &Opts) {
226*67e74705SXin Li llvm::cl::TokenizeWindowsCommandLine(EnvValue, Saver, Opts);
227*67e74705SXin Li // The first instance of '#' should be replaced with '=' in each option.
228*67e74705SXin Li for (const char *Opt : Opts)
229*67e74705SXin Li if (char *NumberSignPtr = const_cast<char *>(::strchr(Opt, '#')))
230*67e74705SXin Li *NumberSignPtr = '=';
231*67e74705SXin Li }
232*67e74705SXin Li
SetBackdoorDriverOutputsFromEnvVars(Driver & TheDriver)233*67e74705SXin Li static void SetBackdoorDriverOutputsFromEnvVars(Driver &TheDriver) {
234*67e74705SXin Li // Handle CC_PRINT_OPTIONS and CC_PRINT_OPTIONS_FILE.
235*67e74705SXin Li TheDriver.CCPrintOptions = !!::getenv("CC_PRINT_OPTIONS");
236*67e74705SXin Li if (TheDriver.CCPrintOptions)
237*67e74705SXin Li TheDriver.CCPrintOptionsFilename = ::getenv("CC_PRINT_OPTIONS_FILE");
238*67e74705SXin Li
239*67e74705SXin Li // Handle CC_PRINT_HEADERS and CC_PRINT_HEADERS_FILE.
240*67e74705SXin Li TheDriver.CCPrintHeaders = !!::getenv("CC_PRINT_HEADERS");
241*67e74705SXin Li if (TheDriver.CCPrintHeaders)
242*67e74705SXin Li TheDriver.CCPrintHeadersFilename = ::getenv("CC_PRINT_HEADERS_FILE");
243*67e74705SXin Li
244*67e74705SXin Li // Handle CC_LOG_DIAGNOSTICS and CC_LOG_DIAGNOSTICS_FILE.
245*67e74705SXin Li TheDriver.CCLogDiagnostics = !!::getenv("CC_LOG_DIAGNOSTICS");
246*67e74705SXin Li if (TheDriver.CCLogDiagnostics)
247*67e74705SXin Li TheDriver.CCLogDiagnosticsFilename = ::getenv("CC_LOG_DIAGNOSTICS_FILE");
248*67e74705SXin Li }
249*67e74705SXin Li
FixupDiagPrefixExeName(TextDiagnosticPrinter * DiagClient,const std::string & Path)250*67e74705SXin Li static void FixupDiagPrefixExeName(TextDiagnosticPrinter *DiagClient,
251*67e74705SXin Li const std::string &Path) {
252*67e74705SXin Li // If the clang binary happens to be named cl.exe for compatibility reasons,
253*67e74705SXin Li // use clang-cl.exe as the prefix to avoid confusion between clang and MSVC.
254*67e74705SXin Li StringRef ExeBasename(llvm::sys::path::filename(Path));
255*67e74705SXin Li if (ExeBasename.equals_lower("cl.exe"))
256*67e74705SXin Li ExeBasename = "clang-cl.exe";
257*67e74705SXin Li DiagClient->setPrefix(ExeBasename);
258*67e74705SXin Li }
259*67e74705SXin Li
260*67e74705SXin Li // This lets us create the DiagnosticsEngine with a properly-filled-out
261*67e74705SXin Li // DiagnosticOptions instance.
262*67e74705SXin Li static DiagnosticOptions *
CreateAndPopulateDiagOpts(ArrayRef<const char * > argv)263*67e74705SXin Li CreateAndPopulateDiagOpts(ArrayRef<const char *> argv) {
264*67e74705SXin Li auto *DiagOpts = new DiagnosticOptions;
265*67e74705SXin Li std::unique_ptr<OptTable> Opts(createDriverOptTable());
266*67e74705SXin Li unsigned MissingArgIndex, MissingArgCount;
267*67e74705SXin Li InputArgList Args =
268*67e74705SXin Li Opts->ParseArgs(argv.slice(1), MissingArgIndex, MissingArgCount);
269*67e74705SXin Li // We ignore MissingArgCount and the return value of ParseDiagnosticArgs.
270*67e74705SXin Li // Any errors that would be diagnosed here will also be diagnosed later,
271*67e74705SXin Li // when the DiagnosticsEngine actually exists.
272*67e74705SXin Li (void)ParseDiagnosticArgs(*DiagOpts, Args);
273*67e74705SXin Li return DiagOpts;
274*67e74705SXin Li }
275*67e74705SXin Li
SetInstallDir(SmallVectorImpl<const char * > & argv,Driver & TheDriver,bool CanonicalPrefixes)276*67e74705SXin Li static void SetInstallDir(SmallVectorImpl<const char *> &argv,
277*67e74705SXin Li Driver &TheDriver, bool CanonicalPrefixes) {
278*67e74705SXin Li // Attempt to find the original path used to invoke the driver, to determine
279*67e74705SXin Li // the installed path. We do this manually, because we want to support that
280*67e74705SXin Li // path being a symlink.
281*67e74705SXin Li SmallString<128> InstalledPath(argv[0]);
282*67e74705SXin Li
283*67e74705SXin Li // Do a PATH lookup, if there are no directory components.
284*67e74705SXin Li if (llvm::sys::path::filename(InstalledPath) == InstalledPath)
285*67e74705SXin Li if (llvm::ErrorOr<std::string> Tmp = llvm::sys::findProgramByName(
286*67e74705SXin Li llvm::sys::path::filename(InstalledPath.str())))
287*67e74705SXin Li InstalledPath = *Tmp;
288*67e74705SXin Li
289*67e74705SXin Li // FIXME: We don't actually canonicalize this, we just make it absolute.
290*67e74705SXin Li if (CanonicalPrefixes)
291*67e74705SXin Li llvm::sys::fs::make_absolute(InstalledPath);
292*67e74705SXin Li
293*67e74705SXin Li StringRef InstalledPathParent(llvm::sys::path::parent_path(InstalledPath));
294*67e74705SXin Li if (llvm::sys::fs::exists(InstalledPathParent))
295*67e74705SXin Li TheDriver.setInstalledDir(InstalledPathParent);
296*67e74705SXin Li }
297*67e74705SXin Li
ExecuteCC1Tool(ArrayRef<const char * > argv,StringRef Tool)298*67e74705SXin Li static int ExecuteCC1Tool(ArrayRef<const char *> argv, StringRef Tool) {
299*67e74705SXin Li void *GetExecutablePathVP = (void *)(intptr_t) GetExecutablePath;
300*67e74705SXin Li if (Tool == "")
301*67e74705SXin Li return cc1_main(argv.slice(2), argv[0], GetExecutablePathVP);
302*67e74705SXin Li if (Tool == "as")
303*67e74705SXin Li return cc1as_main(argv.slice(2), argv[0], GetExecutablePathVP);
304*67e74705SXin Li
305*67e74705SXin Li // Reject unknown tools.
306*67e74705SXin Li llvm::errs() << "error: unknown integrated tool '" << Tool << "'\n";
307*67e74705SXin Li return 1;
308*67e74705SXin Li }
309*67e74705SXin Li
main(int argc_,const char ** argv_)310*67e74705SXin Li int main(int argc_, const char **argv_) {
311*67e74705SXin Li llvm::sys::PrintStackTraceOnErrorSignal(argv_[0]);
312*67e74705SXin Li llvm::PrettyStackTraceProgram X(argc_, argv_);
313*67e74705SXin Li llvm::llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
314*67e74705SXin Li
315*67e74705SXin Li if (llvm::sys::Process::FixupStandardFileDescriptors())
316*67e74705SXin Li return 1;
317*67e74705SXin Li
318*67e74705SXin Li SmallVector<const char *, 256> argv;
319*67e74705SXin Li llvm::SpecificBumpPtrAllocator<char> ArgAllocator;
320*67e74705SXin Li std::error_code EC = llvm::sys::Process::GetArgumentVector(
321*67e74705SXin Li argv, llvm::makeArrayRef(argv_, argc_), ArgAllocator);
322*67e74705SXin Li if (EC) {
323*67e74705SXin Li llvm::errs() << "error: couldn't get arguments: " << EC.message() << '\n';
324*67e74705SXin Li return 1;
325*67e74705SXin Li }
326*67e74705SXin Li
327*67e74705SXin Li llvm::InitializeAllTargets();
328*67e74705SXin Li std::string ProgName = argv[0];
329*67e74705SXin Li std::pair<std::string, std::string> TargetAndMode =
330*67e74705SXin Li ToolChain::getTargetAndModeFromProgramName(ProgName);
331*67e74705SXin Li
332*67e74705SXin Li llvm::BumpPtrAllocator A;
333*67e74705SXin Li llvm::StringSaver Saver(A);
334*67e74705SXin Li
335*67e74705SXin Li // Parse response files using the GNU syntax, unless we're in CL mode. There
336*67e74705SXin Li // are two ways to put clang in CL compatibility mode: argv[0] is either
337*67e74705SXin Li // clang-cl or cl, or --driver-mode=cl is on the command line. The normal
338*67e74705SXin Li // command line parsing can't happen until after response file parsing, so we
339*67e74705SXin Li // have to manually search for a --driver-mode=cl argument the hard way.
340*67e74705SXin Li // Finally, our -cc1 tools don't care which tokenization mode we use because
341*67e74705SXin Li // response files written by clang will tokenize the same way in either mode.
342*67e74705SXin Li bool ClangCLMode = false;
343*67e74705SXin Li if (TargetAndMode.second == "--driver-mode=cl" ||
344*67e74705SXin Li std::find_if(argv.begin(), argv.end(), [](const char *F) {
345*67e74705SXin Li return F && strcmp(F, "--driver-mode=cl") == 0;
346*67e74705SXin Li }) != argv.end()) {
347*67e74705SXin Li ClangCLMode = true;
348*67e74705SXin Li }
349*67e74705SXin Li enum { Default, POSIX, Windows } RSPQuoting = Default;
350*67e74705SXin Li for (const char *F : argv) {
351*67e74705SXin Li if (strcmp(F, "--rsp-quoting=posix") == 0)
352*67e74705SXin Li RSPQuoting = POSIX;
353*67e74705SXin Li else if (strcmp(F, "--rsp-quoting=windows") == 0)
354*67e74705SXin Li RSPQuoting = Windows;
355*67e74705SXin Li }
356*67e74705SXin Li
357*67e74705SXin Li // Determines whether we want nullptr markers in argv to indicate response
358*67e74705SXin Li // files end-of-lines. We only use this for the /LINK driver argument with
359*67e74705SXin Li // clang-cl.exe on Windows.
360*67e74705SXin Li bool MarkEOLs = ClangCLMode;
361*67e74705SXin Li
362*67e74705SXin Li llvm::cl::TokenizerCallback Tokenizer;
363*67e74705SXin Li if (RSPQuoting == Windows || (RSPQuoting == Default && ClangCLMode))
364*67e74705SXin Li Tokenizer = &llvm::cl::TokenizeWindowsCommandLine;
365*67e74705SXin Li else
366*67e74705SXin Li Tokenizer = &llvm::cl::TokenizeGNUCommandLine;
367*67e74705SXin Li
368*67e74705SXin Li if (MarkEOLs && argv.size() > 1 && StringRef(argv[1]).startswith("-cc1"))
369*67e74705SXin Li MarkEOLs = false;
370*67e74705SXin Li llvm::cl::ExpandResponseFiles(Saver, Tokenizer, argv, MarkEOLs);
371*67e74705SXin Li
372*67e74705SXin Li // Handle -cc1 integrated tools, even if -cc1 was expanded from a response
373*67e74705SXin Li // file.
374*67e74705SXin Li auto FirstArg = std::find_if(argv.begin() + 1, argv.end(),
375*67e74705SXin Li [](const char *A) { return A != nullptr; });
376*67e74705SXin Li if (FirstArg != argv.end() && StringRef(*FirstArg).startswith("-cc1")) {
377*67e74705SXin Li // If -cc1 came from a response file, remove the EOL sentinels.
378*67e74705SXin Li if (MarkEOLs) {
379*67e74705SXin Li auto newEnd = std::remove(argv.begin(), argv.end(), nullptr);
380*67e74705SXin Li argv.resize(newEnd - argv.begin());
381*67e74705SXin Li }
382*67e74705SXin Li return ExecuteCC1Tool(argv, argv[1] + 4);
383*67e74705SXin Li }
384*67e74705SXin Li
385*67e74705SXin Li bool CanonicalPrefixes = true;
386*67e74705SXin Li for (int i = 1, size = argv.size(); i < size; ++i) {
387*67e74705SXin Li // Skip end-of-line response file markers
388*67e74705SXin Li if (argv[i] == nullptr)
389*67e74705SXin Li continue;
390*67e74705SXin Li if (StringRef(argv[i]) == "-no-canonical-prefixes") {
391*67e74705SXin Li CanonicalPrefixes = false;
392*67e74705SXin Li break;
393*67e74705SXin Li }
394*67e74705SXin Li }
395*67e74705SXin Li
396*67e74705SXin Li // Handle CL and _CL_ which permits additional command line options to be
397*67e74705SXin Li // prepended or appended.
398*67e74705SXin Li if (Tokenizer == &llvm::cl::TokenizeWindowsCommandLine) {
399*67e74705SXin Li // Arguments in "CL" are prepended.
400*67e74705SXin Li llvm::Optional<std::string> OptCL = llvm::sys::Process::GetEnv("CL");
401*67e74705SXin Li if (OptCL.hasValue()) {
402*67e74705SXin Li SmallVector<const char *, 8> PrependedOpts;
403*67e74705SXin Li getCLEnvVarOptions(OptCL.getValue(), Saver, PrependedOpts);
404*67e74705SXin Li
405*67e74705SXin Li // Insert right after the program name to prepend to the argument list.
406*67e74705SXin Li argv.insert(argv.begin() + 1, PrependedOpts.begin(), PrependedOpts.end());
407*67e74705SXin Li }
408*67e74705SXin Li // Arguments in "_CL_" are appended.
409*67e74705SXin Li llvm::Optional<std::string> Opt_CL_ = llvm::sys::Process::GetEnv("_CL_");
410*67e74705SXin Li if (Opt_CL_.hasValue()) {
411*67e74705SXin Li SmallVector<const char *, 8> AppendedOpts;
412*67e74705SXin Li getCLEnvVarOptions(Opt_CL_.getValue(), Saver, AppendedOpts);
413*67e74705SXin Li
414*67e74705SXin Li // Insert at the end of the argument list to append.
415*67e74705SXin Li argv.append(AppendedOpts.begin(), AppendedOpts.end());
416*67e74705SXin Li }
417*67e74705SXin Li }
418*67e74705SXin Li
419*67e74705SXin Li std::set<std::string> SavedStrings;
420*67e74705SXin Li // Handle CCC_OVERRIDE_OPTIONS, used for editing a command line behind the
421*67e74705SXin Li // scenes.
422*67e74705SXin Li if (const char *OverrideStr = ::getenv("CCC_OVERRIDE_OPTIONS")) {
423*67e74705SXin Li // FIXME: Driver shouldn't take extra initial argument.
424*67e74705SXin Li ApplyQAOverride(argv, OverrideStr, SavedStrings);
425*67e74705SXin Li }
426*67e74705SXin Li
427*67e74705SXin Li std::string Path = GetExecutablePath(argv[0], CanonicalPrefixes);
428*67e74705SXin Li
429*67e74705SXin Li IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts =
430*67e74705SXin Li CreateAndPopulateDiagOpts(argv);
431*67e74705SXin Li
432*67e74705SXin Li TextDiagnosticPrinter *DiagClient
433*67e74705SXin Li = new TextDiagnosticPrinter(llvm::errs(), &*DiagOpts);
434*67e74705SXin Li FixupDiagPrefixExeName(DiagClient, Path);
435*67e74705SXin Li
436*67e74705SXin Li IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
437*67e74705SXin Li
438*67e74705SXin Li DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagClient);
439*67e74705SXin Li
440*67e74705SXin Li if (!DiagOpts->DiagnosticSerializationFile.empty()) {
441*67e74705SXin Li auto SerializedConsumer =
442*67e74705SXin Li clang::serialized_diags::create(DiagOpts->DiagnosticSerializationFile,
443*67e74705SXin Li &*DiagOpts, /*MergeChildRecords=*/true);
444*67e74705SXin Li Diags.setClient(new ChainedDiagnosticConsumer(
445*67e74705SXin Li Diags.takeClient(), std::move(SerializedConsumer)));
446*67e74705SXin Li }
447*67e74705SXin Li
448*67e74705SXin Li ProcessWarningOptions(Diags, *DiagOpts, /*ReportDiags=*/false);
449*67e74705SXin Li
450*67e74705SXin Li Driver TheDriver(Path, llvm::sys::getDefaultTargetTriple(), Diags);
451*67e74705SXin Li SetInstallDir(argv, TheDriver, CanonicalPrefixes);
452*67e74705SXin Li
453*67e74705SXin Li insertTargetAndModeArgs(TargetAndMode.first, TargetAndMode.second, argv,
454*67e74705SXin Li SavedStrings);
455*67e74705SXin Li
456*67e74705SXin Li SetBackdoorDriverOutputsFromEnvVars(TheDriver);
457*67e74705SXin Li
458*67e74705SXin Li std::unique_ptr<Compilation> C(TheDriver.BuildCompilation(argv));
459*67e74705SXin Li int Res = 0;
460*67e74705SXin Li SmallVector<std::pair<int, const Command *>, 4> FailingCommands;
461*67e74705SXin Li if (C.get())
462*67e74705SXin Li Res = TheDriver.ExecuteCompilation(*C, FailingCommands);
463*67e74705SXin Li
464*67e74705SXin Li // Force a crash to test the diagnostics.
465*67e74705SXin Li if (::getenv("FORCE_CLANG_DIAGNOSTICS_CRASH")) {
466*67e74705SXin Li Diags.Report(diag::err_drv_force_crash) << "FORCE_CLANG_DIAGNOSTICS_CRASH";
467*67e74705SXin Li
468*67e74705SXin Li // Pretend that every command failed.
469*67e74705SXin Li FailingCommands.clear();
470*67e74705SXin Li for (const auto &J : C->getJobs())
471*67e74705SXin Li if (const Command *C = dyn_cast<Command>(&J))
472*67e74705SXin Li FailingCommands.push_back(std::make_pair(-1, C));
473*67e74705SXin Li }
474*67e74705SXin Li
475*67e74705SXin Li for (const auto &P : FailingCommands) {
476*67e74705SXin Li int CommandRes = P.first;
477*67e74705SXin Li const Command *FailingCommand = P.second;
478*67e74705SXin Li if (!Res)
479*67e74705SXin Li Res = CommandRes;
480*67e74705SXin Li
481*67e74705SXin Li // If result status is < 0, then the driver command signalled an error.
482*67e74705SXin Li // If result status is 70, then the driver command reported a fatal error.
483*67e74705SXin Li // On Windows, abort will return an exit code of 3. In these cases,
484*67e74705SXin Li // generate additional diagnostic information if possible.
485*67e74705SXin Li bool DiagnoseCrash = CommandRes < 0 || CommandRes == 70;
486*67e74705SXin Li #ifdef LLVM_ON_WIN32
487*67e74705SXin Li DiagnoseCrash |= CommandRes == 3;
488*67e74705SXin Li #endif
489*67e74705SXin Li if (DiagnoseCrash) {
490*67e74705SXin Li TheDriver.generateCompilationDiagnostics(*C, *FailingCommand);
491*67e74705SXin Li break;
492*67e74705SXin Li }
493*67e74705SXin Li }
494*67e74705SXin Li
495*67e74705SXin Li Diags.getClient()->finish();
496*67e74705SXin Li
497*67e74705SXin Li // If any timers were active but haven't been destroyed yet, print their
498*67e74705SXin Li // results now. This happens in -disable-free mode.
499*67e74705SXin Li llvm::TimerGroup::printAll(llvm::errs());
500*67e74705SXin Li
501*67e74705SXin Li #ifdef LLVM_ON_WIN32
502*67e74705SXin Li // Exit status should not be negative on Win32, unless abnormal termination.
503*67e74705SXin Li // Once abnormal termiation was caught, negative status should not be
504*67e74705SXin Li // propagated.
505*67e74705SXin Li if (Res < 0)
506*67e74705SXin Li Res = 1;
507*67e74705SXin Li #endif
508*67e74705SXin Li
509*67e74705SXin Li // If we have multiple failing commands, we return the result of the first
510*67e74705SXin Li // failing command.
511*67e74705SXin Li return Res;
512*67e74705SXin Li }
513