driver.cpp revision 510d73200ec48496a2b10703385fe99b51e31fa5
13ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar//===-- driver.cpp - Clang GCC-Compatible Driver --------------------------===//
23ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar//
33ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar//                     The LLVM Compiler Infrastructure
43ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar//
53ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar// This file is distributed under the University of Illinois Open Source
63ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar// License. See LICENSE.TXT for details.
73ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar//
83ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar//===----------------------------------------------------------------------===//
93ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar//
101eb4e64eed08837b85a375d6a953503daa844f07Daniel Dunbar// This is the entry point to the clang driver; it is a thin wrapper
111eb4e64eed08837b85a375d6a953503daa844f07Daniel Dunbar// for functionality in the Driver clang library.
123ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar//
133ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar//===----------------------------------------------------------------------===//
143ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar
153ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar#include "clang/Driver/Compilation.h"
163ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar#include "clang/Driver/Driver.h"
172c6f6f3c170502c5b810102cf85f05732a2aa9d0Daniel Dunbar#include "clang/Driver/Option.h"
182c6f6f3c170502c5b810102cf85f05732a2aa9d0Daniel Dunbar#include "clang/Driver/Options.h"
192c6f6f3c170502c5b810102cf85f05732a2aa9d0Daniel Dunbar
20510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar#include "llvm/ADT/SmallString.h"
213ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar#include "llvm/ADT/OwningPtr.h"
22dd98e2cad165ca73c769e4f105a4e47c2216387aDaniel Dunbar#include "llvm/Config/config.h"
238f25c79e59d88df41c5a3cabba1c58035d384a6eDaniel Dunbar#include "llvm/Support/ManagedStatic.h"
248f25c79e59d88df41c5a3cabba1c58035d384a6eDaniel Dunbar#include "llvm/Support/PrettyStackTrace.h"
254ad4b3ebbe5769143389dccfcfadb666a4ba5940Daniel Dunbar#include "llvm/Support/raw_ostream.h"
26365c02f65be026f90e67a8e00e7b827cee60e228Daniel Dunbar#include "llvm/System/Path.h"
273ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar#include "llvm/System/Signals.h"
284ad4b3ebbe5769143389dccfcfadb666a4ba5940Daniel Dunbarusing namespace clang;
291b3bb6efc59a21f794b534078f9ae7e95393f510Daniel Dunbarusing namespace clang::driver;
303ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar
31510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbarclass DriverDiagnosticPrinter : public DiagnosticClient {
32510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar  std::string ProgName;
33510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar  llvm::raw_ostream &OS;
34510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar
35510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbarpublic:
36510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar  DriverDiagnosticPrinter(const std::string _ProgName,
37510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar                          llvm::raw_ostream &_OS)
38510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar    : ProgName(_ProgName),
39510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar      OS(_OS) {}
40510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar
41510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar  virtual void HandleDiagnostic(Diagnostic::Level DiagLevel,
42510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar                                const DiagnosticInfo &Info);
43510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar};
44510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar
45510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbarvoid DriverDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level,
46510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar                                               const DiagnosticInfo &Info) {
47510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar  OS << ProgName << ": ";
48510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar
49510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar  switch (Level) {
50510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar  case Diagnostic::Ignored: assert(0 && "Invalid diagnostic type");
51510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar  case Diagnostic::Note:    OS << "note: "; break;
52510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar  case Diagnostic::Warning: OS << "warning: "; break;
53510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar  case Diagnostic::Error:   OS << "error: "; break;
54510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar  case Diagnostic::Fatal:   OS << "fatal error: "; break;
55510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar  }
56510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar
57510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar  llvm::SmallString<100> OutStr;
58510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar  Info.FormatDiagnostic(OutStr);
59510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar  OS.write(OutStr.begin(), OutStr.size());
60510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar  OS << '\n';
61510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar}
62510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar
633ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbarint main(int argc, const char **argv) {
643ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar  llvm::sys::PrintStackTraceOnErrorSignal();
658f25c79e59d88df41c5a3cabba1c58035d384a6eDaniel Dunbar  llvm::PrettyStackTraceProgram X(argc, argv);
663ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar
67365c02f65be026f90e67a8e00e7b827cee60e228Daniel Dunbar  // FIXME: We should use GetMainExecutable here, probably, but we may
68365c02f65be026f90e67a8e00e7b827cee60e228Daniel Dunbar  // want to handle symbolic links slightly differently. The problem
69365c02f65be026f90e67a8e00e7b827cee60e228Daniel Dunbar  // is that the path derived from this will influence search paths.
70365c02f65be026f90e67a8e00e7b827cee60e228Daniel Dunbar  llvm::sys::Path Path(argv[0]);
71365c02f65be026f90e67a8e00e7b827cee60e228Daniel Dunbar
72510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar  llvm::OwningPtr<DiagnosticClient>
73510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar    DiagClient(new DriverDiagnosticPrinter(Path.getBasename(), llvm::errs()));
74510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar
75510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar  Diagnostic Diags(DiagClient.get());
76510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar
77dd98e2cad165ca73c769e4f105a4e47c2216387aDaniel Dunbar  // FIXME: Use the triple of the host, not the triple that we were
78dd98e2cad165ca73c769e4f105a4e47c2216387aDaniel Dunbar  // compiled on.
79365c02f65be026f90e67a8e00e7b827cee60e228Daniel Dunbar  llvm::OwningPtr<Driver> TheDriver(new Driver(Path.getBasename().c_str(),
80dd98e2cad165ca73c769e4f105a4e47c2216387aDaniel Dunbar                                               Path.getDirname().c_str(),
814ad4b3ebbe5769143389dccfcfadb666a4ba5940Daniel Dunbar                                               LLVM_HOSTTRIPLE,
82f353c8cc2ee1cc16ff194b399a8d951f707fb129Daniel Dunbar                                               "a.out",
834ad4b3ebbe5769143389dccfcfadb666a4ba5940Daniel Dunbar                                               Diags));
844ad4b3ebbe5769143389dccfcfadb666a4ba5940Daniel Dunbar
853ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar  llvm::OwningPtr<Compilation> C(TheDriver->BuildCompilation(argc, argv));
863ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar
874ad4b3ebbe5769143389dccfcfadb666a4ba5940Daniel Dunbar  // If there were errors building the compilation, quit now.
884ad4b3ebbe5769143389dccfcfadb666a4ba5940Daniel Dunbar  if (Diags.getNumErrors())
894ad4b3ebbe5769143389dccfcfadb666a4ba5940Daniel Dunbar    return 1;
90ab835430b4f758dd49903251c7c7f21b95933c89Daniel Dunbar  if (!C.get())
91ab835430b4f758dd49903251c7c7f21b95933c89Daniel Dunbar    return 0;
924ad4b3ebbe5769143389dccfcfadb666a4ba5940Daniel Dunbar
938f25c79e59d88df41c5a3cabba1c58035d384a6eDaniel Dunbar  int res = C->Execute();
948f25c79e59d88df41c5a3cabba1c58035d384a6eDaniel Dunbar
958f25c79e59d88df41c5a3cabba1c58035d384a6eDaniel Dunbar  llvm::llvm_shutdown();
968f25c79e59d88df41c5a3cabba1c58035d384a6eDaniel Dunbar
978f25c79e59d88df41c5a3cabba1c58035d384a6eDaniel Dunbar  return res;
983ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar}
99