Home | History | Annotate | Download | only in Option
      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 LLVM_OPTION_OPTION_H
     11 #define LLVM_OPTION_OPTION_H
     12 
     13 #include "llvm/ADT/SmallVector.h"
     14 #include "llvm/ADT/StringRef.h"
     15 #include "llvm/Option/OptTable.h"
     16 #include "llvm/Support/ErrorHandling.h"
     17 
     18 namespace llvm {
     19 namespace opt {
     20 class Arg;
     21 class ArgList;
     22 /// ArgStringList - Type used for constructing argv lists for subprocesses.
     23 typedef SmallVector<const char*, 16> ArgStringList;
     24 
     25 /// Base flags for all options. Custom flags may be added after.
     26 enum DriverFlag {
     27   HelpHidden       = (1 << 0),
     28   RenderAsInput    = (1 << 1),
     29   RenderJoined     = (1 << 2),
     30   RenderSeparate   = (1 << 3)
     31 };
     32 
     33 /// Option - Abstract representation for a single form of driver
     34 /// argument.
     35 ///
     36 /// An Option class represents a form of option that the driver
     37 /// takes, for example how many arguments the option has and how
     38 /// they can be provided. Individual option instances store
     39 /// additional information about what group the option is a member
     40 /// of (if any), if the option is an alias, and a number of
     41 /// flags. At runtime the driver parses the command line into
     42 /// concrete Arg instances, each of which corresponds to a
     43 /// particular Option instance.
     44 class Option {
     45 public:
     46   enum OptionClass {
     47     GroupClass = 0,
     48     InputClass,
     49     UnknownClass,
     50     FlagClass,
     51     JoinedClass,
     52     SeparateClass,
     53     CommaJoinedClass,
     54     MultiArgClass,
     55     JoinedOrSeparateClass,
     56     JoinedAndSeparateClass
     57   };
     58 
     59   enum RenderStyleKind {
     60     RenderCommaJoinedStyle,
     61     RenderJoinedStyle,
     62     RenderSeparateStyle,
     63     RenderValuesStyle
     64   };
     65 
     66 protected:
     67   const OptTable::Info *Info;
     68   const OptTable *Owner;
     69 
     70 public:
     71   Option(const OptTable::Info *Info, const OptTable *Owner);
     72   ~Option();
     73 
     74   bool isValid() const {
     75     return Info != 0;
     76   }
     77 
     78   unsigned getID() const {
     79     assert(Info && "Must have a valid info!");
     80     return Info->ID;
     81   }
     82 
     83   OptionClass getKind() const {
     84     assert(Info && "Must have a valid info!");
     85     return OptionClass(Info->Kind);
     86   }
     87 
     88   /// \brief Get the name of this option without any prefix.
     89   StringRef getName() const {
     90     assert(Info && "Must have a valid info!");
     91     return Info->Name;
     92   }
     93 
     94   const Option getGroup() const {
     95     assert(Info && "Must have a valid info!");
     96     assert(Owner && "Must have a valid owner!");
     97     return Owner->getOption(Info->GroupID);
     98   }
     99 
    100   const Option getAlias() const {
    101     assert(Info && "Must have a valid info!");
    102     assert(Owner && "Must have a valid owner!");
    103     return Owner->getOption(Info->AliasID);
    104   }
    105 
    106   /// \brief Get the alias arguments as a \0 separated list.
    107   /// E.g. ["foo", "bar"] would be returned as "foo\0bar\0".
    108   const char *getAliasArgs() const {
    109     assert(Info && "Must have a valid info!");
    110     assert((!Info->AliasArgs || Info->AliasArgs[0] != 0) &&
    111            "AliasArgs should be either 0 or non-empty.");
    112 
    113     return Info->AliasArgs;
    114   }
    115 
    116   /// \brief Get the default prefix for this option.
    117   StringRef getPrefix() const {
    118     const char *Prefix = *Info->Prefixes;
    119     return Prefix ? Prefix : StringRef();
    120   }
    121 
    122   /// \brief Get the name of this option with the default prefix.
    123   std::string getPrefixedName() const {
    124     std::string Ret = getPrefix();
    125     Ret += getName();
    126     return Ret;
    127   }
    128 
    129   unsigned getNumArgs() const { return Info->Param; }
    130 
    131   bool hasNoOptAsInput() const { return Info->Flags & RenderAsInput;}
    132 
    133   RenderStyleKind getRenderStyle() const {
    134     if (Info->Flags & RenderJoined)
    135       return RenderJoinedStyle;
    136     if (Info->Flags & RenderSeparate)
    137       return RenderSeparateStyle;
    138     switch (getKind()) {
    139     case GroupClass:
    140     case InputClass:
    141     case UnknownClass:
    142       return RenderValuesStyle;
    143     case JoinedClass:
    144     case JoinedAndSeparateClass:
    145       return RenderJoinedStyle;
    146     case CommaJoinedClass:
    147       return RenderCommaJoinedStyle;
    148     case FlagClass:
    149     case SeparateClass:
    150     case MultiArgClass:
    151     case JoinedOrSeparateClass:
    152       return RenderSeparateStyle;
    153     }
    154     llvm_unreachable("Unexpected kind!");
    155   }
    156 
    157   /// Test if this option has the flag \a Val.
    158   bool hasFlag(unsigned Val) const {
    159     return Info->Flags & Val;
    160   }
    161 
    162   /// getUnaliasedOption - Return the final option this option
    163   /// aliases (itself, if the option has no alias).
    164   const Option getUnaliasedOption() const {
    165     const Option Alias = getAlias();
    166     if (Alias.isValid()) return Alias.getUnaliasedOption();
    167     return *this;
    168   }
    169 
    170   /// getRenderName - Return the name to use when rendering this
    171   /// option.
    172   StringRef getRenderName() const {
    173     return getUnaliasedOption().getName();
    174   }
    175 
    176   /// matches - Predicate for whether this option is part of the
    177   /// given option (which may be a group).
    178   ///
    179   /// Note that matches against options which are an alias should never be
    180   /// done -- aliases do not participate in matching and so such a query will
    181   /// always be false.
    182   bool matches(OptSpecifier ID) const;
    183 
    184   /// accept - Potentially accept the current argument, returning a
    185   /// new Arg instance, or 0 if the option does not accept this
    186   /// argument (or the argument is missing values).
    187   ///
    188   /// If the option accepts the current argument, accept() sets
    189   /// Index to the position where argument parsing should resume
    190   /// (even if the argument is missing values).
    191   ///
    192   /// \param ArgSize The number of bytes taken up by the matched Option prefix
    193   ///                and name. This is used to determine where joined values
    194   ///                start.
    195   Arg *accept(const ArgList &Args, unsigned &Index, unsigned ArgSize) const;
    196 
    197   void dump() const;
    198 };
    199 
    200 } // end namespace opt
    201 } // end namespace llvm
    202 
    203 #endif
    204