Daniel Dunbar | 63c4da9 | 2009-03-02 19:59:07 +0000 | [diff] [blame] | 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 | |
Daniel Dunbar | 63c4da9 | 2009-03-02 19:59:07 +0000 | [diff] [blame] | 10 | #include "clang/Driver/Driver.h" |
Daniel Dunbar | 63c4da9 | 2009-03-02 19:59:07 +0000 | [diff] [blame] | 11 | |
Daniel Dunbar | d6f0e37 | 2009-03-04 20:49:20 +0000 | [diff] [blame] | 12 | #include "clang/Driver/Arg.h" |
| 13 | #include "clang/Driver/ArgList.h" |
| 14 | #include "clang/Driver/Compilation.h" |
Daniel Dunbar | 7dc2a04 | 2009-03-05 06:38:47 +0000 | [diff] [blame] | 15 | #include "clang/Driver/Option.h" |
Daniel Dunbar | d6f0e37 | 2009-03-04 20:49:20 +0000 | [diff] [blame] | 16 | #include "clang/Driver/Options.h" |
Daniel Dunbar | 7dc2a04 | 2009-03-05 06:38:47 +0000 | [diff] [blame] | 17 | |
| 18 | #include "llvm/Support/raw_ostream.h" |
Daniel Dunbar | d6f0e37 | 2009-03-04 20:49:20 +0000 | [diff] [blame] | 19 | using namespace clang::driver; |
| 20 | |
Daniel Dunbar | b282ced | 2009-03-10 20:52:46 +0000 | [diff] [blame] | 21 | Driver::Driver(const char *_Name, const char *_Dir) |
| 22 | : Opts(new OptTable()), |
| 23 | Name(_Name), Dir(_Dir), Host(0), |
| 24 | CCCIsCXX(false), CCCEcho(false), |
| 25 | CCCNoClang(false), CCCNoClangCXX(false), CCCNoClangCPP(false) |
| 26 | { |
Daniel Dunbar | d6f0e37 | 2009-03-04 20:49:20 +0000 | [diff] [blame] | 27 | |
Daniel Dunbar | 63c4da9 | 2009-03-02 19:59:07 +0000 | [diff] [blame] | 28 | } |
| 29 | |
| 30 | Driver::~Driver() { |
Daniel Dunbar | d6f0e37 | 2009-03-04 20:49:20 +0000 | [diff] [blame] | 31 | delete Opts; |
Daniel Dunbar | 63c4da9 | 2009-03-02 19:59:07 +0000 | [diff] [blame] | 32 | } |
| 33 | |
Daniel Dunbar | 7dc2a04 | 2009-03-05 06:38:47 +0000 | [diff] [blame] | 34 | ArgList *Driver::ParseArgStrings(const char **ArgBegin, const char **ArgEnd) { |
| 35 | ArgList *Args = new ArgList(ArgBegin, ArgEnd); |
| 36 | |
| 37 | unsigned Index = 0, End = ArgEnd - ArgBegin; |
| 38 | while (Index < End) { |
| 39 | unsigned Prev = Index; |
| 40 | Arg *A = getOpts().ParseOneArg(*Args, Index, End); |
| 41 | if (A) |
| 42 | Args->append(A); |
| 43 | |
| 44 | assert(Index > Prev && "Parser failed to consume argument."); |
| 45 | } |
| 46 | |
| 47 | return Args; |
| 48 | } |
| 49 | |
Daniel Dunbar | 63c4da9 | 2009-03-02 19:59:07 +0000 | [diff] [blame] | 50 | Compilation *Driver::BuildCompilation(int argc, const char **argv) { |
Daniel Dunbar | b282ced | 2009-03-10 20:52:46 +0000 | [diff] [blame] | 51 | // FIXME: This stuff needs to go into the Compilation, not the |
| 52 | // driver. |
| 53 | bool CCCPrintOptions = false, CCCPrintPhases = false; |
Daniel Dunbar | 7dc2a04 | 2009-03-05 06:38:47 +0000 | [diff] [blame] | 54 | |
Daniel Dunbar | b282ced | 2009-03-10 20:52:46 +0000 | [diff] [blame] | 55 | const char **Start = argv + 1, **End = argv + argc; |
| 56 | |
| 57 | // Read -ccc args. |
| 58 | // |
| 59 | // FIXME: We need to figure out where this behavior should |
| 60 | // live. Most of it should be outside in the client; the parts that |
| 61 | // aren't should have proper options, either by introducing new ones |
| 62 | // or by overloading gcc ones like -V or -b. |
| 63 | for (; Start != End && memcmp(*Start, "-ccc-", 5) == 0; ++Start) { |
| 64 | const char *Opt = *Start + 5; |
| 65 | |
| 66 | if (!strcmp(Opt, "print-options")) { |
| 67 | CCCPrintOptions = true; |
| 68 | } else if (!strcmp(Opt, "print-phases")) { |
| 69 | CCCPrintPhases = true; |
| 70 | } else if (!strcmp(Opt, "cxx")) { |
| 71 | CCCIsCXX = true; |
| 72 | } else if (!strcmp(Opt, "echo")) { |
| 73 | CCCEcho = true; |
| 74 | |
| 75 | } else if (!strcmp(Opt, "no-clang")) { |
| 76 | CCCNoClang = true; |
| 77 | } else if (!strcmp(Opt, "no-clang-cxx")) { |
| 78 | CCCNoClangCXX = true; |
| 79 | } else if (!strcmp(Opt, "no-clang-cpp")) { |
| 80 | CCCNoClangCPP = true; |
| 81 | } else if (!strcmp(Opt, "clang-archs")) { |
| 82 | assert(Start+1 < End && "FIXME: -ccc- argument handling."); |
| 83 | const char *Cur = *++Start; |
| 84 | |
| 85 | for (;;) { |
| 86 | const char *Next = strchr(Cur, ','); |
| 87 | |
| 88 | if (Next) { |
| 89 | CCCClangArchs.insert(std::string(Cur, Next)); |
| 90 | Cur = Next + 1; |
| 91 | } else { |
| 92 | CCCClangArchs.insert(std::string(Cur)); |
| 93 | break; |
| 94 | } |
| 95 | } |
| 96 | |
| 97 | } else if (!strcmp(Opt, "host-bits")) { |
| 98 | assert(Start+1 < End && "FIXME: -ccc- argument handling."); |
| 99 | HostBits = *++Start; |
| 100 | } else if (!strcmp(Opt, "host-machine")) { |
| 101 | assert(Start+1 < End && "FIXME: -ccc- argument handling."); |
| 102 | HostMachine = *++Start; |
| 103 | } else if (!strcmp(Opt, "host-release")) { |
| 104 | assert(Start+1 < End && "FIXME: -ccc- argument handling."); |
| 105 | HostRelease = *++Start; |
| 106 | } else if (!strcmp(Opt, "host-system")) { |
| 107 | assert(Start+1 < End && "FIXME: -ccc- argument handling."); |
| 108 | HostSystem = *++Start; |
| 109 | |
| 110 | } else { |
| 111 | // FIXME: Error handling. |
| 112 | llvm::errs() << "invalid option: " << *Start << "\n"; |
| 113 | exit(1); |
| 114 | } |
| 115 | } |
| 116 | |
| 117 | ArgList *Args = ParseArgStrings(Start, End); |
| 118 | |
| 119 | // FIXME: This behavior shouldn't be here. |
| 120 | if (CCCPrintOptions) { |
| 121 | PrintOptions(Args); |
| 122 | exit(0); |
| 123 | } |
| 124 | |
| 125 | assert(0 && "FIXME: Implement"); |
| 126 | |
| 127 | return new Compilation(); |
| 128 | } |
| 129 | |
| 130 | void Driver::PrintOptions(const ArgList *Args) { |
Daniel Dunbar | 7dc2a04 | 2009-03-05 06:38:47 +0000 | [diff] [blame] | 131 | unsigned i = 0; |
Daniel Dunbar | b282ced | 2009-03-10 20:52:46 +0000 | [diff] [blame] | 132 | for (ArgList::const_iterator it = Args->begin(), ie = Args->end(); |
Daniel Dunbar | 7dc2a04 | 2009-03-05 06:38:47 +0000 | [diff] [blame] | 133 | it != ie; ++it, ++i) { |
| 134 | Arg *A = *it; |
| 135 | llvm::errs() << "Option " << i << " - " |
| 136 | << "Name: \"" << A->getOption().getName() << "\", " |
| 137 | << "Values: {"; |
| 138 | for (unsigned j = 0; j < A->getNumValues(); ++j) { |
| 139 | if (j) |
| 140 | llvm::errs() << ", "; |
| 141 | llvm::errs() << '"' << A->getValue(*Args, j) << '"'; |
| 142 | } |
| 143 | llvm::errs() << "}\n"; |
Daniel Dunbar | 7dc2a04 | 2009-03-05 06:38:47 +0000 | [diff] [blame] | 144 | } |
Daniel Dunbar | 63c4da9 | 2009-03-02 19:59:07 +0000 | [diff] [blame] | 145 | } |