driver.cpp revision 734932c7dc77a16b15d466588e10d76bcd6d13c7
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/Driver/Options.h" 19 20#include "llvm/ADT/SmallString.h" 21#include "llvm/ADT/OwningPtr.h" 22#include "llvm/Config/config.h" 23#include "llvm/Support/ManagedStatic.h" 24#include "llvm/Support/PrettyStackTrace.h" 25#include "llvm/Support/raw_ostream.h" 26#include "llvm/System/Path.h" 27#include "llvm/System/Signals.h" 28using namespace clang; 29using namespace clang::driver; 30 31class DriverDiagnosticPrinter : public DiagnosticClient { 32 std::string ProgName; 33 llvm::raw_ostream &OS; 34 35public: 36 DriverDiagnosticPrinter(const std::string _ProgName, 37 llvm::raw_ostream &_OS) 38 : ProgName(_ProgName), 39 OS(_OS) {} 40 41 virtual void HandleDiagnostic(Diagnostic::Level DiagLevel, 42 const DiagnosticInfo &Info); 43}; 44 45void DriverDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level, 46 const DiagnosticInfo &Info) { 47 OS << ProgName << ": "; 48 49 switch (Level) { 50 case Diagnostic::Ignored: assert(0 && "Invalid diagnostic type"); 51 case Diagnostic::Note: OS << "note: "; break; 52 case Diagnostic::Warning: OS << "warning: "; break; 53 case Diagnostic::Error: OS << "error: "; break; 54 case Diagnostic::Fatal: OS << "fatal error: "; break; 55 } 56 57 llvm::SmallString<100> OutStr; 58 Info.FormatDiagnostic(OutStr); 59 OS.write(OutStr.begin(), OutStr.size()); 60 OS << '\n'; 61} 62 63llvm::sys::Path GetExecutablePath(const char *Argv0) { 64 // This just needs to be some symbol in the binary; C++ doesn't 65 // allow taking the address of ::main however. 66 void *P = (void*) (intptr_t) GetExecutablePath; 67 return llvm::sys::Path::GetMainExecutable(Argv0, P); 68} 69 70int main(int argc, const char **argv) { 71 llvm::sys::PrintStackTraceOnErrorSignal(); 72 llvm::PrettyStackTraceProgram X(argc, argv); 73 74 llvm::sys::Path Path = GetExecutablePath(argv[0]); 75 llvm::OwningPtr<DiagnosticClient> 76 DiagClient(new DriverDiagnosticPrinter(Path.getBasename(), llvm::errs())); 77 78 Diagnostic Diags(DiagClient.get()); 79 80 // FIXME: Use the triple of the host, not the triple that we were 81 // compiled on. 82 llvm::OwningPtr<Driver> TheDriver(new Driver(Path.getBasename().c_str(), 83 Path.getDirname().c_str(), 84 LLVM_HOSTTRIPLE, 85 "a.out", 86 Diags)); 87 88 llvm::OwningPtr<Compilation> C(TheDriver->BuildCompilation(argc, argv)); 89 90 // If there were errors building the compilation, quit now. 91 if (Diags.getNumErrors()) 92 return 1; 93 if (!C.get()) 94 return 0; 95 96 int res = C->Execute(); 97 98 llvm::llvm_shutdown(); 99 100 return res; 101} 102