Home | History | Annotate | Download | only in Driver
      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 CLANG_DRIVER_OPTION_H_
     11 #define CLANG_DRIVER_OPTION_H_
     12 
     13 #include "clang/Driver/OptTable.h"
     14 #include "llvm/ADT/StringRef.h"
     15 #include "llvm/Support/ErrorHandling.h"
     16 #include "clang/Basic/LLVM.h"
     17 
     18 namespace clang {
     19 namespace driver {
     20   class Arg;
     21   class ArgList;
     22 
     23 namespace options {
     24   enum DriverFlag {
     25     DriverOption     = (1 << 0),
     26     HelpHidden       = (1 << 1),
     27     LinkerInput      = (1 << 2),
     28     NoArgumentUnused = (1 << 3),
     29     NoForward        = (1 << 4),
     30     RenderAsInput    = (1 << 5),
     31     RenderJoined     = (1 << 6),
     32     RenderSeparate   = (1 << 7),
     33     Unsupported      = (1 << 8),
     34     CC1Option        = (1 << 9)
     35   };
     36 }
     37 
     38   /// Option - Abstract representation for a single form of driver
     39   /// argument.
     40   ///
     41   /// An Option class represents a form of option that the driver
     42   /// takes, for example how many arguments the option has and how
     43   /// they can be provided. Individual option instances store
     44   /// additional information about what group the option is a member
     45   /// of (if any), if the option is an alias, and a number of
     46   /// flags. At runtime the driver parses the command line into
     47   /// concrete Arg instances, each of which corresponds to a
     48   /// particular Option instance.
     49   class Option {
     50   public:
     51     enum OptionClass {
     52       GroupClass = 0,
     53       InputClass,
     54       UnknownClass,
     55       FlagClass,
     56       JoinedClass,
     57       SeparateClass,
     58       CommaJoinedClass,
     59       MultiArgClass,
     60       JoinedOrSeparateClass,
     61       JoinedAndSeparateClass
     62     };
     63 
     64     enum RenderStyleKind {
     65       RenderCommaJoinedStyle,
     66       RenderJoinedStyle,
     67       RenderSeparateStyle,
     68       RenderValuesStyle
     69     };
     70 
     71   private:
     72     const OptTable::Info *Info;
     73 
     74     /// The option ID.
     75     OptSpecifier ID;
     76 
     77     /// Group this option is a member of, if any.
     78     const Option *Group;
     79 
     80     /// Option that this is an alias for, if any.
     81     const Option *Alias;
     82 
     83   public:
     84     Option(const OptTable::Info *Info, OptSpecifier ID,
     85            const Option *Group, const Option *Alias);
     86     ~Option();
     87 
     88     unsigned getID() const { return ID.getID(); }
     89     OptionClass getKind() const { return OptionClass(Info->Kind); }
     90     StringRef getName() const { return Info->Name; }
     91     const Option *getGroup() const { return Group; }
     92     const Option *getAlias() const { return Alias; }
     93 
     94     unsigned getNumArgs() const { return Info->Param; }
     95 
     96     bool isUnsupported() const { return Info->Flags & options::Unsupported; }
     97 
     98     bool isLinkerInput() const { return Info->Flags & options::LinkerInput; }
     99 
    100     bool hasNoOptAsInput() const { return Info->Flags & options::RenderAsInput;}
    101 
    102     RenderStyleKind getRenderStyle() const {
    103       if (Info->Flags & options::RenderJoined)
    104         return RenderJoinedStyle;
    105       if (Info->Flags & options::RenderSeparate)
    106         return RenderSeparateStyle;
    107       switch (getKind()) {
    108       case GroupClass:
    109       case InputClass:
    110       case UnknownClass:
    111         return RenderValuesStyle;
    112       case JoinedClass:
    113       case JoinedAndSeparateClass:
    114         return RenderJoinedStyle;
    115       case CommaJoinedClass:
    116         return RenderCommaJoinedStyle;
    117       case FlagClass:
    118       case SeparateClass:
    119       case MultiArgClass:
    120       case JoinedOrSeparateClass:
    121         return RenderSeparateStyle;
    122       }
    123       llvm_unreachable("Unexpected kind!");
    124     }
    125 
    126     bool isDriverOption() const { return Info->Flags & options::DriverOption; }
    127 
    128     bool hasNoArgumentUnused() const {
    129       return Info->Flags & options::NoArgumentUnused;
    130     }
    131 
    132     bool hasNoForward() const { return Info->Flags & options::NoForward; }
    133 
    134     bool isCC1Option() const { return Info->Flags & options::CC1Option; }
    135 
    136     bool hasForwardToGCC() const {
    137       return !hasNoForward() && !isDriverOption() && !isLinkerInput();
    138     }
    139 
    140     /// getUnaliasedOption - Return the final option this option
    141     /// aliases (itself, if the option has no alias).
    142     const Option *getUnaliasedOption() const {
    143       if (Alias) return Alias->getUnaliasedOption();
    144       return this;
    145     }
    146 
    147     /// getRenderName - Return the name to use when rendering this
    148     /// option.
    149     StringRef getRenderName() const {
    150       return getUnaliasedOption()->getName();
    151     }
    152 
    153     /// matches - Predicate for whether this option is part of the
    154     /// given option (which may be a group).
    155     ///
    156     /// Note that matches against options which are an alias should never be
    157     /// done -- aliases do not participate in matching and so such a query will
    158     /// always be false.
    159     bool matches(OptSpecifier ID) const;
    160 
    161     /// accept - Potentially accept the current argument, returning a
    162     /// new Arg instance, or 0 if the option does not accept this
    163     /// argument (or the argument is missing values).
    164     ///
    165     /// If the option accepts the current argument, accept() sets
    166     /// Index to the position where argument parsing should resume
    167     /// (even if the argument is missing values).
    168     Arg *accept(const ArgList &Args, unsigned &Index) const;
    169 
    170     void dump() const;
    171   };
    172 
    173 } // end namespace driver
    174 } // end namespace clang
    175 
    176 #endif
    177