Home | History | Annotate | Download | only in Driver
      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 
     85     bool isValid() const {
     86       return Info != 0;
     87     }
     88 
     89     unsigned getID() const {
     90       assert(Info && "Must have a valid info!");
     91       return Info->ID;
     92     }
     93 
     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.
    100     StringRef getName() const {
    101       assert(Info && "Must have a valid info!");
    102       return Info->Name;
    103     }
    104 
    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 
    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.
    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.
    124     std::string getPrefixedName() const {
    125       std::string Ret = getPrefix();
    126       Ret += getName();
    127       return Ret;
    128     }
    129 
    130     unsigned getNumArgs() const { return Info->Param; }
    131 
    132     bool hasNoOptAsInput() const { return Info->Flags & options::RenderAsInput;}
    133 
    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.
    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).
    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.
    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