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