clang API Documentation
00001 //===--- Option.h - Abstract Driver Options ---------------------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 00010 #ifndef CLANG_DRIVER_OPTION_H_ 00011 #define CLANG_DRIVER_OPTION_H_ 00012 00013 #include "clang/Driver/OptSpecifier.h" 00014 #include "llvm/ADT/StringRef.h" 00015 #include "clang/Basic/LLVM.h" 00016 00017 namespace clang { 00018 namespace driver { 00019 class Arg; 00020 class ArgList; 00021 class OptionGroup; 00022 00023 /// Option - Abstract representation for a single form of driver 00024 /// argument. 00025 /// 00026 /// An Option class represents a form of option that the driver 00027 /// takes, for example how many arguments the option has and how 00028 /// they can be provided. Individual option instances store 00029 /// additional information about what group the option is a member 00030 /// of (if any), if the option is an alias, and a number of 00031 /// flags. At runtime the driver parses the command line into 00032 /// concrete Arg instances, each of which corresponds to a 00033 /// particular Option instance. 00034 class Option { 00035 public: 00036 enum OptionClass { 00037 GroupClass = 0, 00038 InputClass, 00039 UnknownClass, 00040 FlagClass, 00041 JoinedClass, 00042 SeparateClass, 00043 CommaJoinedClass, 00044 MultiArgClass, 00045 JoinedOrSeparateClass, 00046 JoinedAndSeparateClass 00047 }; 00048 00049 enum RenderStyleKind { 00050 RenderCommaJoinedStyle, 00051 RenderJoinedStyle, 00052 RenderSeparateStyle, 00053 RenderValuesStyle 00054 }; 00055 00056 private: 00057 OptionClass Kind; 00058 00059 /// The option ID. 00060 OptSpecifier ID; 00061 00062 /// The option name. 00063 StringRef Name; 00064 00065 /// Group this option is a member of, if any. 00066 const OptionGroup *Group; 00067 00068 /// Option that this is an alias for, if any. 00069 const Option *Alias; 00070 00071 /// Unsupported options will be rejected. 00072 bool Unsupported : 1; 00073 00074 /// Treat this option like a linker input? 00075 bool LinkerInput : 1; 00076 00077 /// When rendering as an input, don't render the option. 00078 00079 // FIXME: We should ditch the render/renderAsInput distinction. 00080 bool NoOptAsInput : 1; 00081 00082 /// The style to using when rendering arguments parsed by this option. 00083 unsigned RenderStyle : 2; 00084 00085 /// This option is only consumed by the driver. 00086 bool DriverOption : 1; 00087 00088 /// This option should not report argument unused errors. 00089 bool NoArgumentUnused : 1; 00090 00091 /// This option should not be implicitly forwarded. 00092 bool NoForward : 1; 00093 00094 /// CC1Option - This option should be accepted by clang -cc1. 00095 bool CC1Option : 1; 00096 00097 protected: 00098 Option(OptionClass Kind, OptSpecifier ID, const char *Name, 00099 const OptionGroup *Group, const Option *Alias); 00100 public: 00101 virtual ~Option(); 00102 00103 unsigned getID() const { return ID.getID(); } 00104 OptionClass getKind() const { return Kind; } 00105 StringRef getName() const { return Name; } 00106 const OptionGroup *getGroup() const { return Group; } 00107 const Option *getAlias() const { return Alias; } 00108 00109 bool isUnsupported() const { return Unsupported; } 00110 void setUnsupported(bool Value) { Unsupported = Value; } 00111 00112 bool isLinkerInput() const { return LinkerInput; } 00113 void setLinkerInput(bool Value) { LinkerInput = Value; } 00114 00115 bool hasNoOptAsInput() const { return NoOptAsInput; } 00116 void setNoOptAsInput(bool Value) { NoOptAsInput = Value; } 00117 00118 RenderStyleKind getRenderStyle() const { 00119 return RenderStyleKind(RenderStyle); 00120 } 00121 void setRenderStyle(RenderStyleKind Value) { RenderStyle = Value; } 00122 00123 bool isDriverOption() const { return DriverOption; } 00124 void setDriverOption(bool Value) { DriverOption = Value; } 00125 00126 bool hasNoArgumentUnused() const { return NoArgumentUnused; } 00127 void setNoArgumentUnused(bool Value) { NoArgumentUnused = Value; } 00128 00129 bool hasNoForward() const { return NoForward; } 00130 void setNoForward(bool Value) { NoForward = Value; } 00131 00132 bool isCC1Option() const { return CC1Option; } 00133 void setIsCC1Option(bool Value) { CC1Option = Value; } 00134 00135 bool hasForwardToGCC() const { 00136 return !NoForward && !DriverOption && !LinkerInput; 00137 } 00138 00139 /// getUnaliasedOption - Return the final option this option 00140 /// aliases (itself, if the option has no alias). 00141 const Option *getUnaliasedOption() const { 00142 if (Alias) return Alias->getUnaliasedOption(); 00143 return this; 00144 } 00145 00146 /// getRenderName - Return the name to use when rendering this 00147 /// option. 00148 StringRef getRenderName() const { 00149 return getUnaliasedOption()->getName(); 00150 } 00151 00152 /// matches - Predicate for whether this option is part of the 00153 /// given option (which may be a group). 00154 /// 00155 /// Note that matches against options which are an alias should never be 00156 /// done -- aliases do not participate in matching and so such a query will 00157 /// always be false. 00158 bool matches(OptSpecifier ID) const; 00159 00160 /// accept - Potentially accept the current argument, returning a 00161 /// new Arg instance, or 0 if the option does not accept this 00162 /// argument (or the argument is missing values). 00163 /// 00164 /// If the option accepts the current argument, accept() sets 00165 /// Index to the position where argument parsing should resume 00166 /// (even if the argument is missing values). 00167 virtual Arg *accept(const ArgList &Args, unsigned &Index) const = 0; 00168 00169 void dump() const; 00170 00171 static bool classof(const Option *) { return true; } 00172 }; 00173 00174 /// OptionGroup - A set of options which are can be handled uniformly 00175 /// by the driver. 00176 class OptionGroup : public Option { 00177 public: 00178 OptionGroup(OptSpecifier ID, const char *Name, const OptionGroup *Group); 00179 00180 virtual Arg *accept(const ArgList &Args, unsigned &Index) const; 00181 00182 static bool classof(const Option *O) { 00183 return O->getKind() == Option::GroupClass; 00184 } 00185 static bool classof(const OptionGroup *) { return true; } 00186 }; 00187 00188 // Dummy option classes. 00189 00190 /// InputOption - Dummy option class for representing driver inputs. 00191 class InputOption : public Option { 00192 public: 00193 InputOption(OptSpecifier ID); 00194 00195 virtual Arg *accept(const ArgList &Args, unsigned &Index) const; 00196 00197 static bool classof(const Option *O) { 00198 return O->getKind() == Option::InputClass; 00199 } 00200 static bool classof(const InputOption *) { return true; } 00201 }; 00202 00203 /// UnknownOption - Dummy option class for represent unknown arguments. 00204 class UnknownOption : public Option { 00205 public: 00206 UnknownOption(OptSpecifier ID); 00207 00208 virtual Arg *accept(const ArgList &Args, unsigned &Index) const; 00209 00210 static bool classof(const Option *O) { 00211 return O->getKind() == Option::UnknownClass; 00212 } 00213 static bool classof(const UnknownOption *) { return true; } 00214 }; 00215 00216 // Normal options. 00217 00218 class FlagOption : public Option { 00219 public: 00220 FlagOption(OptSpecifier ID, const char *Name, const OptionGroup *Group, 00221 const Option *Alias); 00222 00223 virtual Arg *accept(const ArgList &Args, unsigned &Index) const; 00224 00225 static bool classof(const Option *O) { 00226 return O->getKind() == Option::FlagClass; 00227 } 00228 static bool classof(const FlagOption *) { return true; } 00229 }; 00230 00231 class JoinedOption : public Option { 00232 public: 00233 JoinedOption(OptSpecifier ID, const char *Name, const OptionGroup *Group, 00234 const Option *Alias); 00235 00236 virtual Arg *accept(const ArgList &Args, unsigned &Index) const; 00237 00238 static bool classof(const Option *O) { 00239 return O->getKind() == Option::JoinedClass; 00240 } 00241 static bool classof(const JoinedOption *) { return true; } 00242 }; 00243 00244 class SeparateOption : public Option { 00245 public: 00246 SeparateOption(OptSpecifier ID, const char *Name, 00247 const OptionGroup *Group, const Option *Alias); 00248 00249 virtual Arg *accept(const ArgList &Args, unsigned &Index) const; 00250 00251 static bool classof(const Option *O) { 00252 return O->getKind() == Option::SeparateClass; 00253 } 00254 static bool classof(const SeparateOption *) { return true; } 00255 }; 00256 00257 class CommaJoinedOption : public Option { 00258 public: 00259 CommaJoinedOption(OptSpecifier ID, const char *Name, 00260 const OptionGroup *Group, const Option *Alias); 00261 00262 virtual Arg *accept(const ArgList &Args, unsigned &Index) const; 00263 00264 static bool classof(const Option *O) { 00265 return O->getKind() == Option::CommaJoinedClass; 00266 } 00267 static bool classof(const CommaJoinedOption *) { return true; } 00268 }; 00269 00270 // FIXME: Fold MultiArgOption into SeparateOption? 00271 00272 /// MultiArgOption - An option which takes multiple arguments (these 00273 /// are always separate arguments). 00274 class MultiArgOption : public Option { 00275 unsigned NumArgs; 00276 00277 public: 00278 MultiArgOption(OptSpecifier ID, const char *Name, const OptionGroup *Group, 00279 const Option *Alias, unsigned NumArgs); 00280 00281 unsigned getNumArgs() const { return NumArgs; } 00282 00283 virtual Arg *accept(const ArgList &Args, unsigned &Index) const; 00284 00285 static bool classof(const Option *O) { 00286 return O->getKind() == Option::MultiArgClass; 00287 } 00288 static bool classof(const MultiArgOption *) { return true; } 00289 }; 00290 00291 /// JoinedOrSeparateOption - An option which either literally 00292 /// prefixes its (non-empty) value, or is follwed by a value. 00293 class JoinedOrSeparateOption : public Option { 00294 public: 00295 JoinedOrSeparateOption(OptSpecifier ID, const char *Name, 00296 const OptionGroup *Group, const Option *Alias); 00297 00298 virtual Arg *accept(const ArgList &Args, unsigned &Index) const; 00299 00300 static bool classof(const Option *O) { 00301 return O->getKind() == Option::JoinedOrSeparateClass; 00302 } 00303 static bool classof(const JoinedOrSeparateOption *) { return true; } 00304 }; 00305 00306 /// JoinedAndSeparateOption - An option which literally prefixes its 00307 /// value and is followed by another value. 00308 class JoinedAndSeparateOption : public Option { 00309 public: 00310 JoinedAndSeparateOption(OptSpecifier ID, const char *Name, 00311 const OptionGroup *Group, const Option *Alias); 00312 00313 virtual Arg *accept(const ArgList &Args, unsigned &Index) const; 00314 00315 static bool classof(const Option *O) { 00316 return O->getKind() == Option::JoinedAndSeparateClass; 00317 } 00318 static bool classof(const JoinedAndSeparateOption *) { return true; } 00319 }; 00320 00321 } // end namespace driver 00322 } // end namespace clang 00323 00324 #endif