LLVM API Documentation

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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"
16 #include <algorithm>
17 #include <cassert>
18 
19 using namespace llvm;
20 using namespace llvm::opt;
21 
23  : Info(info), Owner(owner) {
24 
25  // Multi-level aliases are not supported. This just simplifies option
26  // tracking, it is not an inherent limitation.
27  assert((!Info || !getAlias().isValid() || !getAlias().getAlias().isValid()) &&
28  "Multi-level aliases are not supported.");
29 
30  if (Info && getAliasArgs()) {
31  assert(getAlias().isValid() && "Only alias options can have alias args.");
32  assert(getKind() == FlagClass && "Only Flag aliases can have alias args.");
33  assert(getAlias().getKind() != FlagClass &&
34  "Cannot provide alias args to a flag option.");
35  }
36 }
37 
39 }
40 
41 void Option::dump() const {
42  llvm::errs() << "<";
43  switch (getKind()) {
44 #define P(N) case N: llvm::errs() << #N; break
45  P(GroupClass);
46  P(InputClass);
47  P(UnknownClass);
48  P(FlagClass);
49  P(JoinedClass);
56 #undef P
57  }
58 
59  if (Info->Prefixes) {
60  llvm::errs() << " Prefixes:[";
61  for (const char * const *Pre = Info->Prefixes; *Pre != 0; ++Pre) {
62  llvm::errs() << '"' << *Pre << (*(Pre + 1) == 0 ? "\"" : "\", ");
63  }
64  llvm::errs() << ']';
65  }
66 
67  llvm::errs() << " Name:\"" << getName() << '"';
68 
69  const Option Group = getGroup();
70  if (Group.isValid()) {
71  llvm::errs() << " Group:";
72  Group.dump();
73  }
74 
75  const Option Alias = getAlias();
76  if (Alias.isValid()) {
77  llvm::errs() << " Alias:";
78  Alias.dump();
79  }
80 
81  if (getKind() == MultiArgClass)
82  llvm::errs() << " NumArgs:" << getNumArgs();
83 
84  llvm::errs() << ">\n";
85 }
86 
87 bool Option::matches(OptSpecifier Opt) const {
88  // Aliases are never considered in matching, look through them.
89  const Option Alias = getAlias();
90  if (Alias.isValid())
91  return Alias.matches(Opt);
92 
93  // Check exact match.
94  if (getID() == Opt.getID())
95  return true;
96 
97  const Option Group = getGroup();
98  if (Group.isValid())
99  return Group.matches(Opt);
100  return false;
101 }
102 
104  unsigned &Index,
105  unsigned ArgSize) const {
106  const Option &UnaliasedOption = getUnaliasedOption();
107  StringRef Spelling;
108  // If the option was an alias, get the spelling from the unaliased one.
109  if (getID() == UnaliasedOption.getID()) {
110  Spelling = StringRef(Args.getArgString(Index), ArgSize);
111  } else {
112  Spelling = Args.MakeArgString(Twine(UnaliasedOption.getPrefix()) +
113  Twine(UnaliasedOption.getName()));
114  }
115 
116  switch (getKind()) {
117  case FlagClass: {
118  if (ArgSize != strlen(Args.getArgString(Index)))
119  return 0;
120 
121  Arg *A = new Arg(UnaliasedOption, Spelling, Index++);
122  if (getAliasArgs()) {
123  const char *Val = getAliasArgs();
124  while (*Val != '\0') {
125  A->getValues().push_back(Val);
126 
127  // Move past the '\0' to the next argument.
128  Val += strlen(Val) + 1;
129  }
130  }
131  return A;
132  }
133  case JoinedClass: {
134  const char *Value = Args.getArgString(Index) + ArgSize;
135  return new Arg(UnaliasedOption, Spelling, Index++, Value);
136  }
137  case CommaJoinedClass: {
138  // Always matches.
139  const char *Str = Args.getArgString(Index) + ArgSize;
140  Arg *A = new Arg(UnaliasedOption, Spelling, Index++);
141 
142  // Parse out the comma separated values.
143  const char *Prev = Str;
144  for (;; ++Str) {
145  char c = *Str;
146 
147  if (!c || c == ',') {
148  if (Prev != Str) {
149  char *Value = new char[Str - Prev + 1];
150  memcpy(Value, Prev, Str - Prev);
151  Value[Str - Prev] = '\0';
152  A->getValues().push_back(Value);
153  }
154 
155  if (!c)
156  break;
157 
158  Prev = Str + 1;
159  }
160  }
161  A->setOwnsValues(true);
162 
163  return A;
164  }
165  case SeparateClass:
166  // Matches iff this is an exact match.
167  // FIXME: Avoid strlen.
168  if (ArgSize != strlen(Args.getArgString(Index)))
169  return 0;
170 
171  Index += 2;
172  if (Index > Args.getNumInputArgStrings())
173  return 0;
174 
175  return new Arg(UnaliasedOption, Spelling,
176  Index - 2, Args.getArgString(Index - 1));
177  case MultiArgClass: {
178  // Matches iff this is an exact match.
179  // FIXME: Avoid strlen.
180  if (ArgSize != strlen(Args.getArgString(Index)))
181  return 0;
182 
183  Index += 1 + getNumArgs();
184  if (Index > Args.getNumInputArgStrings())
185  return 0;
186 
187  Arg *A = new Arg(UnaliasedOption, Spelling, Index - 1 - getNumArgs(),
188  Args.getArgString(Index - getNumArgs()));
189  for (unsigned i = 1; i != getNumArgs(); ++i)
190  A->getValues().push_back(Args.getArgString(Index - getNumArgs() + i));
191  return A;
192  }
193  case JoinedOrSeparateClass: {
194  // If this is not an exact match, it is a joined arg.
195  // FIXME: Avoid strlen.
196  if (ArgSize != strlen(Args.getArgString(Index))) {
197  const char *Value = Args.getArgString(Index) + ArgSize;
198  return new Arg(*this, Spelling, Index++, Value);
199  }
200 
201  // Otherwise it must be separate.
202  Index += 2;
203  if (Index > Args.getNumInputArgStrings())
204  return 0;
205 
206  return new Arg(UnaliasedOption, Spelling,
207  Index - 2, Args.getArgString(Index - 1));
208  }
210  // Always matches.
211  Index += 2;
212  if (Index > Args.getNumInputArgStrings())
213  return 0;
214 
215  return new Arg(UnaliasedOption, Spelling, Index - 2,
216  Args.getArgString(Index - 2) + ArgSize,
217  Args.getArgString(Index - 1));
218  case RemainingArgsClass: {
219  // Matches iff this is an exact match.
220  // FIXME: Avoid strlen.
221  if (ArgSize != strlen(Args.getArgString(Index)))
222  return 0;
223  Arg *A = new Arg(UnaliasedOption, Spelling, Index++);
224  while (Index < Args.getNumInputArgStrings())
225  A->getValues().push_back(Args.getArgString(Index++));
226  return A;
227  }
228  default:
229  llvm_unreachable("Invalid option kind!");
230  }
231 }
void push_back(const T &Elt)
Definition: SmallVector.h:236
void dump() const
Definition: Option.cpp:41
bool matches(OptSpecifier ID) const
Definition: Option.cpp:87
raw_ostream & errs()
StringRef getName() const
Get the name of this option without any prefix.
Definition: Option.h:90
virtual const char * MakeArgString(StringRef Str) const =0
const OptTable::Info * Info
Definition: Option.h:68
const Option getAlias() const
Definition: Option.h:101
OptionClass getKind() const
Definition: Option.h:84
unsigned getID() const
Definition: Option.h:79
lazy value info
#define llvm_unreachable(msg)
const Option getGroup() const
Definition: Option.h:95
virtual unsigned getNumInputArgStrings() const =0
unsigned getNumArgs() const
Definition: Option.h:130
#define P(N)
A concrete instance of a particular driver option.
Definition: Arg.h:34
Provide access to the Option info table.
Definition: OptTable.h:31
const char *const * Prefixes
Definition: OptTable.h:37
StringRef getPrefix() const
Get the default prefix for this option.
Definition: Option.h:118
unsigned getID() const
Definition: OptSpecifier.h:31
virtual const char * getArgString(unsigned Index) const =0
getArgString - Return the input argument string at Index.
bool isValid() const
Definition: Option.h:75
size_t strlen(const char *s);
Option(const OptTable::Info *Info, const OptTable *Owner)
Definition: Option.cpp:22
Defines the llvm::Arg class for parsed arguments.
void setOwnsValues(bool Value) const
Definition: Arg.h:89
const Option getUnaliasedOption() const
Definition: Option.h:166
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:34
const char * getAliasArgs() const
Get the alias arguments as a \0 separated list. E.g. ["foo", "bar"] would be returned as "foo\0bar\0"...
Definition: Option.h:109
LLVM Value Representation.
Definition: Value.h:66
Arg * accept(const ArgList &Args, unsigned &Index, unsigned ArgSize) const
Definition: Option.cpp:103
SmallVectorImpl< const char * > & getValues()
Definition: Arg.h:101