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);
58#undef P
59 }
60
61 if (!Info->hasNoPrefix()) {
62 O << " Prefixes:[";
63 for (size_t I = 0, N = Info->getNumPrefixes(Owner->getPrefixesTable());
64 I != N; ++I)
65 O << '"'
66 << Info->getPrefix(Owner->getStrTable(), Owner->getPrefixesTable(), I)
67 << (I == N - 1 ? "\"" : "\", ");
68 O << ']';
69 }
70
71 O << " Name:\"" << getName() << '"';
72
73 const Option Group = getGroup();
74 if (Group.isValid()) {
75 O << " Group:";
76 Group.print(O, /*AddNewLine=*/false);
77 }
78
79 const Option Alias = getAlias();
80 if (Alias.isValid()) {
81 O << " Alias:";
82 Alias.print(O, /*AddNewLine=*/false);
83 }
84
85 if (getKind() == MultiArgClass)
86 O << " NumArgs:" << getNumArgs();
87
88 O << ">";
89 if (AddNewLine)
90 O << "\n";
91}
92
93#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
95#endif
96
98 // Aliases are never considered in matching, look through them.
99 const Option Alias = getAlias();
100 if (Alias.isValid())
101 return Alias.matches(Opt);
102
103 // Check exact match.
104 if (getID() == Opt.getID())
105 return true;
106
107 const Option Group = getGroup();
108 if (Group.isValid())
109 return Group.matches(Opt);
110 return false;
111}
112
113std::unique_ptr<Arg> Option::acceptInternal(const ArgList &Args,
114 StringRef CurArg,
115 unsigned &Index) const {
116 const size_t SpellingSize = CurArg.size();
117 const size_t ArgStringSize = StringRef(Args.getArgString(Index)).size();
118 switch (getKind()) {
119 case FlagClass: {
120 if (SpellingSize != ArgStringSize)
121 return nullptr;
122 return std::make_unique<Arg>(*this, CurArg, Index++);
123 }
124 case JoinedClass: {
125 const char *Value = Args.getArgString(Index) + SpellingSize;
126 return std::make_unique<Arg>(*this, CurArg, Index++, Value);
127 }
128 case CommaJoinedClass: {
129 // Always matches.
130 const char *Str = Args.getArgString(Index) + SpellingSize;
131 auto A = std::make_unique<Arg>(*this, CurArg, Index++);
132
133 // Parse out the comma separated values.
134 const char *Prev = Str;
135 for (;; ++Str) {
136 char c = *Str;
137
138 if (!c || c == ',') {
139 if (Prev != Str) {
140 char *Value = new char[Str - Prev + 1];
141 memcpy(Value, Prev, Str - Prev);
142 Value[Str - Prev] = '\0';
143 A->getValues().push_back(Value);
144 }
145
146 if (!c)
147 break;
148
149 Prev = Str + 1;
150 }
151 }
152 A->setOwnsValues(true);
153
154 return A;
155 }
156 case SeparateClass:
157 // Matches iff this is an exact match.
158 if (SpellingSize != ArgStringSize)
159 return nullptr;
160
161 Index += 2;
162 if (Index > Args.getNumInputArgStrings() ||
163 Args.getArgString(Index - 1) == nullptr)
164 return nullptr;
165
166 return std::make_unique<Arg>(*this, CurArg, Index - 2,
167 Args.getArgString(Index - 1));
168 case MultiArgClass: {
169 // Matches iff this is an exact match.
170 if (SpellingSize != ArgStringSize)
171 return nullptr;
172
173 Index += 1 + getNumArgs();
174 if (Index > Args.getNumInputArgStrings())
175 return nullptr;
176
177 auto A = std::make_unique<Arg>(*this, CurArg, Index - 1 - getNumArgs(),
178 Args.getArgString(Index - getNumArgs()));
179 for (unsigned i = 1; i != getNumArgs(); ++i)
180 A->getValues().push_back(Args.getArgString(Index - getNumArgs() + i));
181 return A;
182 }
184 // If this is not an exact match, it is a joined arg.
185 if (SpellingSize != ArgStringSize) {
186 const char *Value = Args.getArgString(Index) + SpellingSize;
187 return std::make_unique<Arg>(*this, CurArg, Index++, Value);
188 }
189
190 // Otherwise it must be separate.
191 Index += 2;
192 if (Index > Args.getNumInputArgStrings() ||
193 Args.getArgString(Index - 1) == nullptr)
194 return nullptr;
195
196 return std::make_unique<Arg>(*this, CurArg, Index - 2,
197 Args.getArgString(Index - 1));
198 }
200 // Always matches.
201 Index += 2;
202 if (Index > Args.getNumInputArgStrings() ||
203 Args.getArgString(Index - 1) == nullptr)
204 return nullptr;
205
206 return std::make_unique<Arg>(*this, CurArg, Index - 2,
207 Args.getArgString(Index - 2) + SpellingSize,
208 Args.getArgString(Index - 1));
209 case RemainingArgsClass: {
210 // Matches iff this is an exact match.
211 if (SpellingSize != ArgStringSize)
212 return nullptr;
213 auto A = std::make_unique<Arg>(*this, CurArg, Index++);
214 while (Index < Args.getNumInputArgStrings() &&
215 Args.getArgString(Index) != nullptr)
216 A->getValues().push_back(Args.getArgString(Index++));
217 return A;
218 }
220 auto A = std::make_unique<Arg>(*this, CurArg, Index);
221 if (SpellingSize != ArgStringSize) {
222 // An inexact match means there is a joined arg.
223 A->getValues().push_back(Args.getArgString(Index) + SpellingSize);
224 }
225 Index++;
226 while (Index < Args.getNumInputArgStrings() &&
227 Args.getArgString(Index) != nullptr)
228 A->getValues().push_back(Args.getArgString(Index++));
229 return A;
230 }
231
232 default:
233 llvm_unreachable("Invalid option kind!");
234 }
235}
236
237std::unique_ptr<Arg> Option::accept(const ArgList &Args, StringRef CurArg,
238 bool GroupedShortOption,
239 unsigned &Index) const {
240 auto A(GroupedShortOption && getKind() == FlagClass
241 ? std::make_unique<Arg>(*this, CurArg, Index)
242 : acceptInternal(Args, CurArg, Index));
243 if (!A)
244 return nullptr;
245
246 const Option &UnaliasedOption = getUnaliasedOption();
247 if (getID() == UnaliasedOption.getID())
248 return A;
249
250 // "A" is an alias for a different flag. For most clients it's more convenient
251 // if this function returns unaliased Args, so create an unaliased arg for
252 // returning.
253
254 // This creates a completely new Arg object for the unaliased Arg because
255 // the alias and the unaliased arg can have different Kinds and different
256 // Values (due to AliasArgs<>).
257
258 // Get the spelling from the unaliased option.
259 StringRef UnaliasedSpelling = Args.MakeArgString(
260 Twine(UnaliasedOption.getPrefix()) + Twine(UnaliasedOption.getName()));
261
262 // It's a bit weird that aliased and unaliased arg share one index, but
263 // the index is mostly use as a memory optimization in render().
264 // Due to this, ArgList::getArgString(A->getIndex()) will return the spelling
265 // of the aliased arg always, while A->getSpelling() returns either the
266 // unaliased or the aliased arg, depending on which Arg object it's called on.
267 auto UnaliasedA =
268 std::make_unique<Arg>(UnaliasedOption, UnaliasedSpelling, A->getIndex());
269 Arg *RawA = A.get();
270 UnaliasedA->setAlias(std::move(A));
271
272 if (getKind() != FlagClass) {
273 // Values are usually owned by the ArgList. The exception are
274 // CommaJoined flags, where the Arg owns the values. For aliased flags,
275 // make the unaliased Arg the owner of the values.
276 // FIXME: There aren't many uses of CommaJoined -- try removing
277 // CommaJoined in favor of just calling StringRef::split(',') instead.
278 UnaliasedA->getValues() = RawA->getValues();
279 UnaliasedA->setOwnsValues(RawA->getOwnsValues());
280 RawA->setOwnsValues(false);
281 return UnaliasedA;
282 }
283
284 // FlagClass aliases can have AliasArgs<>; add those to the unaliased arg.
285 for (const char *Val = getAliasArgs(); *Val; Val += strlen(Val) + 1)
286 UnaliasedA->getValues().push_back(Val);
287 if (UnaliasedOption.getKind() == JoinedClass && !hasAliasArgs())
288 // A Flag alias for a Joined option must provide an argument.
289 UnaliasedA->getValues().push_back("");
290 return UnaliasedA;
291}
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:678
#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:54
const Option getAlias() const
Definition Option.h:114
LLVM_ABI void dump() const
Definition Option.cpp:94
unsigned getNumArgs() const
Definition Option.h:161
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:82
const Option getUnaliasedOption() const
getUnaliasedOption - Return the final option this option aliases (itself, if the option has no alias)...
Definition Option.h:204
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:97
LLVM_ABI Option(const OptTable::Info *Info, const OptTable *Owner)
Definition Option.cpp:26
@ JoinedOrSeparateClass
Definition Option.h:69
@ JoinedAndSeparateClass
Definition Option.h:70
@ RemainingArgsJoinedClass
Definition Option.h:66
bool hasAliasArgs() const
Definition Option.h:128
StringRef getPrefix() const
Get the default prefix for this option.
Definition Option.h:134
const OptTable::Info * Info
Definition Option.h:81
bool isValid() const
Definition Option.h:87
unsigned getID() const
Definition Option.h:91
StringRef getName() const
Get the name of this option without any prefix.
Definition Option.h:102
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:237
OptionClass getKind() const
Definition Option.h:96
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:69