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     RemainingArgsJoinedClass,
     55     CommaJoinedClass,
     56     MultiArgClass,
     57     JoinedOrSeparateClass,
     58     JoinedAndSeparateClass
     59   };
     60 
     61   enum RenderStyleKind {
     62     RenderCommaJoinedStyle,
     63     RenderJoinedStyle,
     64     RenderSeparateStyle,
     65     RenderValuesStyle
     66   };
     67 
     68 protected:
     69   const OptTable::Info *Info;
     70   const OptTable *Owner;
     71 
     72 public:
     73   Option(const OptTable::Info *Info, const OptTable *Owner);
     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     case RemainingArgsJoinedClass:
    155       return RenderSeparateStyle;
    156     }
    157     llvm_unreachable("Unexpected kind!");
    158   }
    159 
    160   /// Test if this option has the flag \a Val.
    161   bool hasFlag(unsigned Val) const {
    162     return Info->Flags & Val;
    163   }
    164 
    165   /// getUnaliasedOption - Return the final option this option
    166   /// aliases (itself, if the option has no alias).
    167   const Option getUnaliasedOption() const {
    168     const Option Alias = getAlias();
    169     if (Alias.isValid()) return Alias.getUnaliasedOption();
    170     return *this;
    171   }
    172 
    173   /// getRenderName - Return the name to use when rendering this
    174   /// option.
    175   StringRef getRenderName() const {
    176     return getUnaliasedOption().getName();
    177   }
    178 
    179   /// matches - Predicate for whether this option is part of the
    180   /// given option (which may be a group).
    181   ///
    182   /// Note that matches against options which are an alias should never be
    183   /// done -- aliases do not participate in matching and so such a query will
    184   /// always be false.
    185   bool matches(OptSpecifier ID) const;
    186 
    187   /// accept - Potentially accept the current argument, returning a
    188   /// new Arg instance, or 0 if the option does not accept this
    189   /// argument (or the argument is missing values).
    190   ///
    191   /// If the option accepts the current argument, accept() sets
    192   /// Index to the position where argument parsing should resume
    193   /// (even if the argument is missing values).
    194   ///
    195   /// \param ArgSize The number of bytes taken up by the matched Option prefix
    196   ///                and name. This is used to determine where joined values
    197   ///                start.
    198   Arg *accept(const ArgList &Args, unsigned &Index, unsigned ArgSize) const;
    199 
    200   void print(raw_ostream &O) const;
    201   void dump() const;
    202 };
    203 
    204 } // end namespace opt
    205 } // end namespace llvm
    206 
    207 #endif
    208