llvm.org GIT mirror llvm / 96a564f
Copy clang/Driver/<Option parsing stuff> to llvm. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@169344 91177308-0d34-0410-b5e6-96231b3b80d8 Michael J. Spencer 6 years ago
24 changed file(s) with 2622 addition(s) and 3 deletion(s). Raw diff Collapse all Expand all
0 //===--- Arg.h - Parsed Argument Classes ------------------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 ///
9 /// \file
10 /// \brief Defines the llvm::Arg class for parsed arguments.
11 ///
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_SUPPORT_ARG_H_
15 #define LLVM_SUPPORT_ARG_H_
16
17 #include "llvm/ADT/SmallVector.h"
18 #include "llvm/ADT/StringRef.h"
19 #include "llvm/Option/Option.h"
20 #include
21
22 namespace llvm {
23 namespace opt {
24 class ArgList;
25
26 /// \brief A concrete instance of a particular driver option.
27 ///
28 /// The Arg class encodes just enough information to be able to
29 /// derive the argument values efficiently. In addition, Arg
30 /// instances have an intrusive double linked list which is used by
31 /// ArgList to provide efficient iteration over all instances of a
32 /// particular option.
33 class Arg {
34 Arg(const Arg &) LLVM_DELETED_FUNCTION;
35 void operator=(const Arg &) LLVM_DELETED_FUNCTION;
36
37 private:
38 /// \brief The option this argument is an instance of.
39 const Option Opt;
40
41 /// \brief The argument this argument was derived from (during tool chain
42 /// argument translation), if any.
43 const Arg *BaseArg;
44
45 /// \brief How this instance of the option was spelled.
46 StringRef Spelling;
47
48 /// \brief The index at which this argument appears in the containing
49 /// ArgList.
50 unsigned Index;
51
52 /// \brief Was this argument used to effect compilation?
53 ///
54 /// This is used for generating "argument unused" diagnostics.
55 mutable unsigned Claimed : 1;
56
57 /// \brief Does this argument own its values?
58 mutable unsigned OwnsValues : 1;
59
60 /// \brief The argument values, as C strings.
61 SmallVector Values;
62
63 public:
64 Arg(const Option Opt, StringRef Spelling, unsigned Index,
65 const Arg *BaseArg = 0);
66 Arg(const Option Opt, StringRef Spelling, unsigned Index,
67 const char *Value0, const Arg *BaseArg = 0);
68 Arg(const Option Opt, StringRef Spelling, unsigned Index,
69 const char *Value0, const char *Value1, const Arg *BaseArg = 0);
70 ~Arg();
71
72 const Option getOption() const { return Opt; }
73 StringRef getSpelling() const { return Spelling; }
74 unsigned getIndex() const { return Index; }
75
76 /// \brief Return the base argument which generated this arg.
77 ///
78 /// This is either the argument itself or the argument it was
79 /// derived from during tool chain specific argument translation.
80 const Arg &getBaseArg() const {
81 return BaseArg ? *BaseArg : *this;
82 }
83 void setBaseArg(const Arg *_BaseArg) {
84 BaseArg = _BaseArg;
85 }
86
87 bool getOwnsValues() const { return OwnsValues; }
88 void setOwnsValues(bool Value) const { OwnsValues = Value; }
89
90 bool isClaimed() const { return getBaseArg().Claimed; }
91
92 /// \brief Set the Arg claimed bit.
93 void claim() const { getBaseArg().Claimed = true; }
94
95 unsigned getNumValues() const { return Values.size(); }
96 const char *getValue(unsigned N = 0) const {
97 return Values[N];
98 }
99
100 SmallVectorImpl &getValues() {
101 return Values;
102 }
103
104 bool containsValue(StringRef Value) const {
105 for (unsigned i = 0, e = getNumValues(); i != e; ++i)
106 if (Values[i] == Value)
107 return true;
108 return false;
109 }
110
111 /// \brief Append the argument onto the given array as strings.
112 void render(const ArgList &Args, ArgStringList &Output) const;
113
114 /// \brief Append the argument, render as an input, onto the given
115 /// array as strings.
116 ///
117 /// The distinction is that some options only render their values
118 /// when rendered as a input (e.g., Xlinker).
119 void renderAsInput(const ArgList &Args, ArgStringList &Output) const;
120
121 void dump() const;
122
123 /// \brief Return a formatted version of the argument and
124 /// its values, for debugging and diagnostics.
125 std::string getAsString(const ArgList &Args) const;
126 };
127
128 } // end namespace opt
129 } // end namespace llvm
130
131 #endif
0 //===--- ArgList.h - Argument List Management -------------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef LLVM_SUPPORT_ARGLIST_H_
10 #define LLVM_SUPPORT_ARGLIST_H_
11
12 #include "llvm/ADT/SmallVector.h"
13 #include "llvm/ADT/StringRef.h"
14 #include "llvm/Option/Option.h"
15 #include "llvm/Option/OptSpecifier.h"
16
17 #include
18 #include
19 #include
20
21 namespace llvm {
22 namespace opt {
23 class Arg;
24 class ArgList;
25 class Option;
26
27 /// arg_iterator - Iterates through arguments stored inside an ArgList.
28 class arg_iterator {
29 /// The current argument.
30 SmallVectorImpl::const_iterator Current;
31
32 /// The argument list we are iterating over.
33 const ArgList &Args;
34
35 /// Optional filters on the arguments which will be match. Most clients
36 /// should never want to iterate over arguments without filters, so we won't
37 /// bother to factor this into two separate iterator implementations.
38 //
39 // FIXME: Make efficient; the idea is to provide efficient iteration over
40 // all arguments which match a particular id and then just provide an
41 // iterator combinator which takes multiple iterators which can be
42 // efficiently compared and returns them in order.
43 OptSpecifier Id0, Id1, Id2;
44
45 void SkipToNextArg();
46
47 public:
48 typedef Arg * const * value_type;
49 typedef Arg * const & reference;
50 typedef Arg * const * pointer;
51 typedef std::forward_iterator_tag iterator_category;
52 typedef std::ptrdiff_t difference_type;
53
54 arg_iterator(SmallVectorImpl::const_iterator it,
55 const ArgList &_Args, OptSpecifier _Id0 = 0U,
56 OptSpecifier _Id1 = 0U, OptSpecifier _Id2 = 0U)
57 : Current(it), Args(_Args), Id0(_Id0), Id1(_Id1), Id2(_Id2) {
58 SkipToNextArg();
59 }
60
61 operator const Arg*() { return *Current; }
62 reference operator*() const { return *Current; }
63 pointer operator->() const { return Current; }
64
65 arg_iterator &operator++() {
66 ++Current;
67 SkipToNextArg();
68 return *this;
69 }
70
71 arg_iterator operator++(int) {
72 arg_iterator tmp(*this);
73 ++(*this);
74 return tmp;
75 }
76
77 friend bool operator==(arg_iterator LHS, arg_iterator RHS) {
78 return LHS.Current == RHS.Current;
79 }
80 friend bool operator!=(arg_iterator LHS, arg_iterator RHS) {
81 return !(LHS == RHS);
82 }
83 };
84
85 /// ArgList - Ordered collection of driver arguments.
86 ///
87 /// The ArgList class manages a list of Arg instances as well as
88 /// auxiliary data and convenience methods to allow Tools to quickly
89 /// check for the presence of Arg instances for a particular Option
90 /// and to iterate over groups of arguments.
91 class ArgList {
92 private:
93 ArgList(const ArgList &) LLVM_DELETED_FUNCTION;
94 void operator=(const ArgList &) LLVM_DELETED_FUNCTION;
95
96 public:
97 typedef SmallVector arglist_type;
98 typedef arglist_type::iterator iterator;
99 typedef arglist_type::const_iterator const_iterator;
100 typedef arglist_type::reverse_iterator reverse_iterator;
101 typedef arglist_type::const_reverse_iterator const_reverse_iterator;
102
103 private:
104 /// The internal list of arguments.
105 arglist_type Args;
106
107 protected:
108 ArgList();
109
110 public:
111 virtual ~ArgList();
112
113 /// @name Arg Access
114 /// @{
115
116 /// append - Append \p A to the arg list.
117 void append(Arg *A);
118
119 arglist_type &getArgs() { return Args; }
120 const arglist_type &getArgs() const { return Args; }
121
122 unsigned size() const { return Args.size(); }
123
124 /// @}
125 /// @name Arg Iteration
126 /// @{
127
128 iterator begin() { return Args.begin(); }
129 iterator end() { return Args.end(); }
130
131 reverse_iterator rbegin() { return Args.rbegin(); }
132 reverse_iterator rend() { return Args.rend(); }
133
134 const_iterator begin() const { return Args.begin(); }
135 const_iterator end() const { return Args.end(); }
136
137 const_reverse_iterator rbegin() const { return Args.rbegin(); }
138 const_reverse_iterator rend() const { return Args.rend(); }
139
140 arg_iterator filtered_begin(OptSpecifier Id0 = 0U, OptSpecifier Id1 = 0U,
141 OptSpecifier Id2 = 0U) const {
142 return arg_iterator(Args.begin(), *this, Id0, Id1, Id2);
143 }
144 arg_iterator filtered_end() const {
145 return arg_iterator(Args.end(), *this);
146 }
147
148 /// @}
149 /// @name Arg Removal
150 /// @{
151
152 /// eraseArg - Remove any option matching \p Id.
153 void eraseArg(OptSpecifier Id);
154
155 /// @}
156 /// @name Arg Access
157 /// @{
158
159 /// hasArg - Does the arg list contain any option matching \p Id.
160 ///
161 /// \p Claim Whether the argument should be claimed, if it exists.
162 bool hasArgNoClaim(OptSpecifier Id) const {
163 return getLastArgNoClaim(Id) != 0;
164 }
165 bool hasArg(OptSpecifier Id) const {
166 return getLastArg(Id) != 0;
167 }
168 bool hasArg(OptSpecifier Id0, OptSpecifier Id1) const {
169 return getLastArg(Id0, Id1) != 0;
170 }
171 bool hasArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2) const {
172 return getLastArg(Id0, Id1, Id2) != 0;
173 }
174
175 /// getLastArg - Return the last argument matching \p Id, or null.
176 ///
177 /// \p Claim Whether the argument should be claimed, if it exists.
178 Arg *getLastArgNoClaim(OptSpecifier Id) const;
179 Arg *getLastArg(OptSpecifier Id) const;
180 Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1) const;
181 Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2) const;
182 Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2,
183 OptSpecifier Id3) const;
184 Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2,
185 OptSpecifier Id3, OptSpecifier Id4) const;
186 Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2,
187 OptSpecifier Id3, OptSpecifier Id4, OptSpecifier Id5) const;
188 Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2,
189 OptSpecifier Id3, OptSpecifier Id4, OptSpecifier Id5,
190 OptSpecifier Id6) const;
191 Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2,
192 OptSpecifier Id3, OptSpecifier Id4, OptSpecifier Id5,
193 OptSpecifier Id6, OptSpecifier Id7) const;
194
195 /// getArgString - Return the input argument string at \p Index.
196 virtual const char *getArgString(unsigned Index) const = 0;
197
198 /// getNumInputArgStrings - Return the number of original argument strings,
199 /// which are guaranteed to be the first strings in the argument string
200 /// list.
201 virtual unsigned getNumInputArgStrings() const = 0;
202
203 /// @}
204 /// @name Argument Lookup Utilities
205 /// @{
206
207 /// getLastArgValue - Return the value of the last argument, or a default.
208 StringRef getLastArgValue(OptSpecifier Id,
209 StringRef Default = "") const;
210
211 /// getAllArgValues - Get the values of all instances of the given argument
212 /// as strings.
213 std::vector getAllArgValues(OptSpecifier Id) const;
214
215 /// @}
216 /// @name Translation Utilities
217 /// @{
218
219 /// hasFlag - Given an option \p Pos and its negative form \p Neg, return
220 /// true if the option is present, false if the negation is present, and
221 /// \p Default if neither option is given. If both the option and its
222 /// negation are present, the last one wins.
223 bool hasFlag(OptSpecifier Pos, OptSpecifier Neg, bool Default=true) const;
224
225 /// AddLastArg - Render only the last argument match \p Id0, if present.
226 void AddLastArg(ArgStringList &Output, OptSpecifier Id0) const;
227
228 /// AddAllArgs - Render all arguments matching the given ids.
229 void AddAllArgs(ArgStringList &Output, OptSpecifier Id0,
230 OptSpecifier Id1 = 0U, OptSpecifier Id2 = 0U) const;
231
232 /// AddAllArgValues - Render the argument values of all arguments
233 /// matching the given ids.
234 void AddAllArgValues(ArgStringList &Output, OptSpecifier Id0,
235 OptSpecifier Id1 = 0U, OptSpecifier Id2 = 0U) const;
236
237 /// AddAllArgsTranslated - Render all the arguments matching the
238 /// given ids, but forced to separate args and using the provided
239 /// name instead of the first option value.
240 ///
241 /// \param Joined - If true, render the argument as joined with
242 /// the option specifier.
243 void AddAllArgsTranslated(ArgStringList &Output, OptSpecifier Id0,
244 const char *Translation,
245 bool Joined = false) const;
246
247 /// ClaimAllArgs - Claim all arguments which match the given
248 /// option id.
249 void ClaimAllArgs(OptSpecifier Id0) const;
250
251 /// ClaimAllArgs - Claim all arguments.
252 ///
253 void ClaimAllArgs() const;
254
255 /// @}
256 /// @name Arg Synthesis
257 /// @{
258
259 /// MakeArgString - Construct a constant string pointer whose
260 /// lifetime will match that of the ArgList.
261 virtual const char *MakeArgString(StringRef Str) const = 0;
262 const char *MakeArgString(const char *Str) const {
263 return MakeArgString(StringRef(Str));
264 }
265 const char *MakeArgString(std::string Str) const {
266 return MakeArgString(StringRef(Str));
267 }
268 const char *MakeArgString(const Twine &Str) const;
269
270 /// \brief Create an arg string for (\p LHS + \p RHS), reusing the
271 /// string at \p Index if possible.
272 const char *GetOrMakeJoinedArgString(unsigned Index, StringRef LHS,
273 StringRef RHS) const;
274
275 /// @}
276 };
277
278 class InputArgList : public ArgList {
279 private:
280 /// List of argument strings used by the contained Args.
281 ///
282 /// This is mutable since we treat the ArgList as being the list
283 /// of Args, and allow routines to add new strings (to have a
284 /// convenient place to store the memory) via MakeIndex.
285 mutable ArgStringList ArgStrings;
286
287 /// Strings for synthesized arguments.
288 ///
289 /// This is mutable since we treat the ArgList as being the list
290 /// of Args, and allow routines to add new strings (to have a
291 /// convenient place to store the memory) via MakeIndex.
292 mutable std::list SynthesizedStrings;
293
294 /// The number of original input argument strings.
295 unsigned NumInputArgStrings;
296
297 public:
298 InputArgList(const char* const *ArgBegin, const char* const *ArgEnd);
299 ~InputArgList();
300
301 virtual const char *getArgString(unsigned Index) const {
302 return ArgStrings[Index];
303 }
304
305 virtual unsigned getNumInputArgStrings() const {
306 return NumInputArgStrings;
307 }
308
309 /// @name Arg Synthesis
310 /// @{
311
312 public:
313 /// MakeIndex - Get an index for the given string(s).
314 unsigned MakeIndex(StringRef String0) const;
315 unsigned MakeIndex(StringRef String0, StringRef String1) const;
316
317 virtual const char *MakeArgString(StringRef Str) const;
318
319 /// @}
320 };
321
322 /// DerivedArgList - An ordered collection of driver arguments,
323 /// whose storage may be in another argument list.
324 class DerivedArgList : public ArgList {
325 const InputArgList &BaseArgs;
326
327 /// The list of arguments we synthesized.
328 mutable arglist_type SynthesizedArgs;
329
330 public:
331 /// Construct a new derived arg list from \p BaseArgs.
332 DerivedArgList(const InputArgList &BaseArgs);
333 ~DerivedArgList();
334
335 virtual const char *getArgString(unsigned Index) const {
336 return BaseArgs.getArgString(Index);
337 }
338
339 virtual unsigned getNumInputArgStrings() const {
340 return BaseArgs.getNumInputArgStrings();
341 }
342
343 const InputArgList &getBaseArgs() const {
344 return BaseArgs;
345 }
346
347 /// @name Arg Synthesis
348 /// @{
349
350 /// AddSynthesizedArg - Add a argument to the list of synthesized arguments
351 /// (to be freed).
352 void AddSynthesizedArg(Arg *A) {
353 SynthesizedArgs.push_back(A);
354 }
355
356 virtual const char *MakeArgString(StringRef Str) const;
357
358 /// AddFlagArg - Construct a new FlagArg for the given option \p Id and
359 /// append it to the argument list.
360 void AddFlagArg(const Arg *BaseArg, const Option Opt) {
361 append(MakeFlagArg(BaseArg, Opt));
362 }
363
364 /// AddPositionalArg - Construct a new Positional arg for the given option
365 /// \p Id, with the provided \p Value and append it to the argument
366 /// list.
367 void AddPositionalArg(const Arg *BaseArg, const Option Opt,
368 StringRef Value) {
369 append(MakePositionalArg(BaseArg, Opt, Value));
370 }
371
372
373 /// AddSeparateArg - Construct a new Positional arg for the given option
374 /// \p Id, with the provided \p Value and append it to the argument
375 /// list.
376 void AddSeparateArg(const Arg *BaseArg, const Option Opt,
377 StringRef Value) {
378 append(MakeSeparateArg(BaseArg, Opt, Value));
379 }
380
381
382 /// AddJoinedArg - Construct a new Positional arg for the given option
383 /// \p Id, with the provided \p Value and append it to the argument list.
384 void AddJoinedArg(const Arg *BaseArg, const Option Opt,
385 StringRef Value) {
386 append(MakeJoinedArg(BaseArg, Opt, Value));
387 }
388
389
390 /// MakeFlagArg - Construct a new FlagArg for the given option \p Id.
391 Arg *MakeFlagArg(const Arg *BaseArg, const Option Opt) const;
392
393 /// MakePositionalArg - Construct a new Positional arg for the
394 /// given option \p Id, with the provided \p Value.
395 Arg *MakePositionalArg(const Arg *BaseArg, const Option Opt,
396 StringRef Value) const;
397
398 /// MakeSeparateArg - Construct a new Positional arg for the
399 /// given option \p Id, with the provided \p Value.
400 Arg *MakeSeparateArg(const Arg *BaseArg, const Option Opt,
401 StringRef Value) const;
402
403 /// MakeJoinedArg - Construct a new Positional arg for the
404 /// given option \p Id, with the provided \p Value.
405 Arg *MakeJoinedArg(const Arg *BaseArg, const Option Opt,
406 StringRef Value) const;
407
408 /// @}
409 };
410
411 } // end namespace opt
412 } // end namespace llvm
413
414 #endif
0 //===--- OptParser.td - Common Option Parsing Interfaces ------------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines the common interfaces used by the option parsing TableGen
10 // backend.
11 //
12 //===----------------------------------------------------------------------===//
13
14 // Define the kinds of options.
15
16 class OptionKind {
17 string Name = name;
18 // The kind precedence, kinds with lower precedence are matched first.
19 int Precedence = predecence;
20 // Indicate a sentinel option.
21 bit Sentinel = sentinel;
22 }
23
24 // An option group.
25 def KIND_GROUP : OptionKind<"Group">;
26 // The input option kind.
27 def KIND_INPUT : OptionKind<"Input", 1, 1>;
28 // The unknown option kind.
29 def KIND_UNKNOWN : OptionKind<"Unknown", 2, 1>;
30 // A flag with no values.
31 def KIND_FLAG : OptionKind<"Flag">;
32 // An option which prefixes its (single) value.
33 def KIND_JOINED : OptionKind<"Joined", 1>;
34 // An option which is followed by its value.
35 def KIND_SEPARATE : OptionKind<"Separate">;
36 // An option followed by its values, which are separated by commas.
37 def KIND_COMMAJOINED : OptionKind<"CommaJoined">;
38 // An option which is which takes multiple (separate) arguments.
39 def KIND_MULTIARG : OptionKind<"MultiArg">;
40 // An option which is either joined to its (non-empty) value, or followed by its
41 // value.
42 def KIND_JOINED_OR_SEPARATE : OptionKind<"JoinedOrSeparate">;
43 // An option which is both joined to its (first) value, and followed by its
44 // (second) value.
45 def KIND_JOINED_AND_SEPARATE : OptionKind<"JoinedAndSeparate">;
46
47 // Define the option flags.
48
49 class OptionFlag {}
50
51 // HelpHidden - The option should not be displayed in --help, even if it has
52 // help text. Clients *can* use this in conjunction with the OptTable::PrintHelp
53 // arguments to implement hidden help groups.
54 def HelpHidden : OptionFlag;
55
56 // RenderAsInput - The option should not render the name when rendered as an
57 // input (i.e., the option is rendered as values).
58 def RenderAsInput : OptionFlag;
59
60 // RenderJoined - The option should be rendered joined, even if separate (only
61 // sensible on single value separate options).
62 def RenderJoined : OptionFlag;
63
64 // RenderSeparate - The option should be rendered separately, even if joined
65 // (only sensible on joined options).
66 def RenderSeparate : OptionFlag;
67
68 // Define the option group class.
69
70 class OptionGroup {
71 string EnumName = ?; // Uses the def name if undefined.
72 string Name = name;
73 string HelpText = ?;
74 OptionGroup Group = ?;
75 }
76
77 // Define the option class.
78
79 class Option prefixes, string name, OptionKind kind> {
80 string EnumName = ?; // Uses the def name if undefined.
81 list Prefixes = prefixes;
82 string Name = name;
83 OptionKind Kind = kind;
84 // Used by MultiArg option kind.
85 int NumArgs = 0;
86 string HelpText = ?;
87 string MetaVarName = ?;
88 list Flags = [];
89 OptionGroup Group = ?;
90 Option Alias = ?;
91 }
92
93 // Helpers for defining options.
94
95 class Flag prefixes, string name>
96 : Option;
97 class Joined prefixes, string name>
98 : Option;
99 class Separate prefixes, string name>
100 : Option;
101 class CommaJoined prefixes, string name>
102 : Option;
103 class MultiArg prefixes, string name, int numargs>
104 : Option {
105 int NumArgs = numargs;
106 }
107 class JoinedOrSeparate prefixes, string name>
108 : Option;
109 class JoinedAndSeparate prefixes, string name>
110 : Option;
111
112 // Mix-ins for adding optional attributes.
113
114 class Alias
115 class EnumName { string EnumName = name; }
116 class Flags flags> { list Flags = flags; }
117 class Group { OptionGroup Group = group; }
118 class HelpText { string HelpText = text; }
119 class MetaVarName { string MetaVarName = name; }
120
121 // Predefined options.
122
123 // FIXME: Have generator validate that these appear in correct position (and
124 // aren't duplicated).
125 def INPUT : Option<[], "", KIND_INPUT>;
126 def UNKNOWN : Option<[], "", KIND_UNKNOWN>;
0 //===--- OptSpecifier.h - Option Specifiers ---------------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef LLVM_SUPPORT_OPTSPECIFIER_H
10 #define LLVM_SUPPORT_OPTSPECIFIER_H
11
12 namespace llvm {
13 namespace opt {
14 class Option;
15
16 /// OptSpecifier - Wrapper class for abstracting references to option IDs.
17 class OptSpecifier {
18 unsigned ID;
19
20 private:
21 explicit OptSpecifier(bool); // DO NOT IMPLEMENT
22
23 public:
24 OptSpecifier() : ID(0) {}
25 /*implicit*/ OptSpecifier(unsigned _ID) : ID(_ID) {}
26 /*implicit*/ OptSpecifier(const Option *Opt);
27
28 bool isValid() const { return ID != 0; }
29
30 unsigned getID() const { return ID; }
31
32 bool operator==(OptSpecifier Opt) const { return ID == Opt.getID(); }
33 bool operator!=(OptSpecifier Opt) const { return !(*this == Opt); }
34 };
35 }
36 }
37
38 #endif
0 //===--- OptTable.h - Option Table ------------------------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef LLVM_SUPPORT_OPTTABLE_H
10 #define LLVM_SUPPORT_OPTTABLE_H
11
12 #include "llvm/ADT/StringSet.h"
13 #include "llvm/Option/OptSpecifier.h"
14
15 namespace llvm {
16 class raw_ostream;
17 namespace opt {
18 class Arg;
19 class ArgList;
20 class InputArgList;
21 class Option;
22
23 /// \brief Provide access to the Option info table.
24 ///
25 /// The OptTable class provides a layer of indirection which allows Option
26 /// instance to be created lazily. In the common case, only a few options will
27 /// be needed at runtime; the OptTable class maintains enough information to
28 /// parse command lines without instantiating Options, while letting other
29 /// parts of the driver still use Option instances where convenient.
30 class OptTable {
31 public:
32 /// \brief Entry for a single option instance in the option data table.
33 struct Info {
34 /// A null terminated array of prefix strings to apply to name while
35 /// matching.
36 const char *const *Prefixes;
37 const char *Name;
38 const char *HelpText;
39 const char *MetaVar;
40 unsigned ID;
41 unsigned char Kind;
42 unsigned char Param;
43 unsigned short Flags;
44 unsigned short GroupID;
45 unsigned short AliasID;
46 };
47
48 private:
49 /// \brief The static option information table.
50 const Info *OptionInfos;
51 unsigned NumOptionInfos;
52
53 unsigned TheInputOptionID;
54 unsigned TheUnknownOptionID;
55
56 /// The index of the first option which can be parsed (i.e., is not a
57 /// special option like 'input' or 'unknown', and is not an option group).
58 unsigned FirstSearchableIndex;
59
60 /// The union of all option prefixes. If an argument does not begin with
61 /// one of these, it is an input.
62 StringSet<> PrefixesUnion;
63 std::string PrefixChars;
64
65 private:
66 const Info &getInfo(OptSpecifier Opt) const {
67 unsigned id = Opt.getID();
68 assert(id > 0 && id - 1 < getNumOptions() && "Invalid Option ID.");
69 return OptionInfos[id - 1];
70 }
71
72 protected:
73 OptTable(const Info *_OptionInfos, unsigned _NumOptionInfos);
74 public:
75 ~OptTable();
76
77 /// \brief Return the total number of option classes.
78 unsigned getNumOptions() const { return NumOptionInfos; }
79
80 /// \brief Get the given Opt's Option instance, lazily creating it
81 /// if necessary.
82 ///
83 /// \return The option, or null for the INVALID option id.
84 const Option getOption(OptSpecifier Opt) const;
85
86 /// \brief Lookup the name of the given option.
87 const char *getOptionName(OptSpecifier id) const {
88 return getInfo(id).Name;
89 }
90
91 /// \brief Get the kind of the given option.
92 unsigned getOptionKind(OptSpecifier id) const {
93 return getInfo(id).Kind;
94 }
95
96 /// \brief Get the group id for the given option.
97 unsigned getOptionGroupID(OptSpecifier id) const {
98 return getInfo(id).GroupID;
99 }
100
101 /// \brief Should the help for the given option be hidden by default.
102 bool isOptionHelpHidden(OptSpecifier id) const;
103
104 /// \brief Get the help text to use to describe this option.
105 const char *getOptionHelpText(OptSpecifier id) const {
106 return getInfo(id).HelpText;
107 }
108
109 /// \brief Get the meta-variable name to use when describing
110 /// this options values in the help text.
111 const char *getOptionMetaVar(OptSpecifier id) const {
112 return getInfo(id).MetaVar;
113 }
114
115 /// \brief Parse a single argument; returning the new argument and
116 /// updating Index.
117 ///
118 /// \param [in,out] Index - The current parsing position in the argument
119 /// string list; on return this will be the index of the next argument
120 /// string to parse.
121 ///
122 /// \return The parsed argument, or 0 if the argument is missing values
123 /// (in which case Index still points at the conceptual next argument string
124 /// to parse).
125 Arg *ParseOneArg(const ArgList &Args, unsigned &Index) const;
126
127 /// \brief Parse an list of arguments into an InputArgList.
128 ///
129 /// The resulting InputArgList will reference the strings in [\p ArgBegin,
130 /// \p ArgEnd), and their lifetime should extend past that of the returned
131 /// InputArgList.
132 ///
133 /// The only error that can occur in this routine is if an argument is
134 /// missing values; in this case \p MissingArgCount will be non-zero.
135 ///
136 /// \param ArgBegin - The beginning of the argument vector.
137 /// \param ArgEnd - The end of the argument vector.
138 /// \param MissingArgIndex - On error, the index of the option which could
139 /// not be parsed.
140 /// \param MissingArgCount - On error, the number of missing options.
141 /// \return An InputArgList; on error this will contain all the options
142 /// which could be parsed.
143 InputArgList *ParseArgs(const char* const *ArgBegin,
144 const char* const *ArgEnd,
145 unsigned &MissingArgIndex,
146 unsigned &MissingArgCount) const;
147
148 /// \brief Render the help text for an option table.
149 ///
150 /// \param OS - The stream to write the help text to.
151 /// \param Name - The name to use in the usage line.
152 /// \param Title - The title to use in the usage line.
153 /// \param ShowHidden - Whether help-hidden arguments should be shown.
154 void PrintHelp(raw_ostream &OS, const char *Name,
155 const char *Title, bool ShowHidden = false) const;
156 };
157 } // end namespace opt
158 } // end namespace llvm
159
160 #endif
0 //===--- Option.h - Abstract Driver Options ---------------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef LLVM_SUPPORT_OPTION_H_
10 #define LLVM_SUPPORT_OPTION_H_
11
12 #include "llvm/ADT/StringRef.h"
13 #include "llvm/ADT/SmallVector.h"
14 #include "llvm/Option/OptTable.h"
15 #include "llvm/Support/ErrorHandling.h"
16
17 namespace llvm {
18 namespace opt {
19 class Arg;
20 class ArgList;
21 /// ArgStringList - Type used for constructing argv lists for subprocesses.
22 typedef SmallVector ArgStringList;
23
24 /// Base flags for all options. Custom flags may be added after.
25 enum DriverFlag {
26 HelpHidden = (1 << 0),
27 RenderAsInput = (1 << 1),
28 RenderJoined = (1 << 2),
29 RenderSeparate = (1 << 3)
30 };
31
32 /// Option - Abstract representation for a single form of driver
33 /// argument.
34 ///
35 /// An Option class represents a form of option that the driver
36 /// takes, for example how many arguments the option has and how
37 /// they can be provided. Individual option instances store
38 /// additional information about what group the option is a member
39 /// of (if any), if the option is an alias, and a number of
40 /// flags. At runtime the driver parses the command line into
41 /// concrete Arg instances, each of which corresponds to a
42 /// particular Option instance.
43 class Option {
44 public:
45 enum OptionClass {
46 GroupClass = 0,
47 InputClass,
48 UnknownClass,
49 FlagClass,
50 JoinedClass,
51 SeparateClass,
52 CommaJoinedClass,
53 MultiArgClass,
54 JoinedOrSeparateClass,
55 JoinedAndSeparateClass
56 };
57
58 enum RenderStyleKind {
59 RenderCommaJoinedStyle,
60 RenderJoinedStyle,
61 RenderSeparateStyle,
62 RenderValuesStyle
63 };
64
65 protected:
66 const OptTable::Info *Info;
67 const OptTable *Owner;
68
69 public:
70 Option(const OptTable::Info *Info, const OptTable *Owner);
71 ~Option();
72
73 bool isValid() const {
74 return Info != 0;
75 }
76
77 unsigned getID() const {
78 assert(Info && "Must have a valid info!");
79 return Info->ID;
80 }
81
82 OptionClass getKind() const {
83 assert(Info && "Must have a valid info!");
84 return OptionClass(Info->Kind);
85 }
86
87 /// \brief Get the name of this option without any prefix.
88 StringRef getName() const {
89 assert(Info && "Must have a valid info!");
90 return Info->Name;
91 }
92
93 const Option getGroup() const {
94 assert(Info && "Must have a valid info!");
95 assert(Owner && "Must have a valid owner!");
96 return Owner->getOption(Info->GroupID);
97 }
98
99 const Option getAlias() const {
100 assert(Info && "Must have a valid info!");
101 assert(Owner && "Must have a valid owner!");
102 return Owner->getOption(Info->AliasID);
103 }
104
105 /// \brief Get the default prefix for this option.
106 StringRef getPrefix() const {
107 const char *Prefix = *Info->Prefixes;
108 return Prefix ? Prefix : StringRef();
109 }
110
111 /// \brief Get the name of this option with the default prefix.
112 std::string getPrefixedName() const {
113 std::string Ret = getPrefix();
114 Ret += getName();
115 return Ret;
116 }
117
118 unsigned getNumArgs() const { return Info->Param; }
119
120 bool hasNoOptAsInput() const { return Info->Flags & RenderAsInput;}
121
122 RenderStyleKind getRenderStyle() const {
123 if (Info->Flags & RenderJoined)
124 return RenderJoinedStyle;
125 if (Info->Flags & RenderSeparate)
126 return RenderSeparateStyle;
127 switch (getKind()) {
128 case GroupClass:
129 case InputClass:
130 case UnknownClass:
131 return RenderValuesStyle;
132 case JoinedClass:
133 case JoinedAndSeparateClass:
134 return RenderJoinedStyle;
135 case CommaJoinedClass:
136 return RenderCommaJoinedStyle;
137 case FlagClass:
138 case SeparateClass:
139 case MultiArgClass:
140 case JoinedOrSeparateClass:
141 return RenderSeparateStyle;
142 }
143 llvm_unreachable("Unexpected kind!");
144 }
145
146 /// Test if this option has the flag \a Val.
147 bool hasFlag(unsigned Val) const {
148 return Info->Flags & Val;
149 }
150
151 /// getUnaliasedOption - Return the final option this option
152 /// aliases (itself, if the option has no alias).
153 const Option getUnaliasedOption() const {
154 const Option Alias = getAlias();
155 if (Alias.isValid()) return Alias.getUnaliasedOption();
156 return *this;
157 }
158
159 /// getRenderName - Return the name to use when rendering this
160 /// option.
161 StringRef getRenderName() const {
162 return getUnaliasedOption().getName();
163 }
164
165 /// matches - Predicate for whether this option is part of the
166 /// given option (which may be a group).
167 ///
168 /// Note that matches against options which are an alias should never be
169 /// done -- aliases do not participate in matching and so such a query will
170 /// always be false.
171 bool matches(OptSpecifier ID) const;
172
173 /// accept - Potentially accept the current argument, returning a
174 /// new Arg instance, or 0 if the option does not accept this
175 /// argument (or the argument is missing values).
176 ///
177 /// If the option accepts the current argument, accept() sets
178 /// Index to the position where argument parsing should resume
179 /// (even if the argument is missing values).
180 ///
181 /// \parm ArgSize The number of bytes taken up by the matched Option prefix
182 /// and name. This is used to determine where joined values
183 /// start.
184 Arg *accept(const ArgList &Args, unsigned &Index, unsigned ArgSize) const;
185
186 void dump() const;
187 };
188
189 } // end namespace opt
190 } // end namespace llvm
191
192 #endif
77 add_subdirectory(Analysis)
88 add_subdirectory(MC)
99 add_subdirectory(Object)
10 add_subdirectory(Option)
1011 add_subdirectory(DebugInfo)
1112 add_subdirectory(ExecutionEngine)
1213 add_subdirectory(Target)
1515 ;===------------------------------------------------------------------------===;
1616
1717 [common]
18 subdirectories = Analysis Archive AsmParser Bitcode CodeGen DebugInfo ExecutionEngine Linker MC Object Support TableGen Target Transforms VMCore
18 subdirectories = Analysis Archive AsmParser Bitcode CodeGen DebugInfo ExecutionEngine Linker MC Object Option Support TableGen Target Transforms VMCore
1919
2020 [component_0]
2121 type = Group
1010 include $(LEVEL)/Makefile.config
1111
1212 PARALLEL_DIRS := VMCore AsmParser Bitcode Archive Analysis Transforms CodeGen \
13 Target ExecutionEngine Linker MC Object DebugInfo
13 Target ExecutionEngine Linker MC Object Option DebugInfo
1414
1515 include $(LEVEL)/Makefile.common
1616
0 //===--- Arg.cpp - Argument Implementations -------------------------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "llvm/Option/Arg.h"
10
11 #include "llvm/ADT/SmallString.h"
12 #include "llvm/ADT/Twine.h"
13 #include "llvm/Option/ArgList.h"
14 #include "llvm/Option/Option.h"
15 #include "llvm/Support/raw_ostream.h"
16
17 using namespace llvm;
18 using namespace llvm::opt;
19
20 Arg::Arg(const Option _Opt, StringRef S, unsigned _Index, const Arg *_BaseArg)
21 : Opt(_Opt), BaseArg(_BaseArg), Spelling(S), Index(_Index),
22 Claimed(false), OwnsValues(false) {
23 }
24
25 Arg::Arg(const Option _Opt, StringRef S, unsigned _Index,
26 const char *Value0, const Arg *_BaseArg)
27 : Opt(_Opt), BaseArg(_BaseArg), Spelling(S), Index(_Index),
28 Claimed(false), OwnsValues(false) {
29 Values.push_back(Value0);
30 }
31
32 Arg::Arg(const Option _Opt, StringRef S, unsigned _Index,
33 const char *Value0, const char *Value1, const Arg *_BaseArg)
34 : Opt(_Opt), BaseArg(_BaseArg), Spelling(S), Index(_Index),
35 Claimed(false), OwnsValues(false) {
36 Values.push_back(Value0);
37 Values.push_back(Value1);
38 }
39
40 Arg::~Arg() {
41 if (OwnsValues) {
42 for (unsigned i = 0, e = Values.size(); i != e; ++i)
43 delete[] Values[i];
44 }
45 }
46
47 void Arg::dump() const {
48 llvm::errs() << "<";
49
50 llvm::errs() << " Opt:";
51 Opt.dump();
52
53 llvm::errs() << " Index:" << Index;
54
55 llvm::errs() << " Values: [";
56 for (unsigned i = 0, e = Values.size(); i != e; ++i) {
57 if (i) llvm::errs() << ", ";
58 llvm::errs() << "'" << Values[i] << "'";
59 }
60
61 llvm::errs() << "]>\n";
62 }
63
64 std::string Arg::getAsString(const ArgList &Args) const {
65 SmallString<256> Res;
66 llvm::raw_svector_ostream OS(Res);
67
68 ArgStringList ASL;
69 render(Args, ASL);
70 for (ArgStringList::iterator
71 it = ASL.begin(), ie = ASL.end(); it != ie; ++it) {
72 if (it != ASL.begin())
73 OS << ' ';
74 OS << *it;
75 }
76
77 return OS.str();
78 }
79
80 void Arg::renderAsInput(const ArgList &Args, ArgStringList &Output) const {
81 if (!getOption().hasNoOptAsInput()) {
82 render(Args, Output);
83 return;
84 }
85
86 for (unsigned i = 0, e = getNumValues(); i != e; ++i)
87 Output.push_back(getValue(i));
88 }
89
90 void Arg::render(const ArgList &Args, ArgStringList &Output) const {
91 switch (getOption().getRenderStyle()) {
92 case Option::RenderValuesStyle:
93 for (unsigned i = 0, e = getNumValues(); i != e; ++i)
94 Output.push_back(getValue(i));
95 break;
96
97 case Option::RenderCommaJoinedStyle: {
98 SmallString<256> Res;
99 llvm::raw_svector_ostream OS(Res);
100 OS << getSpelling();
101 for (unsigned i = 0, e = getNumValues(); i != e; ++i) {
102 if (i) OS << ',';
103 OS << getValue(i);
104 }
105 Output.push_back(Args.MakeArgString(OS.str()));
106 break;
107 }
108
109 case Option::RenderJoinedStyle:
110 Output.push_back(Args.GetOrMakeJoinedArgString(
111 getIndex(), getSpelling(), getValue(0)));
112 for (unsigned i = 1, e = getNumValues(); i != e; ++i)
113 Output.push_back(getValue(i));
114 break;
115
116 case Option::RenderSeparateStyle:
117 Output.push_back(Args.MakeArgString(getSpelling()));
118 for (unsigned i = 0, e = getNumValues(); i != e; ++i)
119 Output.push_back(getValue(i));
120 break;
121 }
122 }
0 //===--- ArgList.cpp - Argument List Management ---------------------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "llvm/Option/ArgList.h"
10
11 #include "llvm/ADT/SmallString.h"
12 #include "llvm/ADT/Twine.h"
13 #include "llvm/Option/Arg.h"
14 #include "llvm/Option/Option.h"
15 #include "llvm/Support/raw_ostream.h"
16
17 using namespace llvm;
18 using namespace llvm::opt;
19
20 void arg_iterator::SkipToNextArg() {
21 for (; Current != Args.end(); ++Current) {
22 // Done if there are no filters.
23 if (!Id0.isValid())
24 break;
25
26 // Otherwise require a match.
27 const Option &O = (*Current)->getOption();
28 if (O.matches(Id0) ||
29 (Id1.isValid() && O.matches(Id1)) ||
30 (Id2.isValid() && O.matches(Id2)))
31 break;
32 }
33 }
34
35 //
36
37 ArgList::ArgList() {
38 }
39
40 ArgList::~ArgList() {
41 }
42
43 void ArgList::append(Arg *A) {
44 Args.push_back(A);
45 }
46
47 void ArgList::eraseArg(OptSpecifier Id) {
48 for (iterator it = begin(), ie = end(); it != ie; ) {
49 if ((*it)->getOption().matches(Id)) {
50 it = Args.erase(it);
51 ie = end();
52 } else {
53 ++it;
54 }
55 }
56 }
57
58 Arg *ArgList::getLastArgNoClaim(OptSpecifier Id) const {
59 // FIXME: Make search efficient?
60 for (const_reverse_iterator it = rbegin(), ie = rend(); it != ie; ++it)
61 if ((*it)->getOption().matches(Id))
62 return *it;
63 return 0;
64 }
65
66 Arg *ArgList::getLastArg(OptSpecifier Id) const {
67 Arg *Res = 0;
68 for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
69 if ((*it)->getOption().matches(Id)) {
70 Res = *it;
71 Res->claim();
72 }
73 }
74
75 return Res;
76 }
77
78 Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1) const {
79 Arg *Res = 0;
80 for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
81 if ((*it)->getOption().matches(Id0) ||
82 (*it)->getOption().matches(Id1)) {
83 Res = *it;
84 Res->claim();
85
86 }
87 }
88
89 return Res;
90 }
91
92 Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1,
93 OptSpecifier Id2) const {
94 Arg *Res = 0;
95 for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
96 if ((*it)->getOption().matches(Id0) ||
97 (*it)->getOption().matches(Id1) ||
98 (*it)->getOption().matches(Id2)) {
99 Res = *it;
100 Res->claim();
101 }
102 }
103
104 return Res;
105 }
106
107 Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1,
108 OptSpecifier Id2, OptSpecifier Id3) const {
109 Arg *Res = 0;
110 for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
111 if ((*it)->getOption().matches(Id0) ||
112 (*it)->getOption().matches(Id1) ||
113 (*it)->getOption().matches(Id2) ||
114 (*it)->getOption().matches(Id3)) {
115 Res = *it;
116 Res->claim();
117 }
118 }
119
120 return Res;
121 }
122
123 Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1,
124 OptSpecifier Id2, OptSpecifier Id3,
125 OptSpecifier Id4) const {
126 Arg *Res = 0;
127 for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
128 if ((*it)->getOption().matches(Id0) ||
129 (*it)->getOption().matches(Id1) ||
130 (*it)->getOption().matches(Id2) ||
131 (*it)->getOption().matches(Id3) ||
132 (*it)->getOption().matches(Id4)) {
133 Res = *it;
134 Res->claim();
135 }
136 }
137
138 return Res;
139 }
140
141 Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1,
142 OptSpecifier Id2, OptSpecifier Id3,
143 OptSpecifier Id4, OptSpecifier Id5) const {
144 Arg *Res = 0;
145 for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
146 if ((*it)->getOption().matches(Id0) ||
147 (*it)->getOption().matches(Id1) ||
148 (*it)->getOption().matches(Id2) ||
149 (*it)->getOption().matches(Id3) ||
150 (*it)->getOption().matches(Id4) ||
151 (*it)->getOption().matches(Id5)) {
152 Res = *it;
153 Res->claim();
154 }
155 }
156
157 return Res;
158 }
159
160 Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1,
161 OptSpecifier Id2, OptSpecifier Id3,
162 OptSpecifier Id4, OptSpecifier Id5,
163 OptSpecifier Id6) const {
164 Arg *Res = 0;
165 for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
166 if ((*it)->getOption().matches(Id0) ||
167 (*it)->getOption().matches(Id1) ||
168 (*it)->getOption().matches(Id2) ||
169 (*it)->getOption().matches(Id3) ||
170 (*it)->getOption().matches(Id4) ||
171 (*it)->getOption().matches(Id5) ||
172 (*it)->getOption().matches(Id6)) {
173 Res = *it;
174 Res->claim();
175 }
176 }
177
178 return Res;
179 }
180
181 Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1,
182 OptSpecifier Id2, OptSpecifier Id3,
183 OptSpecifier Id4, OptSpecifier Id5,
184 OptSpecifier Id6, OptSpecifier Id7) const {
185 Arg *Res = 0;
186 for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
187 if ((*it)->getOption().matches(Id0) ||
188 (*it)->getOption().matches(Id1) ||
189 (*it)->getOption().matches(Id2) ||
190 (*it)->getOption().matches(Id3) ||
191 (*it)->getOption().matches(Id4) ||
192 (*it)->getOption().matches(Id5) ||
193 (*it)->getOption().matches(Id6) ||
194 (*it)->getOption().matches(Id7)) {
195 Res = *it;
196 Res->claim();
197 }
198 }
199
200 return Res;
201 }
202
203 bool ArgList::hasFlag(OptSpecifier Pos, OptSpecifier Neg, bool Default) const {
204 if (Arg *A = getLastArg(Pos, Neg))
205 return A->getOption().matches(Pos);
206 return Default;
207 }
208
209 StringRef ArgList::getLastArgValue(OptSpecifier Id,
210 StringRef Default) const {
211 if (Arg *A = getLastArg(Id))
212 return A->getValue();
213 return Default;
214 }
215
216 std::vector ArgList::getAllArgValues(OptSpecifier Id) const {
217 SmallVector Values;
218 AddAllArgValues(Values, Id);
219 return std::vector(Values.begin(), Values.end());
220 }
221
222 void ArgList::AddLastArg(ArgStringList &Output, OptSpecifier Id) const {
223 if (Arg *A = getLastArg(Id)) {
224 A->claim();
225 A->render(*this, Output);
226 }
227 }
228
229 void ArgList::AddAllArgs(ArgStringList &Output, OptSpecifier Id0,
230 OptSpecifier Id1, OptSpecifier Id2) const {
231 for (arg_iterator it = filtered_begin(Id0, Id1, Id2),
232 ie = filtered_end(); it != ie; ++it) {
233 (*it)->claim();
234 (*it)->render(*this, Output);
235 }
236 }
237
238 void ArgList::AddAllArgValues(ArgStringList &Output, OptSpecifier Id0,
239 OptSpecifier Id1, OptSpecifier Id2) const {
240 for (arg_iterator it = filtered_begin(Id0, Id1, Id2),
241 ie = filtered_end(); it != ie; ++it) {
242 (*it)->claim();
243 for (unsigned i = 0, e = (*it)->getNumValues(); i != e; ++i)
244 Output.push_back((*it)->getValue(i));
245 }
246 }
247
248 void ArgList::AddAllArgsTranslated(ArgStringList &Output, OptSpecifier Id0,
249 const char *Translation,
250 bool Joined) const {
251 for (arg_iterator it = filtered_begin(Id0),
252 ie = filtered_end(); it != ie; ++it) {
253 (*it)->claim();
254
255 if (Joined) {
256 Output.push_back(MakeArgString(StringRef(Translation) +
257 (*it)->getValue(0)));
258 } else {
259 Output.push_back(Translation);
260 Output.push_back((*it)->getValue(0));
261 }
262 }
263 }
264
265 void ArgList::ClaimAllArgs(OptSpecifier Id0) const {
266 for (arg_iterator it = filtered_begin(Id0),
267 ie = filtered_end(); it != ie; ++it)
268 (*it)->claim();
269 }
270
271 void ArgList::ClaimAllArgs() const {
272 for (const_iterator it = begin(), ie = end(); it != ie; ++it)
273 if (!(*it)->isClaimed())
274 (*it)->claim();
275 }
276
277 const char *ArgList::MakeArgString(const Twine &T) const {
278 SmallString<256> Str;
279 T.toVector(Str);
280 return MakeArgString(Str.str());
281 }
282
283 const char *ArgList::GetOrMakeJoinedArgString(unsigned Index,
284 StringRef LHS,
285 StringRef RHS) const {
286 StringRef Cur = getArgString(Index);
287 if (Cur.size() == LHS.size() + RHS.size() &&
288 Cur.startswith(LHS) && Cur.endswith(RHS))
289 return Cur.data();
290
291 return MakeArgString(LHS + RHS);
292 }
293
294 //
295
296 InputArgList::InputArgList(const char* const *ArgBegin,
297 const char* const *ArgEnd)
298 : NumInputArgStrings(ArgEnd - ArgBegin) {
299 ArgStrings.append(ArgBegin, ArgEnd);
300 }
301
302 InputArgList::~InputArgList() {
303 // An InputArgList always owns its arguments.
304 for (iterator it = begin(), ie = end(); it != ie; ++it)
305 delete *it;
306 }
307
308 unsigned InputArgList::MakeIndex(StringRef String0) const {
309 unsigned Index = ArgStrings.size();
310
311 // Tuck away so we have a reliable const char *.
312 SynthesizedStrings.push_back(String0);
313 ArgStrings.push_back(SynthesizedStrings.back().c_str());
314
315 return Index;
316 }
317
318 unsigned InputArgList::MakeIndex(StringRef String0,
319 StringRef String1) const {
320 unsigned Index0 = MakeIndex(String0);
321 unsigned Index1 = MakeIndex(String1);
322 assert(Index0 + 1 == Index1 && "Unexpected non-consecutive indices!");
323 (void) Index1;
324 return Index0;
325 }
326
327 const char *InputArgList::MakeArgString(StringRef Str) const {
328 return getArgString(MakeIndex(Str));
329 }
330
331 //
332
333 DerivedArgList::DerivedArgList(const InputArgList &_BaseArgs)
334 : BaseArgs(_BaseArgs) {
335 }
336
337 DerivedArgList::~DerivedArgList() {
338 // We only own the arguments we explicitly synthesized.
339 for (iterator it = SynthesizedArgs.begin(), ie = SynthesizedArgs.end();
340 it != ie; ++it)
341 delete *it;
342 }
343
344 const char *DerivedArgList::MakeArgString(StringRef Str) const {
345 return BaseArgs.MakeArgString(Str);
346 }
347
348 Arg *DerivedArgList::MakeFlagArg(const Arg *BaseArg, const Option Opt) const {
349 Arg *A = new Arg(Opt, ArgList::MakeArgString(Twine(Opt.getPrefix()) +
350 Twine(Opt.getName())),
351 BaseArgs.MakeIndex(Opt.getName()), BaseArg);
352 SynthesizedArgs.push_back(A);
353 return A;
354 }
355
356 Arg *DerivedArgList::MakePositionalArg(const Arg *BaseArg, const Option Opt,
357 StringRef Value) const {
358 unsigned Index = BaseArgs.MakeIndex(Value);
359 Arg *A = new Arg(Opt, ArgList::MakeArgString(Twine(Opt.getPrefix()) +
360 Twine(Opt.getName())),
361 Index, BaseArgs.getArgString(Index), BaseArg);
362 SynthesizedArgs.push_back(A);
363 return A;
364 }
365
366 Arg *DerivedArgList::MakeSeparateArg(const Arg *BaseArg, const Option Opt,
367 StringRef Value) const {
368 unsigned Index = BaseArgs.MakeIndex(Opt.getName(), Value);
369 Arg *A = new Arg(Opt, ArgList::MakeArgString(Twine(Opt.getPrefix()) +
370 Twine(Opt.getName())),
371 Index, BaseArgs.getArgString(Index + 1), BaseArg);
372 SynthesizedArgs.push_back(A);
373 return A;
374 }
375
376 Arg *DerivedArgList::MakeJoinedArg(const Arg *BaseArg, const Option Opt,
377 StringRef Value) const {
378 unsigned Index = BaseArgs.MakeIndex(Opt.getName().str() + Value.str());
379 Arg *A = new Arg(Opt, ArgList::MakeArgString(Twine(Opt.getPrefix()) +
380 Twine(Opt.getName())), Index,
381 BaseArgs.getArgString(Index) + Opt.getName().size(),
382 BaseArg);
383 SynthesizedArgs.push_back(A);
384 return A;
385 }
0 add_llvm_library(LLVMOption
1 Arg.cpp
2 ArgList.cpp
3 Option.cpp
4 OptTable.cpp
5 )
6
7 target_link_libraries(LLVMOption LLVMSupport)
0 ;===- ./lib/Option/LLVMBuild.txt -------------------------------*- Conf -*--===;
1 ;
2 ; The LLVM Compiler Infrastructure
3 ;
4 ; This file is distributed under the University of Illinois Open Source
5 ; License. See LICENSE.TXT for details.
6 ;
7 ;===------------------------------------------------------------------------===;
8 ;
9 ; This is an LLVMBuild description file for the components in this subdirectory.
10 ;
11 ; For more information on the LLVMBuild system, please see:
12 ;
13 ; http://llvm.org/docs/LLVMBuild.html
14 ;
15 ;===------------------------------------------------------------------------===;
16
17 [component_0]
18 type = Library
19 name = Option
20 parent = Libraries
21 required_libraries = Support
0 ##===- lib/Option/Makefile ---------------------------------*- Makefile -*-===##
1 #
2 # The LLVM Compiler Infrastructure
3 #
4 # This file is distributed under the University of Illinois Open Source
5 # License. See LICENSE.TXT for details.
6 #
7 ##===----------------------------------------------------------------------===##
8
9 LEVEL = ../..
10 LIBRARYNAME = LLVMOption
11 BUILD_ARCHIVE := 1
12
13 include $(LEVEL)/Makefile.common
0 //===--- OptTable.cpp - Option Table Implementation -----------------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "llvm/Option/OptTable.h"
10
11 #include "llvm/Option/Arg.h"
12 #include "llvm/Option/ArgList.h"
13 #include "llvm/Option/Option.h"
14 #include "llvm/Support/raw_ostream.h"
15 #include "llvm/Support/ErrorHandling.h"
16 #include
17 #include
18
19 using namespace llvm;
20 using namespace llvm::opt;
21
22 // Ordering on Info. The ordering is *almost* lexicographic, with two
23 // exceptions. First, '\0' comes at the end of the alphabet instead of
24 // the beginning (thus options precede any other options which prefix
25 // them). Second, for options with the same name, the less permissive
26 // version should come first; a Flag option should precede a Joined
27 // option, for example.
28
29 static int StrCmpOptionName(const char *A, const char *B) {
30 char a = *A, b = *B;
31 while (a == b) {
32 if (a == '\0')
33 return 0;
34
35 a = *++A;
36 b = *++B;
37 }
38
39 if (a == '\0') // A is a prefix of B.
40 return 1;
41 if (b == '\0') // B is a prefix of A.
42 return -1;
43
44 // Otherwise lexicographic.
45 return (a < b) ? -1 : 1;
46 }
47
48 namespace llvm {
49 namespace opt {
50
51 static inline bool operator<(const OptTable::Info &A, const OptTable::Info &B) {
52 if (&A == &B)
53 return false;
54
55 if (int N = StrCmpOptionName(A.Name, B.Name))
56 return N == -1;
57
58 for (const char * const *APre = A.Prefixes,
59 * const *BPre = B.Prefixes;
60 *APre != 0 && *BPre != 0; ++APre, ++BPre) {
61 if (int N = StrCmpOptionName(*APre, *BPre))
62 return N == -1;
63 }
64
65 // Names are the same, check that classes are in order; exactly one
66 // should be joined, and it should succeed the other.
67 assert(((A.Kind == Option::JoinedClass) ^ (B.Kind == Option::JoinedClass)) &&
68 "Unexpected classes for options with same name.");
69 return B.Kind == Option::JoinedClass;
70 }
71
72 // Support lower_bound between info and an option name.
73 static inline bool operator<(const OptTable::Info &I, const char *Name) {
74 return StrCmpOptionName(I.Name, Name) == -1;
75 }
76 static inline bool operator<(const char *Name, const OptTable::Info &I) {
77 return StrCmpOptionName(Name, I.Name) == -1;
78 }
79 }
80 }
81
82 OptSpecifier::OptSpecifier(const Option *Opt) : ID(Opt->getID()) {}
83
84 OptTable::OptTable(const Info *_OptionInfos, unsigned _NumOptionInfos)
85 : OptionInfos(_OptionInfos),
86 NumOptionInfos(_NumOptionInfos),
87 TheInputOptionID(0),
88 TheUnknownOptionID(0),
89 FirstSearchableIndex(0)
90 {
91 // Explicitly zero initialize the error to work around a bug in array
92 // value-initialization on MinGW with gcc 4.3.5.
93
94 // Find start of normal options.
95 for (unsigned i = 0, e = getNumOptions(); i != e; ++i) {
96 unsigned Kind = getInfo(i + 1).Kind;
97 if (Kind == Option::InputClass) {
98 assert(!TheInputOptionID && "Cannot have multiple input options!");
99 TheInputOptionID = getInfo(i + 1).ID;
100 } else if (Kind == Option::UnknownClass) {
101 assert(!TheUnknownOptionID && "Cannot have multiple unknown options!");
102 TheUnknownOptionID = getInfo(i + 1).ID;
103 } else if (Kind != Option::GroupClass) {
104 FirstSearchableIndex = i;
105 break;
106 }
107 }
108 assert(FirstSearchableIndex != 0 && "No searchable options?");
109
110 #ifndef NDEBUG
111 // Check that everything after the first searchable option is a
112 // regular option class.
113 for (unsigned i = FirstSearchableIndex, e = getNumOptions(); i != e; ++i) {
114 Option::OptionClass Kind = (Option::OptionClass) getInfo(i + 1).Kind;
115 assert((Kind != Option::InputClass && Kind != Option::UnknownClass &&
116 Kind != Option::GroupClass) &&
117 "Special options should be defined first!");
118 }
119
120 // Check that options are in order.
121 for (unsigned i = FirstSearchableIndex + 1, e = getNumOptions(); i != e; ++i){
122 if (!(getInfo(i) < getInfo(i + 1))) {
123 getOption(i).dump();
124 getOption(i + 1).dump();
125 llvm_unreachable("Options are not in order!");
126 }
127 }
128 #endif
129
130 // Build prefixes.
131 for (unsigned i = FirstSearchableIndex + 1, e = getNumOptions() + 1;
132 i != e; ++i) {
133 if (const char *const *P = getInfo(i).Prefixes) {
134 for (; *P != 0; ++P) {
135 PrefixesUnion.insert(*P);
136 }
137 }
138 }
139
140 // Build prefix chars.
141 for (llvm::StringSet<>::const_iterator I = PrefixesUnion.begin(),
142 E = PrefixesUnion.end(); I != E; ++I) {
143 StringRef Prefix = I->getKey();
144 for (StringRef::const_iterator C = Prefix.begin(), CE = Prefix.end();
145 C != CE; ++C)
146 if (std::find(PrefixChars.begin(), PrefixChars.end(), *C)
147 == PrefixChars.end())
148 PrefixChars.push_back(*C);
149 }
150 }
151
152 OptTable::~OptTable() {
153 }
154
155 const Option OptTable::getOption(OptSpecifier Opt) const {
156 unsigned id = Opt.getID();
157 if (id == 0)
158 return Option(0, 0);
159 assert((unsigned) (id - 1) < getNumOptions() && "Invalid ID.");
160 return Option(&getInfo(id), this);
161 }
162
163 bool OptTable::isOptionHelpHidden(OptSpecifier id) const {
164 return getInfo(id).Flags & HelpHidden;
165 }
166
167 static bool isInput(const llvm::StringSet<> &Prefixes, StringRef Arg) {
168 if (Arg == "-")
169 return true;
170 for (llvm::StringSet<>::const_iterator I = Prefixes.begin(),
171 E = Prefixes.end(); I != E; ++I)
172 if (Arg.startswith(I->getKey()))
173 return false;
174 return true;
175 }
176
177 /// \returns Matched size. 0 means no match.
178 static unsigned matchOption(const OptTable::Info *I, StringRef Str) {
179 for (const char * const *Pre = I->Prefixes; *Pre != 0; ++Pre) {
180 StringRef Prefix(*Pre);
181 if (Str.startswith(Prefix) && Str.substr(Prefix.size()).startswith(I->Name))
182 return Prefix.size() + StringRef(I->Name).size();
183 }
184 return 0;
185 }
186
187 Arg *OptTable::ParseOneArg(const ArgList &Args, unsigned &Index) const {
188 unsigned Prev = Index;
189 const char *Str = Args.getArgString(Index);
190
191 // Anything that doesn't start with PrefixesUnion is an input, as is '-'
192 // itself.
193 if (isInput(PrefixesUnion, Str))
194 return new Arg(getOption(TheInputOptionID), Str, Index++, Str);
195
196 const Info *Start = OptionInfos + FirstSearchableIndex;
197 const Info *End = OptionInfos + getNumOptions();
198 StringRef Name = StringRef(Str).ltrim(PrefixChars);
199
200 // Search for the first next option which could be a prefix.
201 Start = std::lower_bound(Start, End, Name.data());
202
203 // Options are stored in sorted order, with '\0' at the end of the
204 // alphabet. Since the only options which can accept a string must
205 // prefix it, we iteratively search for the next option which could
206 // be a prefix.
207 //
208 // FIXME: This is searching much more than necessary, but I am
209 // blanking on the simplest way to make it fast. We can solve this
210 // problem when we move to TableGen.
211 for (; Start != End; ++Start) {
212 unsigned ArgSize = 0;
213 // Scan for first option which is a proper prefix.
214 for (; Start != End; ++Start)
215 if ((ArgSize = matchOption(Start, Str)))
216 break;
217 if (Start == End)
218 break;
219
220 // See if this option matches.
221 if (Arg *A = Option(Start, this).accept(Args, Index, ArgSize))
222 return A;
223
224 // Otherwise, see if this argument was missing values.
225 if (Prev != Index)
226 return 0;
227 }
228
229 return new Arg(getOption(TheUnknownOptionID), Str, Index++, Str);
230 }
231
232 InputArgList *OptTable::ParseArgs(const char* const *ArgBegin,
233 const char* const *ArgEnd,
234 unsigned &MissingArgIndex,
235 unsigned &MissingArgCount) const {
236 InputArgList *Args = new InputArgList(ArgBegin, ArgEnd);
237
238 // FIXME: Handle '@' args (or at least error on them).
239
240 MissingArgIndex = MissingArgCount = 0;
241 unsigned Index = 0, End = ArgEnd - ArgBegin;
242 while (Index < End) {
243 // Ignore empty arguments (other things may still take them as arguments).
244 if (Args->getArgString(Index)[0] == '\0') {
245 ++Index;
246 continue;
247 }
248
249 unsigned Prev = Index;
250 Arg *A = ParseOneArg(*Args, Index);
251 assert(Index > Prev && "Parser failed to consume argument.");
252
253 // Check for missing argument error.
254 if (!A) {
255 assert(Index >= End && "Unexpected parser error.");
256 assert(Index - Prev - 1 && "No missing arguments!");
257 MissingArgIndex = Prev;
258 MissingArgCount = Index - Prev - 1;
259 break;
260 }
261
262 Args->append(A);
263 }
264
265 return Args;
266 }
267
268 static std::string getOptionHelpName(const OptTable &Opts, OptSpecifier Id) {
269 const Option O = Opts.getOption(Id);
270 std::string Name = O.getPrefixedName();
271
272 // Add metavar, if used.
273 switch (O.getKind()) {
274 case Option::GroupClass: case Option::InputClass: case Option::UnknownClass:
275 llvm_unreachable("Invalid option with help text.");
276
277 case Option::MultiArgClass:
278 llvm_unreachable("Cannot print metavar for this kind of option.");
279
280 case Option::FlagClass:
281 break;
282
283 case Option::SeparateClass: case Option::JoinedOrSeparateClass:
284 Name += ' ';
285 // FALLTHROUGH
286 case Option::JoinedClass: case Option::CommaJoinedClass:
287 case Option::JoinedAndSeparateClass:
288 if (const char *MetaVarName = Opts.getOptionMetaVar(Id))
289 Name += MetaVarName;
290 else
291 Name += "";
292 break;
293 }
294
295 return Name;
296 }
297
298 static void PrintHelpOptionList(raw_ostream &OS, StringRef Title,
299 std::vector
300 const char*> > &OptionHelp) {
301 OS << Title << ":\n";
302
303 // Find the maximum option length.
304 unsigned OptionFieldWidth = 0;
305 for (unsigned i = 0, e = OptionHelp.size(); i != e; ++i) {
306 // Skip titles.
307 if (!OptionHelp[i].second)
308 continue;
309
310 // Limit the amount of padding we are willing to give up for alignment.
311 unsigned Length = OptionHelp[i].first.size();
312 if (Length <= 23)
313 OptionFieldWidth = std::max(OptionFieldWidth, Length);
314 }
315
316 const unsigned InitialPad = 2;
317 for (unsigned i = 0, e = OptionHelp.size(); i != e; ++i) {
318 const std::string &Option = OptionHelp[i].first;
319 int Pad = OptionFieldWidth - int(Option.size());
320 OS.indent(InitialPad) << Option;
321
322 // Break on long option names.
323 if (Pad < 0) {
324 OS << "\n";
325 Pad = OptionFieldWidth + InitialPad;
326 }
327 OS.indent(Pad + 1) << OptionHelp[i].second << '\n';
328 }
329 }
330
331 static const char *getOptionHelpGroup(const OptTable &Opts, OptSpecifier Id) {
332 unsigned GroupID = Opts.getOptionGroupID(Id);
333
334 // If not in a group, return the default help group.
335 if (!GroupID)
336 return "OPTIONS";
337
338 // Abuse the help text of the option groups to store the "help group"
339 // name.
340 //
341 // FIXME: Split out option groups.
342 if (const char *GroupHelp = Opts.getOptionHelpText(GroupID))
343 return GroupHelp;
344
345 // Otherwise keep looking.
346 return getOptionHelpGroup(Opts, GroupID);
347 }
348
349 void OptTable::PrintHelp(raw_ostream &OS, const char *Name,
350 const char *Title, bool ShowHidden) const {
351 OS << "OVERVIEW: " << Title << "\n";
352 OS << '\n';
353 OS << "USAGE: " << Name << " [options] \n";
354 OS << '\n';
355
356 // Render help text into a map of group-name to a list of (option, help)
357 // pairs.
358 typedef std::map
359 std::vector > > helpmap_ty;
360 helpmap_ty GroupedOptionHelp;
361
362 for (unsigned i = 0, e = getNumOptions(); i != e; ++i) {
363 unsigned Id = i + 1;
364
365 // FIXME: Split out option groups.
366 if (getOptionKind(Id) == Option::GroupClass)
367 continue;
368
369 if (!ShowHidden && isOptionHelpHidden(Id))
370 continue;
371
372 if (const char *Text = getOptionHelpText(Id)) {
373 const char *HelpGroup = getOptionHelpGroup(*this, Id);
374 const std::string &OptName = getOptionHelpName(*this, Id);
375 GroupedOptionHelp[HelpGroup].push_back(std::make_pair(OptName, Text));
376 }
377 }
378
379 for (helpmap_ty::iterator it = GroupedOptionHelp .begin(),
380 ie = GroupedOptionHelp.end(); it != ie; ++it) {
381 if (it != GroupedOptionHelp .begin())
382 OS << "\n";
383 PrintHelpOptionList(OS, it->first, it->second);
384 }
385
386 OS.flush();
387 }
0 //===--- Option.cpp - Abstract Driver Options -----------------------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "llvm/Option/Option.h"
10
11 #include "llvm/ADT/Twine.h"
12 #include "llvm/Option/Arg.h"
13 #include "llvm/Option/ArgList.h"
14 #include "llvm/Support/raw_ostream.h"
15 #include "llvm/Support/ErrorHandling.h"
16
17 #include
18 #include
19
20 using namespace llvm;
21 using namespace llvm::opt;
22
23 Option::Option(const OptTable::Info *info, const OptTable *owner)
24 : Info(info), Owner(owner) {
25
26 // Multi-level aliases are not supported, and alias options cannot
27 // have groups. This just simplifies option tracking, it is not an
28 // inherent limitation.
29 assert((!Info || !getAlias().isValid() || (!getAlias().getAlias().isValid() &&
30 !getGroup().isValid())) &&
31 "Multi-level aliases and aliases with groups are unsupported.");
32 }
33
34 Option::~Option() {
35 }
36
37 void Option::dump() const {
38 llvm::errs() << "<";
39 switch (getKind()) {
40 #define P(N) case N: llvm::errs() << #N; break
41 P(GroupClass);
42 P(InputClass);
43 P(UnknownClass);
44 P(FlagClass);
45 P(JoinedClass);
46 P(SeparateClass);
47 P(CommaJoinedClass);
48 P(MultiArgClass);
49 P(JoinedOrSeparateClass);
50 P(JoinedAndSeparateClass);
51 #undef P
52 }
53
54 llvm::errs() << " Prefixes:[";
55 for (const char * const *Pre = Info->Prefixes; *Pre != 0; ++Pre) {
56 llvm::errs() << '"' << *Pre << (*(Pre + 1) == 0 ? "\"" : "\", ");
57 }
58 llvm::errs() << ']';
59
60 llvm::errs() << " Name:\"" << getName() << '"';
61
62 const Option Group = getGroup();
63 if (Group.isValid()) {
64 llvm::errs() << " Group:";
65 Group.dump();
66 }
67
68 const Option Alias = getAlias();
69 if (Alias.isValid()) {
70 llvm::errs() << " Alias:";
71 Alias.dump();
72 }
73
74 if (getKind() == MultiArgClass)
75 llvm::errs() << " NumArgs:" << getNumArgs();
76
77 llvm::errs() << ">\n";
78 }
79
80 bool Option::matches(OptSpecifier Opt) const {
81 // Aliases are never considered in matching, look through them.
82 const Option Alias = getAlias();
83 if (Alias.isValid())
84 return Alias.matches(Opt);
85
86 // Check exact match.
87 if (getID() == Opt.getID())
88 return true;
89
90 const Option Group = getGroup();
91 if (Group.isValid())
92 return Group.matches(Opt);
93 return false;
94 }
95
96 Arg *Option::accept(const ArgList &Args,
97 unsigned &Index,
98 unsigned ArgSize) const {
99 const Option &UnaliasedOption = getUnaliasedOption();
100 StringRef Spelling;
101 // If the option was an alias, get the spelling from the unaliased one.
102 if (getID() == UnaliasedOption.getID()) {
103 Spelling = StringRef(Args.getArgString(Index), ArgSize);
104 } else {
105 Spelling = Args.MakeArgString(Twine(UnaliasedOption.getPrefix()) +
106 Twine(UnaliasedOption.getName()));
107 }
108
109 switch (getKind()) {
110 case FlagClass:
111 if (ArgSize != strlen(Args.getArgString(Index)))
112 return 0;
113
114 return new Arg(UnaliasedOption, Spelling, Index++);
115 case JoinedClass: {
116 const char *Value = Args.getArgString(Index) + ArgSize;
117 return new Arg(UnaliasedOption, Spelling, Index++, Value);
118 }
119 case CommaJoinedClass: {
120 // Always matches.
121 const char *Str = Args.getArgString(Index) + ArgSize;
122 Arg *A = new Arg(UnaliasedOption, Spelling, Index++);
123
124 // Parse out the comma separated values.
125 const char *Prev = Str;
126 for (;; ++Str) {
127 char c = *Str;
128
129 if (!c || c == ',') {
130 if (Prev != Str) {
131 char *Value = new char[Str - Prev + 1];
132 memcpy(Value, Prev, Str - Prev);
133 Value[Str - Prev] = '\0';
134 A->getValues().push_back(Value);
135 }
136
137 if (!c)
138 break;
139
140 Prev = Str + 1;
141 }
142 }
143 A->setOwnsValues(true);
144
145 return A;
146 }
147 case SeparateClass:
148 // Matches iff this is an exact match.
149 // FIXME: Avoid strlen.
150 if (ArgSize != strlen(Args.getArgString(Index)))
151 return 0;
152
153 Index += 2;
154 if (Index > Args.getNumInputArgStrings())
155 return 0;
156
157 return new Arg(UnaliasedOption, Spelling,
158 Index - 2, Args.getArgString(Index - 1));
159 case MultiArgClass: {
160 // Matches iff this is an exact match.
161 // FIXME: Avoid strlen.
162 if (ArgSize != strlen(Args.getArgString(Index)))
163 return 0;
164
165 Index += 1 + getNumArgs();
166 if (Index > Args.getNumInputArgStrings())
167 return 0;
168
169 Arg *A = new Arg(UnaliasedOption, Spelling, Index - 1 - getNumArgs(),
170 Args.getArgString(Index - getNumArgs()));
171 for (unsigned i = 1; i != getNumArgs(); ++i)
172 A->getValues().push_back(Args.getArgString(Index - getNumArgs() + i));
173 return A;
174 }
175 case JoinedOrSeparateClass: {
176 // If this is not an exact match, it is a joined arg.
177 // FIXME: Avoid strlen.
178 if (ArgSize != strlen(Args.getArgString(Index))) {
179 const char *Value = Args.getArgString(Index) + ArgSize;
180 return new Arg(*this, Spelling, Index++, Value);
181 }
182
183 // Otherwise it must be separate.
184 Index += 2;
185 if (Index > Args.getNumInputArgStrings())
186 return 0;
187
188 return new Arg(UnaliasedOption, Spelling,
189 Index - 2, Args.getArgString(Index - 1));
190 }
191 case JoinedAndSeparateClass:
192 // Always matches.
193 Index += 2;
194 if (Index > Args.getNumInputArgStrings())
195 return 0;
196
197 return new Arg(UnaliasedOption, Spelling, Index - 2,
198 Args.getArgString(Index - 2) + ArgSize,
199 Args.getArgString(Index - 1));
200 default:
201 llvm_unreachable("Invalid option kind!");
202 }
203 }
88 add_subdirectory(Analysis)
99 add_subdirectory(ExecutionEngine)
1010 add_subdirectory(Bitcode)
11 add_subdirectory(Option)
1112 add_subdirectory(Support)
1213 add_subdirectory(Transforms)
1314 add_subdirectory(VMCore)
0 set(LLVM_LINK_COMPONENTS
1 Option
2 Support
3 )
4
5 set(LLVM_TARGET_DEFINITIONS Opts.td)
6
7 tablegen(LLVM Opts.inc -gen-opt-parser-defs)
8 add_public_tablegen_target(OptsTestTableGen)
9
10 add_llvm_unittest(OptionTests
11 OptionParsingTest.cpp
12 )
13
14 add_dependencies(OptionTests OptsTestTableGen)
0 //===- unittest/Support/OptionParsingTest.cpp - OptTable tests ------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "llvm/Option/Arg.h"
10 #include "llvm/Option/ArgList.h"
11 #include "llvm/Option/Option.h"
12
13 #include "gtest/gtest.h"
14
15 using namespace llvm;
16 using namespace llvm::opt;
17
18 enum ID {
19 OPT_INVALID = 0, // This is not an option ID.
20 #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \
21 HELPTEXT, METAVAR) OPT_##ID,
22 #include "Opts.inc"
23 LastOption
24 #undef OPTION
25 };
26
27 #define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;
28 #include "Opts.inc"
29 #undef PREFIX
30
31 static const OptTable::Info InfoTable[] = {
32 #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \
33 HELPTEXT, METAVAR) \
34 { PREFIX, NAME, HELPTEXT, METAVAR, OPT_##ID, Option::KIND##Class, PARAM, \
35 FLAGS, OPT_##GROUP, OPT_##ALIAS },
36 #include "Opts.inc"
37 #undef OPTION
38 };
39
40 namespace {
41 class TestOptTable : public OptTable {
42 public:
43 TestOptTable()
44 : OptTable(InfoTable, sizeof(InfoTable) / sizeof(InfoTable[0])) {}
45 };
46 }
47
48 const char *Args[] = {
49 "-A",
50 "-Bhi",
51 "--C=desu",
52 "-C", "bye",
53 "-D,adena",
54 "-E", "apple", "bloom",
55 "-Fblarg",
56 "-F", "42",
57 "-Gchuu", "2"
58 };
59
60 TEST(Support, OptionParsing) {
61 TestOptTable T;
62 unsigned MAI, MAC;
63 InputArgList *AL = T.ParseArgs(Args, Args + (sizeof(Args) / sizeof(Args[0])), MAI, MAC);
64
65 // Check they all exist.
66 EXPECT_TRUE(AL->hasArg(OPT_A));
67 EXPECT_TRUE(AL->hasArg(OPT_B));
68 EXPECT_TRUE(AL->hasArg(OPT_C));
69 EXPECT_TRUE(AL->hasArg(OPT_D));
70 EXPECT_TRUE(AL->hasArg(OPT_E));
71 EXPECT_TRUE(AL->hasArg(OPT_F));
72 EXPECT_TRUE(AL->hasArg(OPT_G));
73
74 // Check the values.
75 EXPECT_EQ(AL->getLastArgValue(OPT_B), "hi");
76 EXPECT_EQ(AL->getLastArgValue(OPT_C), "bye");
77 EXPECT_EQ(AL->getLastArgValue(OPT_D), "adena");
78 std::vector Es = AL->getAllArgValues(OPT_E);
79 EXPECT_EQ(Es[0], "apple");
80 EXPECT_EQ(Es[1], "bloom");
81 EXPECT_EQ(AL->getLastArgValue(OPT_F), "42");
82 std::vector Gs = AL->getAllArgValues(OPT_G);
83 EXPECT_EQ(Gs[0], "chuu");
84 EXPECT_EQ(Gs[1], "2");
85
86 // Check the help text.
87 std::string Help;
88 raw_string_ostream RSO(Help);
89 T.PrintHelp(RSO, "test", "title!");
90 EXPECT_NE(Help.find("-A"), std::string::npos);
91
92 // Test aliases.
93 arg_iterator Cs = AL->filtered_begin(OPT_C);
94 ASSERT_NE(Cs, AL->filtered_end());
95 EXPECT_EQ(StringRef((*Cs)->getValue()), "desu");
96 ArgStringList ASL;
97 (*Cs)->render(*AL, ASL);
98 ASSERT_EQ(ASL.size(), 2u);
99 EXPECT_EQ(StringRef(ASL[0]), "-C");
100 EXPECT_EQ(StringRef(ASL[1]), "desu");
101 }
0 include "llvm/Option/OptParser.td"
1
2 def A : Flag<["-"], "A">, HelpText<"The A option">;
3 def B : Joined<["-"], "B">, HelpText<"The B option">, MetaVarName<"B">;
4 def C : Separate<["-"], "C">, HelpText<"The C option">, MetaVarName<"C">;
5 def D : CommaJoined<["-"], "D">, HelpText<"The D option">, MetaVarName<"D">;
6 def E : MultiArg<["-"], "E", 2>;
7 def F : JoinedOrSeparate<["-"], "F">, HelpText<"The F option">, MetaVarName<"F">;
8 def G : JoinedAndSeparate<["-"], "G">, HelpText<"The G option">, MetaVarName<"G">;
9
10 def Ceq : Joined<["-", "--"], "C=">, Alias;
11
12 def H : Flag<["-"], "H">, Flags<[HelpHidden]>;
2323 FixedLenDecoderEmitter.cpp
2424 InstrInfoEmitter.cpp
2525 IntrinsicEmitter.cpp
26 OptParserEmitter.cpp
2627 PseudoLoweringEmitter.cpp
2728 RegisterInfoEmitter.cpp
2829 SetTheory.cpp
0 //===- OptParserEmitter.cpp - Table Driven Command Line Parsing -----------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "llvm/TableGen/Error.h"
10 #include "llvm/TableGen/Record.h"
11 #include "llvm/TableGen/TableGenBackend.h"
12 #include "llvm/ADT/STLExtras.h"
13 #include "llvm/ADT/SmallString.h"
14 #include "llvm/ADT/Twine.h"
15
16 #include
17
18 using namespace llvm;
19
20 static int StrCmpOptionName(const char *A, const char *B) {
21 char a = *A, b = *B;
22 while (a == b) {
23 if (a == '\0')
24 return 0;
25
26 a = *++A;
27 b = *++B;
28 }
29
30 if (a == '\0') // A is a prefix of B.
31 return 1;
32 if (b == '\0') // B is a prefix of A.
33 return -1;
34
35 // Otherwise lexicographic.
36 return (a < b) ? -1 : 1;
37 }
38
39 static int CompareOptionRecords(const void *Av, const void *Bv) {
40 const Record *A = *(const Record*const*) Av;
41 const Record *B = *(const Record*const*) Bv;
42
43 // Sentinel options precede all others and are only ordered by precedence.
44 bool ASent = A->getValueAsDef("Kind")->getValueAsBit("Sentinel");
45 bool BSent = B->getValueAsDef("Kind")->getValueAsBit("Sentinel");
46 if (ASent != BSent)
47 return ASent ? -1 : 1;
48
49 // Compare options by name, unless they are sentinels.
50 if (!ASent)
51 if (int Cmp = StrCmpOptionName(A->getValueAsString("Name").c_str(),
52 B->getValueAsString("Name").c_str()))
53 return Cmp;
54
55 if (!ASent) {
56 std::vector APrefixes = A->getValueAsListOfStrings("Prefixes");
57 std::vector BPrefixes = B->getValueAsListOfStrings("Prefixes");
58
59 for (std::vector::const_iterator APre = APrefixes.begin(),
60 AEPre = APrefixes.end(),
61 BPre = BPrefixes.begin(),
62 BEPre = BPrefixes.end();
63 APre != AEPre &&
64 BPre != BEPre;
65 ++APre, ++BPre) {
66 if (int Cmp = StrCmpOptionName(APre->c_str(), BPre->c_str()))
67 return Cmp;
68 }
69 }
70
71 // Then by the kind precedence;
72 int APrec = A->getValueAsDef("Kind")->getValueAsInt("Precedence");
73 int BPrec = B->getValueAsDef("Kind")->getValueAsInt("Precedence");
74 if (APrec == BPrec &&
75 A->getValueAsListOfStrings("Prefixes") ==
76 B->getValueAsListOfStrings("Prefixes")) {
77 PrintError(A->getLoc(), Twine("Option is equivilent to"));
78 PrintError(B->getLoc(), Twine("Other defined here"));
79 PrintFatalError("Equivalent Options found.");
80 }
81 return APrec < BPrec ? -1 : 1;
82 }
83
84 static const std::string getOptionName(const Record &R) {
85 // Use the record name unless EnumName is defined.
86 if (isa(R.getValueInit("EnumName")))
87 return R.getName();
88
89 return R.getValueAsString("EnumName");
90 }
91
92 static raw_ostream &write_cstring(raw_ostream &OS, llvm::StringRef Str) {
93 OS << '"';
94 OS.write_escaped(Str);
95 OS << '"';
96 return OS;
97 }
98
99 /// OptParserEmitter - This tablegen backend takes an input .td file
100 /// describing a list of options and emits a data structure for parsing and
101 /// working with those options when given an input command line.
102 namespace llvm {
103 void EmitOptParser(RecordKeeper &Records, raw_ostream &OS) {
104 // Get the option groups and options.
105 const std::vector &Groups =
106 Records.getAllDerivedDefinitions("OptionGroup");
107 std::vector Opts = Records.getAllDerivedDefinitions("Option");
108
109 emitSourceFileHeader("Option Parsing Definitions", OS);
110
111 array_pod_sort(Opts.begin(), Opts.end(), CompareOptionRecords);
112 // Generate prefix groups.
113 typedef SmallVector, 2> PrefixKeyT;
114 typedef std::map PrefixesT;
115 PrefixesT Prefixes;
116 Prefixes.insert(std::make_pair(PrefixKeyT(), "prefix_0"));
117 unsigned CurPrefix = 0;
118 for (unsigned i = 0, e = Opts.size(); i != e; ++i) {
119 const Record &R = *Opts[i];
120 std::vector prf = R.getValueAsListOfStrings("Prefixes");
121 PrefixKeyT prfkey(prf.begin(), prf.end());
122 unsigned NewPrefix = CurPrefix + 1;
123 if (Prefixes.insert(std::make_pair(prfkey, (Twine("prefix_") +
124 Twine(NewPrefix)).str())).second)
125 CurPrefix = NewPrefix;
126 }
127
128 // Dump prefixes.
129
130 OS << "/////////\n";
131 OS << "// Prefixes\n\n";
132 OS << "#ifdef PREFIX\n";
133 OS << "#define COMMA ,\n";
134 for (PrefixesT::const_iterator I = Prefixes.begin(), E = Prefixes.end();
135 I != E; ++I) {
136 OS << "PREFIX(";
137
138 // Prefix name.
139 OS << I->second;
140
141 // Prefix values.
142 OS << ", {";
143 for (PrefixKeyT::const_iterator PI = I->first.begin(),
144 PE = I->first.end(); PI != PE; ++PI) {
145 OS << "\"" << *PI << "\" COMMA ";
146 }
147 OS << "0})\n";
148 }
149 OS << "#undef COMMA\n";
150 OS << "#endif\n\n";
151
152 OS << "/////////\n";
153 OS << "// Groups\n\n";
154 OS << "#ifdef OPTION\n";
155 for (unsigned i = 0, e = Groups.size(); i != e; ++i) {
156 const Record &R = *Groups[i];
157
158 // Start a single option entry.
159 OS << "OPTION(";
160
161 // The option prefix;
162 OS << "0";
163
164 // The option string.
165 OS << ", \"" << R.getValueAsString("Name") << '"';
166
167 // The option identifier name.
168 OS << ", "<< getOptionName(R);
169
170 // The option kind.
171 OS << ", Group";
172
173 // The containing option group (if any).
174 OS << ", ";
175 if (const DefInit *DI = dyn_cast(R.getValueInit("Group")))
176 OS << getOptionName(*DI->getDef());
177 else
178 OS << "INVALID";
179
180 // The other option arguments (unused for groups).
181 OS << ", INVALID, 0, 0";
182
183 // The option help text.
184 if (!isa(R.getValueInit("HelpText"))) {
185 OS << ",\n";
186 OS << " ";
187 write_cstring(OS, R.getValueAsString("HelpText"));
188 } else
189 OS << ", 0";
190
191 // The option meta-variable name (unused).
192 OS << ", 0)\n";
193 }
194 OS << "\n";
195
196 OS << "//////////\n";
197 OS << "// Options\n\n";
198 for (unsigned i = 0, e = Opts.size(); i != e; ++i) {
199 const Record &R = *Opts[i];
200
201 // Start a single option entry.
202 OS << "OPTION(";
203
204 // The option prefix;
205 std::vector prf = R.getValueAsListOfStrings("Prefixes");
206 OS << Prefixes[PrefixKeyT(prf.begin(), prf.end())] << ", ";
207
208 // The option string.
209 write_cstring(OS, R.getValueAsString("Name"));
210
211 // The option identifier name.
212 OS << ", "<< getOptionName(R);
213
214 // The option kind.
215 OS << ", " << R.getValueAsDef("Kind")->getValueAsString("Name");
216
217 // The containing option group (if any).
218 OS << ", ";
219 if (const DefInit *DI = dyn_cast(R.getValueInit("Group")))
220 OS << getOptionName(*DI->getDef());
221 else
222 OS << "INVALID";
223
224 // The option alias (if any).
225 OS << ", ";
226 if (const DefInit *DI = dyn_cast(R.getValueInit("Alias")))
227 OS << getOptionName(*DI->getDef());
228 else
229 OS << "INVALID";
230
231 // The option flags.
232 const ListInit *LI = R.getValueAsListInit("Flags");
233 if (LI->empty()) {
234 OS << ", 0";
235 } else {
236 OS << ", ";
237 for (unsigned i = 0, e = LI->size(); i != e; ++i) {
238 if (i)
239 OS << " | ";
240 OS << cast(LI->getElement(i))->getDef()->getName();
241 }
242 }
243
244 // The option parameter field.
245 OS << ", " << R.getValueAsInt("NumArgs");
246
247 // The option help text.
248 if (!isa(R.getValueInit("HelpText"))) {
249 OS << ",\n";
250 OS << " ";
251 write_cstring(OS, R.getValueAsString("HelpText"));
252 } else
253 OS << ", 0";
254
255 // The option meta-variable name.
256 OS << ", ";
257 if (!isa(R.getValueInit("MetaVarName")))
258 write_cstring(OS, R.getValueAsString("MetaVarName"));
259 else
260 OS << "0";
261
262 OS << ")\n";
263 }
264 OS << "#endif\n";
265 }
266 } // end namespace llvm
3939 GenTgtIntrinsic,
4040 GenEDInfo,
4141 PrintEnums,
42 PrintSets
42 PrintSets,
43 GenOptParserDefs
4344 };
4445
4546 namespace {
8182 "Print enum values for a class"),
8283 clEnumValN(PrintSets, "print-sets",
8384 "Print expanded sets for testing DAG exprs"),
85 clEnumValN(GenOptParserDefs, "gen-opt-parser-defs",
86 "Generate option definitions"),
8487 clEnumValEnd));
8588
8689 cl::opt
137140 case GenEDInfo:
138141 EmitEnhancedDisassemblerInfo(Records, OS);
139142 break;
143 case GenOptParserDefs:
144 EmitOptParser(Records, OS);
145 break;
140146 case PrintEnums:
141147 {
142148 std::vector Recs = Records.getAllDerivedDefinitions(Class);
7474 void EmitRegisterInfo(RecordKeeper &RK, raw_ostream &OS);
7575 void EmitSubtarget(RecordKeeper &RK, raw_ostream &OS);
7676 void EmitMapTable(RecordKeeper &RK, raw_ostream &OS);
77 void EmitOptParser(RecordKeeper &RK, raw_ostream &OS);
7778
7879 } // End llvm namespace