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 
     74   bool isValid() const {
     75     return Info != nullptr;
     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     case RemainingArgsClass:
    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   /// \param 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 opt
    202 } // end namespace llvm
    203 
    204 #endif
    205