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