LLVM 24.0.0git
Option.cpp
Go to the documentation of this file.
1//===- Option.cpp - Abstract Driver Options -------------------------------===//
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
10#include "llvm/ADT/StringRef.h"
11#include "llvm/ADT/Twine.h"
12#include "llvm/Config/llvm-config.h"
13#include "llvm/Option/Arg.h"
14#include "llvm/Option/ArgList.h"
17#include "llvm/Support/Debug.h"
20#include <cassert>
21#include <cstring>
22
23using namespace llvm;
24using namespace llvm::opt;
25
27 : Info(Info), Owner(Owner) {
28 // Multi-level aliases are not supported. This just simplifies option
29 // tracking, it is not an inherent limitation.
30 assert((!Info || !getAlias().isValid() || !getAlias().getAlias().isValid()) &&
31 "Multi-level aliases are not supported.");
32
33 if (Info && hasAliasArgs()) {
34 assert(getAlias().isValid() && "Only alias options can have alias args.");
35 assert(getKind() == FlagClass && "Only Flag aliases can have alias args.");
37 "Cannot provide alias args to a flag option.");
38 }
39}
40
41void Option::print(raw_ostream &O, bool AddNewLine) const {
42 O << "<";
43 switch (getKind()) {
44#define P(N) case N: O << #N; break
48 P(FlagClass);
60#undef P
61 }
62
63 if (!Info->hasNoPrefix()) {
64 O << " Prefixes:[";
65 for (size_t I = 0, N = Info->getNumPrefixes(Owner->getPrefixesTable());
66 I != N; ++I)
67 O << '"'
68 << Info->getPrefix(Owner->getStrTable(), Owner->getPrefixesTable(), I)
69 << (I == N - 1 ? "\"" : "\", ");
70 O << ']';
71 }
72
73 O << " Name:\"" << getName() << '"';
74
75 const Option Group = getGroup();
76 if (Group.isValid()) {
77 O << " Group:";
78 Group.print(O, /*AddNewLine=*/false);
79 }
80
81 const Option Alias = getAlias();
82 if (Alias.isValid()) {
83 O << " Alias:";
84 Alias.print(O, /*AddNewLine=*/false);
85 }
86
87 if (getKind() == MultiArgClass)
88 O << " NumArgs:" << getNumArgs();
89
90 O << ">";
91 if (AddNewLine)
92 O << "\n";
93}
94
95#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
97#endif
98
100 // Aliases are never considered in matching, look through them.
101 const Option Alias = getAlias();
102 if (Alias.isValid())
103 return Alias.matches(Opt);
104
105 // Check exact match.
106 if (getID() == Opt.getID())
107 return true;
108
109 const Option Group = getGroup();
110 if (Group.isValid())
111 return Group.matches(Opt);
112 return false;
113}
114
115std::unique_ptr<Arg> Option::acceptInternal(const ArgList &Args,
116 StringRef CurArg,
117 unsigned &Index) const {
118 const size_t SpellingSize = CurArg.size();
119 const size_t ArgStringSize = StringRef(Args.getArgString(Index)).size();
120 switch (getKind()) {
121 case FlagClass: {
122 if (SpellingSize != ArgStringSize)
123 return nullptr;
124 return std::make_unique<Arg>(*this, CurArg, Index++);
125 }
126 case JoinedClass: {
127 const char *Value = Args.getArgString(Index) + SpellingSize;
128 return std::make_unique<Arg>(*this, CurArg, Index++, Value);
129 }
130 case CommaJoinedClass: {
131 // Always matches.
132 const char *Str = Args.getArgString(Index) + SpellingSize;
133 auto A = std::make_unique<Arg>(*this, CurArg, Index++);
134
135 // Parse out the comma separated values.
136 const char *Prev = Str;
137 for (;; ++Str) {
138 char c = *Str;
139
140 if (!c || c == ',') {
141 if (Prev != Str) {
142 char *Value = new char[Str - Prev + 1];
143 memcpy(Value, Prev, Str - Prev);
144 Value[Str - Prev] = '\0';
145 A->getValues().push_back(Value);
146 }
147
148 if (!c)
149 break;
150
151 Prev = Str + 1;
152 }
153 }
154 A->setOwnsValues(true);
155
156 return A;
157 }
158 case SeparateClass:
159 // Matches iff this is an exact match.
160 if (SpellingSize != ArgStringSize)
161 return nullptr;
162
163 Index += 2;
164 if (Index > Args.getNumInputArgStrings() ||
165 Args.getArgString(Index - 1) == nullptr)
166 return nullptr;
167
168 return std::make_unique<Arg>(*this, CurArg, Index - 2,
169 Args.getArgString(Index - 1));
170 case MultiArgClass: {
171 // Matches iff this is an exact match.
172 if (SpellingSize != ArgStringSize)
173 return nullptr;
174
175 Index += 1 + getNumArgs();
176 if (Index > Args.getNumInputArgStrings())
177 return nullptr;
178
179 auto A = std::make_unique<Arg>(*this, CurArg, Index - 1 - getNumArgs(),
180 Args.getArgString(Index - getNumArgs()));
181 for (unsigned i = 1; i != getNumArgs(); ++i)
182 A->getValues().push_back(Args.getArgString(Index - getNumArgs() + i));
183 return A;
184 }
186 // If this is not an exact match, it is a joined arg.
187 if (SpellingSize != ArgStringSize) {
188 const char *Value = Args.getArgString(Index) + SpellingSize;
189 return std::make_unique<Arg>(*this, CurArg, Index++, Value);
190 }
191
192 // Otherwise it must be separate.
193 Index += 2;
194 if (Index > Args.getNumInputArgStrings() ||
195 Args.getArgString(Index - 1) == nullptr)
196 return nullptr;
197
198 return std::make_unique<Arg>(*this, CurArg, Index - 2,
199 Args.getArgString(Index - 1));
200 }
202 // Always matches.
203 Index += 2;
204 if (Index > Args.getNumInputArgStrings() ||
205 Args.getArgString(Index - 1) == nullptr)
206 return nullptr;
207
208 return std::make_unique<Arg>(*this, CurArg, Index - 2,
209 Args.getArgString(Index - 2) + SpellingSize,
210 Args.getArgString(Index - 1));
211 case RemainingArgsClass: {
212 // Matches iff this is an exact match.
213 if (SpellingSize != ArgStringSize)
214 return nullptr;
215 auto A = std::make_unique<Arg>(*this, CurArg, Index++);
216 while (Index < Args.getNumInputArgStrings() &&
217 Args.getArgString(Index) != nullptr)
218 A->getValues().push_back(Args.getArgString(Index++));
219 return A;
220 }
221 case FlagOrEqClass:
222 case SeparateOrEqClass: {
223 const char *Rest = Args.getArgString(Index) + SpellingSize;
224 if (*Rest == '=')
225 return std::make_unique<Arg>(*this, CurArg, Index++, Rest + 1);
226 if (*Rest)
227 return nullptr;
228 if (getKind() == FlagOrEqClass)
229 return std::make_unique<Arg>(*this, CurArg, Index++);
230
231 Index += 2;
232 if (Index > Args.getNumInputArgStrings() ||
233 Args.getArgString(Index - 1) == nullptr)
234 return nullptr;
235 return std::make_unique<Arg>(*this, CurArg, Index - 2,
236 Args.getArgString(Index - 1));
237 }
239 auto A = std::make_unique<Arg>(*this, CurArg, Index);
240 if (SpellingSize != ArgStringSize) {
241 // An inexact match means there is a joined arg.
242 A->getValues().push_back(Args.getArgString(Index) + SpellingSize);
243 }
244 Index++;
245 while (Index < Args.getNumInputArgStrings() &&
246 Args.getArgString(Index) != nullptr)
247 A->getValues().push_back(Args.getArgString(Index++));
248 return A;
249 }
250
251 default:
252 llvm_unreachable("Invalid option kind!");
253 }
254}
255
256std::unique_ptr<Arg> Option::accept(const ArgList &Args, StringRef CurArg,
257 bool GroupedShortOption,
258 unsigned &Index) const {
259 auto A(GroupedShortOption && getKind() == FlagClass
260 ? std::make_unique<Arg>(*this, CurArg, Index)
261 : acceptInternal(Args, CurArg, Index));
262 if (!A)
263 return nullptr;
264
265 const Option &UnaliasedOption = getUnaliasedOption();
266 if (getID() == UnaliasedOption.getID())
267 return A;
268
269 // "A" is an alias for a different flag. For most clients it's more convenient
270 // if this function returns unaliased Args, so create an unaliased arg for
271 // returning.
272
273 // This creates a completely new Arg object for the unaliased Arg because
274 // the alias and the unaliased arg can have different Kinds and different
275 // Values (due to AliasArgs<>).
276
277 // Get the spelling from the unaliased option.
278 StringRef UnaliasedSpelling = Args.MakeArgString(
279 Twine(UnaliasedOption.getPrefix()) + Twine(UnaliasedOption.getName()));
280
281 // It's a bit weird that aliased and unaliased arg share one index, but
282 // the index is mostly use as a memory optimization in render().
283 // Due to this, ArgList::getArgString(A->getIndex()) will return the spelling
284 // of the aliased arg always, while A->getSpelling() returns either the
285 // unaliased or the aliased arg, depending on which Arg object it's called on.
286 auto UnaliasedA =
287 std::make_unique<Arg>(UnaliasedOption, UnaliasedSpelling, A->getIndex());
288 Arg *RawA = A.get();
289 UnaliasedA->setAlias(std::move(A));
290
291 if (getKind() != FlagClass) {
292 // Values are usually owned by the ArgList. The exception are
293 // CommaJoined flags, where the Arg owns the values. For aliased flags,
294 // make the unaliased Arg the owner of the values.
295 // FIXME: There aren't many uses of CommaJoined -- try removing
296 // CommaJoined in favor of just calling StringRef::split(',') instead.
297 UnaliasedA->getValues() = RawA->getValues();
298 UnaliasedA->setOwnsValues(RawA->getOwnsValues());
299 RawA->setOwnsValues(false);
300 return UnaliasedA;
301 }
302
303 // FlagClass aliases can have AliasArgs<>; add those to the unaliased arg.
304 for (const char *Val = getAliasArgs(); *Val; Val += strlen(Val) + 1)
305 UnaliasedA->getValues().push_back(Val);
306 if (UnaliasedOption.getKind() == JoinedClass && !hasAliasArgs())
307 // A Flag alias for a Joined option must provide an argument.
308 UnaliasedA->getValues().push_back("");
309 return UnaliasedA;
310}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Defines the llvm::Arg class for parsed arguments.
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Definition Compiler.h:686
#define I(x, y, z)
Definition MD5.cpp:57
#define P(N)
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
constexpr size_t size() const
Get the string size.
Definition StringRef.h:144
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
LLVM Value Representation.
Definition Value.h:75
ArgList - Ordered collection of driver arguments.
Definition ArgList.h:118
A concrete instance of a particular driver option.
Definition Arg.h:35
bool getOwnsValues() const
Definition Arg.h:112
SmallVectorImpl< const char * > & getValues()
Definition Arg.h:131
void setOwnsValues(bool Value) const
Definition Arg.h:113
OptSpecifier - Wrapper class for abstracting references to option IDs.
unsigned getID() const
Provide access to the Option info table.
Definition OptTable.h:55
const Option getAlias() const
Definition Option.h:114
LLVM_ABI void dump() const
Definition Option.cpp:96
unsigned getNumArgs() const
Definition Option.h:142
const char * getAliasArgs() const
Get the alias arguments as a \0 separated list.
Definition Option.h:122
const Option getGroup() const
Definition Option.h:108
const OptTable * Owner
Definition Option.h:85
const Option getUnaliasedOption() const
getUnaliasedOption - Return the final option this option aliases (itself, if the option has no alias)...
Definition Option.h:188
LLVM_ABI bool matches(OptSpecifier ID) const
matches - Predicate for whether this option is part of the given option (which may be a group).
Definition Option.cpp:99
LLVM_ABI Option(const OptTable::Info *Info, const OptTable *Owner)
Definition Option.cpp:26
@ JoinedOrSeparateClass
Definition Option.h:71
@ JoinedAndSeparateClass
Definition Option.h:72
@ RemainingArgsJoinedClass
Definition Option.h:68
bool hasAliasArgs() const
Definition Option.h:126
StringRef getPrefix() const
Get the default prefix for this option.
Definition Option.h:129
const OptTable::Info * Info
Definition Option.h:84
bool isValid() const
Definition Option.h:90
unsigned getID() const
Definition Option.h:94
StringRef getName() const
Get the name of this option without any prefix.
Definition Option.h:106
LLVM_ABI std::unique_ptr< Arg > accept(const ArgList &Args, StringRef CurArg, bool GroupedShortOption, unsigned &Index) const
Potentially accept the current argument, returning a new Arg instance, or 0 if the option does not ac...
Definition Option.cpp:256
OptionClass getKind() const
Definition Option.h:100
LLVM_ABI void print(raw_ostream &O, bool AddNewLine=true) const
Definition Option.cpp:41
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
This is an optimization pass for GlobalISel generic memory operations.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
#define N
Entry for a single option instance in the option data table.
Definition OptTable.h:96