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