1 //===- ArgList.h - Argument List Management ---------------------*- C++ -*-===// 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 #ifndef LLVM_OPTION_ARGLIST_H 11 #define LLVM_OPTION_ARGLIST_H 12 13 #include "llvm/ADT/ArrayRef.h" 14 #include "llvm/ADT/DenseMap.h" 15 #include "llvm/ADT/iterator_range.h" 16 #include "llvm/ADT/SmallString.h" 17 #include "llvm/ADT/SmallVector.h" 18 #include "llvm/ADT/StringRef.h" 19 #include "llvm/ADT/Twine.h" 20 #include "llvm/Option/Arg.h" 21 #include "llvm/Option/OptSpecifier.h" 22 #include "llvm/Option/Option.h" 23 #include <algorithm> 24 #include <cstddef> 25 #include <initializer_list> 26 #include <iterator> 27 #include <list> 28 #include <memory> 29 #include <string> 30 #include <utility> 31 #include <vector> 32 33 namespace llvm { 34 35 class raw_ostream; 36 37 namespace opt { 38 39 /// arg_iterator - Iterates through arguments stored inside an ArgList. 40 template<typename BaseIter, unsigned NumOptSpecifiers = 0> 41 class arg_iterator { 42 /// The current argument and the end of the sequence we're iterating. 43 BaseIter Current, End; 44 45 /// Optional filters on the arguments which will be match. To avoid a 46 /// zero-sized array, we store one specifier even if we're asked for none. 47 OptSpecifier Ids[NumOptSpecifiers ? NumOptSpecifiers : 1]; 48 49 void SkipToNextArg() { 50 for (; Current != End; ++Current) { 51 // Skip erased elements. 52 if (!*Current) 53 continue; 54 55 // Done if there are no filters. 56 if (!NumOptSpecifiers) 57 return; 58 59 // Otherwise require a match. 60 const Option &O = (*Current)->getOption(); 61 for (auto Id : Ids) { 62 if (!Id.isValid()) 63 break; 64 if (O.matches(Id)) 65 return; 66 } 67 } 68 } 69 70 using Traits = std::iterator_traits<BaseIter>; 71 72 public: 73 using value_type = typename Traits::value_type; 74 using reference = typename Traits::reference; 75 using pointer = typename Traits::pointer; 76 using iterator_category = std::forward_iterator_tag; 77 using difference_type = std::ptrdiff_t; 78 79 arg_iterator( 80 BaseIter Current, BaseIter End, 81 const OptSpecifier (&Ids)[NumOptSpecifiers ? NumOptSpecifiers : 1] = {}) 82 : Current(Current), End(End) { 83 for (unsigned I = 0; I != NumOptSpecifiers; ++I) 84 this->Ids[I] = Ids[I]; 85 SkipToNextArg(); 86 } 87 88 // FIXME: This conversion function makes no sense. 89 operator const Arg*() { return *Current; } 90 91 reference operator*() const { return *Current; } 92 pointer operator->() const { return Current; } 93 94 arg_iterator &operator++() { 95 ++Current; 96 SkipToNextArg(); 97 return *this; 98 } 99 100 arg_iterator operator++(int) { 101 arg_iterator tmp(*this); 102 ++(*this); 103 return tmp; 104 } 105 106 friend bool operator==(arg_iterator LHS, arg_iterator RHS) { 107 return LHS.Current == RHS.Current; 108 } 109 friend bool operator!=(arg_iterator LHS, arg_iterator RHS) { 110 return !(LHS == RHS); 111 } 112 }; 113 114 /// ArgList - Ordered collection of driver arguments. 115 /// 116 /// The ArgList class manages a list of Arg instances as well as 117 /// auxiliary data and convenience methods to allow Tools to quickly 118 /// check for the presence of Arg instances for a particular Option 119 /// and to iterate over groups of arguments. 120 class ArgList { 121 public: 122 using arglist_type = SmallVector<Arg *, 16>; 123 using iterator = arg_iterator<arglist_type::iterator>; 124 using const_iterator = arg_iterator<arglist_type::const_iterator>; 125 using reverse_iterator = arg_iterator<arglist_type::reverse_iterator>; 126 using const_reverse_iterator = 127 arg_iterator<arglist_type::const_reverse_iterator>; 128 129 template<unsigned N> using filtered_iterator = 130 arg_iterator<arglist_type::const_iterator, N>; 131 template<unsigned N> using filtered_reverse_iterator = 132 arg_iterator<arglist_type::const_reverse_iterator, N>; 133 134 private: 135 /// The internal list of arguments. 136 arglist_type Args; 137 138 using OptRange = std::pair<unsigned, unsigned>; 139 static OptRange emptyRange() { return {-1u, 0u}; } 140 141 /// The first and last index of each different OptSpecifier ID. 142 DenseMap<unsigned, OptRange> OptRanges; 143 144 /// Get the range of indexes in which options with the specified IDs might 145 /// reside, or (0, 0) if there are no such options. 146 OptRange getRange(std::initializer_list<OptSpecifier> Ids) const; 147 148 protected: 149 // Make the default special members protected so they won't be used to slice 150 // derived objects, but can still be used by derived objects to implement 151 // their own special members. 152 ArgList() = default; 153 154 // Explicit move operations to ensure the container is cleared post-move 155 // otherwise it could lead to a double-delete in the case of moving of an 156 // InputArgList which deletes the contents of the container. If we could fix 157 // up the ownership here (delegate storage/ownership to the derived class so 158 // it can be a container of unique_ptr) this would be simpler. 159 ArgList(ArgList &&RHS) 160 : Args(std::move(RHS.Args)), OptRanges(std::move(RHS.OptRanges)) { 161 RHS.Args.clear(); 162 RHS.OptRanges.clear(); 163 } 164 165 ArgList &operator=(ArgList &&RHS) { 166 Args = std::move(RHS.Args); 167 RHS.Args.clear(); 168 OptRanges = std::move(RHS.OptRanges); 169 RHS.OptRanges.clear(); 170 return *this; 171 } 172 173 // Protect the dtor to ensure this type is never destroyed polymorphically. 174 ~ArgList() = default; 175 176 // Implicitly convert a value to an OptSpecifier. Used to work around a bug 177 // in MSVC's implementation of narrowing conversion checking. 178 static OptSpecifier toOptSpecifier(OptSpecifier S) { return S; } 179 180 public: 181 /// @name Arg Access 182 /// @{ 183 184 /// append - Append \p A to the arg list. 185 void append(Arg *A); 186 187 const arglist_type &getArgs() const { return Args; } 188 189 unsigned size() const { return Args.size(); } 190 191 /// @} 192 /// @name Arg Iteration 193 /// @{ 194 195 iterator begin() { return {Args.begin(), Args.end()}; } 196 iterator end() { return {Args.end(), Args.end()}; } 197 198 reverse_iterator rbegin() { return {Args.rbegin(), Args.rend()}; } 199 reverse_iterator rend() { return {Args.rend(), Args.rend()}; } 200 201 const_iterator begin() const { return {Args.begin(), Args.end()}; } 202 const_iterator end() const { return {Args.end(), Args.end()}; } 203 204 const_reverse_iterator rbegin() const { return {Args.rbegin(), Args.rend()}; } 205 const_reverse_iterator rend() const { return {Args.rend(), Args.rend()}; } 206 207 template<typename ...OptSpecifiers> 208 iterator_range<filtered_iterator<sizeof...(OptSpecifiers)>> 209 filtered(OptSpecifiers ...Ids) const { 210 OptRange Range = getRange({toOptSpecifier(Ids)...}); 211 auto B = Args.begin() + Range.first; 212 auto E = Args.begin() + Range.second; 213 using Iterator = filtered_iterator<sizeof...(OptSpecifiers)>; 214 return make_range(Iterator(B, E, {toOptSpecifier(Ids)...}), 215 Iterator(E, E, {toOptSpecifier(Ids)...})); 216 } 217 218 template<typename ...OptSpecifiers> 219 iterator_range<filtered_reverse_iterator<sizeof...(OptSpecifiers)>> 220 filtered_reverse(OptSpecifiers ...Ids) const { 221 OptRange Range = getRange({toOptSpecifier(Ids)...}); 222 auto B = Args.rend() - Range.second; 223 auto E = Args.rend() - Range.first; 224 using Iterator = filtered_reverse_iterator<sizeof...(OptSpecifiers)>; 225 return make_range(Iterator(B, E, {toOptSpecifier(Ids)...}), 226 Iterator(E, E, {toOptSpecifier(Ids)...})); 227 } 228 229 /// @} 230 /// @name Arg Removal 231 /// @{ 232 233 /// eraseArg - Remove any option matching \p Id. 234 void eraseArg(OptSpecifier Id); 235 236 /// @} 237 /// @name Arg Access 238 /// @{ 239 240 /// hasArg - Does the arg list contain any option matching \p Id. 241 /// 242 /// \p Claim Whether the argument should be claimed, if it exists. 243 template<typename ...OptSpecifiers> 244 bool hasArgNoClaim(OptSpecifiers ...Ids) const { 245 return getLastArgNoClaim(Ids...) != nullptr; 246 } 247 template<typename ...OptSpecifiers> 248 bool hasArg(OptSpecifiers ...Ids) const { 249 return getLastArg(Ids...) != nullptr; 250 } 251 252 /// Return the last argument matching \p Id, or null. 253 template<typename ...OptSpecifiers> 254 Arg *getLastArg(OptSpecifiers ...Ids) const { 255 Arg *Res = nullptr; 256 for (Arg *A : filtered(Ids...)) { 257 Res = A; 258 Res->claim(); 259 } 260 return Res; 261 } 262 263 /// Return the last argument matching \p Id, or null. Do not "claim" the 264 /// option (don't mark it as having been used). 265 template<typename ...OptSpecifiers> 266 Arg *getLastArgNoClaim(OptSpecifiers ...Ids) const { 267 for (Arg *A : filtered_reverse(Ids...)) 268 return A; 269 return nullptr; 270 } 271 272 /// getArgString - Return the input argument string at \p Index. 273 virtual const char *getArgString(unsigned Index) const = 0; 274 275 /// getNumInputArgStrings - Return the number of original argument strings, 276 /// which are guaranteed to be the first strings in the argument string 277 /// list. 278 virtual unsigned getNumInputArgStrings() const = 0; 279 280 /// @} 281 /// @name Argument Lookup Utilities 282 /// @{ 283 284 /// getLastArgValue - Return the value of the last argument, or a default. 285 StringRef getLastArgValue(OptSpecifier Id, StringRef Default = "") const; 286 287 /// getAllArgValues - Get the values of all instances of the given argument 288 /// as strings. 289 std::vector<std::string> getAllArgValues(OptSpecifier Id) const; 290 291 /// @} 292 /// @name Translation Utilities 293 /// @{ 294 295 /// hasFlag - Given an option \p Pos and its negative form \p Neg, return 296 /// true if the option is present, false if the negation is present, and 297 /// \p Default if neither option is given. If both the option and its 298 /// negation are present, the last one wins. 299 bool hasFlag(OptSpecifier Pos, OptSpecifier Neg, bool Default=true) const; 300 301 /// hasFlag - Given an option \p Pos, an alias \p PosAlias and its negative 302 /// form \p Neg, return true if the option or its alias is present, false if 303 /// the negation is present, and \p Default if none of the options are 304 /// given. If multiple options are present, the last one wins. 305 bool hasFlag(OptSpecifier Pos, OptSpecifier PosAlias, OptSpecifier Neg, 306 bool Default = true) const; 307 308 /// AddLastArg - Render only the last argument match \p Id0, if present. 309 void AddLastArg(ArgStringList &Output, OptSpecifier Id0) const; 310 void AddLastArg(ArgStringList &Output, OptSpecifier Id0, 311 OptSpecifier Id1) const; 312 313 /// AddAllArgsExcept - Render all arguments matching any of the given ids 314 /// and not matching any of the excluded ids. 315 void AddAllArgsExcept(ArgStringList &Output, ArrayRef<OptSpecifier> Ids, 316 ArrayRef<OptSpecifier> ExcludeIds) const; 317 /// AddAllArgs - Render all arguments matching any of the given ids. 318 void AddAllArgs(ArgStringList &Output, ArrayRef<OptSpecifier> Ids) const; 319 320 /// AddAllArgs - Render all arguments matching the given ids. 321 void AddAllArgs(ArgStringList &Output, OptSpecifier Id0, 322 OptSpecifier Id1 = 0U, OptSpecifier Id2 = 0U) const; 323 324 /// AddAllArgValues - Render the argument values of all arguments 325 /// matching the given ids. 326 void AddAllArgValues(ArgStringList &Output, OptSpecifier Id0, 327 OptSpecifier Id1 = 0U, OptSpecifier Id2 = 0U) const; 328 329 /// AddAllArgsTranslated - Render all the arguments matching the 330 /// given ids, but forced to separate args and using the provided 331 /// name instead of the first option value. 332 /// 333 /// \param Joined - If true, render the argument as joined with 334 /// the option specifier. 335 void AddAllArgsTranslated(ArgStringList &Output, OptSpecifier Id0, 336 const char *Translation, 337 bool Joined = false) const; 338 339 /// ClaimAllArgs - Claim all arguments which match the given 340 /// option id. 341 void ClaimAllArgs(OptSpecifier Id0) const; 342 343 /// ClaimAllArgs - Claim all arguments. 344 /// 345 void ClaimAllArgs() const; 346 347 /// @} 348 /// @name Arg Synthesis 349 /// @{ 350 351 /// Construct a constant string pointer whose 352 /// lifetime will match that of the ArgList. 353 virtual const char *MakeArgStringRef(StringRef Str) const = 0; 354 const char *MakeArgString(const Twine &Str) const { 355 SmallString<256> Buf; 356 return MakeArgStringRef(Str.toStringRef(Buf)); 357 } 358 359 /// \brief Create an arg string for (\p LHS + \p RHS), reusing the 360 /// string at \p Index if possible. 361 const char *GetOrMakeJoinedArgString(unsigned Index, StringRef LHS, 362 StringRef RHS) const; 363 364 void print(raw_ostream &O) const; 365 void dump() const; 366 367 /// @} 368 }; 369 370 class InputArgList final : public ArgList { 371 private: 372 /// List of argument strings used by the contained Args. 373 /// 374 /// This is mutable since we treat the ArgList as being the list 375 /// of Args, and allow routines to add new strings (to have a 376 /// convenient place to store the memory) via MakeIndex. 377 mutable ArgStringList ArgStrings; 378 379 /// Strings for synthesized arguments. 380 /// 381 /// This is mutable since we treat the ArgList as being the list 382 /// of Args, and allow routines to add new strings (to have a 383 /// convenient place to store the memory) via MakeIndex. 384 mutable std::list<std::string> SynthesizedStrings; 385 386 /// The number of original input argument strings. 387 unsigned NumInputArgStrings; 388 389 /// Release allocated arguments. 390 void releaseMemory(); 391 392 public: 393 InputArgList(const char* const *ArgBegin, const char* const *ArgEnd); 394 395 InputArgList(InputArgList &&RHS) 396 : ArgList(std::move(RHS)), ArgStrings(std::move(RHS.ArgStrings)), 397 SynthesizedStrings(std::move(RHS.SynthesizedStrings)), 398 NumInputArgStrings(RHS.NumInputArgStrings) {} 399 400 InputArgList &operator=(InputArgList &&RHS) { 401 releaseMemory(); 402 ArgList::operator=(std::move(RHS)); 403 ArgStrings = std::move(RHS.ArgStrings); 404 SynthesizedStrings = std::move(RHS.SynthesizedStrings); 405 NumInputArgStrings = RHS.NumInputArgStrings; 406 return *this; 407 } 408 409 ~InputArgList() { releaseMemory(); } 410 411 const char *getArgString(unsigned Index) const override { 412 return ArgStrings[Index]; 413 } 414 415 unsigned getNumInputArgStrings() const override { 416 return NumInputArgStrings; 417 } 418 419 /// @name Arg Synthesis 420 /// @{ 421 422 public: 423 /// MakeIndex - Get an index for the given string(s). 424 unsigned MakeIndex(StringRef String0) const; 425 unsigned MakeIndex(StringRef String0, StringRef String1) const; 426 427 using ArgList::MakeArgString; 428 const char *MakeArgStringRef(StringRef Str) const override; 429 430 /// @} 431 }; 432 433 /// DerivedArgList - An ordered collection of driver arguments, 434 /// whose storage may be in another argument list. 435 class DerivedArgList final : public ArgList { 436 const InputArgList &BaseArgs; 437 438 /// The list of arguments we synthesized. 439 mutable SmallVector<std::unique_ptr<Arg>, 16> SynthesizedArgs; 440 441 public: 442 /// Construct a new derived arg list from \p BaseArgs. 443 DerivedArgList(const InputArgList &BaseArgs); 444 445 const char *getArgString(unsigned Index) const override { 446 return BaseArgs.getArgString(Index); 447 } 448 449 unsigned getNumInputArgStrings() const override { 450 return BaseArgs.getNumInputArgStrings(); 451 } 452 453 const InputArgList &getBaseArgs() const { 454 return BaseArgs; 455 } 456 457 /// @name Arg Synthesis 458 /// @{ 459 460 /// AddSynthesizedArg - Add a argument to the list of synthesized arguments 461 /// (to be freed). 462 void AddSynthesizedArg(Arg *A); 463 464 using ArgList::MakeArgString; 465 const char *MakeArgStringRef(StringRef Str) const override; 466 467 /// AddFlagArg - Construct a new FlagArg for the given option \p Id and 468 /// append it to the argument list. 469 void AddFlagArg(const Arg *BaseArg, const Option Opt) { 470 append(MakeFlagArg(BaseArg, Opt)); 471 } 472 473 /// AddPositionalArg - Construct a new Positional arg for the given option 474 /// \p Id, with the provided \p Value and append it to the argument 475 /// list. 476 void AddPositionalArg(const Arg *BaseArg, const Option Opt, 477 StringRef Value) { 478 append(MakePositionalArg(BaseArg, Opt, Value)); 479 } 480 481 /// AddSeparateArg - Construct a new Positional arg for the given option 482 /// \p Id, with the provided \p Value and append it to the argument 483 /// list. 484 void AddSeparateArg(const Arg *BaseArg, const Option Opt, 485 StringRef Value) { 486 append(MakeSeparateArg(BaseArg, Opt, Value)); 487 } 488 489 /// AddJoinedArg - Construct a new Positional arg for the given option 490 /// \p Id, with the provided \p Value and append it to the argument list. 491 void AddJoinedArg(const Arg *BaseArg, const Option Opt, 492 StringRef Value) { 493 append(MakeJoinedArg(BaseArg, Opt, Value)); 494 } 495 496 /// MakeFlagArg - Construct a new FlagArg for the given option \p Id. 497 Arg *MakeFlagArg(const Arg *BaseArg, const Option Opt) const; 498 499 /// MakePositionalArg - Construct a new Positional arg for the 500 /// given option \p Id, with the provided \p Value. 501 Arg *MakePositionalArg(const Arg *BaseArg, const Option Opt, 502 StringRef Value) const; 503 504 /// MakeSeparateArg - Construct a new Positional arg for the 505 /// given option \p Id, with the provided \p Value. 506 Arg *MakeSeparateArg(const Arg *BaseArg, const Option Opt, 507 StringRef Value) const; 508 509 /// MakeJoinedArg - Construct a new Positional arg for the 510 /// given option \p Id, with the provided \p Value. 511 Arg *MakeJoinedArg(const Arg *BaseArg, const Option Opt, 512 StringRef Value) const; 513 514 /// @} 515 }; 516 517 } // end namespace opt 518 519 } // end namespace llvm 520 521 #endif // LLVM_OPTION_ARGLIST_H 522