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 CommaJoinedClass, 54 MultiArgClass, 55 JoinedOrSeparateClass, 56 JoinedAndSeparateClass 57 }; 58 59 enum RenderStyleKind { 60 RenderCommaJoinedStyle, 61 RenderJoinedStyle, 62 RenderSeparateStyle, 63 RenderValuesStyle 64 }; 65 66 protected: 67 const OptTable::Info *Info; 68 const OptTable *Owner; 69 70 public: 71 Option(const OptTable::Info *Info, const OptTable *Owner); 72 ~Option(); 73 74 bool isValid() const { 75 return Info != 0; 76 } 77 78 unsigned getID() const { 79 assert(Info && "Must have a valid info!"); 80 return Info->ID; 81 } 82 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. 89 StringRef getName() const { 90 assert(Info && "Must have a valid info!"); 91 return Info->Name; 92 } 93 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 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". 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. 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. 123 std::string getPrefixedName() const { 124 std::string Ret = getPrefix(); 125 Ret += getName(); 126 return Ret; 127 } 128 129 unsigned getNumArgs() const { return Info->Param; } 130 131 bool hasNoOptAsInput() const { return Info->Flags & RenderAsInput;} 132 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 return RenderSeparateStyle; 153 } 154 llvm_unreachable("Unexpected kind!"); 155 } 156 157 /// Test if this option has the flag \a Val. 158 bool hasFlag(unsigned Val) const { 159 return Info->Flags & Val; 160 } 161 162 /// getUnaliasedOption - Return the final option this option 163 /// aliases (itself, if the option has no alias). 164 const Option getUnaliasedOption() const { 165 const Option Alias = getAlias(); 166 if (Alias.isValid()) return Alias.getUnaliasedOption(); 167 return *this; 168 } 169 170 /// getRenderName - Return the name to use when rendering this 171 /// option. 172 StringRef getRenderName() const { 173 return getUnaliasedOption().getName(); 174 } 175 176 /// matches - Predicate for whether this option is part of the 177 /// given option (which may be a group). 178 /// 179 /// Note that matches against options which are an alias should never be 180 /// done -- aliases do not participate in matching and so such a query will 181 /// always be false. 182 bool matches(OptSpecifier ID) const; 183 184 /// accept - Potentially accept the current argument, returning a 185 /// new Arg instance, or 0 if the option does not accept this 186 /// argument (or the argument is missing values). 187 /// 188 /// If the option accepts the current argument, accept() sets 189 /// Index to the position where argument parsing should resume 190 /// (even if the argument is missing values). 191 /// 192 /// \param ArgSize The number of bytes taken up by the matched Option prefix 193 /// and name. This is used to determine where joined values 194 /// start. 195 Arg *accept(const ArgList &Args, unsigned &Index, unsigned ArgSize) const; 196 197 void dump() const; 198 }; 199 200 } // end namespace opt 201 } // end namespace llvm 202 203 #endif 204