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