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     RemainingArgsClass,
     54     CommaJoinedClass,
     55     MultiArgClass,
     56     JoinedOrSeparateClass,
     57     JoinedAndSeparateClass
     58   };
     59 
     60   enum RenderStyleKind {
     61     RenderCommaJoinedStyle,
     62     RenderJoinedStyle,
     63     RenderSeparateStyle,
     64     RenderValuesStyle
     65   };
     66 
     67 protected:
     68   const OptTable::Info *Info;
     69   const OptTable *Owner;
     70 
     71 public:
     72   Option(const OptTable::Info *Info, const OptTable *Owner);
     73   ~Option();
     74 
     75   bool isValid() const {
     76     return Info != nullptr;
     77   }
     78 
     79   unsigned getID() const {
     80     assert(Info && "Must have a valid info!");
     81     return Info->ID;
     82   }
     83 
     84   OptionClass getKind() const {
     85     assert(Info && "Must have a valid info!");
     86     return OptionClass(Info->Kind);
     87   }
     88 
     89   /// \brief Get the name of this option without any prefix.
     90   StringRef getName() const {
     91     assert(Info && "Must have a valid info!");
     92     return Info->Name;
     93   }
     94 
     95   const Option getGroup() const {
     96     assert(Info && "Must have a valid info!");
     97     assert(Owner && "Must have a valid owner!");
     98     return Owner->getOption(Info->GroupID);
     99   }
    100 
    101   const Option getAlias() const {
    102     assert(Info && "Must have a valid info!");
    103     assert(Owner && "Must have a valid owner!");
    104     return Owner->getOption(Info->AliasID);
    105   }
    106 
    107   /// \brief Get the alias arguments as a \0 separated list.
    108   /// E.g. ["foo", "bar"] would be returned as "foo\0bar\0".
    109   const char *getAliasArgs() const {
    110     assert(Info && "Must have a valid info!");
    111     assert((!Info->AliasArgs || Info->AliasArgs[0] != 0) &&
    112            "AliasArgs should be either 0 or non-empty.");
    113 
    114     return Info->AliasArgs;
    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 & RenderAsInput;}
    133 
    134   RenderStyleKind getRenderStyle() const {
    135     if (Info->Flags & RenderJoined)
    136       return RenderJoinedStyle;
    137     if (Info->Flags & 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     case RemainingArgsClass:
    154       return RenderSeparateStyle;
    155     }
    156     llvm_unreachable("Unexpected kind!");
    157   }
    158 
    159   /// Test if this option has the flag \a Val.
    160   bool hasFlag(unsigned Val) const {
    161     return Info->Flags & Val;
    162   }
    163 
    164   /// getUnaliasedOption - Return the final option this option
    165   /// aliases (itself, if the option has no alias).
    166   const Option getUnaliasedOption() const {
    167     const Option Alias = getAlias();
    168     if (Alias.isValid()) return Alias.getUnaliasedOption();
    169     return *this;
    170   }
    171 
    172   /// getRenderName - Return the name to use when rendering this
    173   /// option.
    174   StringRef getRenderName() const {
    175     return getUnaliasedOption().getName();
    176   }
    177 
    178   /// matches - Predicate for whether this option is part of the
    179   /// given option (which may be a group).
    180   ///
    181   /// Note that matches against options which are an alias should never be
    182   /// done -- aliases do not participate in matching and so such a query will
    183   /// always be false.
    184   bool matches(OptSpecifier ID) const;
    185 
    186   /// accept - Potentially accept the current argument, returning a
    187   /// new Arg instance, or 0 if the option does not accept this
    188   /// argument (or the argument is missing values).
    189   ///
    190   /// If the option accepts the current argument, accept() sets
    191   /// Index to the position where argument parsing should resume
    192   /// (even if the argument is missing values).
    193   ///
    194   /// \param ArgSize The number of bytes taken up by the matched Option prefix
    195   ///                and name. This is used to determine where joined values
    196   ///                start.
    197   Arg *accept(const ArgList &Args, unsigned &Index, unsigned ArgSize) const;
    198 
    199   void dump() const;
    200 };
    201 
    202 } // end namespace opt
    203 } // end namespace llvm
    204 
    205 #endif
    206