1 //===- Arg.h - Parsed Argument Classes --------------------------*- 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 /// \file 10 /// Defines the llvm::Arg class for parsed arguments. 11 /// 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_OPTION_ARG_H 15 #define LLVM_OPTION_ARG_H 16 17 #include "llvm/ADT/SmallVector.h" 18 #include "llvm/ADT/StringRef.h" 19 #include "llvm/Option/Option.h" 20 #include "llvm/Support/Compiler.h" 21 #include <string> 22 23 namespace llvm { 24 25 class raw_ostream; 26 27 namespace opt { 28 29 class ArgList; 30 31 /// A concrete instance of a particular driver option. 32 /// 33 /// The Arg class encodes just enough information to be able to 34 /// derive the argument values efficiently. 35 class Arg { 36 private: 37 /// The option this argument is an instance of. 38 const Option Opt; 39 40 /// The argument this argument was derived from (during tool chain 41 /// argument translation), if any. 42 const Arg *BaseArg; 43 44 /// How this instance of the option was spelled. 45 StringRef Spelling; 46 47 /// The index at which this argument appears in the containing 48 /// ArgList. 49 unsigned Index; 50 51 /// Was this argument used to affect compilation? 52 /// 53 /// This is used to generate an "argument unused" warning (without 54 /// clang::driver::options::TargetSpecific) or "unsupported option" error 55 /// (with TargetSpecific). 56 mutable unsigned Claimed : 1; 57 58 /// Used by an unclaimed option with the TargetSpecific flag. If set, report 59 /// an "argument unused" warning instead of an "unsupported option" error. 60 unsigned IgnoredTargetSpecific : 1; 61 62 /// Does this argument own its values? 63 mutable unsigned OwnsValues : 1; 64 65 /// The argument values, as C strings. 66 SmallVector<const char *, 2> Values; 67 68 /// If this arg was created through an alias, this is the original alias arg. 69 /// For example, *this might be "-finput-charset=utf-8" and Alias might 70 /// point to an arg representing "/source-charset:utf-8". 71 std::unique_ptr<Arg> Alias; 72 73 public: 74 LLVM_ABI Arg(const Option Opt, StringRef Spelling, unsigned Index, 75 const Arg *BaseArg = nullptr); 76 LLVM_ABI Arg(const Option Opt, StringRef Spelling, unsigned Index, 77 const char *Value0, const Arg *BaseArg = nullptr); 78 LLVM_ABI Arg(const Option Opt, StringRef Spelling, unsigned Index, 79 const char *Value0, const char *Value1, 80 const Arg *BaseArg = nullptr); 81 Arg(const Arg &) = delete; 82 Arg &operator=(const Arg &) = delete; 83 LLVM_ABI ~Arg(); 84 getOption()85 const Option &getOption() const { return Opt; } 86 87 /// Returns the used prefix and name of the option: 88 /// For `--foo=bar`, returns `--foo=`. 89 /// This is often the wrong function to call: 90 /// * Use `getValue()` to get `bar`. 91 /// * Use `getAsString()` to get a string suitable for printing an Arg in 92 /// a diagnostic. getSpelling()93 StringRef getSpelling() const { return Spelling; } 94 getIndex()95 unsigned getIndex() const { return Index; } 96 97 /// Return the base argument which generated this arg. 98 /// 99 /// This is either the argument itself or the argument it was 100 /// derived from during tool chain specific argument translation. getBaseArg()101 const Arg &getBaseArg() const { 102 return BaseArg ? *BaseArg : *this; 103 } getBaseArg()104 Arg &getBaseArg() { return BaseArg ? const_cast<Arg &>(*BaseArg) : *this; } setBaseArg(const Arg * BaseArg)105 void setBaseArg(const Arg *BaseArg) { this->BaseArg = BaseArg; } 106 107 /// Args are converted to their unaliased form. For args that originally 108 /// came from an alias, this returns the alias the arg was produced from. getAlias()109 const Arg* getAlias() const { return Alias.get(); } setAlias(std::unique_ptr<Arg> Alias)110 void setAlias(std::unique_ptr<Arg> Alias) { this->Alias = std::move(Alias); } 111 getOwnsValues()112 bool getOwnsValues() const { return OwnsValues; } setOwnsValues(bool Value)113 void setOwnsValues(bool Value) const { OwnsValues = Value; } 114 isClaimed()115 bool isClaimed() const { return getBaseArg().Claimed; } claim()116 void claim() const { getBaseArg().Claimed = true; } 117 isIgnoredTargetSpecific()118 bool isIgnoredTargetSpecific() const { 119 return getBaseArg().IgnoredTargetSpecific; 120 } ignoreTargetSpecific()121 void ignoreTargetSpecific() { 122 getBaseArg().IgnoredTargetSpecific = true; 123 } 124 getNumValues()125 unsigned getNumValues() const { return Values.size(); } 126 127 const char *getValue(unsigned N = 0) const { 128 return Values[N]; 129 } 130 getValues()131 SmallVectorImpl<const char *> &getValues() { return Values; } getValues()132 const SmallVectorImpl<const char *> &getValues() const { return Values; } 133 containsValue(StringRef Value)134 bool containsValue(StringRef Value) const { 135 return llvm::is_contained(Values, Value); 136 } 137 138 /// Append the argument onto the given array as strings. 139 LLVM_ABI void render(const ArgList &Args, ArgStringList &Output) const; 140 141 /// Append the argument, render as an input, onto the given 142 /// array as strings. 143 /// 144 /// The distinction is that some options only render their values 145 /// when rendered as a input (e.g., Xlinker). 146 LLVM_ABI void renderAsInput(const ArgList &Args, ArgStringList &Output) const; 147 148 LLVM_ABI void print(raw_ostream &O) const; 149 LLVM_ABI void dump() const; 150 151 /// Return a formatted version of the argument and its values, for 152 /// diagnostics. Since this is for diagnostics, if this Arg was produced 153 /// through an alias, this returns the string representation of the alias 154 /// that the user wrote. 155 LLVM_ABI std::string getAsString(const ArgList &Args) const; 156 }; 157 158 } // end namespace opt 159 160 } // end namespace llvm 161 162 #endif // LLVM_OPTION_ARG_H 163