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 isValid()74 bool isValid() const { 75 return Info != nullptr; 76 } 77 getID()78 unsigned getID() const { 79 assert(Info && "Must have a valid info!"); 80 return Info->ID; 81 } 82 getKind()83 OptionClass getKind() const { 84 assert(Info && "Must have a valid info!"); 85 return OptionClass(Info->Kind); 86 } 87 88 /// \brief Get the name of this option without any prefix. getName()89 StringRef getName() const { 90 assert(Info && "Must have a valid info!"); 91 return Info->Name; 92 } 93 getGroup()94 const Option getGroup() const { 95 assert(Info && "Must have a valid info!"); 96 assert(Owner && "Must have a valid owner!"); 97 return Owner->getOption(Info->GroupID); 98 } 99 getAlias()100 const Option getAlias() const { 101 assert(Info && "Must have a valid info!"); 102 assert(Owner && "Must have a valid owner!"); 103 return Owner->getOption(Info->AliasID); 104 } 105 106 /// \brief Get the alias arguments as a \0 separated list. 107 /// E.g. ["foo", "bar"] would be returned as "foo\0bar\0". getAliasArgs()108 const char *getAliasArgs() const { 109 assert(Info && "Must have a valid info!"); 110 assert((!Info->AliasArgs || Info->AliasArgs[0] != 0) && 111 "AliasArgs should be either 0 or non-empty."); 112 113 return Info->AliasArgs; 114 } 115 116 /// \brief Get the default prefix for this option. getPrefix()117 StringRef getPrefix() const { 118 const char *Prefix = *Info->Prefixes; 119 return Prefix ? Prefix : StringRef(); 120 } 121 122 /// \brief Get the name of this option with the default prefix. getPrefixedName()123 std::string getPrefixedName() const { 124 std::string Ret = getPrefix(); 125 Ret += getName(); 126 return Ret; 127 } 128 getNumArgs()129 unsigned getNumArgs() const { return Info->Param; } 130 hasNoOptAsInput()131 bool hasNoOptAsInput() const { return Info->Flags & RenderAsInput;} 132 getRenderStyle()133 RenderStyleKind getRenderStyle() const { 134 if (Info->Flags & RenderJoined) 135 return RenderJoinedStyle; 136 if (Info->Flags & RenderSeparate) 137 return RenderSeparateStyle; 138 switch (getKind()) { 139 case GroupClass: 140 case InputClass: 141 case UnknownClass: 142 return RenderValuesStyle; 143 case JoinedClass: 144 case JoinedAndSeparateClass: 145 return RenderJoinedStyle; 146 case CommaJoinedClass: 147 return RenderCommaJoinedStyle; 148 case FlagClass: 149 case SeparateClass: 150 case MultiArgClass: 151 case JoinedOrSeparateClass: 152 case RemainingArgsClass: 153 return RenderSeparateStyle; 154 } 155 llvm_unreachable("Unexpected kind!"); 156 } 157 158 /// Test if this option has the flag \a Val. hasFlag(unsigned Val)159 bool hasFlag(unsigned Val) const { 160 return Info->Flags & Val; 161 } 162 163 /// getUnaliasedOption - Return the final option this option 164 /// aliases (itself, if the option has no alias). getUnaliasedOption()165 const Option getUnaliasedOption() const { 166 const Option Alias = getAlias(); 167 if (Alias.isValid()) return Alias.getUnaliasedOption(); 168 return *this; 169 } 170 171 /// getRenderName - Return the name to use when rendering this 172 /// option. getRenderName()173 StringRef getRenderName() const { 174 return getUnaliasedOption().getName(); 175 } 176 177 /// matches - Predicate for whether this option is part of the 178 /// given option (which may be a group). 179 /// 180 /// Note that matches against options which are an alias should never be 181 /// done -- aliases do not participate in matching and so such a query will 182 /// always be false. 183 bool matches(OptSpecifier ID) const; 184 185 /// accept - Potentially accept the current argument, returning a 186 /// new Arg instance, or 0 if the option does not accept this 187 /// argument (or the argument is missing values). 188 /// 189 /// If the option accepts the current argument, accept() sets 190 /// Index to the position where argument parsing should resume 191 /// (even if the argument is missing values). 192 /// 193 /// \param ArgSize The number of bytes taken up by the matched Option prefix 194 /// and name. This is used to determine where joined values 195 /// start. 196 Arg *accept(const ArgList &Args, unsigned &Index, unsigned ArgSize) const; 197 198 void dump() const; 199 }; 200 201 } // end namespace opt 202 } // end namespace llvm 203 204 #endif 205