]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/Driver/ArgList.cpp
Import Clang r73340.
[FreeBSD/FreeBSD.git] / lib / Driver / ArgList.cpp
1 //===--- ArgList.cpp - Argument List Management -------------------------*-===//
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 #include "clang/Driver/ArgList.h"
11 #include "clang/Driver/Arg.h"
12 #include "clang/Driver/Option.h"
13
14 using namespace clang::driver;
15
16 ArgList::ArgList(arglist_type &_Args) : Args(_Args) {
17 }
18
19 ArgList::~ArgList() {
20 }
21
22 void ArgList::append(Arg *A) {
23   Args.push_back(A);
24 }
25
26 Arg *ArgList::getLastArg(options::ID Id, bool Claim) const {
27   // FIXME: Make search efficient?
28   for (const_reverse_iterator it = rbegin(), ie = rend(); it != ie; ++it) {
29     if ((*it)->getOption().matches(Id)) {
30       if (Claim) (*it)->claim();
31       return *it;
32     }
33   }
34   
35   return 0;
36 }
37
38 Arg *ArgList::getLastArg(options::ID Id0, options::ID Id1, bool Claim) const {
39   Arg *Res, *A0 = getLastArg(Id0, false), *A1 = getLastArg(Id1, false);
40   
41   if (A0 && A1)
42     Res = A0->getIndex() > A1->getIndex() ? A0 : A1;
43   else
44     Res = A0 ? A0 : A1;
45
46   if (Claim && Res)
47     Res->claim();
48
49   return Res;
50 }
51
52 bool ArgList::hasFlag(options::ID Pos, options::ID Neg, bool Default) const {
53   if (Arg *A = getLastArg(Pos, Neg))
54     return A->getOption().matches(Pos);
55   return Default;
56 }
57
58 void ArgList::AddLastArg(ArgStringList &Output, options::ID Id) const {
59   if (Arg *A = getLastArg(Id)) {
60     A->claim();
61     A->render(*this, Output);
62   }
63 }
64
65 void ArgList::AddAllArgs(ArgStringList &Output, options::ID Id0) const {
66   // FIXME: Make fast.
67   for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
68     const Arg *A = *it;
69     if (A->getOption().matches(Id0)) {
70       A->claim();
71       A->render(*this, Output);
72     }
73   }
74 }
75
76 void ArgList::AddAllArgs(ArgStringList &Output, options::ID Id0, 
77                          options::ID Id1) const {
78   // FIXME: Make fast.
79   for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
80     const Arg *A = *it;
81     if (A->getOption().matches(Id0) || A->getOption().matches(Id1)) {
82       A->claim();
83       A->render(*this, Output);
84     }
85   }
86 }
87
88 void ArgList::AddAllArgs(ArgStringList &Output, options::ID Id0, 
89                          options::ID Id1, options::ID Id2) const {
90   // FIXME: Make fast.
91   for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
92     const Arg *A = *it;
93     if (A->getOption().matches(Id0) || A->getOption().matches(Id1) ||
94         A->getOption().matches(Id2)) {
95       A->claim();
96       A->render(*this, Output);
97     }
98   }
99 }
100
101 void ArgList::AddAllArgValues(ArgStringList &Output, options::ID Id0) const {
102   // FIXME: Make fast.
103   for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
104     const Arg *A = *it;
105     if (A->getOption().matches(Id0)) {
106       A->claim();
107       for (unsigned i = 0, e = A->getNumValues(); i != e; ++i)
108         Output.push_back(A->getValue(*this, i));
109     }
110   }
111 }
112
113 void ArgList::AddAllArgValues(ArgStringList &Output, options::ID Id0, 
114                               options::ID Id1) const {
115   // FIXME: Make fast.
116   for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
117     const Arg *A = *it;
118     if (A->getOption().matches(Id0) || A->getOption().matches(Id1)) {
119       A->claim();
120       for (unsigned i = 0, e = A->getNumValues(); i != e; ++i)
121         Output.push_back(A->getValue(*this, i));
122     }
123   }
124 }
125
126 void ArgList::AddAllArgsTranslated(ArgStringList &Output, options::ID Id0,
127                                    const char *Translation,
128                                    bool Joined) const {
129   // FIXME: Make fast.
130   for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
131     const Arg *A = *it;
132     if (A->getOption().matches(Id0)) {
133       A->claim();
134
135       if (Joined) {
136         std::string Value = Translation;
137         Value += A->getValue(*this, 0);
138         Output.push_back(MakeArgString(Value.c_str()));
139       } else {
140         Output.push_back(Translation);
141         Output.push_back(A->getValue(*this, 0));
142       }
143     }
144   }
145 }
146
147 void ArgList::ClaimAllArgs(options::ID Id0) const {
148   // FIXME: Make fast.
149   for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
150     const Arg *A = *it;
151     if (A->getOption().matches(Id0))
152       A->claim();
153   }
154 }
155
156 //
157
158 InputArgList::InputArgList(const char **ArgBegin, const char **ArgEnd) 
159   : ArgList(ActualArgs), NumInputArgStrings(ArgEnd - ArgBegin) 
160 {
161   ArgStrings.append(ArgBegin, ArgEnd);
162 }
163
164 InputArgList::~InputArgList() {
165   // An InputArgList always owns its arguments.
166   for (iterator it = begin(), ie = end(); it != ie; ++it)
167     delete *it;
168 }
169
170 unsigned InputArgList::MakeIndex(const char *String0) const {
171   unsigned Index = ArgStrings.size();
172
173   // Tuck away so we have a reliable const char *.
174   SynthesizedStrings.push_back(String0);
175   ArgStrings.push_back(SynthesizedStrings.back().c_str());
176
177   return Index;
178 }
179
180 unsigned InputArgList::MakeIndex(const char *String0, 
181                                  const char *String1) const {
182   unsigned Index0 = MakeIndex(String0);
183   unsigned Index1 = MakeIndex(String1);
184   assert(Index0 + 1 == Index1 && "Unexpected non-consecutive indices!");
185   (void) Index1;
186   return Index0;
187 }
188
189 const char *InputArgList::MakeArgString(const char *Str) const {
190   return getArgString(MakeIndex(Str));
191 }
192
193 //
194
195 DerivedArgList::DerivedArgList(InputArgList &_BaseArgs, bool _OnlyProxy)
196   : ArgList(_OnlyProxy ? _BaseArgs.getArgs() : ActualArgs),
197     BaseArgs(_BaseArgs), OnlyProxy(_OnlyProxy)
198 {
199 }
200
201 DerivedArgList::~DerivedArgList() {
202   // We only own the arguments we explicitly synthesized.
203   for (iterator it = SynthesizedArgs.begin(), ie = SynthesizedArgs.end(); 
204        it != ie; ++it)
205     delete *it;
206 }
207
208 const char *DerivedArgList::MakeArgString(const char *Str) const {
209   return BaseArgs.MakeArgString(Str);
210 }
211
212 Arg *DerivedArgList::MakeFlagArg(const Arg *BaseArg, const Option *Opt) const {
213   return new FlagArg(Opt, BaseArgs.MakeIndex(Opt->getName()), BaseArg);
214 }
215
216 Arg *DerivedArgList::MakePositionalArg(const Arg *BaseArg, const Option *Opt, 
217                                        const char *Value) const {
218   return new PositionalArg(Opt, BaseArgs.MakeIndex(Value), BaseArg);
219 }
220
221 Arg *DerivedArgList::MakeSeparateArg(const Arg *BaseArg, const Option *Opt, 
222                                      const char *Value) const {
223   return new SeparateArg(Opt, BaseArgs.MakeIndex(Opt->getName(), Value), 1, 
224                          BaseArg);
225 }
226
227 Arg *DerivedArgList::MakeJoinedArg(const Arg *BaseArg, const Option *Opt, 
228                                    const char *Value) const {
229   std::string Joined(Opt->getName());
230   Joined += Value;
231   return new JoinedArg(Opt, BaseArgs.MakeIndex(Joined.c_str()), BaseArg);
232 }