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)