driver.cpp revision a57b3b4fea1c962678972af8fc74e121ff8b296d
12cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor//===-- driver.cpp - Clang GCC-Compatible Driver --------------------------===// 22cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor// 32cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor// The LLVM Compiler Infrastructure 42cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor// 52cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor// This file is distributed under the University of Illinois Open Source 62cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor// License. See LICENSE.TXT for details. 72cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor// 82cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor//===----------------------------------------------------------------------===// 92cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor// 102cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor// This is the entry point to the clang driver; it is a thin wrapper 112cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor// for functionality in the Driver clang library. 122cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor// 132cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor//===----------------------------------------------------------------------===// 142cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 15e7785040107266d01ebdcc066365f70b7ace371fDouglas Gregor#include "clang/Basic/DiagnosticOptions.h" 163251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor#include "clang/Driver/ArgList.h" 172cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor#include "clang/Driver/Compilation.h" 182cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor#include "clang/Driver/Driver.h" 192cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor#include "clang/Driver/DriverDiagnostic.h" 202cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor#include "clang/Driver/OptTable.h" 210b7489194f9f89fac39d57211c1e7953ae50251fDouglas Gregor#include "clang/Driver/Option.h" 220b7489194f9f89fac39d57211c1e7953ae50251fDouglas Gregor#include "clang/Driver/Options.h" 232cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor#include "clang/Frontend/CompilerInvocation.h" 247c5d24efcd2e505b5739f7def08dfe25ce59a1b2Chris Lattner#include "clang/Frontend/TextDiagnosticPrinter.h" 257c5d24efcd2e505b5739f7def08dfe25ce59a1b2Chris Lattner#include "clang/Frontend/Utils.h" 2683d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff#include "llvm/ADT/ArrayRef.h" 2714f79002e58556798e86168c63e48d533287eda5Douglas Gregor#include "llvm/ADT/OwningPtr.h" 283251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor#include "llvm/ADT/SmallString.h" 2914f79002e58556798e86168c63e48d533287eda5Douglas Gregor#include "llvm/ADT/SmallVector.h" 30bd94500d3aa60092fb0f1e90f53fb0d03fa502a8Douglas Gregor#include "llvm/Support/ErrorHandling.h" 312bec0410d268779f601bd509e0302a500af7ac6aDouglas Gregor#include "llvm/Support/FileSystem.h" 3217fc223395d51be582fc666bb6ea21bd1dff26dcDouglas Gregor#include "llvm/Support/Host.h" 3317fc223395d51be582fc666bb6ea21bd1dff26dcDouglas Gregor#include "llvm/Support/ManagedStatic.h" 342cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor#include "llvm/Support/MemoryBuffer.h" 352cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor#include "llvm/Support/Path.h" 3614f79002e58556798e86168c63e48d533287eda5Douglas Gregor#include "llvm/Support/PrettyStackTrace.h" 373c304bd9ec2b4611572d4cbae9e1727bbecb5dc9Chris Lattner#include "llvm/Support/Program.h" 382cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor#include "llvm/Support/Regex.h" 392cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor#include "llvm/Support/Signals.h" 402cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor#include "llvm/Support/TargetRegistry.h" 412cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor#include "llvm/Support/TargetSelect.h" 422cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor#include "llvm/Support/Timer.h" 432cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor#include "llvm/Support/raw_ostream.h" 442cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor#include "llvm/Support/system_error.h" 452cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor#include <cctype> 462cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregorusing namespace clang; 472cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregorusing namespace clang::driver; 482cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 492cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregorllvm::sys::Path GetExecutablePath(const char *Argv0, bool CanonicalPrefixes) { 502cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor if (!CanonicalPrefixes) 512cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor return llvm::sys::Path(Argv0); 522cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 532cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor // This just needs to be some symbol in the binary; C++ doesn't 542cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor // allow taking the address of ::main however. 552cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor void *P = (void*) (intptr_t) GetExecutablePath; 562cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor return llvm::sys::Path::GetMainExecutable(Argv0, P); 572cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor} 582cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 592cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregorstatic const char *SaveStringInSet(std::set<std::string> &SavedStrings, 602cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor StringRef S) { 612cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor return SavedStrings.insert(S).first->c_str(); 622cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor} 632cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 642cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor/// ApplyQAOverride - Apply a list of edits to the input argument lists. 652cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor/// 662cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor/// The input string is a space separate list of edits to perform, 672cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor/// they are applied in order to the input argument lists. Edits 682cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor/// should be one of the following forms: 692cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor/// 702cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor/// '#': Silence information about the changes to the command line arguments. 712cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor/// 722cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor/// '^': Add FOO as a new argument at the beginning of the command line. 732cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor/// 742cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor/// '+': Add FOO as a new argument at the end of the command line. 752cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor/// 762cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor/// 's/XXX/YYY/': Substitute the regular expression XXX with YYY in the command 772cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor/// line. 782cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor/// 792cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor/// 'xOPTION': Removes all instances of the literal argument OPTION. 802cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor/// 812cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor/// 'XOPTION': Removes all instances of the literal argument OPTION, 822cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor/// and the following argument. 832cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor/// 842cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor/// 'Ox': Removes all flags matching 'O' or 'O[sz0-9]' and adds 'Ox' 852cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor/// at the end of the command line. 862cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor/// 872cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor/// \param OS - The stream to write edit information to. 882cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor/// \param Args - The vector of command line arguments. 892cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor/// \param Edit - The override command to perform. 902cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor/// \param SavedStrings - Set to use for storing string representations. 912cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregorstatic void ApplyOneQAOverride(raw_ostream &OS, 922cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor SmallVectorImpl<const char*> &Args, 932cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor StringRef Edit, 942cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor std::set<std::string> &SavedStrings) { 952cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor // This does not need to be efficient. 962cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 972cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor if (Edit[0] == '^') { 982cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor const char *Str = 992cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor SaveStringInSet(SavedStrings, Edit.substr(1)); 1002cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor OS << "### Adding argument " << Str << " at beginning\n"; 1012cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor Args.insert(Args.begin() + 1, Str); 1022cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor } else if (Edit[0] == '+') { 1032cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor const char *Str = 1042cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor SaveStringInSet(SavedStrings, Edit.substr(1)); 1052cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor OS << "### Adding argument " << Str << " at end\n"; 1062cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor Args.push_back(Str); 1072cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor } else if (Edit[0] == 's' && Edit[1] == '/' && Edit.endswith("/") && 1082cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor Edit.slice(2, Edit.size()-1).find('/') != StringRef::npos) { 1092cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor StringRef MatchPattern = Edit.substr(2).split('/').first; 1102cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor StringRef ReplPattern = Edit.substr(2).split('/').second; 1112cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor ReplPattern = ReplPattern.slice(0, ReplPattern.size()-1); 1122cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 1132cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor for (unsigned i = 1, e = Args.size(); i != e; ++i) { 1142cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor std::string Repl = llvm::Regex(MatchPattern).sub(ReplPattern, Args[i]); 1152cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 1162cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor if (Repl != Args[i]) { 1172cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor OS << "### Replacing '" << Args[i] << "' with '" << Repl << "'\n"; 1182cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor Args[i] = SaveStringInSet(SavedStrings, Repl); 1192cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor } 1202cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor } 1212cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor } else if (Edit[0] == 'x' || Edit[0] == 'X') { 1222cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor std::string Option = Edit.substr(1, std::string::npos); 1232cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor for (unsigned i = 1; i < Args.size();) { 1242cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor if (Option == Args[i]) { 1252cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor OS << "### Deleting argument " << Args[i] << '\n'; 1262cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor Args.erase(Args.begin() + i); 1272cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor if (Edit[0] == 'X') { 1282cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor if (i < Args.size()) { 1292cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor OS << "### Deleting argument " << Args[i] << '\n'; 1302cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor Args.erase(Args.begin() + i); 1312cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor } else 1322cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor OS << "### Invalid X edit, end of command line!\n"; 133c9490c000f515c29f200a1215328d8ab9a0f3818Douglas Gregor } 1342cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor } else 1352cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor ++i; 1362cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor } 1372cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor } else if (Edit[0] == 'O') { 1382cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor for (unsigned i = 1; i < Args.size();) { 1392cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor const char *A = Args[i]; 1402cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor if (A[0] == '-' && A[1] == 'O' && 1412cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor (A[2] == '\0' || 1422cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor (A[3] == '\0' && (A[2] == 's' || A[2] == 'z' || 1432cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor ('0' <= A[2] && A[2] <= '9'))))) { 1442cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor OS << "### Deleting argument " << Args[i] << '\n'; 1452cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor Args.erase(Args.begin() + i); 1462cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor } else 1472cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor ++i; 1482cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor } 1492cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor OS << "### Adding argument " << Edit << " at end\n"; 1502cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor Args.push_back(SaveStringInSet(SavedStrings, '-' + Edit.str())); 1512cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor } else { 1522cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor OS << "### Unrecognized edit: " << Edit << "\n"; 1532cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor } 1542cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor} 1552cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 1562cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor/// ApplyQAOverride - Apply a comma separate list of edits to the 1572cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor/// input argument lists. See ApplyOneQAOverride. 1582cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregorstatic void ApplyQAOverride(SmallVectorImpl<const char*> &Args, 1592cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor const char *OverrideStr, 1602cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor std::set<std::string> &SavedStrings) { 1612cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor raw_ostream *OS = &llvm::errs(); 1622cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 1632cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor if (OverrideStr[0] == '#') { 1642cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor ++OverrideStr; 1652cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor OS = &llvm::nulls(); 1662cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor } 1672cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 1682cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor *OS << "### QA_OVERRIDE_GCC3_OPTIONS: " << OverrideStr << "\n"; 1692cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 1702cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor // This does not need to be efficient. 1712cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 1722cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor const char *S = OverrideStr; 173c9490c000f515c29f200a1215328d8ab9a0f3818Douglas Gregor while (*S) { 1742cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor const char *End = ::strchr(S, ' '); 1752cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor if (!End) 1762cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor End = S + strlen(S); 1772cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor if (End != S) 1782cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor ApplyOneQAOverride(*OS, Args, std::string(S, End), SavedStrings); 1792cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor S = End; 1802cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor if (*S != '\0') 1812cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor ++S; 1822cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor } 1832cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor} 1842cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 1852cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregorextern int cc1_main(const char **ArgBegin, const char **ArgEnd, 1862cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor const char *Argv0, void *MainAddr); 1872cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregorextern int cc1as_main(const char **ArgBegin, const char **ArgEnd, 1882cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor const char *Argv0, void *MainAddr); 1892cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 1902cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregorstatic void ExpandArgsFromBuf(const char *Arg, 1912cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor SmallVectorImpl<const char*> &ArgVector, 1922cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor std::set<std::string> &SavedStrings) { 1932cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor const char *FName = Arg + 1; 1942cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor OwningPtr<llvm::MemoryBuffer> MemBuf; 1952cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor if (llvm::MemoryBuffer::getFile(FName, MemBuf)) { 1962cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor ArgVector.push_back(SaveStringInSet(SavedStrings, Arg)); 1972cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor return; 1982cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor } 1992cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 2002cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor const char *Buf = MemBuf->getBufferStart(); 2016a2bfb2ead4489db37e80b696a6d7cc073c76fd7Douglas Gregor char InQuote = ' '; 2022cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor std::string CurArg; 2032cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 2042cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor for (const char *P = Buf; ; ++P) { 2052cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor if (*P == '\0' || (isspace(*P) && InQuote == ' ')) { 2066a2bfb2ead4489db37e80b696a6d7cc073c76fd7Douglas Gregor if (!CurArg.empty()) { 2072cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 2082cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor if (CurArg[0] != '@') { 2092cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor ArgVector.push_back(SaveStringInSet(SavedStrings, CurArg)); 2102cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor } else { 2112cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor ExpandArgsFromBuf(CurArg.c_str(), ArgVector, SavedStrings); 2122cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor } 2132cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 2142cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor CurArg = ""; 2152cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor } 2162cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor if (*P == '\0') 2172cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor break; 2182cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor else 2192cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor continue; 2202cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor } 2212cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 2222cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor if (isspace(*P)) { 2232cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor if (InQuote != ' ') 2242cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor CurArg.push_back(*P); 2252cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor continue; 2262cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor } 2272cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 2282cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor if (*P == '"' || *P == '\'') { 2292cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor if (InQuote == *P) 2302cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor InQuote = ' '; 2312cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor else if (InQuote == ' ') 2322cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor InQuote = *P; 2332cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor else 2342cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor CurArg.push_back(*P); 2352cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor continue; 2362cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor } 2372cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 2382cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor if (*P == '\\') { 2392cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor ++P; 2407297134f128423fce2e88f92421ed135bded7d4eDouglas Gregor if (*P != '\0') 2412cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor CurArg.push_back(*P); 2422cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor continue; 2432cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor } 2442cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor CurArg.push_back(*P); 2452cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor } 2467297134f128423fce2e88f92421ed135bded7d4eDouglas Gregor} 2477297134f128423fce2e88f92421ed135bded7d4eDouglas Gregor 2487297134f128423fce2e88f92421ed135bded7d4eDouglas Gregorstatic void ExpandArgv(int argc, const char **argv, 2492cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor SmallVectorImpl<const char*> &ArgVector, 2502cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor std::set<std::string> &SavedStrings) { 2512cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor for (int i = 0; i < argc; ++i) { 2522cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor const char *Arg = argv[i]; 2532cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor if (Arg[0] != '@') { 2542cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor ArgVector.push_back(SaveStringInSet(SavedStrings, std::string(Arg))); 2550a2b45e5885b6b8477b167042c0f6cd1d99a1f13Douglas Gregor continue; 2560a2b45e5885b6b8477b167042c0f6cd1d99a1f13Douglas Gregor } 2578c70006581a9b9e9485570ca727a6c5f7be63521Douglas Gregor 2582cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor ExpandArgsFromBuf(Arg, ArgVector, SavedStrings); 2590a2b45e5885b6b8477b167042c0f6cd1d99a1f13Douglas Gregor } 2603a2f7e42514ddbec983c61826ce85d3071e23e8eDouglas Gregor} 2618c70006581a9b9e9485570ca727a6c5f7be63521Douglas Gregor 2622cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregorstatic void ParseProgName(SmallVectorImpl<const char *> &ArgVector, 2633a2f7e42514ddbec983c61826ce85d3071e23e8eDouglas Gregor std::set<std::string> &SavedStrings, 2643a2f7e42514ddbec983c61826ce85d3071e23e8eDouglas Gregor Driver &TheDriver) 2651028bc67d56ea088c3a57c4c44c3f6aeff60a031Douglas Gregor{ 2661028bc67d56ea088c3a57c4c44c3f6aeff60a031Douglas Gregor // Try to infer frontend type and default target from the program name. 2672cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 2682cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor // suffixes[] contains the list of known driver suffixes. 26953c9d8a4b8f0a76cb9dd2fdd8c433ccf110f2eecSteve Naroff // Suffixes are compared against the program name in order. 27033feeb019a5742b286eededd5446ec0fe87c5a61Steve Naroff // If there is a match, the frontend type is updated as necessary (CPP/C++). 27133feeb019a5742b286eededd5446ec0fe87c5a61Steve Naroff // If there is no match, a second round is done after stripping the last 27233feeb019a5742b286eededd5446ec0fe87c5a61Steve Naroff // hyphen and everything following it. This allows using something like 27330833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff // "clang++-2.9". 27430833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff 27530833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff // If there is a match in either the first or second round, 27630833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff // the function tries to identify a target as prefix. E.g. 27730833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff // "x86_64-linux-clang" as interpreted as suffix "clang" with 27830833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff // target prefix "x86_64-linux". If such a target prefix is found, 27930833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff // is gets added via -target as implicit first argument. 28030833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff static const struct { 28130833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff const char *Suffix; 28230833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff bool IsCXX; 28330833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff bool IsCPP; 2842cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor } suffixes [] = { 2852cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor { "clang", false, false }, 2862cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor { "clang++", true, false }, 2872cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor { "clang-c++", true, false }, 2882cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor { "clang-cc", false, false }, 2892cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor { "clang-cpp", false, true }, 2902cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor { "clang-g++", true, false }, 2912cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor { "clang-gcc", false, false }, 29268a2eb0cc76267ba0615992fb5e0977853c397b2Douglas Gregor { "cc", false, false }, 2932cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor { "cpp", false, true }, 2942cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor { "++", true, false }, 2952cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor }; 2962cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor std::string ProgName(llvm::sys::path::stem(ArgVector[0])); 2972cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor StringRef ProgNameRef(ProgName); 2982cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor StringRef Prefix; 2992cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 3002cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor for (int Components = 2; Components; --Components) { 3012cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor bool FoundMatch = false; 3022cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor size_t i; 3032cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 3042cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor for (i = 0; i < sizeof(suffixes) / sizeof(suffixes[0]); ++i) { 3052cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor if (ProgNameRef.endswith(suffixes[i].Suffix)) { 3062cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor FoundMatch = true; 3072cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor if (suffixes[i].IsCXX) 3082cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor TheDriver.CCCIsCXX = true; 3092cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor if (suffixes[i].IsCPP) 3102cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor TheDriver.CCCIsCPP = true; 3112cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor break; 3122cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor } 3132cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor } 3142cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 3152cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor if (FoundMatch) { 3162cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor StringRef::size_type LastComponent = ProgNameRef.rfind('-', 3172cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor ProgNameRef.size() - strlen(suffixes[i].Suffix)); 3180a2b45e5885b6b8477b167042c0f6cd1d99a1f13Douglas Gregor if (LastComponent != StringRef::npos) 3190a2b45e5885b6b8477b167042c0f6cd1d99a1f13Douglas Gregor Prefix = ProgNameRef.slice(0, LastComponent); 3200a2b45e5885b6b8477b167042c0f6cd1d99a1f13Douglas Gregor break; 3210a2b45e5885b6b8477b167042c0f6cd1d99a1f13Douglas Gregor } 3220a2b45e5885b6b8477b167042c0f6cd1d99a1f13Douglas Gregor 3230a2b45e5885b6b8477b167042c0f6cd1d99a1f13Douglas Gregor StringRef::size_type LastComponent = ProgNameRef.rfind('-'); 3240a2b45e5885b6b8477b167042c0f6cd1d99a1f13Douglas Gregor if (LastComponent == StringRef::npos) 3250a2b45e5885b6b8477b167042c0f6cd1d99a1f13Douglas Gregor break; 3260a2b45e5885b6b8477b167042c0f6cd1d99a1f13Douglas Gregor ProgNameRef = ProgNameRef.slice(0, LastComponent); 3270a2b45e5885b6b8477b167042c0f6cd1d99a1f13Douglas Gregor } 3280a2b45e5885b6b8477b167042c0f6cd1d99a1f13Douglas Gregor 3290a2b45e5885b6b8477b167042c0f6cd1d99a1f13Douglas Gregor if (Prefix.empty()) 3300a2b45e5885b6b8477b167042c0f6cd1d99a1f13Douglas Gregor return; 3318c70006581a9b9e9485570ca727a6c5f7be63521Douglas Gregor 3328c70006581a9b9e9485570ca727a6c5f7be63521Douglas Gregor std::string IgnoredError; 3338c70006581a9b9e9485570ca727a6c5f7be63521Douglas Gregor if (llvm::TargetRegistry::lookupTarget(Prefix, IgnoredError)) { 3348c70006581a9b9e9485570ca727a6c5f7be63521Douglas Gregor SmallVectorImpl<const char *>::iterator it = ArgVector.begin(); 3358c70006581a9b9e9485570ca727a6c5f7be63521Douglas Gregor if (it != ArgVector.end()) 3368c70006581a9b9e9485570ca727a6c5f7be63521Douglas Gregor ++it; 3378c70006581a9b9e9485570ca727a6c5f7be63521Douglas Gregor ArgVector.insert(it, SaveStringInSet(SavedStrings, Prefix)); 3382cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor ArgVector.insert(it, 3392cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor SaveStringInSet(SavedStrings, std::string("-target"))); 3402cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor } 3412cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor} 3422cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 3430a2b45e5885b6b8477b167042c0f6cd1d99a1f13Douglas Gregorint main(int argc_, const char **argv_) { 3440a2b45e5885b6b8477b167042c0f6cd1d99a1f13Douglas Gregor llvm::sys::PrintStackTraceOnErrorSignal(); 3450b7489194f9f89fac39d57211c1e7953ae50251fDouglas Gregor llvm::PrettyStackTraceProgram X(argc_, argv_); 3460b7489194f9f89fac39d57211c1e7953ae50251fDouglas Gregor 347c9490c000f515c29f200a1215328d8ab9a0f3818Douglas Gregor std::set<std::string> SavedStrings; 3480a2b45e5885b6b8477b167042c0f6cd1d99a1f13Douglas Gregor SmallVector<const char*, 256> argv; 3490a2b45e5885b6b8477b167042c0f6cd1d99a1f13Douglas Gregor 3500a2b45e5885b6b8477b167042c0f6cd1d99a1f13Douglas Gregor ExpandArgv(argc_, argv_, argv, SavedStrings); 3510a2b45e5885b6b8477b167042c0f6cd1d99a1f13Douglas Gregor 3523a2f7e42514ddbec983c61826ce85d3071e23e8eDouglas Gregor // Handle -cc1 integrated tools. 3533a2f7e42514ddbec983c61826ce85d3071e23e8eDouglas Gregor if (argv.size() > 1 && StringRef(argv[1]).startswith("-cc1")) { 354025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor StringRef Tool = argv[1] + 4; 355025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor 3567297134f128423fce2e88f92421ed135bded7d4eDouglas Gregor if (Tool == "") 3573a2f7e42514ddbec983c61826ce85d3071e23e8eDouglas Gregor return cc1_main(argv.data()+2, argv.data()+argv.size(), argv[0], 3583a2f7e42514ddbec983c61826ce85d3071e23e8eDouglas Gregor (void*) (intptr_t) GetExecutablePath); 3593a2f7e42514ddbec983c61826ce85d3071e23e8eDouglas Gregor if (Tool == "as") 360b3efa98e320590e8be9d62818e89e599303e65b4Douglas Gregor return cc1as_main(argv.data()+2, argv.data()+argv.size(), argv[0], 3613a2f7e42514ddbec983c61826ce85d3071e23e8eDouglas Gregor (void*) (intptr_t) GetExecutablePath); 3623a2f7e42514ddbec983c61826ce85d3071e23e8eDouglas Gregor 3633a2f7e42514ddbec983c61826ce85d3071e23e8eDouglas Gregor // Reject unknown tools. 3643a2f7e42514ddbec983c61826ce85d3071e23e8eDouglas Gregor llvm::errs() << "error: unknown integrated tool '" << Tool << "'\n"; 3653a2f7e42514ddbec983c61826ce85d3071e23e8eDouglas Gregor return 1; 3663a2f7e42514ddbec983c61826ce85d3071e23e8eDouglas Gregor } 3673a2f7e42514ddbec983c61826ce85d3071e23e8eDouglas Gregor 3683a2f7e42514ddbec983c61826ce85d3071e23e8eDouglas Gregor bool CanonicalPrefixes = true; 3693a2f7e42514ddbec983c61826ce85d3071e23e8eDouglas Gregor for (int i = 1, size = argv.size(); i < size; ++i) { 3703a2f7e42514ddbec983c61826ce85d3071e23e8eDouglas Gregor if (StringRef(argv[i]) == "-no-canonical-prefixes") { 3713a2f7e42514ddbec983c61826ce85d3071e23e8eDouglas Gregor CanonicalPrefixes = false; 3723a2f7e42514ddbec983c61826ce85d3071e23e8eDouglas Gregor break; 3733a2f7e42514ddbec983c61826ce85d3071e23e8eDouglas Gregor } 37453c9d8a4b8f0a76cb9dd2fdd8c433ccf110f2eecSteve Naroff } 37553c9d8a4b8f0a76cb9dd2fdd8c433ccf110f2eecSteve Naroff 37653c9d8a4b8f0a76cb9dd2fdd8c433ccf110f2eecSteve Naroff llvm::sys::Path Path = GetExecutablePath(argv[0], CanonicalPrefixes); 37753c9d8a4b8f0a76cb9dd2fdd8c433ccf110f2eecSteve Naroff 37853c9d8a4b8f0a76cb9dd2fdd8c433ccf110f2eecSteve Naroff IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions; 37953c9d8a4b8f0a76cb9dd2fdd8c433ccf110f2eecSteve Naroff { 38053c9d8a4b8f0a76cb9dd2fdd8c433ccf110f2eecSteve Naroff // Note that ParseDiagnosticArgs() uses the cc1 option table. 38153c9d8a4b8f0a76cb9dd2fdd8c433ccf110f2eecSteve Naroff OwningPtr<OptTable> CC1Opts(createDriverOptTable()); 38253c9d8a4b8f0a76cb9dd2fdd8c433ccf110f2eecSteve Naroff unsigned MissingArgIndex, MissingArgCount; 38353c9d8a4b8f0a76cb9dd2fdd8c433ccf110f2eecSteve Naroff OwningPtr<InputArgList> Args(CC1Opts->ParseArgs(argv.begin()+1, argv.end(), 38453c9d8a4b8f0a76cb9dd2fdd8c433ccf110f2eecSteve Naroff MissingArgIndex, MissingArgCount)); 38553c9d8a4b8f0a76cb9dd2fdd8c433ccf110f2eecSteve Naroff // We ignore MissingArgCount and the return value of ParseDiagnosticArgs. 38653c9d8a4b8f0a76cb9dd2fdd8c433ccf110f2eecSteve Naroff // Any errors that would be diagnosed here will also be diagnosed later, 38753c9d8a4b8f0a76cb9dd2fdd8c433ccf110f2eecSteve Naroff // when the DiagnosticsEngine actually exists. 38853c9d8a4b8f0a76cb9dd2fdd8c433ccf110f2eecSteve Naroff (void) ParseDiagnosticArgs(*DiagOpts, *Args); 38953c9d8a4b8f0a76cb9dd2fdd8c433ccf110f2eecSteve Naroff } 39053c9d8a4b8f0a76cb9dd2fdd8c433ccf110f2eecSteve Naroff // Now we can create the DiagnosticsEngine with a properly-filled-out 39153c9d8a4b8f0a76cb9dd2fdd8c433ccf110f2eecSteve Naroff // DiagnosticOptions instance. 39253c9d8a4b8f0a76cb9dd2fdd8c433ccf110f2eecSteve Naroff TextDiagnosticPrinter *DiagClient 39353c9d8a4b8f0a76cb9dd2fdd8c433ccf110f2eecSteve Naroff = new TextDiagnosticPrinter(llvm::errs(), &*DiagOpts); 39453c9d8a4b8f0a76cb9dd2fdd8c433ccf110f2eecSteve Naroff DiagClient->setPrefix(llvm::sys::path::stem(Path.str())); 39553c9d8a4b8f0a76cb9dd2fdd8c433ccf110f2eecSteve Naroff IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); 39653c9d8a4b8f0a76cb9dd2fdd8c433ccf110f2eecSteve Naroff 39753c9d8a4b8f0a76cb9dd2fdd8c433ccf110f2eecSteve Naroff DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagClient); 39853c9d8a4b8f0a76cb9dd2fdd8c433ccf110f2eecSteve Naroff ProcessWarningOptions(Diags, *DiagOpts); 39953c9d8a4b8f0a76cb9dd2fdd8c433ccf110f2eecSteve Naroff 40033feeb019a5742b286eededd5446ec0fe87c5a61Steve Naroff Driver TheDriver(Path.str(), llvm::sys::getDefaultTargetTriple(), 40133feeb019a5742b286eededd5446ec0fe87c5a61Steve Naroff "a.out", Diags); 40233feeb019a5742b286eededd5446ec0fe87c5a61Steve Naroff 40333feeb019a5742b286eededd5446ec0fe87c5a61Steve Naroff // Attempt to find the original path used to invoke the driver, to determine 40433feeb019a5742b286eededd5446ec0fe87c5a61Steve Naroff // the installed path. We do this manually, because we want to support that 40533feeb019a5742b286eededd5446ec0fe87c5a61Steve Naroff // path being a symlink. 40633feeb019a5742b286eededd5446ec0fe87c5a61Steve Naroff { 40733feeb019a5742b286eededd5446ec0fe87c5a61Steve Naroff SmallString<128> InstalledPath(argv[0]); 40833feeb019a5742b286eededd5446ec0fe87c5a61Steve Naroff 40933feeb019a5742b286eededd5446ec0fe87c5a61Steve Naroff // Do a PATH lookup, if there are no directory components. 410291be393aa33759e6e34b6429c5ffa206ba50115Douglas Gregor if (llvm::sys::path::filename(InstalledPath) == InstalledPath) { 411291be393aa33759e6e34b6429c5ffa206ba50115Douglas Gregor llvm::sys::Path Tmp = llvm::sys::Program::FindProgramByName( 412291be393aa33759e6e34b6429c5ffa206ba50115Douglas Gregor llvm::sys::path::filename(InstalledPath.str())); 413291be393aa33759e6e34b6429c5ffa206ba50115Douglas Gregor if (!Tmp.empty()) 414291be393aa33759e6e34b6429c5ffa206ba50115Douglas Gregor InstalledPath = Tmp.str(); 41533feeb019a5742b286eededd5446ec0fe87c5a61Steve Naroff } 41633feeb019a5742b286eededd5446ec0fe87c5a61Steve Naroff llvm::sys::fs::make_absolute(InstalledPath); 41733feeb019a5742b286eededd5446ec0fe87c5a61Steve Naroff InstalledPath = llvm::sys::path::parent_path(InstalledPath); 41833feeb019a5742b286eededd5446ec0fe87c5a61Steve Naroff bool exists; 419133f482ddc2704ebcb23e2a743f1812173a42e91Douglas Gregor if (!llvm::sys::fs::exists(InstalledPath.str(), exists) && exists) 42033feeb019a5742b286eededd5446ec0fe87c5a61Steve Naroff TheDriver.setInstalledDir(InstalledPath); 42133feeb019a5742b286eededd5446ec0fe87c5a61Steve Naroff } 42233feeb019a5742b286eededd5446ec0fe87c5a61Steve Naroff 42333feeb019a5742b286eededd5446ec0fe87c5a61Steve Naroff llvm::InitializeAllTargets(); 42433feeb019a5742b286eededd5446ec0fe87c5a61Steve Naroff ParseProgName(argv, SavedStrings, TheDriver); 42530833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff 42633feeb019a5742b286eededd5446ec0fe87c5a61Steve Naroff // Handle CC_PRINT_OPTIONS and CC_PRINT_OPTIONS_FILE. 42733feeb019a5742b286eededd5446ec0fe87c5a61Steve Naroff TheDriver.CCPrintOptions = !!::getenv("CC_PRINT_OPTIONS"); 42833feeb019a5742b286eededd5446ec0fe87c5a61Steve Naroff if (TheDriver.CCPrintOptions) 42933feeb019a5742b286eededd5446ec0fe87c5a61Steve Naroff TheDriver.CCPrintOptionsFilename = ::getenv("CC_PRINT_OPTIONS_FILE"); 43033feeb019a5742b286eededd5446ec0fe87c5a61Steve Naroff 43133feeb019a5742b286eededd5446ec0fe87c5a61Steve Naroff // Handle CC_PRINT_HEADERS and CC_PRINT_HEADERS_FILE. 43230833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff TheDriver.CCPrintHeaders = !!::getenv("CC_PRINT_HEADERS"); 43330833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff if (TheDriver.CCPrintHeaders) 43430833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff TheDriver.CCPrintHeadersFilename = ::getenv("CC_PRINT_HEADERS_FILE"); 43530833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff 43630833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff // Handle CC_LOG_DIAGNOSTICS and CC_LOG_DIAGNOSTICS_FILE. 43730833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff TheDriver.CCLogDiagnostics = !!::getenv("CC_LOG_DIAGNOSTICS"); 43830833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff if (TheDriver.CCLogDiagnostics) 43930833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff TheDriver.CCLogDiagnosticsFilename = ::getenv("CC_LOG_DIAGNOSTICS_FILE"); 44030833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff 44130833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff // Handle QA_OVERRIDE_GCC3_OPTIONS and CCC_ADD_ARGS, used for editing a 44230833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff // command line behind the scenes. 44330833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff if (const char *OverrideStr = ::getenv("QA_OVERRIDE_GCC3_OPTIONS")) { 44430833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff // FIXME: Driver shouldn't take extra initial argument. 44530833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff ApplyQAOverride(argv, OverrideStr, SavedStrings); 44630833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff } else if (const char *Cur = ::getenv("CCC_ADD_ARGS")) { 44730833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff // FIXME: Driver shouldn't take extra initial argument. 44830833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff std::vector<const char*> ExtraArgs; 44930833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff 45030833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff for (;;) { 45130833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff const char *Next = strchr(Cur, ','); 45230833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff 45330833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff if (Next) { 45430833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff ExtraArgs.push_back(SaveStringInSet(SavedStrings, 45530833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff std::string(Cur, Next))); 45630833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff Cur = Next + 1; 45730833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff } else { 45830833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff if (*Cur != '\0') 45930833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff ExtraArgs.push_back(SaveStringInSet(SavedStrings, Cur)); 46030833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff break; 46130833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff } 46230833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff } 46330833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff 46430833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff argv.insert(&argv[1], ExtraArgs.begin(), ExtraArgs.end()); 46530833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff } 46630833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff 46730833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff OwningPtr<Compilation> C(TheDriver.BuildCompilation(argv)); 46830833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff int Res = 0; 46930833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff const Command *FailingCommand = 0; 47030833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff if (C.get()) 47130833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff Res = TheDriver.ExecuteCompilation(*C, FailingCommand); 47230833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff 47330833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff // Force a crash to test the diagnostics. 47430833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff if (::getenv("FORCE_CLANG_DIAGNOSTICS_CRASH")) { 47530833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff Diags.Report(diag::err_drv_force_crash) << "FORCE_CLANG_DIAGNOSTICS_CRASH"; 47630833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff Res = -1; 47730833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff } 47830833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff 47930833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff // If result status is < 0, then the driver command signalled an error. 48030833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff // If result status is 70, then the driver command reported a fatal error. 48130833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff // In these cases, generate additional diagnostic information if possible. 48230833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff if (Res < 0 || Res == 70) 48330833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff TheDriver.generateCompilationDiagnostics(*C, FailingCommand); 48430833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff 48530833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff // If any timers were active but haven't been destroyed yet, print their 48630833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff // results now. This happens in -disable-free mode. 48730833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff llvm::TimerGroup::printAll(llvm::errs()); 48870e5a14c6076d63833c62d1d6d628c26309897c1Douglas Gregor 48970e5a14c6076d63833c62d1d6d628c26309897c1Douglas Gregor llvm::llvm_shutdown(); 49070e5a14c6076d63833c62d1d6d628c26309897c1Douglas Gregor 49170e5a14c6076d63833c62d1d6d628c26309897c1Douglas Gregor#ifdef _WIN32 49270e5a14c6076d63833c62d1d6d628c26309897c1Douglas Gregor // Exit status should not be negative on Win32, unless abnormal termination. 49370e5a14c6076d63833c62d1d6d628c26309897c1Douglas Gregor // Once abnormal termiation was caught, negative status should not be 49470e5a14c6076d63833c62d1d6d628c26309897c1Douglas Gregor // propagated. 49570e5a14c6076d63833c62d1d6d628c26309897c1Douglas Gregor if (Res < 0) 49670e5a14c6076d63833c62d1d6d628c26309897c1Douglas Gregor Res = 1; 49770e5a14c6076d63833c62d1d6d628c26309897c1Douglas Gregor#endif 49830833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff 49930833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff return Res; 50030833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff} 50130833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff