Line data Source code
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/OptSpecifier.h"
16 : #include "llvm/Option/OptTable.h"
17 : #include "llvm/Support/ErrorHandling.h"
18 : #include <cassert>
19 : #include <string>
20 :
21 : namespace llvm {
22 :
23 : class raw_ostream;
24 :
25 : namespace opt {
26 :
27 : class Arg;
28 : class ArgList;
29 :
30 : /// ArgStringList - Type used for constructing argv lists for subprocesses.
31 : using ArgStringList = SmallVector<const char *, 16>;
32 :
33 : /// Base flags for all options. Custom flags may be added after.
34 : enum DriverFlag {
35 : HelpHidden = (1 << 0),
36 : RenderAsInput = (1 << 1),
37 : RenderJoined = (1 << 2),
38 : RenderSeparate = (1 << 3)
39 : };
40 :
41 : /// Option - Abstract representation for a single form of driver
42 : /// argument.
43 : ///
44 : /// An Option class represents a form of option that the driver
45 : /// takes, for example how many arguments the option has and how
46 : /// they can be provided. Individual option instances store
47 : /// additional information about what group the option is a member
48 : /// of (if any), if the option is an alias, and a number of
49 : /// flags. At runtime the driver parses the command line into
50 : /// concrete Arg instances, each of which corresponds to a
51 : /// particular Option instance.
52 : class Option {
53 : public:
54 : enum OptionClass {
55 : GroupClass = 0,
56 : InputClass,
57 : UnknownClass,
58 : FlagClass,
59 : JoinedClass,
60 : ValuesClass,
61 : SeparateClass,
62 : RemainingArgsClass,
63 : RemainingArgsJoinedClass,
64 : CommaJoinedClass,
65 : MultiArgClass,
66 : JoinedOrSeparateClass,
67 : JoinedAndSeparateClass
68 : };
69 :
70 : enum RenderStyleKind {
71 : RenderCommaJoinedStyle,
72 : RenderJoinedStyle,
73 : RenderSeparateStyle,
74 : RenderValuesStyle
75 : };
76 :
77 : protected:
78 : const OptTable::Info *Info;
79 : const OptTable *Owner;
80 :
81 : public:
82 : Option(const OptTable::Info *Info, const OptTable *Owner);
83 :
84 0 : bool isValid() const {
85 0 : return Info != nullptr;
86 : }
87 :
88 0 : unsigned getID() const {
89 : assert(Info && "Must have a valid info!");
90 112797689 : return Info->ID;
91 : }
92 :
93 0 : OptionClass getKind() const {
94 : assert(Info && "Must have a valid info!");
95 4559406 : return OptionClass(Info->Kind);
96 : }
97 :
98 : /// Get the name of this option without any prefix.
99 0 : StringRef getName() const {
100 : assert(Info && "Must have a valid info!");
101 41937 : return Info->Name;
102 : }
103 :
104 0 : const Option getGroup() const {
105 : assert(Info && "Must have a valid info!");
106 : assert(Owner && "Must have a valid owner!");
107 211646860 : return Owner->getOption(Info->GroupID);
108 : }
109 :
110 0 : const Option getAlias() const {
111 : assert(Info && "Must have a valid info!");
112 : assert(Owner && "Must have a valid owner!");
113 205859153 : return Owner->getOption(Info->AliasID);
114 : }
115 :
116 : /// Get the alias arguments as a \0 separated list.
117 : /// E.g. ["foo", "bar"] would be returned as "foo\0bar\0".
118 0 : const char *getAliasArgs() const {
119 : assert(Info && "Must have a valid info!");
120 : assert((!Info->AliasArgs || Info->AliasArgs[0] != 0) &&
121 : "AliasArgs should be either 0 or non-empty.");
122 :
123 481696 : return Info->AliasArgs;
124 : }
125 :
126 : /// Get the default prefix for this option.
127 0 : StringRef getPrefix() const {
128 0 : const char *Prefix = *Info->Prefixes;
129 0 : return Prefix ? Prefix : StringRef();
130 : }
131 :
132 : /// Get the name of this option with the default prefix.
133 810932 : std::string getPrefixedName() const {
134 810932 : std::string Ret = getPrefix();
135 810932 : Ret += getName();
136 810932 : return Ret;
137 : }
138 :
139 28 : unsigned getNumArgs() const { return Info->Param; }
140 :
141 72182 : bool hasNoOptAsInput() const { return Info->Flags & RenderAsInput;}
142 :
143 : RenderStyleKind getRenderStyle() const {
144 581236 : if (Info->Flags & RenderJoined)
145 : return RenderJoinedStyle;
146 508886 : if (Info->Flags & RenderSeparate)
147 : return RenderSeparateStyle;
148 : switch (getKind()) {
149 : case GroupClass:
150 : case InputClass:
151 : case UnknownClass:
152 : return RenderValuesStyle;
153 : case JoinedClass:
154 : case JoinedAndSeparateClass:
155 : return RenderJoinedStyle;
156 : case CommaJoinedClass:
157 : return RenderCommaJoinedStyle;
158 : case FlagClass:
159 : case ValuesClass:
160 : case SeparateClass:
161 : case MultiArgClass:
162 : case JoinedOrSeparateClass:
163 : case RemainingArgsClass:
164 : case RemainingArgsJoinedClass:
165 : return RenderSeparateStyle;
166 : }
167 0 : llvm_unreachable("Unexpected kind!");
168 : }
169 :
170 : /// Test if this option has the flag \a Val.
171 0 : bool hasFlag(unsigned Val) const {
172 4067298 : return Info->Flags & Val;
173 : }
174 :
175 : /// getUnaliasedOption - Return the final option this option
176 : /// aliases (itself, if the option has no alias).
177 6096931 : const Option getUnaliasedOption() const {
178 6096931 : const Option Alias = getAlias();
179 6096931 : if (Alias.isValid()) return Alias.getUnaliasedOption();
180 6071579 : return *this;
181 : }
182 :
183 : /// getRenderName - Return the name to use when rendering this
184 : /// option.
185 : StringRef getRenderName() const {
186 : return getUnaliasedOption().getName();
187 : }
188 :
189 : /// matches - Predicate for whether this option is part of the
190 : /// given option (which may be a group).
191 : ///
192 : /// Note that matches against options which are an alias should never be
193 : /// done -- aliases do not participate in matching and so such a query will
194 : /// always be false.
195 : bool matches(OptSpecifier ID) const;
196 :
197 : /// accept - Potentially accept the current argument, returning a
198 : /// new Arg instance, or 0 if the option does not accept this
199 : /// argument (or the argument is missing values).
200 : ///
201 : /// If the option accepts the current argument, accept() sets
202 : /// Index to the position where argument parsing should resume
203 : /// (even if the argument is missing values).
204 : ///
205 : /// \param ArgSize The number of bytes taken up by the matched Option prefix
206 : /// and name. This is used to determine where joined values
207 : /// start.
208 : Arg *accept(const ArgList &Args, unsigned &Index, unsigned ArgSize) const;
209 :
210 : void print(raw_ostream &O) const;
211 : void dump() const;
212 : };
213 :
214 : } // end namespace opt
215 :
216 : } // end namespace llvm
217 :
218 : #endif // LLVM_OPTION_OPTION_H
|