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