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