• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
isValid()75   bool isValid() const {
76     return Info != nullptr;
77   }
78 
getID()79   unsigned getID() const {
80     assert(Info && "Must have a valid info!");
81     return Info->ID;
82   }
83 
getKind()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.
getName()90   StringRef getName() const {
91     assert(Info && "Must have a valid info!");
92     return Info->Name;
93   }
94 
getGroup()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 
getAlias()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".
getAliasArgs()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.
getPrefix()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.
getPrefixedName()124   std::string getPrefixedName() const {
125     std::string Ret = getPrefix();
126     Ret += getName();
127     return Ret;
128   }
129 
getNumArgs()130   unsigned getNumArgs() const { return Info->Param; }
131 
hasNoOptAsInput()132   bool hasNoOptAsInput() const { return Info->Flags & RenderAsInput;}
133 
getRenderStyle()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.
hasFlag(unsigned 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).
getUnaliasedOption()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.
getRenderName()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