1 //===--- Option.h - Abstract Driver Options ---------------------*- 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_OPTION_H 11 #define LLVM_OPTION_OPTION_H 12 13 #include "llvm/ADT/SmallVector.h" 14 #include "llvm/ADT/StringRef.h" 15 #include "llvm/Option/OptTable.h" 16 #include "llvm/Support/ErrorHandling.h" 17 18 namespace llvm { 19 namespace opt { 20 class Arg; 21 class ArgList; 22 /// ArgStringList - Type used for constructing argv lists for subprocesses. 23 typedef SmallVector<const char*, 16> ArgStringList; 24 25 /// Base flags for all options. Custom flags may be added after. 26 enum DriverFlag { 27 HelpHidden = (1 << 0), 28 RenderAsInput = (1 << 1), 29 RenderJoined = (1 << 2), 30 RenderSeparate = (1 << 3) 31 }; 32 33 /// Option - Abstract representation for a single form of driver 34 /// argument. 35 /// 36 /// An Option class represents a form of option that the driver 37 /// takes, for example how many arguments the option has and how 38 /// they can be provided. Individual option instances store 39 /// additional information about what group the option is a member 40 /// of (if any), if the option is an alias, and a number of 41 /// flags. At runtime the driver parses the command line into 42 /// concrete Arg instances, each of which corresponds to a 43 /// particular Option instance. 44 class Option { 45 public: 46 enum OptionClass { 47 GroupClass = 0, 48 InputClass, 49 UnknownClass, 50 FlagClass, 51 JoinedClass, 52 SeparateClass, 53 RemainingArgsClass, 54 CommaJoinedClass, 55 MultiArgClass, 56 JoinedOrSeparateClass, 57 JoinedAndSeparateClass 58 }; 59 60 enum RenderStyleKind { 61 RenderCommaJoinedStyle, 62 RenderJoinedStyle, 63 RenderSeparateStyle, 64 RenderValuesStyle 65 }; 66 67 protected: 68 const OptTable::Info *Info; 69 const OptTable *Owner; 70 71 public: 72 Option(const OptTable::Info *Info, const OptTable *Owner); 73 ~Option(); 74 isValid()75 bool isValid() const { 76 return Info != nullptr; 77 } 78 getID()79 unsigned getID() const { 80 assert(Info && "Must have a valid info!"); 81 return Info->ID; 82 } 83 getKind()84 OptionClass getKind() const { 85 assert(Info && "Must have a valid info!"); 86 return OptionClass(Info->Kind); 87 } 88 89 /// \brief Get the name of this option without any prefix. getName()90 StringRef getName() const { 91 assert(Info && "Must have a valid info!"); 92 return Info->Name; 93 } 94 getGroup()95 const Option getGroup() const { 96 assert(Info && "Must have a valid info!"); 97 assert(Owner && "Must have a valid owner!"); 98 return Owner->getOption(Info->GroupID); 99 } 100 getAlias()101 const Option getAlias() const { 102 assert(Info && "Must have a valid info!"); 103 assert(Owner && "Must have a valid owner!"); 104 return Owner->getOption(Info->AliasID); 105 } 106 107 /// \brief Get the alias arguments as a \0 separated list. 108 /// E.g. ["foo", "bar"] would be returned as "foo\0bar\0". getAliasArgs()109 const char *getAliasArgs() const { 110 assert(Info && "Must have a valid info!"); 111 assert((!Info->AliasArgs || Info->AliasArgs[0] != 0) && 112 "AliasArgs should be either 0 or non-empty."); 113 114 return Info->AliasArgs; 115 } 116 117 /// \brief Get the default prefix for this option. getPrefix()118 StringRef getPrefix() const { 119 const char *Prefix = *Info->Prefixes; 120 return Prefix ? Prefix : StringRef(); 121 } 122 123 /// \brief Get the name of this option with the default prefix. getPrefixedName()124 std::string getPrefixedName() const { 125 std::string Ret = getPrefix(); 126 Ret += getName(); 127 return Ret; 128 } 129 getNumArgs()130 unsigned getNumArgs() const { return Info->Param; } 131 hasNoOptAsInput()132 bool hasNoOptAsInput() const { return Info->Flags & RenderAsInput;} 133 getRenderStyle()134 RenderStyleKind getRenderStyle() const { 135 if (Info->Flags & RenderJoined) 136 return RenderJoinedStyle; 137 if (Info->Flags & RenderSeparate) 138 return RenderSeparateStyle; 139 switch (getKind()) { 140 case GroupClass: 141 case InputClass: 142 case UnknownClass: 143 return RenderValuesStyle; 144 case JoinedClass: 145 case JoinedAndSeparateClass: 146 return RenderJoinedStyle; 147 case CommaJoinedClass: 148 return RenderCommaJoinedStyle; 149 case FlagClass: 150 case SeparateClass: 151 case MultiArgClass: 152 case JoinedOrSeparateClass: 153 case RemainingArgsClass: 154 return RenderSeparateStyle; 155 } 156 llvm_unreachable("Unexpected kind!"); 157 } 158 159 /// Test if this option has the flag \a Val. hasFlag(unsigned Val)160 bool hasFlag(unsigned Val) const { 161 return Info->Flags & Val; 162 } 163 164 /// getUnaliasedOption - Return the final option this option 165 /// aliases (itself, if the option has no alias). getUnaliasedOption()166 const Option getUnaliasedOption() const { 167 const Option Alias = getAlias(); 168 if (Alias.isValid()) return Alias.getUnaliasedOption(); 169 return *this; 170 } 171 172 /// getRenderName - Return the name to use when rendering this 173 /// option. getRenderName()174 StringRef getRenderName() const { 175 return getUnaliasedOption().getName(); 176 } 177 178 /// matches - Predicate for whether this option is part of the 179 /// given option (which may be a group). 180 /// 181 /// Note that matches against options which are an alias should never be 182 /// done -- aliases do not participate in matching and so such a query will 183 /// always be false. 184 bool matches(OptSpecifier ID) const; 185 186 /// accept - Potentially accept the current argument, returning a 187 /// new Arg instance, or 0 if the option does not accept this 188 /// argument (or the argument is missing values). 189 /// 190 /// If the option accepts the current argument, accept() sets 191 /// Index to the position where argument parsing should resume 192 /// (even if the argument is missing values). 193 /// 194 /// \param ArgSize The number of bytes taken up by the matched Option prefix 195 /// and name. This is used to determine where joined values 196 /// start. 197 Arg *accept(const ArgList &Args, unsigned &Index, unsigned ArgSize) const; 198 199 void dump() const; 200 }; 201 202 } // end namespace opt 203 } // end namespace llvm 204 205 #endif 206