blob: 6b1d44e5e75592e166ba14b40e06c583fedce312 [file] [log] [blame]
Daniel Dunbar63c4da92009-03-02 19:59:07 +00001//===--- 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 Dunbar63c4da92009-03-02 19:59:07 +000010#include "clang/Driver/Driver.h"
Daniel Dunbar63c4da92009-03-02 19:59:07 +000011
Daniel Dunbard6f0e372009-03-04 20:49:20 +000012#include "clang/Driver/Arg.h"
13#include "clang/Driver/ArgList.h"
14#include "clang/Driver/Compilation.h"
Daniel Dunbar7dc2a042009-03-05 06:38:47 +000015#include "clang/Driver/Option.h"
Daniel Dunbard6f0e372009-03-04 20:49:20 +000016#include "clang/Driver/Options.h"
Daniel Dunbar7dc2a042009-03-05 06:38:47 +000017
18#include "llvm/Support/raw_ostream.h"
Daniel Dunbard6f0e372009-03-04 20:49:20 +000019using namespace clang::driver;
20
Daniel Dunbarb282ced2009-03-10 20:52:46 +000021Driver::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 Dunbard6f0e372009-03-04 20:49:20 +000027
Daniel Dunbar63c4da92009-03-02 19:59:07 +000028}
29
30Driver::~Driver() {
Daniel Dunbard6f0e372009-03-04 20:49:20 +000031 delete Opts;
Daniel Dunbar63c4da92009-03-02 19:59:07 +000032}
33
Daniel Dunbar7dc2a042009-03-05 06:38:47 +000034ArgList *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 Dunbar63c4da92009-03-02 19:59:07 +000050Compilation *Driver::BuildCompilation(int argc, const char **argv) {
Daniel Dunbarb282ced2009-03-10 20:52:46 +000051 // FIXME: This stuff needs to go into the Compilation, not the
52 // driver.
53 bool CCCPrintOptions = false, CCCPrintPhases = false;
Daniel Dunbar7dc2a042009-03-05 06:38:47 +000054
Daniel Dunbarb282ced2009-03-10 20:52:46 +000055 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
130void Driver::PrintOptions(const ArgList *Args) {
Daniel Dunbar7dc2a042009-03-05 06:38:47 +0000131 unsigned i = 0;
Daniel Dunbarb282ced2009-03-10 20:52:46 +0000132 for (ArgList::const_iterator it = Args->begin(), ie = Args->end();
Daniel Dunbar7dc2a042009-03-05 06:38:47 +0000133 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 Dunbar7dc2a042009-03-05 06:38:47 +0000144 }
Daniel Dunbar63c4da92009-03-02 19:59:07 +0000145}