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