1 | //===- Option.h - Abstract Driver Options -----------------------*- C++ -*-===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #ifndef LLVM_OPTION_OPTION_H |
10 | #define LLVM_OPTION_OPTION_H |
11 | |
12 | #include "llvm/ADT/SmallVector.h" |
13 | #include "llvm/ADT/StringRef.h" |
14 | #include "llvm/Option/OptSpecifier.h" |
15 | #include "llvm/Option/OptTable.h" |
16 | #include "llvm/Support/ErrorHandling.h" |
17 | #include <cassert> |
18 | |
19 | namespace llvm { |
20 | |
21 | class raw_ostream; |
22 | |
23 | namespace opt { |
24 | |
25 | class Arg; |
26 | class ArgList; |
27 | |
28 | /// ArgStringList - Type used for constructing argv lists for subprocesses. |
29 | using ArgStringList = SmallVector<const char *, 16>; |
30 | |
31 | /// Base flags for all options. Custom flags may be added after. |
32 | enum DriverFlag { |
33 | HelpHidden = (1 << 0), |
34 | RenderAsInput = (1 << 1), |
35 | RenderJoined = (1 << 2), |
36 | RenderSeparate = (1 << 3) |
37 | }; |
38 | |
39 | enum DriverVisibility { |
40 | DefaultVis = (1 << 0), |
41 | }; |
42 | |
43 | /// Option - Abstract representation for a single form of driver |
44 | /// argument. |
45 | /// |
46 | /// An Option class represents a form of option that the driver |
47 | /// takes, for example how many arguments the option has and how |
48 | /// they can be provided. Individual option instances store |
49 | /// additional information about what group the option is a member |
50 | /// of (if any), if the option is an alias, and a number of |
51 | /// flags. At runtime the driver parses the command line into |
52 | /// concrete Arg instances, each of which corresponds to a |
53 | /// particular Option instance. |
54 | class Option { |
55 | public: |
56 | enum OptionClass { |
57 | GroupClass = 0, |
58 | InputClass, |
59 | UnknownClass, |
60 | FlagClass, |
61 | JoinedClass, |
62 | ValuesClass, |
63 | SeparateClass, |
64 | RemainingArgsClass, |
65 | RemainingArgsJoinedClass, |
66 | CommaJoinedClass, |
67 | MultiArgClass, |
68 | JoinedOrSeparateClass, |
69 | JoinedAndSeparateClass |
70 | }; |
71 | |
72 | enum RenderStyleKind { |
73 | RenderCommaJoinedStyle, |
74 | RenderJoinedStyle, |
75 | RenderSeparateStyle, |
76 | RenderValuesStyle |
77 | }; |
78 | |
79 | protected: |
80 | const OptTable::Info *Info; |
81 | const OptTable *Owner; |
82 | |
83 | public: |
84 | Option(const OptTable::Info *Info, const OptTable *Owner); |
85 | |
86 | bool isValid() const { |
87 | return Info != nullptr; |
88 | } |
89 | |
90 | unsigned getID() const { |
91 | assert(Info && "Must have a valid info!" ); |
92 | return Info->ID; |
93 | } |
94 | |
95 | OptionClass getKind() const { |
96 | assert(Info && "Must have a valid info!" ); |
97 | return OptionClass(Info->Kind); |
98 | } |
99 | |
100 | /// Get the name of this option without any prefix. |
101 | StringRef getName() const { |
102 | assert(Info && "Must have a valid info!" ); |
103 | return Info->getName(); |
104 | } |
105 | |
106 | const Option getGroup() const { |
107 | assert(Info && "Must have a valid info!" ); |
108 | assert(Owner && "Must have a valid owner!" ); |
109 | return Owner->getOption(Opt: Info->GroupID); |
110 | } |
111 | |
112 | const Option getAlias() const { |
113 | assert(Info && "Must have a valid info!" ); |
114 | assert(Owner && "Must have a valid owner!" ); |
115 | return Owner->getOption(Opt: Info->AliasID); |
116 | } |
117 | |
118 | /// Get the alias arguments as a \0 separated list. |
119 | /// E.g. ["foo", "bar"] would be returned as "foo\0bar\0". |
120 | const char *getAliasArgs() const { |
121 | assert(Info && "Must have a valid info!" ); |
122 | assert((!Info->AliasArgs || Info->AliasArgs[0] != 0) && |
123 | "AliasArgs should be either 0 or non-empty." ); |
124 | |
125 | return Info->AliasArgs; |
126 | } |
127 | |
128 | /// Get the default prefix for this option. |
129 | StringRef getPrefix() const { |
130 | return Info->Prefixes.empty() |
131 | ? StringRef() |
132 | : static_cast<const StringRef &>(Info->Prefixes[0]); |
133 | } |
134 | |
135 | /// Get the name of this option with the default prefix. |
136 | StringLiteral getPrefixedName() const { |
137 | assert(Info && "Must have a valid info!" ); |
138 | return Info->PrefixedName; |
139 | } |
140 | |
141 | /// Get the help text for this option. |
142 | StringRef getHelpText() const { |
143 | assert(Info && "Must have a valid info!" ); |
144 | return Info->HelpText; |
145 | } |
146 | |
147 | /// Get the meta-variable list for this option. |
148 | StringRef getMetaVar() const { |
149 | assert(Info && "Must have a valid info!" ); |
150 | return Info->MetaVar; |
151 | } |
152 | |
153 | unsigned getNumArgs() const { return Info->Param; } |
154 | |
155 | bool hasNoOptAsInput() const { return Info->Flags & RenderAsInput;} |
156 | |
157 | RenderStyleKind getRenderStyle() const { |
158 | if (Info->Flags & RenderJoined) |
159 | return RenderJoinedStyle; |
160 | if (Info->Flags & RenderSeparate) |
161 | return RenderSeparateStyle; |
162 | switch (getKind()) { |
163 | case GroupClass: |
164 | case InputClass: |
165 | case UnknownClass: |
166 | return RenderValuesStyle; |
167 | case JoinedClass: |
168 | case JoinedAndSeparateClass: |
169 | return RenderJoinedStyle; |
170 | case CommaJoinedClass: |
171 | return RenderCommaJoinedStyle; |
172 | case FlagClass: |
173 | case ValuesClass: |
174 | case SeparateClass: |
175 | case MultiArgClass: |
176 | case JoinedOrSeparateClass: |
177 | case RemainingArgsClass: |
178 | case RemainingArgsJoinedClass: |
179 | return RenderSeparateStyle; |
180 | } |
181 | llvm_unreachable("Unexpected kind!" ); |
182 | } |
183 | |
184 | /// Test if this option has the flag \a Val. |
185 | bool hasFlag(unsigned Val) const { |
186 | return Info->Flags & Val; |
187 | } |
188 | |
189 | /// Test if this option has the visibility flag \a Val. |
190 | bool hasVisibilityFlag(unsigned Val) const { |
191 | return Info->Visibility & Val; |
192 | } |
193 | |
194 | /// getUnaliasedOption - Return the final option this option |
195 | /// aliases (itself, if the option has no alias). |
196 | const Option getUnaliasedOption() const { |
197 | const Option Alias = getAlias(); |
198 | if (Alias.isValid()) return Alias.getUnaliasedOption(); |
199 | return *this; |
200 | } |
201 | |
202 | /// getRenderName - Return the name to use when rendering this |
203 | /// option. |
204 | StringRef getRenderName() const { |
205 | return getUnaliasedOption().getName(); |
206 | } |
207 | |
208 | /// matches - Predicate for whether this option is part of the |
209 | /// given option (which may be a group). |
210 | /// |
211 | /// Note that matches against options which are an alias should never be |
212 | /// done -- aliases do not participate in matching and so such a query will |
213 | /// always be false. |
214 | bool matches(OptSpecifier ID) const; |
215 | |
216 | /// Potentially accept the current argument, returning a new Arg instance, |
217 | /// or 0 if the option does not accept this argument (or the argument is |
218 | /// missing values). |
219 | /// |
220 | /// If the option accepts the current argument, accept() sets |
221 | /// Index to the position where argument parsing should resume |
222 | /// (even if the argument is missing values). |
223 | /// |
224 | /// \p CurArg The argument to be matched. It may be shorter than the |
225 | /// underlying storage to represent a Joined argument. |
226 | /// \p GroupedShortOption If true, we are handling the fallback case of |
227 | /// parsing a prefix of the current argument as a short option. |
228 | std::unique_ptr<Arg> accept(const ArgList &Args, StringRef CurArg, |
229 | bool GroupedShortOption, unsigned &Index) const; |
230 | |
231 | private: |
232 | std::unique_ptr<Arg> acceptInternal(const ArgList &Args, StringRef CurArg, |
233 | unsigned &Index) const; |
234 | |
235 | public: |
236 | void print(raw_ostream &O, bool AddNewLine = true) const; |
237 | void dump() const; |
238 | }; |
239 | |
240 | } // end namespace opt |
241 | |
242 | } // end namespace llvm |
243 | |
244 | #endif // LLVM_OPTION_OPTION_H |
245 | |