LLVM  8.0.1
Option.cpp
Go to the documentation of this file.
1 //===- Option.cpp - Abstract Driver Options -------------------------------===//
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 #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"
15 #include "llvm/Option/Option.h"
16 #include "llvm/Option/OptTable.h"
17 #include "llvm/Support/Compiler.h"
18 #include "llvm/Support/Debug.h"
21 #include <cassert>
22 #include <cstring>
23 
24 using namespace llvm;
25 using namespace llvm::opt;
26 
28  : Info(info), Owner(owner) {
29  // Multi-level aliases are not supported. This just simplifies option
30  // tracking, it is not an inherent limitation.
31  assert((!Info || !getAlias().isValid() || !getAlias().getAlias().isValid()) &&
32  "Multi-level aliases are not supported.");
33 
34  if (Info && getAliasArgs()) {
35  assert(getAlias().isValid() && "Only alias options can have alias args.");
36  assert(getKind() == FlagClass && "Only Flag aliases can have alias args.");
38  "Cannot provide alias args to a flag option.");
39  }
40 }
41 
42 void Option::print(raw_ostream &O) const {
43  O << "<";
44  switch (getKind()) {
45 #define P(N) case N: O << #N; break
46  P(GroupClass);
47  P(InputClass);
48  P(UnknownClass);
49  P(FlagClass);
50  P(JoinedClass);
51  P(ValuesClass);
59 #undef P
60  }
61 
62  if (Info->Prefixes) {
63  O << " Prefixes:[";
64  for (const char *const *Pre = Info->Prefixes; *Pre != nullptr; ++Pre) {
65  O << '"' << *Pre << (*(Pre + 1) == nullptr ? "\"" : "\", ");
66  }
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);
76  }
77 
78  const Option Alias = getAlias();
79  if (Alias.isValid()) {
80  O << " Alias:";
81  Alias.print(O);
82  }
83 
84  if (getKind() == MultiArgClass)
85  O << " NumArgs:" << getNumArgs();
86 
87  O << ">\n";
88 }
89 
90 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
92 #endif
93 
94 bool Option::matches(OptSpecifier Opt) const {
95  // Aliases are never considered in matching, look through them.
96  const Option Alias = getAlias();
97  if (Alias.isValid())
98  return Alias.matches(Opt);
99 
100  // Check exact match.
101  if (getID() == Opt.getID())
102  return true;
103 
104  const Option Group = getGroup();
105  if (Group.isValid())
106  return Group.matches(Opt);
107  return false;
108 }
109 
111  unsigned &Index,
112  unsigned ArgSize) const {
113  const Option &UnaliasedOption = getUnaliasedOption();
114  StringRef Spelling;
115  // If the option was an alias, get the spelling from the unaliased one.
116  if (getID() == UnaliasedOption.getID()) {
117  Spelling = StringRef(Args.getArgString(Index), ArgSize);
118  } else {
119  Spelling = Args.MakeArgString(Twine(UnaliasedOption.getPrefix()) +
120  Twine(UnaliasedOption.getName()));
121  }
122 
123  switch (getKind()) {
124  case FlagClass: {
125  if (ArgSize != strlen(Args.getArgString(Index)))
126  return nullptr;
127 
128  Arg *A = new Arg(UnaliasedOption, Spelling, Index++);
129  if (getAliasArgs()) {
130  const char *Val = getAliasArgs();
131  while (*Val != '\0') {
132  A->getValues().push_back(Val);
133 
134  // Move past the '\0' to the next argument.
135  Val += strlen(Val) + 1;
136  }
137  }
138 
139  if (UnaliasedOption.getKind() == JoinedClass && !getAliasArgs())
140  // A Flag alias for a Joined option must provide an argument.
141  A->getValues().push_back("");
142 
143  return A;
144  }
145  case JoinedClass: {
146  const char *Value = Args.getArgString(Index) + ArgSize;
147  return new Arg(UnaliasedOption, Spelling, Index++, Value);
148  }
149  case CommaJoinedClass: {
150  // Always matches.
151  const char *Str = Args.getArgString(Index) + ArgSize;
152  Arg *A = new Arg(UnaliasedOption, Spelling, Index++);
153 
154  // Parse out the comma separated values.
155  const char *Prev = Str;
156  for (;; ++Str) {
157  char c = *Str;
158 
159  if (!c || c == ',') {
160  if (Prev != Str) {
161  char *Value = new char[Str - Prev + 1];
162  memcpy(Value, Prev, Str - Prev);
163  Value[Str - Prev] = '\0';
164  A->getValues().push_back(Value);
165  }
166 
167  if (!c)
168  break;
169 
170  Prev = Str + 1;
171  }
172  }
173  A->setOwnsValues(true);
174 
175  return A;
176  }
177  case SeparateClass:
178  // Matches iff this is an exact match.
179  // FIXME: Avoid strlen.
180  if (ArgSize != strlen(Args.getArgString(Index)))
181  return nullptr;
182 
183  Index += 2;
184  if (Index > Args.getNumInputArgStrings() ||
185  Args.getArgString(Index - 1) == nullptr)
186  return nullptr;
187 
188  return new Arg(UnaliasedOption, Spelling,
189  Index - 2, Args.getArgString(Index - 1));
190  case MultiArgClass: {
191  // Matches iff this is an exact match.
192  // FIXME: Avoid strlen.
193  if (ArgSize != strlen(Args.getArgString(Index)))
194  return nullptr;
195 
196  Index += 1 + getNumArgs();
197  if (Index > Args.getNumInputArgStrings())
198  return nullptr;
199 
200  Arg *A = new Arg(UnaliasedOption, Spelling, Index - 1 - getNumArgs(),
201  Args.getArgString(Index - getNumArgs()));
202  for (unsigned i = 1; i != getNumArgs(); ++i)
203  A->getValues().push_back(Args.getArgString(Index - getNumArgs() + i));
204  return A;
205  }
206  case JoinedOrSeparateClass: {
207  // If this is not an exact match, it is a joined arg.
208  // FIXME: Avoid strlen.
209  if (ArgSize != strlen(Args.getArgString(Index))) {
210  const char *Value = Args.getArgString(Index) + ArgSize;
211  return new Arg(*this, Spelling, Index++, Value);
212  }
213 
214  // Otherwise it must be separate.
215  Index += 2;
216  if (Index > Args.getNumInputArgStrings() ||
217  Args.getArgString(Index - 1) == nullptr)
218  return nullptr;
219 
220  return new Arg(UnaliasedOption, Spelling,
221  Index - 2, Args.getArgString(Index - 1));
222  }
224  // Always matches.
225  Index += 2;
226  if (Index > Args.getNumInputArgStrings() ||
227  Args.getArgString(Index - 1) == nullptr)
228  return nullptr;
229 
230  return new Arg(UnaliasedOption, Spelling, Index - 2,
231  Args.getArgString(Index - 2) + ArgSize,
232  Args.getArgString(Index - 1));
233  case RemainingArgsClass: {
234  // Matches iff this is an exact match.
235  // FIXME: Avoid strlen.
236  if (ArgSize != strlen(Args.getArgString(Index)))
237  return nullptr;
238  Arg *A = new Arg(UnaliasedOption, Spelling, Index++);
239  while (Index < Args.getNumInputArgStrings() &&
240  Args.getArgString(Index) != nullptr)
241  A->getValues().push_back(Args.getArgString(Index++));
242  return A;
243  }
245  Arg *A = new Arg(UnaliasedOption, Spelling, Index);
246  if (ArgSize != strlen(Args.getArgString(Index))) {
247  // An inexact match means there is a joined arg.
248  A->getValues().push_back(Args.getArgString(Index) + ArgSize);
249  }
250  Index++;
251  while (Index < Args.getNumInputArgStrings() &&
252  Args.getArgString(Index) != nullptr)
253  A->getValues().push_back(Args.getArgString(Index++));
254  return A;
255  }
256 
257  default:
258  llvm_unreachable("Invalid option kind!");
259  }
260 }
StringRef getPrefix() const
Get the default prefix for this option.
Definition: Option.h:127
This class represents lattice values for constants.
Definition: AllocatorList.h:24
const Option getUnaliasedOption() const
getUnaliasedOption - Return the final option this option aliases (itself, if the option has no alias)...
Definition: Option.h:177
void push_back(const T &Elt)
Definition: SmallVector.h:218
void dump() const
Definition: Option.cpp:91
const OptTable::Info * Info
Definition: Option.h:78
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
unsigned getID() const
Definition: OptSpecifier.h:30
#define LLVM_DUMP_METHOD
Definition: Compiler.h:74
void print(raw_ostream &O) const
Definition: Option.cpp:42
SmallVectorImpl< const char * > & getValues()
Definition: Arg.h:100
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:21
OptionClass getKind() const
Definition: Option.h:93
#define P(N)
Option - Abstract representation for a single form of driver argument.
Definition: Option.h:52
Definition: Arg.h:27
StringRef getName() const
Get the name of this option without any prefix.
Definition: Option.h:99
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:94
A concrete instance of a particular driver option.
Definition: Arg.h:35
Provide access to the Option info table.
Definition: OptTable.h:39
const char *const * Prefixes
A null terminated array of prefix strings to apply to name while matching.
Definition: OptTable.h:45
const char * MakeArgString(const Twine &Str) const
Definition: ArgList.h:351
bool isValid() const
Definition: Option.h:84
const Option getGroup() const
Definition: Option.h:104
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:110
virtual const char * getArgString(unsigned Index) const =0
getArgString - Return the input argument string at Index.
unsigned getNumArgs() const
Definition: Option.h:139
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:133
Option(const OptTable::Info *Info, const OptTable *Owner)
Definition: Option.cpp:27
Defines the llvm::Arg class for parsed arguments.
amdgpu Simplify well known AMD library false Value Value * Arg
OptSpecifier - Wrapper class for abstracting references to option IDs.
Definition: OptSpecifier.h:19
Entry for a single option instance in the option data table.
Definition: OptTable.h:42
void setOwnsValues(bool Value) const
Definition: Arg.h:87
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
unsigned getID() const
Definition: Option.h:88
LLVM Value Representation.
Definition: Value.h:73
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:46
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
ArgList - Ordered collection of driver arguments.
Definition: ArgList.h:117
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
const char * getAliasArgs() const
Get the alias arguments as a \0 separated list.
Definition: Option.h:118
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:110