driver.cpp revision d5b08bee799d4f77f1a25fa5977ca77b983ab031
1//===-- driver.cpp - Clang GCC-Compatible Driver --------------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This is the entry point to the clang driver; it is a thin wrapper 11// for functionality in the Driver clang library. 12// 13//===----------------------------------------------------------------------===// 14 15#include "clang/Driver/Compilation.h" 16#include "clang/Driver/Driver.h" 17#include "clang/Driver/Option.h" 18#include "clang/Frontend/DiagnosticOptions.h" 19#include "clang/Frontend/TextDiagnosticPrinter.h" 20 21#include "llvm/ADT/SmallString.h" 22#include "llvm/ADT/SmallVector.h" 23#include "llvm/ADT/OwningPtr.h" 24#include "llvm/Config/config.h" 25#include "llvm/Support/ErrorHandling.h" 26#include "llvm/Support/ManagedStatic.h" 27#include "llvm/Support/MemoryBuffer.h" 28#include "llvm/Support/PrettyStackTrace.h" 29#include "llvm/Support/Regex.h" 30#include "llvm/Support/Timer.h" 31#include "llvm/Support/raw_ostream.h" 32#include "llvm/Support/Host.h" 33#include "llvm/Support/Path.h" 34#include "llvm/Support/Program.h" 35#include "llvm/Support/Signals.h" 36#include "llvm/Support/system_error.h" 37using namespace clang; 38using namespace clang::driver; 39 40llvm::sys::Path GetExecutablePath(const char *Argv0, bool CanonicalPrefixes) { 41 if (!CanonicalPrefixes) 42 return llvm::sys::Path(Argv0); 43 44 // This just needs to be some symbol in the binary; C++ doesn't 45 // allow taking the address of ::main however. 46 void *P = (void*) (intptr_t) GetExecutablePath; 47 return llvm::sys::Path::GetMainExecutable(Argv0, P); 48} 49 50static const char *SaveStringInSet(std::set<std::string> &SavedStrings, 51 llvm::StringRef S) { 52 return SavedStrings.insert(S).first->c_str(); 53} 54 55/// ApplyQAOverride - Apply a list of edits to the input argument lists. 56/// 57/// The input string is a space separate list of edits to perform, 58/// they are applied in order to the input argument lists. Edits 59/// should be one of the following forms: 60/// 61/// '#': Silence information about the changes to the command line arguments. 62/// 63/// '^': Add FOO as a new argument at the beginning of the command line. 64/// 65/// '+': Add FOO as a new argument at the end of the command line. 66/// 67/// 's/XXX/YYY/': Substitute the regular expression XXX with YYY in the command 68/// line. 69/// 70/// 'xOPTION': Removes all instances of the literal argument OPTION. 71/// 72/// 'XOPTION': Removes all instances of the literal argument OPTION, 73/// and the following argument. 74/// 75/// 'Ox': Removes all flags matching 'O' or 'O[sz0-9]' and adds 'Ox' 76/// at the end of the command line. 77/// 78/// \param OS - The stream to write edit information to. 79/// \param Args - The vector of command line arguments. 80/// \param Edit - The override command to perform. 81/// \param SavedStrings - Set to use for storing string representations. 82static void ApplyOneQAOverride(llvm::raw_ostream &OS, 83 llvm::SmallVectorImpl<const char*> &Args, 84 llvm::StringRef Edit, 85 std::set<std::string> &SavedStrings) { 86 // This does not need to be efficient. 87 88 if (Edit[0] == '^') { 89 const char *Str = 90 SaveStringInSet(SavedStrings, Edit.substr(1)); 91 OS << "### Adding argument " << Str << " at beginning\n"; 92 Args.insert(Args.begin() + 1, Str); 93 } else if (Edit[0] == '+') { 94 const char *Str = 95 SaveStringInSet(SavedStrings, Edit.substr(1)); 96 OS << "### Adding argument " << Str << " at end\n"; 97 Args.push_back(Str); 98 } else if (Edit[0] == 's' && Edit[1] == '/' && Edit.endswith("/") && 99 Edit.slice(2, Edit.size()-1).find('/') != llvm::StringRef::npos) { 100 llvm::StringRef MatchPattern = Edit.substr(2).split('/').first; 101 llvm::StringRef ReplPattern = Edit.substr(2).split('/').second; 102 ReplPattern = ReplPattern.slice(0, ReplPattern.size()-1); 103 104 for (unsigned i = 1, e = Args.size(); i != e; ++i) { 105 std::string Repl = llvm::Regex(MatchPattern).sub(ReplPattern, Args[i]); 106 107 if (Repl != Args[i]) { 108 OS << "### Replacing '" << Args[i] << "' with '" << Repl << "'\n"; 109 Args[i] = SaveStringInSet(SavedStrings, Repl); 110 } 111 } 112 } else if (Edit[0] == 'x' || Edit[0] == 'X') { 113 std::string Option = Edit.substr(1, std::string::npos); 114 for (unsigned i = 1; i < Args.size();) { 115 if (Option == Args[i]) { 116 OS << "### Deleting argument " << Args[i] << '\n'; 117 Args.erase(Args.begin() + i); 118 if (Edit[0] == 'X') { 119 if (i < Args.size()) { 120 OS << "### Deleting argument " << Args[i] << '\n'; 121 Args.erase(Args.begin() + i); 122 } else 123 OS << "### Invalid X edit, end of command line!\n"; 124 } 125 } else 126 ++i; 127 } 128 } else if (Edit[0] == 'O') { 129 for (unsigned i = 1; i < Args.size();) { 130 const char *A = Args[i]; 131 if (A[0] == '-' && A[1] == 'O' && 132 (A[2] == '\0' || 133 (A[3] == '\0' && (A[2] == 's' || A[2] == 'z' || 134 ('0' <= A[2] && A[2] <= '9'))))) { 135 OS << "### Deleting argument " << Args[i] << '\n'; 136 Args.erase(Args.begin() + i); 137 } else 138 ++i; 139 } 140 OS << "### Adding argument " << Edit << " at end\n"; 141 Args.push_back(SaveStringInSet(SavedStrings, '-' + Edit.str())); 142 } else { 143 OS << "### Unrecognized edit: " << Edit << "\n"; 144 } 145} 146 147/// ApplyQAOverride - Apply a comma separate list of edits to the 148/// input argument lists. See ApplyOneQAOverride. 149static void ApplyQAOverride(llvm::SmallVectorImpl<const char*> &Args, 150 const char *OverrideStr, 151 std::set<std::string> &SavedStrings) { 152 llvm::raw_ostream *OS = &llvm::errs(); 153 154 if (OverrideStr[0] == '#') { 155 ++OverrideStr; 156 OS = &llvm::nulls(); 157 } 158 159 *OS << "### QA_OVERRIDE_GCC3_OPTIONS: " << OverrideStr << "\n"; 160 161 // This does not need to be efficient. 162 163 const char *S = OverrideStr; 164 while (*S) { 165 const char *End = ::strchr(S, ' '); 166 if (!End) 167 End = S + strlen(S); 168 if (End != S) 169 ApplyOneQAOverride(*OS, Args, std::string(S, End), SavedStrings); 170 S = End; 171 if (*S != '\0') 172 ++S; 173 } 174} 175 176extern int cc1_main(const char **ArgBegin, const char **ArgEnd, 177 const char *Argv0, void *MainAddr); 178extern int cc1as_main(const char **ArgBegin, const char **ArgEnd, 179 const char *Argv0, void *MainAddr); 180 181static void ExpandArgsFromBuf(const char *Arg, 182 llvm::SmallVectorImpl<const char*> &ArgVector, 183 std::set<std::string> &SavedStrings) { 184 const char *FName = Arg + 1; 185 llvm::OwningPtr<llvm::MemoryBuffer> MemBuf; 186 if (llvm::MemoryBuffer::getFile(FName, MemBuf)) { 187 ArgVector.push_back(SaveStringInSet(SavedStrings, Arg)); 188 return; 189 } 190 191 const char *Buf = MemBuf->getBufferStart(); 192 char InQuote = ' '; 193 std::string CurArg; 194 195 for (const char *P = Buf; ; ++P) { 196 if (*P == '\0' || (isspace(*P) && InQuote == ' ')) { 197 if (!CurArg.empty()) { 198 199 if (CurArg[0] != '@') { 200 ArgVector.push_back(SaveStringInSet(SavedStrings, CurArg)); 201 } else { 202 ExpandArgsFromBuf(CurArg.c_str(), ArgVector, SavedStrings); 203 } 204 205 CurArg = ""; 206 } 207 if (*P == '\0') 208 break; 209 else 210 continue; 211 } 212 213 if (isspace(*P)) { 214 if (InQuote != ' ') 215 CurArg.push_back(*P); 216 continue; 217 } 218 219 if (*P == '"' || *P == '\'') { 220 if (InQuote == *P) 221 InQuote = ' '; 222 else if (InQuote == ' ') 223 InQuote = *P; 224 else 225 CurArg.push_back(*P); 226 continue; 227 } 228 229 if (*P == '\\') { 230 ++P; 231 if (*P != '\0') 232 CurArg.push_back(*P); 233 continue; 234 } 235 CurArg.push_back(*P); 236 } 237} 238 239static void ExpandArgv(int argc, const char **argv, 240 llvm::SmallVectorImpl<const char*> &ArgVector, 241 std::set<std::string> &SavedStrings) { 242 for (int i = 0; i < argc; ++i) { 243 const char *Arg = argv[i]; 244 if (Arg[0] != '@') { 245 ArgVector.push_back(SaveStringInSet(SavedStrings, std::string(Arg))); 246 continue; 247 } 248 249 ExpandArgsFromBuf(Arg, ArgVector, SavedStrings); 250 } 251} 252 253int main(int argc_, const char **argv_) { 254 llvm::sys::PrintStackTraceOnErrorSignal(); 255 llvm::PrettyStackTraceProgram X(argc_, argv_); 256 257 std::set<std::string> SavedStrings; 258 llvm::SmallVector<const char*, 256> argv; 259 260 ExpandArgv(argc_, argv_, argv, SavedStrings); 261 262 // Handle -cc1 integrated tools. 263 if (argv.size() > 1 && llvm::StringRef(argv[1]).startswith("-cc1")) { 264 llvm::StringRef Tool = argv[1] + 4; 265 266 if (Tool == "") 267 return cc1_main(argv.data()+2, argv.data()+argv.size(), argv[0], 268 (void*) (intptr_t) GetExecutablePath); 269 if (Tool == "as") 270 return cc1as_main(argv.data()+2, argv.data()+argv.size(), argv[0], 271 (void*) (intptr_t) GetExecutablePath); 272 273 // Reject unknown tools. 274 llvm::errs() << "error: unknown integrated tool '" << Tool << "'\n"; 275 return 1; 276 } 277 278 bool CanonicalPrefixes = true; 279 for (int i = 1, size = argv.size(); i < size; ++i) { 280 if (llvm::StringRef(argv[i]) == "-no-canonical-prefixes") { 281 CanonicalPrefixes = false; 282 break; 283 } 284 } 285 286 llvm::sys::Path Path = GetExecutablePath(argv[0], CanonicalPrefixes); 287 288 TextDiagnosticPrinter *DiagClient 289 = new TextDiagnosticPrinter(llvm::errs(), DiagnosticOptions()); 290 DiagClient->setPrefix(llvm::sys::path::stem(Path.str())); 291 llvm::IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); 292 Diagnostic Diags(DiagID, DiagClient); 293 294#ifdef CLANG_IS_PRODUCTION 295 const bool IsProduction = true; 296# ifdef CLANGXX_IS_PRODUCTION 297 const bool CXXIsProduction = true; 298# else 299 const bool CXXIsProduction = false; 300# endif 301#else 302 const bool IsProduction = false; 303 const bool CXXIsProduction = false; 304#endif 305 Driver TheDriver(Path.str(), llvm::sys::getHostTriple(), 306 "a.out", IsProduction, CXXIsProduction, 307 Diags); 308 309 // Attempt to find the original path used to invoke the driver, to determine 310 // the installed path. We do this manually, because we want to support that 311 // path being a symlink. 312 llvm::sys::Path InstalledPath(argv[0]); 313 314 // Do a PATH lookup, if there are no directory components. 315 if (llvm::sys::path::filename(InstalledPath.str()) == InstalledPath.str()) { 316 llvm::sys::Path Tmp = llvm::sys::Program::FindProgramByName( 317 llvm::sys::path::filename(InstalledPath.str())); 318 if (!Tmp.empty()) 319 InstalledPath = Tmp; 320 } 321 InstalledPath.makeAbsolute(); 322 InstalledPath.eraseComponent(); 323 if (InstalledPath.exists()) 324 TheDriver.setInstalledDir(InstalledPath.str()); 325 326 // Check for ".*++" or ".*++-[^-]*" to determine if we are a C++ 327 // compiler. This matches things like "c++", "clang++", and "clang++-1.1". 328 // 329 // Note that we intentionally want to use argv[0] here, to support "clang++" 330 // being a symlink. 331 // 332 // We use *argv instead of argv[0] to work around a bogus g++ warning. 333 const char *progname = argv_[0]; 334 std::string ProgName(llvm::sys::path::stem(progname)); 335 if (llvm::StringRef(ProgName).endswith("++") || 336 llvm::StringRef(ProgName).rsplit('-').first.endswith("++")) { 337 TheDriver.CCCIsCXX = true; 338 } 339 340 // Handle CC_PRINT_OPTIONS and CC_PRINT_OPTIONS_FILE. 341 TheDriver.CCPrintOptions = !!::getenv("CC_PRINT_OPTIONS"); 342 if (TheDriver.CCPrintOptions) 343 TheDriver.CCPrintOptionsFilename = ::getenv("CC_PRINT_OPTIONS_FILE"); 344 345 // Handle QA_OVERRIDE_GCC3_OPTIONS and CCC_ADD_ARGS, used for editing a 346 // command line behind the scenes. 347 if (const char *OverrideStr = ::getenv("QA_OVERRIDE_GCC3_OPTIONS")) { 348 // FIXME: Driver shouldn't take extra initial argument. 349 ApplyQAOverride(argv, OverrideStr, SavedStrings); 350 } else if (const char *Cur = ::getenv("CCC_ADD_ARGS")) { 351 // FIXME: Driver shouldn't take extra initial argument. 352 std::vector<const char*> ExtraArgs; 353 354 for (;;) { 355 const char *Next = strchr(Cur, ','); 356 357 if (Next) { 358 ExtraArgs.push_back(SaveStringInSet(SavedStrings, 359 std::string(Cur, Next))); 360 Cur = Next + 1; 361 } else { 362 if (*Cur != '\0') 363 ExtraArgs.push_back(SaveStringInSet(SavedStrings, Cur)); 364 break; 365 } 366 } 367 368 argv.insert(&argv[1], ExtraArgs.begin(), ExtraArgs.end()); 369 } 370 371 llvm::OwningPtr<Compilation> C(TheDriver.BuildCompilation(argv.size(), 372 &argv[0])); 373 int Res = 0; 374 if (C.get()) 375 Res = TheDriver.ExecuteCompilation(*C); 376 377 // If any timers were active but haven't been destroyed yet, print their 378 // results now. This happens in -disable-free mode. 379 llvm::TimerGroup::printAll(llvm::errs()); 380 381 llvm::llvm_shutdown(); 382 383 return Res; 384} 385