Option.h revision bcf6a8025aa50f3f28cfbd0470cf3e8f5cffbab2
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/Driver/OptSpecifier.h" 14#include "llvm/ADT/StringRef.h" 15#include "llvm/Support/Casting.h" 16using llvm::isa; 17using llvm::cast; 18using llvm::cast_or_null; 19using llvm::dyn_cast; 20using llvm::dyn_cast_or_null; 21 22namespace clang { 23namespace driver { 24 class Arg; 25 class ArgList; 26 class OptionGroup; 27 28 /// Option - Abstract representation for a single form of driver 29 /// argument. 30 /// 31 /// An Option class represents a form of option that the driver 32 /// takes, for example how many arguments the option has and how 33 /// they can be provided. Individual option instances store 34 /// additional information about what group the option is a member 35 /// of (if any), if the option is an alias, and a number of 36 /// flags. At runtime the driver parses the command line into 37 /// concrete Arg instances, each of which corresponds to a 38 /// particular Option instance. 39 class Option { 40 public: 41 enum OptionClass { 42 GroupClass = 0, 43 InputClass, 44 UnknownClass, 45 FlagClass, 46 JoinedClass, 47 SeparateClass, 48 CommaJoinedClass, 49 MultiArgClass, 50 JoinedOrSeparateClass, 51 JoinedAndSeparateClass 52 }; 53 54 enum RenderStyleKind { 55 RenderCommaJoinedStyle, 56 RenderJoinedStyle, 57 RenderSeparateStyle, 58 RenderValuesStyle 59 }; 60 61 private: 62 OptionClass Kind; 63 64 /// The option ID. 65 OptSpecifier ID; 66 67 /// The option name. 68 llvm::StringRef Name; 69 70 /// Group this option is a member of, if any. 71 const OptionGroup *Group; 72 73 /// Option that this is an alias for, if any. 74 const Option *Alias; 75 76 /// Unsupported options will be rejected. 77 bool Unsupported : 1; 78 79 /// Treat this option like a linker input? 80 bool LinkerInput : 1; 81 82 /// When rendering as an input, don't render the option. 83 84 // FIXME: We should ditch the render/renderAsInput distinction. 85 bool NoOptAsInput : 1; 86 87 /// The style to using when rendering arguments parsed by this option. 88 unsigned RenderStyle : 2; 89 90 /// This option is only consumed by the driver. 91 bool DriverOption : 1; 92 93 /// This option should not report argument unused errors. 94 bool NoArgumentUnused : 1; 95 96 /// This option should not be implicitly forwarded. 97 bool NoForward : 1; 98 99 protected: 100 Option(OptionClass Kind, OptSpecifier ID, const char *Name, 101 const OptionGroup *Group, const Option *Alias); 102 public: 103 virtual ~Option(); 104 105 unsigned getID() const { return ID.getID(); } 106 OptionClass getKind() const { return Kind; } 107 llvm::StringRef getName() const { return Name; } 108 const OptionGroup *getGroup() const { return Group; } 109 const Option *getAlias() const { return Alias; } 110 111 bool isUnsupported() const { return Unsupported; } 112 void setUnsupported(bool Value) { Unsupported = Value; } 113 114 bool isLinkerInput() const { return LinkerInput; } 115 void setLinkerInput(bool Value) { LinkerInput = Value; } 116 117 bool hasNoOptAsInput() const { return NoOptAsInput; } 118 void setNoOptAsInput(bool Value) { NoOptAsInput = Value; } 119 120 RenderStyleKind getRenderStyle() const { 121 return RenderStyleKind(RenderStyle); 122 } 123 void setRenderStyle(RenderStyleKind Value) { RenderStyle = Value; } 124 125 bool isDriverOption() const { return DriverOption; } 126 void setDriverOption(bool Value) { DriverOption = Value; } 127 128 bool hasNoArgumentUnused() const { return NoArgumentUnused; } 129 void setNoArgumentUnused(bool Value) { NoArgumentUnused = Value; } 130 131 bool hasNoForward() const { return NoForward; } 132 void setNoForward(bool Value) { NoForward = Value; } 133 134 bool hasForwardToGCC() const { 135 return !NoForward && !DriverOption && !LinkerInput; 136 } 137 138 /// getUnaliasedOption - Return the final option this option 139 /// aliases (itself, if the option has no alias). 140 const Option *getUnaliasedOption() const { 141 if (Alias) return Alias->getUnaliasedOption(); 142 return this; 143 } 144 145 /// getRenderName - Return the name to use when rendering this 146 /// option. 147 llvm::StringRef getRenderName() const { 148 return getUnaliasedOption()->getName(); 149 } 150 151 /// matches - Predicate for whether this option is part of the 152 /// given option (which may be a group). 153 /// 154 /// Note that matches against options which are an alias should never be 155 /// done -- aliases do not participate in matching and so such a query will 156 /// always be false. 157 bool matches(OptSpecifier ID) const; 158 159 /// accept - Potentially accept the current argument, returning a 160 /// new Arg instance, or 0 if the option does not accept this 161 /// argument (or the argument is missing values). 162 /// 163 /// If the option accepts the current argument, accept() sets 164 /// Index to the position where argument parsing should resume 165 /// (even if the argument is missing values). 166 virtual Arg *accept(const ArgList &Args, unsigned &Index) const = 0; 167 168 void dump() const; 169 170 static bool classof(const Option *) { return true; } 171 }; 172 173 /// OptionGroup - A set of options which are can be handled uniformly 174 /// by the driver. 175 class OptionGroup : public Option { 176 public: 177 OptionGroup(OptSpecifier ID, const char *Name, const OptionGroup *Group); 178 179 virtual Arg *accept(const ArgList &Args, unsigned &Index) const; 180 181 static bool classof(const Option *O) { 182 return O->getKind() == Option::GroupClass; 183 } 184 static bool classof(const OptionGroup *) { return true; } 185 }; 186 187 // Dummy option classes. 188 189 /// InputOption - Dummy option class for representing driver inputs. 190 class InputOption : public Option { 191 public: 192 InputOption(OptSpecifier ID); 193 194 virtual Arg *accept(const ArgList &Args, unsigned &Index) const; 195 196 static bool classof(const Option *O) { 197 return O->getKind() == Option::InputClass; 198 } 199 static bool classof(const InputOption *) { return true; } 200 }; 201 202 /// UnknownOption - Dummy option class for represent unknown arguments. 203 class UnknownOption : public Option { 204 public: 205 UnknownOption(OptSpecifier ID); 206 207 virtual Arg *accept(const ArgList &Args, unsigned &Index) const; 208 209 static bool classof(const Option *O) { 210 return O->getKind() == Option::UnknownClass; 211 } 212 static bool classof(const UnknownOption *) { return true; } 213 }; 214 215 // Normal options. 216 217 class FlagOption : public Option { 218 public: 219 FlagOption(OptSpecifier ID, const char *Name, const OptionGroup *Group, 220 const Option *Alias); 221 222 virtual Arg *accept(const ArgList &Args, unsigned &Index) const; 223 224 static bool classof(const Option *O) { 225 return O->getKind() == Option::FlagClass; 226 } 227 static bool classof(const FlagOption *) { return true; } 228 }; 229 230 class JoinedOption : public Option { 231 public: 232 JoinedOption(OptSpecifier ID, const char *Name, const OptionGroup *Group, 233 const Option *Alias); 234 235 virtual Arg *accept(const ArgList &Args, unsigned &Index) const; 236 237 static bool classof(const Option *O) { 238 return O->getKind() == Option::JoinedClass; 239 } 240 static bool classof(const JoinedOption *) { return true; } 241 }; 242 243 class SeparateOption : public Option { 244 public: 245 SeparateOption(OptSpecifier ID, const char *Name, 246 const OptionGroup *Group, const Option *Alias); 247 248 virtual Arg *accept(const ArgList &Args, unsigned &Index) const; 249 250 static bool classof(const Option *O) { 251 return O->getKind() == Option::SeparateClass; 252 } 253 static bool classof(const SeparateOption *) { return true; } 254 }; 255 256 class CommaJoinedOption : public Option { 257 public: 258 CommaJoinedOption(OptSpecifier ID, const char *Name, 259 const OptionGroup *Group, const Option *Alias); 260 261 virtual Arg *accept(const ArgList &Args, unsigned &Index) const; 262 263 static bool classof(const Option *O) { 264 return O->getKind() == Option::CommaJoinedClass; 265 } 266 static bool classof(const CommaJoinedOption *) { return true; } 267 }; 268 269 // FIXME: Fold MultiArgOption into SeparateOption? 270 271 /// MultiArgOption - An option which takes multiple arguments (these 272 /// are always separate arguments). 273 class MultiArgOption : public Option { 274 unsigned NumArgs; 275 276 public: 277 MultiArgOption(OptSpecifier ID, const char *Name, const OptionGroup *Group, 278 const Option *Alias, unsigned NumArgs); 279 280 unsigned getNumArgs() const { return NumArgs; } 281 282 virtual Arg *accept(const ArgList &Args, unsigned &Index) const; 283 284 static bool classof(const Option *O) { 285 return O->getKind() == Option::MultiArgClass; 286 } 287 static bool classof(const MultiArgOption *) { return true; } 288 }; 289 290 /// JoinedOrSeparateOption - An option which either literally 291 /// prefixes its (non-empty) value, or is follwed by a value. 292 class JoinedOrSeparateOption : public Option { 293 public: 294 JoinedOrSeparateOption(OptSpecifier ID, const char *Name, 295 const OptionGroup *Group, const Option *Alias); 296 297 virtual Arg *accept(const ArgList &Args, unsigned &Index) const; 298 299 static bool classof(const Option *O) { 300 return O->getKind() == Option::JoinedOrSeparateClass; 301 } 302 static bool classof(const JoinedOrSeparateOption *) { return true; } 303 }; 304 305 /// JoinedAndSeparateOption - An option which literally prefixes its 306 /// value and is followed by another value. 307 class JoinedAndSeparateOption : public Option { 308 public: 309 JoinedAndSeparateOption(OptSpecifier ID, const char *Name, 310 const OptionGroup *Group, const Option *Alias); 311 312 virtual Arg *accept(const ArgList &Args, unsigned &Index) const; 313 314 static bool classof(const Option *O) { 315 return O->getKind() == Option::JoinedAndSeparateClass; 316 } 317 static bool classof(const JoinedAndSeparateOption *) { return true; } 318 }; 319 320} // end namespace driver 321} // end namespace clang 322 323#endif 324