driver.cpp revision e5be6dac24946e9521af78fce8e531e605f563d4
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===-- driver.cpp - Clang GCC-Compatible Driver --------------------------===// 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The LLVM Compiler Infrastructure 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file is distributed under the University of Illinois Open Source 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// License. See LICENSE.TXT for details. 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===// 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This is the entry point to the clang driver; it is a thin wrapper 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// for functionality in the Driver clang library. 12f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// 13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)//===----------------------------------------------------------------------===// 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "clang/Driver/Compilation.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "clang/Driver/Driver.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "clang/Driver/Option.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "clang/Driver/Options.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/ADT/SmallString.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/ADT/OwningPtr.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/Config/config.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/Support/ManagedStatic.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/Support/PrettyStackTrace.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/Support/raw_ostream.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/System/Host.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/System/Path.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/System/Signals.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using namespace clang; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using namespace clang::driver; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DriverDiagnosticPrinter : public DiagnosticClient { 33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::string ProgName; 34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) llvm::raw_ostream &OS; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)public: 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DriverDiagnosticPrinter(const std::string _ProgName, 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) llvm::raw_ostream &_OS) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : ProgName(_ProgName), 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OS(_OS) {} 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void HandleDiagnostic(Diagnostic::Level DiagLevel, 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const DiagnosticInfo &Info); 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DriverDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level, 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const DiagnosticInfo &Info) { 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OS << ProgName << ": "; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (Level) { 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case Diagnostic::Ignored: assert(0 && "Invalid diagnostic type"); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case Diagnostic::Note: OS << "note: "; break; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case Diagnostic::Warning: OS << "warning: "; break; 54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case Diagnostic::Error: OS << "error: "; break; 55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case Diagnostic::Fatal: OS << "fatal error: "; break; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) llvm::SmallString<100> OutStr; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Info.FormatDiagnostic(OutStr); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OS.write(OutStr.begin(), OutStr.size()); 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OS << '\n'; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)llvm::sys::Path GetExecutablePath(const char *Argv0) { 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This just needs to be some symbol in the binary; C++ doesn't 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // allow taking the address of ::main however. 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *P = (void*) (intptr_t) GetExecutablePath; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return llvm::sys::Path::GetMainExecutable(Argv0, P); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int main(int argc, const char **argv) { 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) llvm::sys::PrintStackTraceOnErrorSignal(); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) llvm::PrettyStackTraceProgram X(argc, argv); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) llvm::sys::Path Path = GetExecutablePath(argv[0]); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) llvm::OwningPtr<DiagnosticClient> 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DiagClient(new DriverDiagnosticPrinter(Path.getBasename(), llvm::errs())); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Diagnostic Diags(DiagClient.get()); 805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) llvm::OwningPtr<Driver> 825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TheDriver(new Driver(Path.getBasename().c_str(), Path.getDirname().c_str(), 835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) llvm::sys::getHostTriple().c_str(), 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "a.out", Diags)); 855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) llvm::OwningPtr<Compilation> C; 875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Handle CCC_ADD_ARGS, a comma separated list of extra arguments. 895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (const char *Cur = ::getenv("CCC_ADD_ARGS")) { 905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::set<std::string> SavedStrings; 915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::vector<const char*> StringPointers; 925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // FIXME: Driver shouldn't take extra initial argument. 945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) StringPointers.push_back(argv[0]); 955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (;;) { 975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const char *Next = strchr(Cur, ','); 985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (Next) { 1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (Cur != Next) { 1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const char *P = 1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SavedStrings.insert(std::string(Cur, Next)).first->c_str(); 1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) StringPointers.push_back(P); 1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Cur = Next + 1; 1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (*Cur != '\0') { 1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const char *P = 1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SavedStrings.insert(std::string(Cur)).first->c_str(); 1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) StringPointers.push_back(P); 1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StringPointers.insert(StringPointers.end(), argv + 1, argv + argc); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) C.reset(TheDriver->BuildCompilation(StringPointers.size(), 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &StringPointers[0])); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) C.reset(TheDriver->BuildCompilation(argc, argv)); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int Res = 0; 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (C.get()) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Res = C->Execute(); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) llvm::llvm_shutdown(); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Res; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)