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 CLANG_DRIVER_OPTION_H_ 11 #define CLANG_DRIVER_OPTION_H_ 12 13 #include "clang/Basic/LLVM.h" 14 #include "clang/Driver/OptTable.h" 15 #include "llvm/ADT/StringRef.h" 16 #include "llvm/Support/ErrorHandling.h" 17 18 namespace clang { 19 namespace driver { 20 class Arg; 21 class ArgList; 22 23 namespace options { 24 /// Base flags for all options. Custom flags may be added after. 25 enum DriverFlag { 26 HelpHidden = (1 << 0), 27 RenderAsInput = (1 << 1), 28 RenderJoined = (1 << 2), 29 RenderSeparate = (1 << 3) 30 }; 31 32 /// Flags specifically for clang options. 33 enum ClangFlags { 34 DriverOption = (1 << 4), 35 LinkerInput = (1 << 5), 36 NoArgumentUnused = (1 << 6), 37 NoForward = (1 << 7), 38 Unsupported = (1 << 8), 39 CC1Option = (1 << 9), 40 NoDriverOption = (1 << 10) 41 }; 42 } 43 44 /// Option - Abstract representation for a single form of driver 45 /// argument. 46 /// 47 /// An Option class represents a form of option that the driver 48 /// takes, for example how many arguments the option has and how 49 /// they can be provided. Individual option instances store 50 /// additional information about what group the option is a member 51 /// of (if any), if the option is an alias, and a number of 52 /// flags. At runtime the driver parses the command line into 53 /// concrete Arg instances, each of which corresponds to a 54 /// particular Option instance. 55 class Option { 56 public: 57 enum OptionClass { 58 GroupClass = 0, 59 InputClass, 60 UnknownClass, 61 FlagClass, 62 JoinedClass, 63 SeparateClass, 64 CommaJoinedClass, 65 MultiArgClass, 66 JoinedOrSeparateClass, 67 JoinedAndSeparateClass 68 }; 69 70 enum RenderStyleKind { 71 RenderCommaJoinedStyle, 72 RenderJoinedStyle, 73 RenderSeparateStyle, 74 RenderValuesStyle 75 }; 76 77 protected: 78 const OptTable::Info *Info; 79 const OptTable *Owner; 80 81 public: 82 Option(const OptTable::Info *Info, const OptTable *Owner); 83 ~Option(); 84 isValid()85 bool isValid() const { 86 return Info != 0; 87 } 88 getID()89 unsigned getID() const { 90 assert(Info && "Must have a valid info!"); 91 return Info->ID; 92 } 93 getKind()94 OptionClass getKind() const { 95 assert(Info && "Must have a valid info!"); 96 return OptionClass(Info->Kind); 97 } 98 99 /// \brief Get the name of this option without any prefix. getName()100 StringRef getName() const { 101 assert(Info && "Must have a valid info!"); 102 return Info->Name; 103 } 104 getGroup()105 const Option getGroup() const { 106 assert(Info && "Must have a valid info!"); 107 assert(Owner && "Must have a valid owner!"); 108 return Owner->getOption(Info->GroupID); 109 } 110 getAlias()111 const Option getAlias() const { 112 assert(Info && "Must have a valid info!"); 113 assert(Owner && "Must have a valid owner!"); 114 return Owner->getOption(Info->AliasID); 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 & options::RenderAsInput;} 133 getRenderStyle()134 RenderStyleKind getRenderStyle() const { 135 if (Info->Flags & options::RenderJoined) 136 return RenderJoinedStyle; 137 if (Info->Flags & options::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 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 /// \parm 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 driver 202 } // end namespace clang 203 204 #endif 205