driver.cpp revision 2dec85b21822f950bf6035640c496ad835e11728
18852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry//===-- driver.cpp - Clang GCC-Compatible Driver --------------------------===// 28852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry// 38852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry// The LLVM Compiler Infrastructure 48852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry// 58852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry// This file is distributed under the University of Illinois Open Source 68852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry// License. See LICENSE.TXT for details. 78852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry// 88852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry//===----------------------------------------------------------------------===// 98852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry// 108852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry// This is the entry point to the clang driver; it is a thin wrapper 118852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry// for functionality in the Driver clang library. 128852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry// 138852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry//===----------------------------------------------------------------------===// 148852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 158852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#include "clang/Driver/ArgList.h" 168852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#include "clang/Driver/CC1Options.h" 178852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#include "clang/Driver/Compilation.h" 188852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#include "clang/Driver/Driver.h" 198852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#include "clang/Driver/Option.h" 208852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#include "clang/Driver/OptTable.h" 218852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#include "clang/Frontend/CompilerInvocation.h" 228852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#include "clang/Frontend/DiagnosticOptions.h" 238852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#include "clang/Frontend/TextDiagnosticPrinter.h" 248852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#include "clang/Frontend/Utils.h" 258852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 268852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#include "llvm/ADT/ArrayRef.h" 278852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#include "llvm/ADT/SmallString.h" 288852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#include "llvm/ADT/SmallVector.h" 298852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#include "llvm/ADT/OwningPtr.h" 308852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#include "llvm/Support/ErrorHandling.h" 318852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#include "llvm/Support/FileSystem.h" 328852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#include "llvm/Support/ManagedStatic.h" 338852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#include "llvm/Support/MemoryBuffer.h" 348852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#include "llvm/Support/PrettyStackTrace.h" 358852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#include "llvm/Support/Regex.h" 368852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#include "llvm/Support/Timer.h" 378852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#include "llvm/Support/raw_ostream.h" 388852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#include "llvm/Support/Host.h" 398852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#include "llvm/Support/Path.h" 408852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#include "llvm/Support/Program.h" 418852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#include "llvm/Support/Signals.h" 428852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#include "llvm/Support/TargetRegistry.h" 438852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#include "llvm/Support/TargetSelect.h" 448852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#include "llvm/Support/system_error.h" 458852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#include <cctype> 468852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryusing namespace clang; 478852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryusing namespace clang::driver; 488852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 498852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryllvm::sys::Path GetExecutablePath(const char *Argv0, bool CanonicalPrefixes) { 508852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (!CanonicalPrefixes) 518852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry return llvm::sys::Path(Argv0); 528852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 538852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // This just needs to be some symbol in the binary; C++ doesn't 548852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // allow taking the address of ::main however. 558852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry void *P = (void*) (intptr_t) GetExecutablePath; 568852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry return llvm::sys::Path::GetMainExecutable(Argv0, P); 578852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry} 588852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 598852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyrystatic const char *SaveStringInSet(std::set<std::string> &SavedStrings, 608852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry StringRef S) { 618852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry return SavedStrings.insert(S).first->c_str(); 628852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry} 638852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 648852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry/// ApplyQAOverride - Apply a list of edits to the input argument lists. 658852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry/// 668852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry/// The input string is a space separate list of edits to perform, 678852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry/// they are applied in order to the input argument lists. Edits 688852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry/// should be one of the following forms: 698852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry/// 708852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry/// '#': Silence information about the changes to the command line arguments. 718852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry/// 728852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry/// '^': Add FOO as a new argument at the beginning of the command line. 738852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry/// 748852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry/// '+': Add FOO as a new argument at the end of the command line. 758852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry/// 768852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry/// 's/XXX/YYY/': Substitute the regular expression XXX with YYY in the command 778852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry/// line. 788852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry/// 798852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry/// 'xOPTION': Removes all instances of the literal argument OPTION. 808852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry/// 818852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry/// 'XOPTION': Removes all instances of the literal argument OPTION, 828852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry/// and the following argument. 838852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry/// 848852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry/// 'Ox': Removes all flags matching 'O' or 'O[sz0-9]' and adds 'Ox' 858852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry/// at the end of the command line. 868852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry/// 878852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry/// \param OS - The stream to write edit information to. 888852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry/// \param Args - The vector of command line arguments. 898852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry/// \param Edit - The override command to perform. 908852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry/// \param SavedStrings - Set to use for storing string representations. 918852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyrystatic void ApplyOneQAOverride(raw_ostream &OS, 928852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry SmallVectorImpl<const char*> &Args, 938852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry StringRef Edit, 948852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry std::set<std::string> &SavedStrings) { 958852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // This does not need to be efficient. 968852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 978852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (Edit[0] == '^') { 988852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const char *Str = 998852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry SaveStringInSet(SavedStrings, Edit.substr(1)); 1008852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry OS << "### Adding argument " << Str << " at beginning\n"; 1018852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry Args.insert(Args.begin() + 1, Str); 1028852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } else if (Edit[0] == '+') { 1038852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const char *Str = 1048852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry SaveStringInSet(SavedStrings, Edit.substr(1)); 1058852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry OS << "### Adding argument " << Str << " at end\n"; 1068852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry Args.push_back(Str); 1078852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } else if (Edit[0] == 's' && Edit[1] == '/' && Edit.endswith("/") && 1088852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry Edit.slice(2, Edit.size()-1).find('/') != StringRef::npos) { 1098852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry StringRef MatchPattern = Edit.substr(2).split('/').first; 1108852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry StringRef ReplPattern = Edit.substr(2).split('/').second; 1118852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry ReplPattern = ReplPattern.slice(0, ReplPattern.size()-1); 1128852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 1138852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry for (unsigned i = 1, e = Args.size(); i != e; ++i) { 1148852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry std::string Repl = llvm::Regex(MatchPattern).sub(ReplPattern, Args[i]); 1158852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 1168852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (Repl != Args[i]) { 1178852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry OS << "### Replacing '" << Args[i] << "' with '" << Repl << "'\n"; 1188852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry Args[i] = SaveStringInSet(SavedStrings, Repl); 1198852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 1208852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 1218852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } else if (Edit[0] == 'x' || Edit[0] == 'X') { 1228852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry std::string Option = Edit.substr(1, std::string::npos); 1238852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry for (unsigned i = 1; i < Args.size();) { 1248852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (Option == Args[i]) { 1258852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry OS << "### Deleting argument " << Args[i] << '\n'; 1268852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry Args.erase(Args.begin() + i); 1278852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (Edit[0] == 'X') { 1288852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (i < Args.size()) { 1298852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry OS << "### Deleting argument " << Args[i] << '\n'; 1308852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry Args.erase(Args.begin() + i); 1318852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } else 1328852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry OS << "### Invalid X edit, end of command line!\n"; 1338852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 1348852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } else 1358852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry ++i; 1368852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 1378852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } else if (Edit[0] == 'O') { 1388852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry for (unsigned i = 1; i < Args.size();) { 1398852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const char *A = Args[i]; 1408852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (A[0] == '-' && A[1] == 'O' && 1418852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry (A[2] == '\0' || 1428852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry (A[3] == '\0' && (A[2] == 's' || A[2] == 'z' || 1438852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry ('0' <= A[2] && A[2] <= '9'))))) { 1448852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry OS << "### Deleting argument " << Args[i] << '\n'; 1458852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry Args.erase(Args.begin() + i); 1468852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } else 1478852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry ++i; 1488852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 1498852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry OS << "### Adding argument " << Edit << " at end\n"; 1508852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry Args.push_back(SaveStringInSet(SavedStrings, '-' + Edit.str())); 1518852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } else { 1528852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry OS << "### Unrecognized edit: " << Edit << "\n"; 1538852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 1548852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry} 1558852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 1568852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry/// ApplyQAOverride - Apply a comma separate list of edits to the 1578852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry/// input argument lists. See ApplyOneQAOverride. 1588852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyrystatic void ApplyQAOverride(SmallVectorImpl<const char*> &Args, 1598852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const char *OverrideStr, 1608852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry std::set<std::string> &SavedStrings) { 1618852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry raw_ostream *OS = &llvm::errs(); 1628852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 1638852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (OverrideStr[0] == '#') { 1648852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry ++OverrideStr; 1658852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry OS = &llvm::nulls(); 1668852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 1678852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 1688852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry *OS << "### QA_OVERRIDE_GCC3_OPTIONS: " << OverrideStr << "\n"; 1698852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 1708852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // This does not need to be efficient. 1718852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 1728852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const char *S = OverrideStr; 1738852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry while (*S) { 1748852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const char *End = ::strchr(S, ' '); 1758852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (!End) 1768852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry End = S + strlen(S); 1778852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (End != S) 1788852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry ApplyOneQAOverride(*OS, Args, std::string(S, End), SavedStrings); 1798852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry S = End; 1808852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (*S != '\0') 1818852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry ++S; 1828852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 1838852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry} 1848852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 1858852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryextern int cc1_main(const char **ArgBegin, const char **ArgEnd, 1868852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const char *Argv0, void *MainAddr); 1878852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryextern int cc1as_main(const char **ArgBegin, const char **ArgEnd, 1888852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const char *Argv0, void *MainAddr); 1898852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 1908852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyrystatic void ExpandArgsFromBuf(const char *Arg, 1918852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry SmallVectorImpl<const char*> &ArgVector, 1928852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry std::set<std::string> &SavedStrings) { 1938852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const char *FName = Arg + 1; 1948852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry OwningPtr<llvm::MemoryBuffer> MemBuf; 1958852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (llvm::MemoryBuffer::getFile(FName, MemBuf)) { 1968852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry ArgVector.push_back(SaveStringInSet(SavedStrings, Arg)); 1978852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry return; 1988852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 1998852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 2008852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const char *Buf = MemBuf->getBufferStart(); 2018852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry char InQuote = ' '; 2028852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry std::string CurArg; 2038852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 2048852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry for (const char *P = Buf; ; ++P) { 2058852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (*P == '\0' || (isspace(*P) && InQuote == ' ')) { 2068852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (!CurArg.empty()) { 2078852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 2088852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (CurArg[0] != '@') { 2098852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry ArgVector.push_back(SaveStringInSet(SavedStrings, CurArg)); 2108852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } else { 2118852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry ExpandArgsFromBuf(CurArg.c_str(), ArgVector, SavedStrings); 2128852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 2138852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 2148852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry CurArg = ""; 2158852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 2168852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (*P == '\0') 2178852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry break; 2188852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry else 2198852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry continue; 2208852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 2218852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 2228852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (isspace(*P)) { 2238852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (InQuote != ' ') 2248852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry CurArg.push_back(*P); 2258852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry continue; 2268852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 2278852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 2288852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (*P == '"' || *P == '\'') { 2298852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (InQuote == *P) 2308852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry InQuote = ' '; 2318852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry else if (InQuote == ' ') 2328852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry InQuote = *P; 2338852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry else 2348852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry CurArg.push_back(*P); 2358852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry continue; 2368852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 2378852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 2388852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (*P == '\\') { 2398852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry ++P; 2408852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (*P != '\0') 2418852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry CurArg.push_back(*P); 2428852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry continue; 2438852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 2448852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry CurArg.push_back(*P); 2458852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 2468852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry} 2478852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 2488852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyrystatic void ExpandArgv(int argc, const char **argv, 2498852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry SmallVectorImpl<const char*> &ArgVector, 2508852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry std::set<std::string> &SavedStrings) { 2518852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry for (int i = 0; i < argc; ++i) { 2528852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const char *Arg = argv[i]; 2538852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (Arg[0] != '@') { 2548852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry ArgVector.push_back(SaveStringInSet(SavedStrings, std::string(Arg))); 2558852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry continue; 2568852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 2578852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 2588852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry ExpandArgsFromBuf(Arg, ArgVector, SavedStrings); 2598852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 2608852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry} 2618852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 2628852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyrystatic void ParseProgName(SmallVectorImpl<const char *> &ArgVector, 2638852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry std::set<std::string> &SavedStrings, 2648852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry Driver &TheDriver) 2658852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry{ 2668852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // Try to infer frontend type and default target from the program name. 2678852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 2688852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // suffixes[] contains the list of known driver suffixes. 2698852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // Suffixes are compared against the program name in order. 2708852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // If there is a match, the frontend type is updated as necessary (CPP/C++). 2718852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // If there is no match, a second round is done after stripping the last 2728852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // hyphen and everything following it. This allows using something like 2738852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // "clang++-2.9". 2748852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 2758852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // If there is a match in either the first or second round, 2768852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // the function tries to identify a target as prefix. E.g. 2778852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // "x86_64-linux-clang" as interpreted as suffix "clang" with 2788852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // target prefix "x86_64-linux". If such a target prefix is found, 2798852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // is gets added via -target as implicit first argument. 2808852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry static const struct { 2818852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const char *Suffix; 2828852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry bool IsCXX; 2838852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry bool IsCPP; 2848852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } suffixes [] = { 2858852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry { "clang", false, false }, 2868852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry { "clang++", true, false }, 2878852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry { "clang-c++", true, false }, 2888852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry { "clang-cc", false, false }, 2898852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry { "clang-cpp", false, true }, 2908852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry { "clang-g++", true, false }, 2918852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry { "clang-gcc", false, false }, 2928852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry { "cc", false, false }, 2938852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry { "cpp", false, true }, 2948852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry { "++", true, false }, 2958852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry }; 2968852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry std::string ProgName(llvm::sys::path::stem(ArgVector[0])); 2978852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry StringRef ProgNameRef(ProgName); 2988852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry StringRef Prefix; 2998852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 3008852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry for (int Components = 2; Components; --Components) { 3018852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry bool FoundMatch = false; 3028852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry size_t i; 3038852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 3048852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry for (i = 0; i < sizeof(suffixes) / sizeof(suffixes[0]); ++i) { 3058852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (ProgNameRef.endswith(suffixes[i].Suffix)) { 3068852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry FoundMatch = true; 3078852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (suffixes[i].IsCXX) 3088852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry TheDriver.CCCIsCXX = true; 3098852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (suffixes[i].IsCPP) 3108852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry TheDriver.CCCIsCPP = true; 3118852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry break; 3128852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 3138852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 3148852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 3158852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (FoundMatch) { 3168852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry StringRef::size_type LastComponent = ProgNameRef.rfind('-', 3178852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry ProgNameRef.size() - strlen(suffixes[i].Suffix)); 3188852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (LastComponent != StringRef::npos) 3198852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry Prefix = ProgNameRef.slice(0, LastComponent); 3208852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry break; 3218852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 3228852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 3238852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry StringRef::size_type LastComponent = ProgNameRef.rfind('-'); 3248852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (LastComponent == StringRef::npos) 3258852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry break; 3268852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry ProgNameRef = ProgNameRef.slice(0, LastComponent); 3278852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 3288852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 3298852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (Prefix.empty()) 3308852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry return; 3318852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 3328852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry std::string IgnoredError; 3338852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (llvm::TargetRegistry::lookupTarget(Prefix, IgnoredError)) { 3348852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry SmallVectorImpl<const char *>::iterator it = ArgVector.begin(); 3358852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (it != ArgVector.end()) 3368852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry ++it; 3378852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry ArgVector.insert(it, SaveStringInSet(SavedStrings, Prefix)); 3388852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry ArgVector.insert(it, 3398852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry SaveStringInSet(SavedStrings, std::string("-target"))); 3408852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 3418852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry} 3428852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 3438852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryint main(int argc_, const char **argv_) { 3448852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry llvm::sys::PrintStackTraceOnErrorSignal(); 3458852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry llvm::PrettyStackTraceProgram X(argc_, argv_); 3468852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 3478852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry std::set<std::string> SavedStrings; 3488852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry SmallVector<const char*, 256> argv; 3498852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 3508852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry ExpandArgv(argc_, argv_, argv, SavedStrings); 3518852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 3528852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // Handle -cc1 integrated tools. 3538852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (argv.size() > 1 && StringRef(argv[1]).startswith("-cc1")) { 3548852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry StringRef Tool = argv[1] + 4; 3558852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 3568852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (Tool == "") 3578852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry return cc1_main(argv.data()+2, argv.data()+argv.size(), argv[0], 3588852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry (void*) (intptr_t) GetExecutablePath); 3598852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (Tool == "as") 3608852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry return cc1as_main(argv.data()+2, argv.data()+argv.size(), argv[0], 3618852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry (void*) (intptr_t) GetExecutablePath); 3628852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 3638852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // Reject unknown tools. 3648852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry llvm::errs() << "error: unknown integrated tool '" << Tool << "'\n"; 3658852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry return 1; 3668852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 3678852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 3688852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry bool CanonicalPrefixes = true; 3698852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry for (int i = 1, size = argv.size(); i < size; ++i) { 3708852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (StringRef(argv[i]) == "-no-canonical-prefixes") { 3718852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry CanonicalPrefixes = false; 3728852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry break; 3738852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 3748852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 3758852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 3768852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry llvm::sys::Path Path = GetExecutablePath(argv[0], CanonicalPrefixes); 3778852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 3788852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry DiagnosticOptions DiagOpts; 3798852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry { 3808852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // Note that ParseDiagnosticArgs() uses the cc1 option table. 3818852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry OwningPtr<OptTable> CC1Opts(createCC1OptTable()); 3828852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry unsigned MissingArgIndex, MissingArgCount; 3838852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry OwningPtr<InputArgList> Args(CC1Opts->ParseArgs(argv.begin()+1, argv.end(), 3848852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry MissingArgIndex, MissingArgCount)); 3858852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // We ignore MissingArgCount and the return value of ParseDiagnosticArgs. 3868852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // Any errors that would be diagnosed here will also be diagnosed later, 3878852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // when the DiagnosticsEngine actually exists. 3888852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry (void) ParseDiagnosticArgs(DiagOpts, *Args); 3898852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 3908852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // Now we can create the DiagnosticsEngine with a properly-filled-out 3918852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // DiagnosticOptions instance. 3928852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry TextDiagnosticPrinter *DiagClient 3938852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry = new TextDiagnosticPrinter(llvm::errs(), DiagOpts); 3948852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry DiagClient->setPrefix(llvm::sys::path::stem(Path.str())); 3958852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); 3968852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 3978852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry DiagnosticsEngine Diags(DiagID, DiagClient); 3988852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry ProcessWarningOptions(Diags, DiagOpts); 3998852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 4008852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#ifdef CLANG_IS_PRODUCTION 4018852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const bool IsProduction = true; 4028852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#else 4038852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const bool IsProduction = false; 4048852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#endif 4058852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry Driver TheDriver(Path.str(), llvm::sys::getDefaultTargetTriple(), 4068852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry "a.out", IsProduction, Diags); 4078852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 4088852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // Attempt to find the original path used to invoke the driver, to determine 4098852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // the installed path. We do this manually, because we want to support that 4108852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // path being a symlink. 4118852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry { 4128852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry SmallString<128> InstalledPath(argv[0]); 4138852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 4148852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // Do a PATH lookup, if there are no directory components. 4158852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (llvm::sys::path::filename(InstalledPath) == InstalledPath) { 4168852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry llvm::sys::Path Tmp = llvm::sys::Program::FindProgramByName( 4178852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry llvm::sys::path::filename(InstalledPath.str())); 4188852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (!Tmp.empty()) 4198852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry InstalledPath = Tmp.str(); 4208852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 4218852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry llvm::sys::fs::make_absolute(InstalledPath); 4228852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry InstalledPath = llvm::sys::path::parent_path(InstalledPath); 4238852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry bool exists; 4248852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (!llvm::sys::fs::exists(InstalledPath.str(), exists) && exists) 4258852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry TheDriver.setInstalledDir(InstalledPath); 4268852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 4278852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 4288852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry llvm::InitializeAllTargets(); 4298852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry ParseProgName(argv, SavedStrings, TheDriver); 4308852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 4318852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // Handle CC_PRINT_OPTIONS and CC_PRINT_OPTIONS_FILE. 4328852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry TheDriver.CCPrintOptions = !!::getenv("CC_PRINT_OPTIONS"); 4338852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (TheDriver.CCPrintOptions) 4348852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry TheDriver.CCPrintOptionsFilename = ::getenv("CC_PRINT_OPTIONS_FILE"); 4358852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 4368852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // Handle CC_PRINT_HEADERS and CC_PRINT_HEADERS_FILE. 4378852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry TheDriver.CCPrintHeaders = !!::getenv("CC_PRINT_HEADERS"); 4388852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (TheDriver.CCPrintHeaders) 4398852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry TheDriver.CCPrintHeadersFilename = ::getenv("CC_PRINT_HEADERS_FILE"); 4408852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 4418852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // Handle CC_LOG_DIAGNOSTICS and CC_LOG_DIAGNOSTICS_FILE. 4428852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry TheDriver.CCLogDiagnostics = !!::getenv("CC_LOG_DIAGNOSTICS"); 4438852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (TheDriver.CCLogDiagnostics) 4448852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry TheDriver.CCLogDiagnosticsFilename = ::getenv("CC_LOG_DIAGNOSTICS_FILE"); 4458852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 4468852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // Handle QA_OVERRIDE_GCC3_OPTIONS and CCC_ADD_ARGS, used for editing a 4478852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // command line behind the scenes. 4488852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (const char *OverrideStr = ::getenv("QA_OVERRIDE_GCC3_OPTIONS")) { 4498852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // FIXME: Driver shouldn't take extra initial argument. 4508852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry ApplyQAOverride(argv, OverrideStr, SavedStrings); 4518852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } else if (const char *Cur = ::getenv("CCC_ADD_ARGS")) { 4528852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // FIXME: Driver shouldn't take extra initial argument. 4538852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry std::vector<const char*> ExtraArgs; 4548852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 4558852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry for (;;) { 4568852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const char *Next = strchr(Cur, ','); 4578852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 4588852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (Next) { 4598852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry ExtraArgs.push_back(SaveStringInSet(SavedStrings, 4608852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry std::string(Cur, Next))); 4618852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry Cur = Next + 1; 4628852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } else { 4638852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (*Cur != '\0') 4648852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry ExtraArgs.push_back(SaveStringInSet(SavedStrings, Cur)); 4658852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry break; 4668852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 4678852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 4688852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 4698852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry argv.insert(&argv[1], ExtraArgs.begin(), ExtraArgs.end()); 4708852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 4718852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 4728852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry OwningPtr<Compilation> C(TheDriver.BuildCompilation(argv)); 4738852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry int Res = 0; 4748852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const Command *FailingCommand = 0; 4758852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (C.get()) 4768852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry Res = TheDriver.ExecuteCompilation(*C, FailingCommand); 4778852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 4788852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // If result status is < 0, then the driver command signalled an error. 4798852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // In this case, generate additional diagnostic information if possible. 4808852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (Res < 0) 4818852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry TheDriver.generateCompilationDiagnostics(*C, FailingCommand); 4828852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 4838852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // If any timers were active but haven't been destroyed yet, print their 4848852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // results now. This happens in -disable-free mode. 4858852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry llvm::TimerGroup::printAll(llvm::errs()); 4868852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 4878852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry llvm::llvm_shutdown(); 4888852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 4898852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry return Res; 4908852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry} 4918852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry