LLVM  14.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 
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 std::unique_ptr<Arg> Option::acceptInternal(const ArgList &Args,
110  StringRef Spelling,
111  unsigned &Index) const {
112  size_t ArgSize = Spelling.size();
113  switch (getKind()) {
114  case FlagClass: {
115  if (ArgSize != strlen(Args.getArgString(Index)))
116  return nullptr;
117  return std::make_unique<Arg>(*this, Spelling, Index++);
118  }
119  case JoinedClass: {
120  const char *Value = Args.getArgString(Index) + ArgSize;
121  return std::make_unique<Arg>(*this, Spelling, Index++, Value);
122  }
123  case CommaJoinedClass: {
124  // Always matches.
125  const char *Str = Args.getArgString(Index) + ArgSize;
126  auto A = std::make_unique<Arg>(*this, Spelling, Index++);
127 
128  // Parse out the comma separated values.
129  const char *Prev = Str;
130  for (;; ++Str) {
131  char c = *Str;
132 
133  if (!c || c == ',') {
134  if (Prev != Str) {
135  char *Value = new char[Str - Prev + 1];
136  memcpy(Value, Prev, Str - Prev);
137  Value[Str - Prev] = '\0';
138  A->getValues().push_back(Value);
139  }
140 
141  if (!c)
142  break;
143 
144  Prev = Str + 1;
145  }
146  }
147  A->setOwnsValues(true);
148 
149  return A;
150  }
151  case SeparateClass:
152  // Matches iff this is an exact match.
153  // FIXME: Avoid strlen.
154  if (ArgSize != strlen(Args.getArgString(Index)))
155  return nullptr;
156 
157  Index += 2;
158  if (Index > Args.getNumInputArgStrings() ||
159  Args.getArgString(Index - 1) == nullptr)
160  return nullptr;
161 
162  return std::make_unique<Arg>(*this, Spelling, Index - 2,
163  Args.getArgString(Index - 1));
164  case MultiArgClass: {
165  // Matches iff this is an exact match.
166  // FIXME: Avoid strlen.
167  if (ArgSize != strlen(Args.getArgString(Index)))
168  return nullptr;
169 
170  Index += 1 + getNumArgs();
171  if (Index > Args.getNumInputArgStrings())
172  return nullptr;
173 
174  auto A = std::make_unique<Arg>(*this, Spelling, Index - 1 - getNumArgs(),
175  Args.getArgString(Index - getNumArgs()));
176  for (unsigned i = 1; i != getNumArgs(); ++i)
177  A->getValues().push_back(Args.getArgString(Index - getNumArgs() + i));
178  return A;
179  }
180  case JoinedOrSeparateClass: {
181  // If this is not an exact match, it is a joined arg.
182  // FIXME: Avoid strlen.
183  if (ArgSize != strlen(Args.getArgString(Index))) {
184  const char *Value = Args.getArgString(Index) + ArgSize;
185  return std::make_unique<Arg>(*this, Spelling, Index++, Value);
186  }
187 
188  // Otherwise it must be separate.
189  Index += 2;
190  if (Index > Args.getNumInputArgStrings() ||
191  Args.getArgString(Index - 1) == nullptr)
192  return nullptr;
193 
194  return std::make_unique<Arg>(*this, Spelling, Index - 2,
195  Args.getArgString(Index - 1));
196  }
198  // Always matches.
199  Index += 2;
200  if (Index > Args.getNumInputArgStrings() ||
201  Args.getArgString(Index - 1) == nullptr)
202  return nullptr;
203 
204  return std::make_unique<Arg>(*this, Spelling, Index - 2,
205  Args.getArgString(Index - 2) + ArgSize,
206  Args.getArgString(Index - 1));
207  case RemainingArgsClass: {
208  // Matches iff this is an exact match.
209  // FIXME: Avoid strlen.
210  if (ArgSize != strlen(Args.getArgString(Index)))
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 (ArgSize != strlen(Args.getArgString(Index))) {
221  // An inexact match means there is a joined arg.
222  A->getValues().push_back(Args.getArgString(Index) + ArgSize);
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 
236 std::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 }
llvm::opt::Option::dump
void dump() const
Definition: Option.cpp:90
i
i
Definition: README.txt:29
llvm::opt::OptTable
Provide access to the Option info table.
Definition: OptTable.h:40
Option.h
llvm::opt::Option::Option
Option(const OptTable::Info *Info, const OptTable *Owner)
Definition: Option.cpp:26
LLVM_DUMP_METHOD
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Definition: Compiler.h:506
llvm
This file implements support for optimizing divisions by a constant.
Definition: AllocatorList.h:23
llvm::opt::Option::MultiArgClass
@ MultiArgClass
Definition: Option.h:64
llvm::opt::Arg
A concrete instance of a particular driver option.
Definition: Arg.h:34
llvm::opt::Option::CommaJoinedClass
@ CommaJoinedClass
Definition: Option.h:63
StringRef.h
llvm::opt::ArgList
ArgList - Ordered collection of driver arguments.
Definition: ArgList.h:116
ErrorHandling.h
llvm::opt::Option::getUnaliasedOption
const Option getUnaliasedOption() const
getUnaliasedOption - Return the final option this option aliases (itself, if the option has no alias)...
Definition: Option.h:188
llvm::opt::Option::Info
const OptTable::Info * Info
Definition: Option.h:77
llvm::opt::Option::InputClass
@ InputClass
Definition: Option.h:55
llvm::opt::Option::accept
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
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
llvm::opt::Option::getAliasArgs
const char * getAliasArgs() const
Get the alias arguments as a \0 separated list.
Definition: Option.h:117
llvm::opt::Arg::getValues
SmallVectorImpl< const char * > & getValues()
Definition: Arg.h:117
llvm::opt::Arg::setOwnsValues
void setOwnsValues(bool Value) const
Definition: Arg.h:104
llvm::ARM_PROC::A
@ A
Definition: ARMBaseInfo.h:34
Twine.h
llvm::opt::Option::RemainingArgsJoinedClass
@ RemainingArgsJoinedClass
Definition: Option.h:62
llvm::opt::Option::getID
unsigned getID() const
Definition: Option.h:87
llvm::opt::Option::matches
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
llvm::opt::Arg::getOwnsValues
bool getOwnsValues() const
Definition: Arg.h:103
llvm::opt
Definition: Arg.h:26
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
llvm::opt::Option::SeparateClass
@ SeparateClass
Definition: Option.h:60
llvm::opt::Option::JoinedAndSeparateClass
@ JoinedAndSeparateClass
Definition: Option.h:66
Info
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
c
the resulting code requires compare and branches when and if the revised code is with conditional branches instead of More there is a byte word extend before each where there should be only and the condition codes are not remembered when the same two values are compared twice More LSR enhancements i8 and i32 load store addressing modes are identical int int c
Definition: README.txt:418
llvm::opt::Option::print
void print(raw_ostream &O) const
Definition: Option.cpp:41
llvm::opt::OptSpecifier
OptSpecifier - Wrapper class for abstracting references to option IDs.
Definition: OptSpecifier.h:18
llvm::opt::Option::UnknownClass
@ UnknownClass
Definition: Option.h:56
llvm::opt::Option::getKind
OptionClass getKind() const
Definition: Option.h:92
llvm::RISCVFenceField::O
@ O
Definition: RISCVBaseInfo.h:197
Index
uint32_t Index
Definition: ELFObjHandler.cpp:84
OptTable.h
llvm::opt::Option::getName
StringRef getName() const
Get the name of this option without any prefix.
Definition: Option.h:98
move
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Definition: README.txt:546
llvm::opt::Option::getPrefix
StringRef getPrefix() const
Get the default prefix for this option.
Definition: Option.h:126
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::opt::Option::isValid
bool isValid() const
Definition: Option.h:83
memcpy
<%struct.s * > cast struct s *S to sbyte *< sbyte * > sbyte uint cast struct s *agg result to sbyte *< sbyte * > sbyte uint cast struct s *memtmp to sbyte *< sbyte * > sbyte uint ret void llc ends up issuing two memcpy or custom lower memcpy(of small size) to be ldmia/stmia. I think option 2 is better but the current register allocator cannot allocate a chunk of registers at a time. A feasible temporary solution is to use specific physical registers at the lowering time for small(<
llvm::opt::Option::ValuesClass
@ ValuesClass
Definition: Option.h:59
llvm::opt::Option::getNumArgs
unsigned getNumArgs() const
Definition: Option.h:150
llvm::opt::Option::GroupClass
@ GroupClass
Definition: Option.h:54
info
lazy value info
Definition: LazyValueInfo.cpp:59
Arg.h
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:134
llvm::opt::Option::RemainingArgsClass
@ RemainingArgsClass
Definition: Option.h:61
Compiler.h
llvm::opt::OptTable::Info::Prefixes
const char *const * Prefixes
A null terminated array of prefix strings to apply to name while matching.
Definition: OptTable.h:46
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:83
ArgList.h
llvm::opt::Option
Option - Abstract representation for a single form of driver argument.
Definition: Option.h:51
llvm::opt::Option::JoinedOrSeparateClass
@ JoinedOrSeparateClass
Definition: Option.h:65
llvm::opt::Option::FlagClass
@ FlagClass
Definition: Option.h:57
llvm::opt::Option::getGroup
const Option getGroup() const
Definition: Option.h:103
P
#define P(N)
llvm::opt::OptTable::Info
Entry for a single option instance in the option data table.
Definition: OptTable.h:43
llvm::AMDGPU::HSAMD::Kernel::Key::Args
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
Definition: AMDGPUMetadata.h:389
llvm::opt::Option::getAlias
const Option getAlias() const
Definition: Option.h:109
raw_ostream.h
llvm::StringRef::size
LLVM_NODISCARD size_t size() const
size - Get the string size.
Definition: StringRef.h:157
llvm::opt::Option::JoinedClass
@ JoinedClass
Definition: Option.h:58
llvm::Value
LLVM Value Representation.
Definition: Value.h:75
Debug.h
llvm::opt::OptSpecifier::getID
unsigned getID() const
Definition: OptSpecifier.h:29