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