clang API Documentation
00001 //===--- ArgList.cpp - Argument List Management ---------------------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 00010 #include "clang/Driver/ArgList.h" 00011 #include "clang/Driver/Arg.h" 00012 #include "clang/Driver/DriverDiagnostic.h" 00013 #include "clang/Driver/Option.h" 00014 00015 #include "llvm/ADT/SmallString.h" 00016 #include "llvm/ADT/Twine.h" 00017 #include "llvm/Support/raw_ostream.h" 00018 00019 using namespace clang; 00020 using namespace clang::driver; 00021 00022 void arg_iterator::SkipToNextArg() { 00023 for (; Current != Args.end(); ++Current) { 00024 // Done if there are no filters. 00025 if (!Id0.isValid()) 00026 break; 00027 00028 // Otherwise require a match. 00029 const Option &O = (*Current)->getOption(); 00030 if (O.matches(Id0) || 00031 (Id1.isValid() && O.matches(Id1)) || 00032 (Id2.isValid() && O.matches(Id2))) 00033 break; 00034 } 00035 } 00036 00037 // 00038 00039 ArgList::ArgList() { 00040 } 00041 00042 ArgList::~ArgList() { 00043 } 00044 00045 void ArgList::append(Arg *A) { 00046 Args.push_back(A); 00047 } 00048 00049 void ArgList::eraseArg(OptSpecifier Id) { 00050 for (iterator it = begin(), ie = end(); it != ie; ) { 00051 if ((*it)->getOption().matches(Id)) { 00052 it = Args.erase(it); 00053 ie = end(); 00054 } else { 00055 ++it; 00056 } 00057 } 00058 } 00059 00060 Arg *ArgList::getLastArgNoClaim(OptSpecifier Id) const { 00061 // FIXME: Make search efficient? 00062 for (const_reverse_iterator it = rbegin(), ie = rend(); it != ie; ++it) 00063 if ((*it)->getOption().matches(Id)) 00064 return *it; 00065 return 0; 00066 } 00067 00068 Arg *ArgList::getLastArg(OptSpecifier Id) const { 00069 Arg *Res = 0; 00070 for (const_iterator it = begin(), ie = end(); it != ie; ++it) { 00071 if ((*it)->getOption().matches(Id)) { 00072 Res = *it; 00073 Res->claim(); 00074 } 00075 } 00076 00077 return Res; 00078 } 00079 00080 Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1) const { 00081 Arg *Res = 0; 00082 for (const_iterator it = begin(), ie = end(); it != ie; ++it) { 00083 if ((*it)->getOption().matches(Id0) || 00084 (*it)->getOption().matches(Id1)) { 00085 Res = *it; 00086 Res->claim(); 00087 00088 } 00089 } 00090 00091 return Res; 00092 } 00093 00094 Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1, 00095 OptSpecifier Id2) const { 00096 Arg *Res = 0; 00097 for (const_iterator it = begin(), ie = end(); it != ie; ++it) { 00098 if ((*it)->getOption().matches(Id0) || 00099 (*it)->getOption().matches(Id1) || 00100 (*it)->getOption().matches(Id2)) { 00101 Res = *it; 00102 Res->claim(); 00103 } 00104 } 00105 00106 return Res; 00107 } 00108 00109 Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1, 00110 OptSpecifier Id2, OptSpecifier Id3) const { 00111 Arg *Res = 0; 00112 for (const_iterator it = begin(), ie = end(); it != ie; ++it) { 00113 if ((*it)->getOption().matches(Id0) || 00114 (*it)->getOption().matches(Id1) || 00115 (*it)->getOption().matches(Id2) || 00116 (*it)->getOption().matches(Id3)) { 00117 Res = *it; 00118 Res->claim(); 00119 } 00120 } 00121 00122 return Res; 00123 } 00124 00125 Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1, 00126 OptSpecifier Id2, OptSpecifier Id3, 00127 OptSpecifier Id4) const { 00128 Arg *Res = 0; 00129 for (const_iterator it = begin(), ie = end(); it != ie; ++it) { 00130 if ((*it)->getOption().matches(Id0) || 00131 (*it)->getOption().matches(Id1) || 00132 (*it)->getOption().matches(Id2) || 00133 (*it)->getOption().matches(Id3) || 00134 (*it)->getOption().matches(Id4)) { 00135 Res = *it; 00136 Res->claim(); 00137 } 00138 } 00139 00140 return Res; 00141 } 00142 00143 bool ArgList::hasFlag(OptSpecifier Pos, OptSpecifier Neg, bool Default) const { 00144 if (Arg *A = getLastArg(Pos, Neg)) 00145 return A->getOption().matches(Pos); 00146 return Default; 00147 } 00148 00149 StringRef ArgList::getLastArgValue(OptSpecifier Id, 00150 StringRef Default) const { 00151 if (Arg *A = getLastArg(Id)) 00152 return A->getValue(*this); 00153 return Default; 00154 } 00155 00156 int ArgList::getLastArgIntValue(OptSpecifier Id, int Default, 00157 clang::DiagnosticsEngine *Diags) const { 00158 int Res = Default; 00159 00160 if (Arg *A = getLastArg(Id)) { 00161 if (StringRef(A->getValue(*this)).getAsInteger(10, Res)) { 00162 if (Diags) 00163 Diags->Report(diag::err_drv_invalid_int_value) 00164 << A->getAsString(*this) << A->getValue(*this); 00165 } 00166 } 00167 00168 return Res; 00169 } 00170 00171 std::vector<std::string> ArgList::getAllArgValues(OptSpecifier Id) const { 00172 SmallVector<const char *, 16> Values; 00173 AddAllArgValues(Values, Id); 00174 return std::vector<std::string>(Values.begin(), Values.end()); 00175 } 00176 00177 void ArgList::AddLastArg(ArgStringList &Output, OptSpecifier Id) const { 00178 if (Arg *A = getLastArg(Id)) { 00179 A->claim(); 00180 A->render(*this, Output); 00181 } 00182 } 00183 00184 void ArgList::AddAllArgs(ArgStringList &Output, OptSpecifier Id0, 00185 OptSpecifier Id1, OptSpecifier Id2) const { 00186 for (arg_iterator it = filtered_begin(Id0, Id1, Id2), 00187 ie = filtered_end(); it != ie; ++it) { 00188 (*it)->claim(); 00189 (*it)->render(*this, Output); 00190 } 00191 } 00192 00193 void ArgList::AddAllArgValues(ArgStringList &Output, OptSpecifier Id0, 00194 OptSpecifier Id1, OptSpecifier Id2) const { 00195 for (arg_iterator it = filtered_begin(Id0, Id1, Id2), 00196 ie = filtered_end(); it != ie; ++it) { 00197 (*it)->claim(); 00198 for (unsigned i = 0, e = (*it)->getNumValues(); i != e; ++i) 00199 Output.push_back((*it)->getValue(*this, i)); 00200 } 00201 } 00202 00203 void ArgList::AddAllArgsTranslated(ArgStringList &Output, OptSpecifier Id0, 00204 const char *Translation, 00205 bool Joined) const { 00206 for (arg_iterator it = filtered_begin(Id0), 00207 ie = filtered_end(); it != ie; ++it) { 00208 (*it)->claim(); 00209 00210 if (Joined) { 00211 Output.push_back(MakeArgString(StringRef(Translation) + 00212 (*it)->getValue(*this, 0))); 00213 } else { 00214 Output.push_back(Translation); 00215 Output.push_back((*it)->getValue(*this, 0)); 00216 } 00217 } 00218 } 00219 00220 void ArgList::ClaimAllArgs(OptSpecifier Id0) const { 00221 for (arg_iterator it = filtered_begin(Id0), 00222 ie = filtered_end(); it != ie; ++it) 00223 (*it)->claim(); 00224 } 00225 00226 void ArgList::ClaimAllArgs() const { 00227 for (const_iterator it = begin(), ie = end(); it != ie; ++it) 00228 if (!(*it)->isClaimed()) 00229 (*it)->claim(); 00230 } 00231 00232 const char *ArgList::MakeArgString(const Twine &T) const { 00233 SmallString<256> Str; 00234 T.toVector(Str); 00235 return MakeArgString(Str.str()); 00236 } 00237 00238 const char *ArgList::GetOrMakeJoinedArgString(unsigned Index, 00239 StringRef LHS, 00240 StringRef RHS) const { 00241 StringRef Cur = getArgString(Index); 00242 if (Cur.size() == LHS.size() + RHS.size() && 00243 Cur.startswith(LHS) && Cur.endswith(RHS)) 00244 return Cur.data(); 00245 00246 return MakeArgString(LHS + RHS); 00247 } 00248 00249 // 00250 00251 InputArgList::InputArgList(const char* const *ArgBegin, 00252 const char* const *ArgEnd) 00253 : NumInputArgStrings(ArgEnd - ArgBegin) { 00254 ArgStrings.append(ArgBegin, ArgEnd); 00255 } 00256 00257 InputArgList::~InputArgList() { 00258 // An InputArgList always owns its arguments. 00259 for (iterator it = begin(), ie = end(); it != ie; ++it) 00260 delete *it; 00261 } 00262 00263 unsigned InputArgList::MakeIndex(StringRef String0) const { 00264 unsigned Index = ArgStrings.size(); 00265 00266 // Tuck away so we have a reliable const char *. 00267 SynthesizedStrings.push_back(String0); 00268 ArgStrings.push_back(SynthesizedStrings.back().c_str()); 00269 00270 return Index; 00271 } 00272 00273 unsigned InputArgList::MakeIndex(StringRef String0, 00274 StringRef String1) const { 00275 unsigned Index0 = MakeIndex(String0); 00276 unsigned Index1 = MakeIndex(String1); 00277 assert(Index0 + 1 == Index1 && "Unexpected non-consecutive indices!"); 00278 (void) Index1; 00279 return Index0; 00280 } 00281 00282 const char *InputArgList::MakeArgString(StringRef Str) const { 00283 return getArgString(MakeIndex(Str)); 00284 } 00285 00286 // 00287 00288 DerivedArgList::DerivedArgList(const InputArgList &_BaseArgs) 00289 : BaseArgs(_BaseArgs) { 00290 } 00291 00292 DerivedArgList::~DerivedArgList() { 00293 // We only own the arguments we explicitly synthesized. 00294 for (iterator it = SynthesizedArgs.begin(), ie = SynthesizedArgs.end(); 00295 it != ie; ++it) 00296 delete *it; 00297 } 00298 00299 const char *DerivedArgList::MakeArgString(StringRef Str) const { 00300 return BaseArgs.MakeArgString(Str); 00301 } 00302 00303 Arg *DerivedArgList::MakeFlagArg(const Arg *BaseArg, const Option *Opt) const { 00304 Arg *A = new Arg(Opt, BaseArgs.MakeIndex(Opt->getName()), BaseArg); 00305 SynthesizedArgs.push_back(A); 00306 return A; 00307 } 00308 00309 Arg *DerivedArgList::MakePositionalArg(const Arg *BaseArg, const Option *Opt, 00310 StringRef Value) const { 00311 unsigned Index = BaseArgs.MakeIndex(Value); 00312 Arg *A = new Arg(Opt, Index, BaseArgs.getArgString(Index), BaseArg); 00313 SynthesizedArgs.push_back(A); 00314 return A; 00315 } 00316 00317 Arg *DerivedArgList::MakeSeparateArg(const Arg *BaseArg, const Option *Opt, 00318 StringRef Value) const { 00319 unsigned Index = BaseArgs.MakeIndex(Opt->getName(), Value); 00320 Arg *A = new Arg(Opt, Index, BaseArgs.getArgString(Index + 1), BaseArg); 00321 SynthesizedArgs.push_back(A); 00322 return A; 00323 } 00324 00325 Arg *DerivedArgList::MakeJoinedArg(const Arg *BaseArg, const Option *Opt, 00326 StringRef Value) const { 00327 unsigned Index = BaseArgs.MakeIndex(Opt->getName().str() + Value.str()); 00328 Arg *A = new Arg(Opt, Index, 00329 BaseArgs.getArgString(Index) + Opt->getName().size(), 00330 BaseArg); 00331 SynthesizedArgs.push_back(A); 00332 return A; 00333 }