clang API Documentation

Option.h
Go to the documentation of this file.
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