Home | History | Annotate | Download | only in Driver
      1 //===--- OptTable.h - Option Table ------------------------------*- 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_OPTTABLE_H
     11 #define CLANG_DRIVER_OPTTABLE_H
     12 
     13 #include "clang/Driver/OptSpecifier.h"
     14 #include <cassert>
     15 
     16 namespace llvm {
     17   class raw_ostream;
     18 }
     19 
     20 namespace clang {
     21 namespace driver {
     22 namespace options {
     23   enum DriverFlag {
     24     DriverOption     = (1 << 0),
     25     HelpHidden       = (1 << 1),
     26     LinkerInput      = (1 << 2),
     27     NoArgumentUnused = (1 << 3),
     28     NoForward        = (1 << 4),
     29     RenderAsInput    = (1 << 5),
     30     RenderJoined     = (1 << 6),
     31     RenderSeparate   = (1 << 7),
     32     Unsupported      = (1 << 8)
     33   };
     34 }
     35 
     36   class Arg;
     37   class ArgList;
     38   class InputArgList;
     39   class Option;
     40 
     41   /// OptTable - Provide access to the Option info table.
     42   ///
     43   /// The OptTable class provides a layer of indirection which allows Option
     44   /// instance to be created lazily. In the common case, only a few options will
     45   /// be needed at runtime; the OptTable class maintains enough information to
     46   /// parse command lines without instantiating Options, while letting other
     47   /// parts of the driver still use Option instances where convenient.
     48   class OptTable {
     49   public:
     50     /// Info - Entry for a single option instance in the option data table.
     51     struct Info {
     52       const char *Name;
     53       const char *HelpText;
     54       const char *MetaVar;
     55       unsigned char Kind;
     56       unsigned short Flags;
     57       unsigned char Param;
     58       unsigned short GroupID;
     59       unsigned short AliasID;
     60     };
     61 
     62   private:
     63     /// The static option information table.
     64     const Info *OptionInfos;
     65     unsigned NumOptionInfos;
     66 
     67     /// The lazily constructed options table, indexed by option::ID - 1.
     68     mutable Option **Options;
     69 
     70     /// Prebound input option instance.
     71     const Option *TheInputOption;
     72 
     73     /// Prebound unknown option instance.
     74     const Option *TheUnknownOption;
     75 
     76     /// The index of the first option which can be parsed (i.e., is not a
     77     /// special option like 'input' or 'unknown', and is not an option group).
     78     unsigned FirstSearchableIndex;
     79 
     80   private:
     81     const Info &getInfo(OptSpecifier Opt) const {
     82       unsigned id = Opt.getID();
     83       assert(id > 0 && id - 1 < getNumOptions() && "Invalid Option ID.");
     84       return OptionInfos[id - 1];
     85     }
     86 
     87     Option *CreateOption(unsigned id) const;
     88 
     89   protected:
     90     OptTable(const Info *_OptionInfos, unsigned _NumOptionInfos);
     91   public:
     92     ~OptTable();
     93 
     94     /// getNumOptions - Return the total number of option classes.
     95     unsigned getNumOptions() const { return NumOptionInfos; }
     96 
     97     /// getOption - Get the given \arg id's Option instance, lazily creating it
     98     /// if necessary.
     99     ///
    100     /// \return The option, or null for the INVALID option id.
    101     const Option *getOption(OptSpecifier Opt) const {
    102       unsigned id = Opt.getID();
    103       if (id == 0)
    104         return 0;
    105 
    106       assert((unsigned) (id - 1) < getNumOptions() && "Invalid ID.");
    107       Option *&Entry = Options[id - 1];
    108       if (!Entry)
    109         Entry = CreateOption(id);
    110       return Entry;
    111     }
    112 
    113     /// getOptionName - Lookup the name of the given option.
    114     const char *getOptionName(OptSpecifier id) const {
    115       return getInfo(id).Name;
    116     }
    117 
    118     /// getOptionKind - Get the kind of the given option.
    119     unsigned getOptionKind(OptSpecifier id) const {
    120       return getInfo(id).Kind;
    121     }
    122 
    123     /// getOptionGroupID - Get the group id for the given option.
    124     unsigned getOptionGroupID(OptSpecifier id) const {
    125       return getInfo(id).GroupID;
    126     }
    127 
    128     /// isOptionHelpHidden - Should the help for the given option be hidden by
    129     /// default.
    130     bool isOptionHelpHidden(OptSpecifier id) const {
    131       return getInfo(id).Flags & options::HelpHidden;
    132     }
    133 
    134     /// getOptionHelpText - Get the help text to use to describe this option.
    135     const char *getOptionHelpText(OptSpecifier id) const {
    136       return getInfo(id).HelpText;
    137     }
    138 
    139     /// getOptionMetaVar - Get the meta-variable name to use when describing
    140     /// this options values in the help text.
    141     const char *getOptionMetaVar(OptSpecifier id) const {
    142       return getInfo(id).MetaVar;
    143     }
    144 
    145     /// ParseOneArg - Parse a single argument; returning the new argument and
    146     /// updating Index.
    147     ///
    148     /// \param [in] [out] Index - The current parsing position in the argument
    149     /// string list; on return this will be the index of the next argument
    150     /// string to parse.
    151     ///
    152     /// \return - The parsed argument, or 0 if the argument is missing values
    153     /// (in which case Index still points at the conceptual next argument string
    154     /// to parse).
    155     Arg *ParseOneArg(const ArgList &Args, unsigned &Index) const;
    156 
    157     /// ParseArgs - Parse an list of arguments into an InputArgList.
    158     ///
    159     /// The resulting InputArgList will reference the strings in [ArgBegin,
    160     /// ArgEnd), and their lifetime should extend past that of the returned
    161     /// InputArgList.
    162     ///
    163     /// The only error that can occur in this routine is if an argument is
    164     /// missing values; in this case \arg MissingArgCount will be non-zero.
    165     ///
    166     /// \param ArgBegin - The beginning of the argument vector.
    167     /// \param ArgEnd - The end of the argument vector.
    168     /// \param MissingArgIndex - On error, the index of the option which could
    169     /// not be parsed.
    170     /// \param MissingArgCount - On error, the number of missing options.
    171     /// \return - An InputArgList; on error this will contain all the options
    172     /// which could be parsed.
    173     InputArgList *ParseArgs(const char* const *ArgBegin,
    174                             const char* const *ArgEnd,
    175                             unsigned &MissingArgIndex,
    176                             unsigned &MissingArgCount) const;
    177 
    178     /// PrintHelp - Render the help text for an option table.
    179     ///
    180     /// \param OS - The stream to write the help text to.
    181     /// \param Name - The name to use in the usage line.
    182     /// \param Title - The title to use in the usage line.
    183     /// \param ShowHidden - Whether help-hidden arguments should be shown.
    184     void PrintHelp(llvm::raw_ostream &OS, const char *Name,
    185                    const char *Title, bool ShowHidden = false) const;
    186   };
    187 }
    188 }
    189 
    190 #endif
    191