LLVM  14.0.0git
Optional.h
Go to the documentation of this file.
1 //===- Optional.h - Simple variant for passing optional values --*- C++ -*-===//
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 // This file provides Optional, a template class modeled in the spirit of
10 // OCaml's 'opt' variant. The idea is to strongly type whether or not
11 // a value can be optional.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef LLVM_ADT_OPTIONAL_H
16 #define LLVM_ADT_OPTIONAL_H
17 
18 #include "llvm/ADT/Hashing.h"
19 #include "llvm/ADT/None.h"
21 #include "llvm/Support/Compiler.h"
23 #include <cassert>
24 #include <memory>
25 #include <new>
26 #include <utility>
27 
28 namespace llvm {
29 
30 class raw_ostream;
31 
32 namespace optional_detail {
33 
34 /// Storage for any type.
35 //
36 // The specialization condition intentionally uses
37 // llvm::is_trivially_copy_constructible instead of
38 // std::is_trivially_copy_constructible. GCC versions prior to 7.4 may
39 // instantiate the copy constructor of `T` when
40 // std::is_trivially_copy_constructible is instantiated. This causes
41 // compilation to fail if we query the trivially copy constructible property of
42 // a class which is not copy constructible.
43 //
44 // The current implementation of OptionalStorage insists that in order to use
45 // the trivial specialization, the value_type must be trivially copy
46 // constructible and trivially copy assignable due to =default implementations
47 // of the copy/move constructor/assignment. It does not follow that this is
48 // necessarily the case std::is_trivially_copyable is true (hence the expanded
49 // specialization condition).
50 //
51 // The move constructible / assignable conditions emulate the remaining behavior
52 // of std::is_trivially_copyable.
53 template <typename T, bool = (llvm::is_trivially_copy_constructible<T>::value &&
54  std::is_trivially_copy_assignable<T>::value &&
55  (std::is_trivially_move_constructible<T>::value ||
56  !std::is_move_constructible<T>::value) &&
57  (std::is_trivially_move_assignable<T>::value ||
58  !std::is_move_assignable<T>::value))>
60  union {
61  char empty;
63  };
64  bool hasVal;
65 
66 public:
68 
69  constexpr OptionalStorage() noexcept : empty(), hasVal(false) {}
70 
71  constexpr OptionalStorage(OptionalStorage const &other) : OptionalStorage() {
72  if (other.hasValue()) {
73  emplace(other.value);
74  }
75  }
77  if (other.hasValue()) {
78  emplace(std::move(other.value));
79  }
80  }
81 
82  template <class... Args>
83  constexpr explicit OptionalStorage(in_place_t, Args &&... args)
84  : value(std::forward<Args>(args)...), hasVal(true) {}
85 
86  void reset() noexcept {
87  if (hasVal) {
88  value.~T();
89  hasVal = false;
90  }
91  }
92 
93  constexpr bool hasValue() const noexcept { return hasVal; }
94 
96  assert(hasVal);
97  return value;
98  }
99  constexpr T const &getValue() const LLVM_LVALUE_FUNCTION noexcept {
100  assert(hasVal);
101  return value;
102  }
103 #if LLVM_HAS_RVALUE_REFERENCE_THIS
104  T &&getValue() && noexcept {
105  assert(hasVal);
106  return std::move(value);
107  }
108 #endif
109 
110  template <class... Args> void emplace(Args &&... args) {
111  reset();
112  ::new ((void *)std::addressof(value)) T(std::forward<Args>(args)...);
113  hasVal = true;
114  }
115 
117  if (hasValue()) {
118  value = y;
119  } else {
120  ::new ((void *)std::addressof(value)) T(y);
121  hasVal = true;
122  }
123  return *this;
124  }
126  if (hasValue()) {
127  value = std::move(y);
128  } else {
129  ::new ((void *)std::addressof(value)) T(std::move(y));
130  hasVal = true;
131  }
132  return *this;
133  }
134 
136  if (other.hasValue()) {
137  if (hasValue()) {
138  value = other.value;
139  } else {
140  ::new ((void *)std::addressof(value)) T(other.value);
141  hasVal = true;
142  }
143  } else {
144  reset();
145  }
146  return *this;
147  }
148 
150  if (other.hasValue()) {
151  if (hasValue()) {
152  value = std::move(other.value);
153  } else {
154  ::new ((void *)std::addressof(value)) T(std::move(other.value));
155  hasVal = true;
156  }
157  } else {
158  reset();
159  }
160  return *this;
161  }
162 };
163 
164 template <typename T> class OptionalStorage<T, true> {
165  union {
166  char empty;
168  };
169  bool hasVal = false;
170 
171 public:
172  ~OptionalStorage() = default;
173 
174  constexpr OptionalStorage() noexcept : empty{} {}
175 
176  constexpr OptionalStorage(OptionalStorage const &other) = default;
177  constexpr OptionalStorage(OptionalStorage &&other) = default;
178 
179  OptionalStorage &operator=(OptionalStorage const &other) = default;
180  OptionalStorage &operator=(OptionalStorage &&other) = default;
181 
182  template <class... Args>
183  constexpr explicit OptionalStorage(in_place_t, Args &&... args)
184  : value(std::forward<Args>(args)...), hasVal(true) {}
185 
186  void reset() noexcept {
187  if (hasVal) {
188  value.~T();
189  hasVal = false;
190  }
191  }
192 
193  constexpr bool hasValue() const noexcept { return hasVal; }
194 
196  assert(hasVal);
197  return value;
198  }
199  constexpr T const &getValue() const LLVM_LVALUE_FUNCTION noexcept {
200  assert(hasVal);
201  return value;
202  }
203 #if LLVM_HAS_RVALUE_REFERENCE_THIS
204  T &&getValue() && noexcept {
205  assert(hasVal);
206  return std::move(value);
207  }
208 #endif
209 
210  template <class... Args> void emplace(Args &&... args) {
211  reset();
212  ::new ((void *)std::addressof(value)) T(std::forward<Args>(args)...);
213  hasVal = true;
214  }
215 
217  if (hasValue()) {
218  value = y;
219  } else {
220  ::new ((void *)std::addressof(value)) T(y);
221  hasVal = true;
222  }
223  return *this;
224  }
226  if (hasValue()) {
227  value = std::move(y);
228  } else {
229  ::new ((void *)std::addressof(value)) T(std::move(y));
230  hasVal = true;
231  }
232  return *this;
233  }
234 };
235 
236 } // namespace optional_detail
237 
238 template <typename T> class Optional {
239  optional_detail::OptionalStorage<T> Storage;
240 
241 public:
242  using value_type = T;
243 
244  constexpr Optional() {}
245  constexpr Optional(NoneType) {}
246 
247  constexpr Optional(const T &y) : Storage(in_place, y) {}
248  constexpr Optional(const Optional &O) = default;
249 
250  constexpr Optional(T &&y) : Storage(in_place, std::move(y)) {}
251  constexpr Optional(Optional &&O) = default;
252 
253  template <typename... ArgTypes>
254  constexpr Optional(in_place_t, ArgTypes &&...Args)
255  : Storage(in_place, std::forward<ArgTypes>(Args)...) {}
256 
258  Storage = std::move(y);
259  return *this;
260  }
261  Optional &operator=(Optional &&O) = default;
262 
263  /// Create a new object by constructing it in place with the given arguments.
264  template <typename... ArgTypes> void emplace(ArgTypes &&... Args) {
265  Storage.emplace(std::forward<ArgTypes>(Args)...);
266  }
267 
268  static constexpr Optional create(const T *y) {
269  return y ? Optional(*y) : Optional();
270  }
271 
272  Optional &operator=(const T &y) {
273  Storage = y;
274  return *this;
275  }
276  Optional &operator=(const Optional &O) = default;
277 
278  void reset() { Storage.reset(); }
279 
280  constexpr const T *getPointer() const { return &Storage.getValue(); }
281  T *getPointer() { return &Storage.getValue(); }
282  constexpr const T &getValue() const LLVM_LVALUE_FUNCTION {
283  return Storage.getValue();
284  }
285  T &getValue() LLVM_LVALUE_FUNCTION { return Storage.getValue(); }
286 
287  constexpr explicit operator bool() const { return hasValue(); }
288  constexpr bool hasValue() const { return Storage.hasValue(); }
289  constexpr const T *operator->() const { return getPointer(); }
290  T *operator->() { return getPointer(); }
291  constexpr const T &operator*() const LLVM_LVALUE_FUNCTION {
292  return getValue();
293  }
295 
296  template <typename U>
297  constexpr T getValueOr(U &&value) const LLVM_LVALUE_FUNCTION {
298  return hasValue() ? getValue() : std::forward<U>(value);
299  }
300 
301  /// Apply a function to the value if present; otherwise return None.
302  template <class Function>
303  auto map(const Function &F) const LLVM_LVALUE_FUNCTION
304  -> Optional<decltype(F(getValue()))> {
305  if (*this) return F(getValue());
306  return None;
307  }
308 
309 #if LLVM_HAS_RVALUE_REFERENCE_THIS
310  T &&getValue() && { return std::move(Storage.getValue()); }
311  T &&operator*() && { return std::move(Storage.getValue()); }
312 
313  template <typename U>
314  T getValueOr(U &&value) && {
315  return hasValue() ? std::move(getValue()) : std::forward<U>(value);
316  }
317 
318  /// Apply a function to the value if present; otherwise return None.
319  template <class Function>
320  auto map(const Function &F) &&
321  -> Optional<decltype(F(std::move(*this).getValue()))> {
322  if (*this) return F(std::move(*this).getValue());
323  return None;
324  }
325 #endif
326 };
327 
328 template <class T> llvm::hash_code hash_value(const Optional<T> &O) {
329  return O ? hash_combine(true, *O) : hash_value(false);
330 }
331 
332 template <typename T, typename U>
333 constexpr bool operator==(const Optional<T> &X, const Optional<U> &Y) {
334  if (X && Y)
335  return *X == *Y;
336  return X.hasValue() == Y.hasValue();
337 }
338 
339 template <typename T, typename U>
340 constexpr bool operator!=(const Optional<T> &X, const Optional<U> &Y) {
341  return !(X == Y);
342 }
343 
344 template <typename T, typename U>
345 constexpr bool operator<(const Optional<T> &X, const Optional<U> &Y) {
346  if (X && Y)
347  return *X < *Y;
348  return X.hasValue() < Y.hasValue();
349 }
350 
351 template <typename T, typename U>
352 constexpr bool operator<=(const Optional<T> &X, const Optional<U> &Y) {
353  return !(Y < X);
354 }
355 
356 template <typename T, typename U>
357 constexpr bool operator>(const Optional<T> &X, const Optional<U> &Y) {
358  return Y < X;
359 }
360 
361 template <typename T, typename U>
362 constexpr bool operator>=(const Optional<T> &X, const Optional<U> &Y) {
363  return !(X < Y);
364 }
365 
366 template <typename T>
367 constexpr bool operator==(const Optional<T> &X, NoneType) {
368  return !X;
369 }
370 
371 template <typename T>
372 constexpr bool operator==(NoneType, const Optional<T> &X) {
373  return X == None;
374 }
375 
376 template <typename T>
377 constexpr bool operator!=(const Optional<T> &X, NoneType) {
378  return !(X == None);
379 }
380 
381 template <typename T>
382 constexpr bool operator!=(NoneType, const Optional<T> &X) {
383  return X != None;
384 }
385 
386 template <typename T> constexpr bool operator<(const Optional<T> &, NoneType) {
387  return false;
388 }
389 
390 template <typename T> constexpr bool operator<(NoneType, const Optional<T> &X) {
391  return X.hasValue();
392 }
393 
394 template <typename T>
395 constexpr bool operator<=(const Optional<T> &X, NoneType) {
396  return !(None < X);
397 }
398 
399 template <typename T>
400 constexpr bool operator<=(NoneType, const Optional<T> &X) {
401  return !(X < None);
402 }
403 
404 template <typename T> constexpr bool operator>(const Optional<T> &X, NoneType) {
405  return None < X;
406 }
407 
408 template <typename T> constexpr bool operator>(NoneType, const Optional<T> &X) {
409  return X < None;
410 }
411 
412 template <typename T>
413 constexpr bool operator>=(const Optional<T> &X, NoneType) {
414  return None <= X;
415 }
416 
417 template <typename T>
418 constexpr bool operator>=(NoneType, const Optional<T> &X) {
419  return X <= None;
420 }
421 
422 template <typename T>
423 constexpr bool operator==(const Optional<T> &X, const T &Y) {
424  return X && *X == Y;
425 }
426 
427 template <typename T>
428 constexpr bool operator==(const T &X, const Optional<T> &Y) {
429  return Y && X == *Y;
430 }
431 
432 template <typename T>
433 constexpr bool operator!=(const Optional<T> &X, const T &Y) {
434  return !(X == Y);
435 }
436 
437 template <typename T>
438 constexpr bool operator!=(const T &X, const Optional<T> &Y) {
439  return !(X == Y);
440 }
441 
442 template <typename T>
443 constexpr bool operator<(const Optional<T> &X, const T &Y) {
444  return !X || *X < Y;
445 }
446 
447 template <typename T>
448 constexpr bool operator<(const T &X, const Optional<T> &Y) {
449  return Y && X < *Y;
450 }
451 
452 template <typename T>
453 constexpr bool operator<=(const Optional<T> &X, const T &Y) {
454  return !(Y < X);
455 }
456 
457 template <typename T>
458 constexpr bool operator<=(const T &X, const Optional<T> &Y) {
459  return !(Y < X);
460 }
461 
462 template <typename T>
463 constexpr bool operator>(const Optional<T> &X, const T &Y) {
464  return Y < X;
465 }
466 
467 template <typename T>
468 constexpr bool operator>(const T &X, const Optional<T> &Y) {
469  return Y < X;
470 }
471 
472 template <typename T>
473 constexpr bool operator>=(const Optional<T> &X, const T &Y) {
474  return !(X < Y);
475 }
476 
477 template <typename T>
478 constexpr bool operator>=(const T &X, const Optional<T> &Y) {
479  return !(X < Y);
480 }
481 
482 raw_ostream &operator<<(raw_ostream &OS, NoneType);
483 
484 template <typename T, typename = decltype(std::declval<raw_ostream &>()
485  << std::declval<const T &>())>
486 raw_ostream &operator<<(raw_ostream &OS, const Optional<T> &O) {
487  if (O)
488  OS << *O;
489  else
490  OS << None;
491  return OS;
492 }
493 
494 } // end namespace llvm
495 
496 #endif // LLVM_ADT_OPTIONAL_H
llvm::optional_detail::OptionalStorage::getValue
constexpr const T & getValue() const LLVM_LVALUE_FUNCTION noexcept
Definition: Optional.h:99
llvm::optional_detail::OptionalStorage::OptionalStorage
constexpr OptionalStorage(OptionalStorage &&other)
Definition: Optional.h:76
llvm
---------------------— PointerInfo ------------------------------------—
Definition: AllocatorList.h:23
llvm::Optional::Optional
constexpr Optional(NoneType)
Definition: Optional.h:245
llvm::Function
Definition: Function.h:61
llvm::operator<=
bool operator<=(int64_t V1, const APSInt &V2)
Definition: APSInt.h:336
llvm::Optional::Optional
constexpr Optional(const T &y)
Definition: Optional.h:247
llvm::optional_detail::OptionalStorage::operator=
OptionalStorage & operator=(OptionalStorage &&other)
Definition: Optional.h:149
llvm::Optional::operator*
T & operator*() LLVM_LVALUE_FUNCTION
Definition: Optional.h:294
llvm::optional_detail::OptionalStorage< T, true >::getValue
T & getValue() LLVM_LVALUE_FUNCTION noexcept
Definition: Optional.h:195
llvm::optional_detail::OptionalStorage::value
T value
Definition: Optional.h:62
llvm::Optional::operator=
Optional & operator=(T &&y)
Definition: Optional.h:257
llvm::optional_detail::OptionalStorage::OptionalStorage
constexpr OptionalStorage() noexcept
Definition: Optional.h:69
llvm::operator!=
bool operator!=(uint64_t V1, const APInt &V2)
Definition: APInt.h:1976
llvm::Optional
Definition: APInt.h:33
LLVM_LVALUE_FUNCTION
#define LLVM_LVALUE_FUNCTION
Expands to '&' if ref-qualifiers for *this are supported.
Definition: Compiler.h:114
T
#define T
Definition: Mips16ISelLowering.cpp:341
Hashing.h
llvm::optional_detail::OptionalStorage::getValue
T & getValue() LLVM_LVALUE_FUNCTION noexcept
Definition: Optional.h:95
llvm::hash_value
hash_code hash_value(const APFloat &Arg)
See friend declarations above.
Definition: APFloat.cpp:4827
llvm::optional_detail::OptionalStorage< T, true >::emplace
void emplace(Args &&... args)
Definition: Optional.h:210
new
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM ID Predecessors according to mbb< bb27, 0x8b0a7c0 > Note ADDri is not a two address instruction its result reg1037 is an operand of the PHI node in bb76 and its operand reg1039 is the result of the PHI node We should treat it as a two address code and make sure the ADDri is scheduled after any node that reads reg1039 Use info(i.e. register scavenger) to assign it a free register to allow reuse the collector could move the objects and invalidate the derived pointer This is bad enough in the first but safe points can crop up unpredictably **array_addr i32 n y store obj * new
Definition: README.txt:125
F
#define F(x, y, z)
Definition: MD5.cpp:56
llvm::Optional::getPointer
constexpr const T * getPointer() const
Definition: Optional.h:280
llvm::Optional::hasValue
constexpr bool hasValue() const
Definition: Optional.h:288
Y
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
false
Definition: StackSlotColoring.cpp:142
llvm::optional_detail::OptionalStorage::OptionalStorage
constexpr OptionalStorage(OptionalStorage const &other)
Definition: Optional.h:71
STLForwardCompat.h
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::operator<<
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
Definition: APFixedPoint.h:230
llvm::Optional::create
static constexpr Optional create(const T *y)
Definition: Optional.h:268
llvm::None
const NoneType None
Definition: None.h:23
X
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
llvm::Optional::Optional
constexpr Optional(T &&y)
Definition: Optional.h:250
llvm::Optional::getValueOr
constexpr T getValueOr(U &&value) const LLVM_LVALUE_FUNCTION
Definition: Optional.h:297
llvm::operator>=
bool operator>=(int64_t V1, const APSInt &V2)
Definition: APSInt.h:337
llvm::RISCVFenceField::O
@ O
Definition: RISCVBaseInfo.h:197
uint64_t
llvm::optional_detail::OptionalStorage< T, true >::OptionalStorage
constexpr OptionalStorage(in_place_t, Args &&... args)
Definition: Optional.h:183
llvm::Optional::reset
void reset()
Definition: Optional.h:278
llvm::NoneType
NoneType
A simple null object to allow implicit construction of Optional<T> and similar types without having t...
Definition: None.h:22
const
aarch64 promote const
Definition: AArch64PromoteConstant.cpp:232
llvm::Optional::emplace
void emplace(ArgTypes &&... Args)
Create a new object by constructing it in place with the given arguments.
Definition: Optional.h:264
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::operator<
bool operator<(int64_t V1, const APSInt &V2)
Definition: APSInt.h:338
llvm::Optional::getPointer
T * getPointer()
Definition: Optional.h:281
llvm::optional_detail::OptionalStorage< T, true >::hasValue
constexpr bool hasValue() const noexcept
Definition: Optional.h:193
llvm::Optional::Optional
constexpr Optional(in_place_t, ArgTypes &&...Args)
Definition: Optional.h:254
llvm::optional_detail::OptionalStorage::~OptionalStorage
~OptionalStorage()
Definition: Optional.h:67
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::optional_detail::OptionalStorage::OptionalStorage
constexpr OptionalStorage(in_place_t, Args &&... args)
Definition: Optional.h:83
llvm::move
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1609
llvm::operator==
bool operator==(uint64_t V1, const APInt &V2)
Definition: APInt.h:1974
llvm::optional_detail::OptionalStorage::operator=
OptionalStorage & operator=(T const &y)
Definition: Optional.h:116
llvm::in_place
constexpr in_place_t in_place
Definition: STLForwardCompat.h:52
llvm::Optional::map
auto map(const Function &F) const LLVM_LVALUE_FUNCTION -> Optional< decltype(F(getValue()))>
Apply a function to the value if present; otherwise return None.
Definition: Optional.h:303
llvm::optional_detail::OptionalStorage< T, true >::OptionalStorage
constexpr OptionalStorage() noexcept
Definition: Optional.h:174
llvm::optional_detail::OptionalStorage< T, true >::getValue
constexpr const T & getValue() const LLVM_LVALUE_FUNCTION noexcept
Definition: Optional.h:199
None.h
llvm::optional_detail::OptionalStorage::reset
void reset() noexcept
Definition: Optional.h:86
Compiler.h
llvm::optional_detail::OptionalStorage::operator=
OptionalStorage & operator=(OptionalStorage const &other)
Definition: Optional.h:135
llvm::Optional::operator->
constexpr const T * operator->() const
Definition: Optional.h:289
llvm::optional_detail::OptionalStorage::hasValue
constexpr bool hasValue() const noexcept
Definition: Optional.h:93
llvm::optional_detail::OptionalStorage< T, true >::operator=
OptionalStorage & operator=(T &&y)
Definition: Optional.h:225
llvm::cl::Optional
@ Optional
Definition: CommandLine.h:119
std
Definition: BitVector.h:838
type_traits.h
llvm::Optional::Optional
constexpr Optional()
Definition: Optional.h:244
llvm::optional_detail::OptionalStorage< T, true >::value
T value
Definition: Optional.h:167
llvm::optional_detail::OptionalStorage::operator=
OptionalStorage & operator=(T &&y)
Definition: Optional.h:125
llvm::Optional::operator->
T * operator->()
Definition: Optional.h:290
y
into llvm powi allowing the code generator to produce balanced multiplication trees the intrinsic needs to be extended to support and second the code generator needs to be enhanced to lower these to multiplication trees Interesting testcase for add shift mul int y
Definition: README.txt:61
llvm::optional_detail::OptionalStorage::empty
char empty
Definition: Optional.h:61
llvm::in_place_t
Definition: STLForwardCompat.h:47
llvm::Optional::getValue
T & getValue() LLVM_LVALUE_FUNCTION
Definition: Optional.h:285
llvm::hash_combine
hash_code hash_combine(const Ts &...args)
Combine values into a single hash_code.
Definition: Hashing.h:604
llvm::Optional::operator=
Optional & operator=(const T &y)
Definition: Optional.h:272
llvm::operator>
bool operator>(int64_t V1, const APSInt &V2)
Definition: APSInt.h:339
llvm::optional_detail::OptionalStorage< T, true >::empty
char empty
Definition: Optional.h:166
llvm::optional_detail::OptionalStorage::emplace
void emplace(Args &&... args)
Definition: Optional.h:110
llvm::AMDGPU::HSAMD::Kernel::Key::Args
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
Definition: AMDGPUMetadata.h:389
llvm::optional_detail::OptionalStorage< T, true >::reset
void reset() noexcept
Definition: Optional.h:186
llvm::optional_detail::OptionalStorage< T, true >::operator=
OptionalStorage & operator=(T const &y)
Definition: Optional.h:216
true
basic Basic Alias true
Definition: BasicAliasAnalysis.cpp:1853
llvm::optional_detail::OptionalStorage
Storage for any type.
Definition: Optional.h:59
llvm::Optional::operator*
constexpr const T & operator*() const LLVM_LVALUE_FUNCTION
Definition: Optional.h:291
llvm::Optional::getValue
constexpr const T & getValue() const LLVM_LVALUE_FUNCTION
Definition: Optional.h:282
llvm::hash_code
An opaque object representing a hash code.
Definition: Hashing.h:72