Update prebuilt Clang to r365631c1 from Android.
The version we had was segfaulting.
Bug: 132420445
Change-Id: Icb45a6fe0b4e2166f7895e669df1157cec9fb4e0
diff --git a/linux-x64/clang/include/llvm/ADT/APFloat.h b/linux-x64/clang/include/llvm/ADT/APFloat.h
index 6255823..a9648d3 100644
--- a/linux-x64/clang/include/llvm/ADT/APFloat.h
+++ b/linux-x64/clang/include/llvm/ADT/APFloat.h
@@ -147,6 +147,17 @@
/// \name Floating Point Semantics.
/// @{
+ enum Semantics {
+ S_IEEEhalf,
+ S_IEEEsingle,
+ S_IEEEdouble,
+ S_x87DoubleExtended,
+ S_IEEEquad,
+ S_PPCDoubleDouble
+ };
+
+ static const llvm::fltSemantics &EnumToSemantics(Semantics S);
+ static Semantics SemanticsToEnum(const llvm::fltSemantics &Sem);
static const fltSemantics &IEEEhalf() LLVM_READNONE;
static const fltSemantics &IEEEsingle() LLVM_READNONE;
diff --git a/linux-x64/clang/include/llvm/ADT/APInt.h b/linux-x64/clang/include/llvm/ADT/APInt.h
index 0f27dbf..2381b75 100644
--- a/linux-x64/clang/include/llvm/ADT/APInt.h
+++ b/linux-x64/clang/include/llvm/ADT/APInt.h
@@ -2212,6 +2212,15 @@
// See friend declaration above. This additional declaration is required in
// order to compile LLVM with IBM xlC compiler.
hash_code hash_value(const APInt &Arg);
-} // End of llvm namespace
+
+/// StoreIntToMemory - Fills the StoreBytes bytes of memory starting from Dst
+/// with the integer held in IntVal.
+void StoreIntToMemory(const APInt &IntVal, uint8_t *Dst, unsigned StoreBytes);
+
+/// LoadIntFromMemory - Loads the integer stored in the LoadBytes bytes starting
+/// from Src into IntVal, which is assumed to be wide enough and to hold zero.
+void LoadIntFromMemory(APInt &IntVal, uint8_t *Src, unsigned LoadBytes);
+
+} // namespace llvm
#endif
diff --git a/linux-x64/clang/include/llvm/ADT/APSInt.h b/linux-x64/clang/include/llvm/ADT/APSInt.h
index be36611..0f99182 100644
--- a/linux-x64/clang/include/llvm/ADT/APSInt.h
+++ b/linux-x64/clang/include/llvm/ADT/APSInt.h
@@ -42,6 +42,24 @@
/// \param Str the string to be interpreted.
explicit APSInt(StringRef Str);
+ /// Determine sign of this APSInt.
+ ///
+ /// \returns true if this APSInt is negative, false otherwise
+ bool isNegative() const { return isSigned() && APInt::isNegative(); }
+
+ /// Determine if this APSInt Value is non-negative (>= 0)
+ ///
+ /// \returns true if this APSInt is non-negative, false otherwise
+ bool isNonNegative() const { return !isNegative(); }
+
+ /// Determine if this APSInt Value is positive.
+ ///
+ /// This tests if the value of this APSInt is positive (> 0). Note
+ /// that 0 is not a positive value.
+ ///
+ /// \returns true if this APSInt is positive.
+ bool isStrictlyPositive() const { return isNonNegative() && !isNullValue(); }
+
APSInt &operator=(APInt RHS) {
// Retain our current sign.
APInt::operator=(std::move(RHS));
diff --git a/linux-x64/clang/include/llvm/ADT/ArrayRef.h b/linux-x64/clang/include/llvm/ADT/ArrayRef.h
index 75bb7d6..773c88f 100644
--- a/linux-x64/clang/include/llvm/ADT/ArrayRef.h
+++ b/linux-x64/clang/include/llvm/ADT/ArrayRef.h
@@ -430,7 +430,7 @@
std::copy(Data.begin(), Data.end(), this->begin());
}
- OwningArrayRef(OwningArrayRef &&Other) { *this = Other; }
+ OwningArrayRef(OwningArrayRef &&Other) { *this = std::move(Other); }
OwningArrayRef &operator=(OwningArrayRef &&Other) {
delete[] this->data();
diff --git a/linux-x64/clang/include/llvm/ADT/BreadthFirstIterator.h b/linux-x64/clang/include/llvm/ADT/BreadthFirstIterator.h
index cc6c860..e97d766 100644
--- a/linux-x64/clang/include/llvm/ADT/BreadthFirstIterator.h
+++ b/linux-x64/clang/include/llvm/ADT/BreadthFirstIterator.h
@@ -124,7 +124,7 @@
const NodeRef &operator*() const { return VisitQueue.front()->first; }
- // This is a nonstandard operator-> that dereferenfces the pointer an extra
+ // This is a nonstandard operator-> that dereferences the pointer an extra
// time so that you can actually call methods on the node, because the
// contained type is a pointer.
NodeRef operator->() const { return **this; }
diff --git a/linux-x64/clang/include/llvm/ADT/DenseMap.h b/linux-x64/clang/include/llvm/ADT/DenseMap.h
index e7cd370..a05cf81 100644
--- a/linux-x64/clang/include/llvm/ADT/DenseMap.h
+++ b/linux-x64/clang/include/llvm/ADT/DenseMap.h
@@ -63,7 +63,7 @@
template <typename AltPairT>
DenseMapPair(AltPairT &&AltPair,
typename std::enable_if<std::is_convertible<
- AltPairT, std::pair<KeyT, ValueT>>::value>::type * = 0)
+ AltPairT, std::pair<KeyT, ValueT>>::value>::type * = nullptr)
: std::pair<KeyT, ValueT>(std::forward<AltPairT>(AltPair)) {}
KeyT &getFirst() { return std::pair<KeyT, ValueT>::first; }
diff --git a/linux-x64/clang/include/llvm/ADT/DenseMapInfo.h b/linux-x64/clang/include/llvm/ADT/DenseMapInfo.h
index 18d6dff..5ef6f3a 100644
--- a/linux-x64/clang/include/llvm/ADT/DenseMapInfo.h
+++ b/linux-x64/clang/include/llvm/ADT/DenseMapInfo.h
@@ -17,6 +17,7 @@
#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/PointerLikeTypeTraits.h"
+#include "llvm/Support/ScalableSize.h"
#include <cassert>
#include <cstddef>
#include <cstdint>
@@ -268,6 +269,21 @@
static bool isEqual(hash_code LHS, hash_code RHS) { return LHS == RHS; }
};
+template <> struct DenseMapInfo<ElementCount> {
+ static inline ElementCount getEmptyKey() { return {~0U, true}; }
+ static inline ElementCount getTombstoneKey() { return {~0U - 1, false}; }
+ static unsigned getHashValue(const ElementCount& EltCnt) {
+ if (EltCnt.Scalable)
+ return (EltCnt.Min * 37U) - 1U;
+
+ return EltCnt.Min * 37U;
+ }
+
+ static bool isEqual(const ElementCount& LHS, const ElementCount& RHS) {
+ return LHS == RHS;
+ }
+};
+
} // end namespace llvm
#endif // LLVM_ADT_DENSEMAPINFO_H
diff --git a/linux-x64/clang/include/llvm/ADT/DenseSet.h b/linux-x64/clang/include/llvm/ADT/DenseSet.h
index 5eaaf27..9afb715 100644
--- a/linux-x64/clang/include/llvm/ADT/DenseSet.h
+++ b/linux-x64/clang/include/llvm/ADT/DenseSet.h
@@ -130,7 +130,7 @@
class ConstIterator {
typename MapTy::const_iterator I;
- friend class DenseSet;
+ friend class DenseSetImpl;
friend class Iterator;
public:
diff --git a/linux-x64/clang/include/llvm/ADT/Optional.h b/linux-x64/clang/include/llvm/ADT/Optional.h
index 25a3185..b45a740 100644
--- a/linux-x64/clang/include/llvm/ADT/Optional.h
+++ b/linux-x64/clang/include/llvm/ADT/Optional.h
@@ -16,11 +16,10 @@
#define LLVM_ADT_OPTIONAL_H
#include "llvm/ADT/None.h"
-#include "llvm/Support/AlignOf.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/type_traits.h"
-#include <algorithm>
#include <cassert>
+#include <memory>
#include <new>
#include <utility>
@@ -29,83 +28,185 @@
class raw_ostream;
namespace optional_detail {
+
+struct in_place_t {};
+
/// Storage for any type.
-template <typename T, bool = is_trivially_copyable<T>::value> struct OptionalStorage {
- AlignedCharArrayUnion<T> storage;
- bool hasVal = false;
+template <typename T, bool = is_trivially_copyable<T>::value>
+class OptionalStorage {
+ union {
+ char empty;
+ T value;
+ };
+ bool hasVal;
- OptionalStorage() = default;
-
- OptionalStorage(const T &y) : hasVal(true) { new (storage.buffer) T(y); }
- OptionalStorage(const OptionalStorage &O) : hasVal(O.hasVal) {
- if (hasVal)
- new (storage.buffer) T(*O.getPointer());
- }
- OptionalStorage(T &&y) : hasVal(true) {
- new (storage.buffer) T(std::forward<T>(y));
- }
- OptionalStorage(OptionalStorage &&O) : hasVal(O.hasVal) {
- if (O.hasVal) {
- new (storage.buffer) T(std::move(*O.getPointer()));
- }
- }
-
- OptionalStorage &operator=(T &&y) {
- if (hasVal)
- *getPointer() = std::move(y);
- else {
- new (storage.buffer) T(std::move(y));
- hasVal = true;
- }
- return *this;
- }
- OptionalStorage &operator=(OptionalStorage &&O) {
- if (!O.hasVal)
- reset();
- else {
- *this = std::move(*O.getPointer());
- }
- return *this;
- }
-
- // FIXME: these assignments (& the equivalent const T&/const Optional& ctors)
- // could be made more efficient by passing by value, possibly unifying them
- // with the rvalue versions above - but this could place a different set of
- // requirements (notably: the existence of a default ctor) when implemented
- // in that way. Careful SFINAE to avoid such pitfalls would be required.
- OptionalStorage &operator=(const T &y) {
- if (hasVal)
- *getPointer() = y;
- else {
- new (storage.buffer) T(y);
- hasVal = true;
- }
- return *this;
- }
- OptionalStorage &operator=(const OptionalStorage &O) {
- if (!O.hasVal)
- reset();
- else
- *this = *O.getPointer();
- return *this;
- }
-
+public:
~OptionalStorage() { reset(); }
- void reset() {
+ OptionalStorage() noexcept : empty(), hasVal(false) {}
+
+ OptionalStorage(OptionalStorage const &other) : OptionalStorage() {
+ if (other.hasValue()) {
+ emplace(other.value);
+ }
+ }
+ OptionalStorage(OptionalStorage &&other) : OptionalStorage() {
+ if (other.hasValue()) {
+ emplace(std::move(other.value));
+ }
+ }
+
+ template <class... Args>
+ explicit OptionalStorage(in_place_t, Args &&... args)
+ : value(std::forward<Args>(args)...), hasVal(true) {}
+
+ void reset() noexcept {
if (hasVal) {
- (*getPointer()).~T();
+ value.~T();
hasVal = false;
}
}
- T *getPointer() {
+ bool hasValue() const noexcept { return hasVal; }
+
+ T &getValue() LLVM_LVALUE_FUNCTION noexcept {
assert(hasVal);
- return reinterpret_cast<T *>(storage.buffer);
+ return value;
}
- const T *getPointer() const {
+ T const &getValue() const LLVM_LVALUE_FUNCTION noexcept {
assert(hasVal);
- return reinterpret_cast<const T *>(storage.buffer);
+ return value;
+ }
+#if LLVM_HAS_RVALUE_REFERENCE_THIS
+ T &&getValue() && noexcept {
+ assert(hasVal);
+ return std::move(value);
+ }
+#endif
+
+ template <class... Args> void emplace(Args &&... args) {
+ reset();
+ ::new ((void *)std::addressof(value)) T(std::forward<Args>(args)...);
+ hasVal = true;
+ }
+
+ OptionalStorage &operator=(T const &y) {
+ if (hasValue()) {
+ value = y;
+ } else {
+ ::new ((void *)std::addressof(value)) T(y);
+ hasVal = true;
+ }
+ return *this;
+ }
+ OptionalStorage &operator=(T &&y) {
+ if (hasValue()) {
+ value = std::move(y);
+ } else {
+ ::new ((void *)std::addressof(value)) T(std::move(y));
+ hasVal = true;
+ }
+ return *this;
+ }
+
+ OptionalStorage &operator=(OptionalStorage const &other) {
+ if (other.hasValue()) {
+ if (hasValue()) {
+ value = other.value;
+ } else {
+ ::new ((void *)std::addressof(value)) T(other.value);
+ hasVal = true;
+ }
+ } else {
+ reset();
+ }
+ return *this;
+ }
+
+ OptionalStorage &operator=(OptionalStorage &&other) {
+ if (other.hasValue()) {
+ if (hasValue()) {
+ value = std::move(other.value);
+ } else {
+ ::new ((void *)std::addressof(value)) T(std::move(other.value));
+ hasVal = true;
+ }
+ } else {
+ reset();
+ }
+ return *this;
+ }
+};
+
+template <typename T> class OptionalStorage<T, true> {
+ union {
+ char empty;
+ T value;
+ };
+ bool hasVal = false;
+
+public:
+ ~OptionalStorage() = default;
+
+ OptionalStorage() noexcept : empty{} {}
+
+ OptionalStorage(OptionalStorage const &other) = default;
+ OptionalStorage(OptionalStorage &&other) = default;
+
+ OptionalStorage &operator=(OptionalStorage const &other) = default;
+ OptionalStorage &operator=(OptionalStorage &&other) = default;
+
+ template <class... Args>
+ explicit OptionalStorage(in_place_t, Args &&... args)
+ : value(std::forward<Args>(args)...), hasVal(true) {}
+
+ void reset() noexcept {
+ if (hasVal) {
+ value.~T();
+ hasVal = false;
+ }
+ }
+
+ bool hasValue() const noexcept { return hasVal; }
+
+ T &getValue() LLVM_LVALUE_FUNCTION noexcept {
+ assert(hasVal);
+ return value;
+ }
+ T const &getValue() const LLVM_LVALUE_FUNCTION noexcept {
+ assert(hasVal);
+ return value;
+ }
+#if LLVM_HAS_RVALUE_REFERENCE_THIS
+ T &&getValue() && noexcept {
+ assert(hasVal);
+ return std::move(value);
+ }
+#endif
+
+ template <class... Args> void emplace(Args &&... args) {
+ reset();
+ ::new ((void *)std::addressof(value)) T(std::forward<Args>(args)...);
+ hasVal = true;
+ }
+
+ OptionalStorage &operator=(T const &y) {
+ if (hasValue()) {
+ value = y;
+ } else {
+ ::new ((void *)std::addressof(value)) T(y);
+ hasVal = true;
+ }
+ return *this;
+ }
+ OptionalStorage &operator=(T &&y) {
+ if (hasValue()) {
+ value = std::move(y);
+ } else {
+ ::new ((void *)std::addressof(value)) T(std::move(y));
+ hasVal = true;
+ }
+ return *this;
}
};
@@ -120,10 +221,10 @@
constexpr Optional() {}
constexpr Optional(NoneType) {}
- Optional(const T &y) : Storage(y) {}
+ Optional(const T &y) : Storage(optional_detail::in_place_t{}, y) {}
Optional(const Optional &O) = default;
- Optional(T &&y) : Storage(std::forward<T>(y)) {}
+ Optional(T &&y) : Storage(optional_detail::in_place_t{}, std::move(y)) {}
Optional(Optional &&O) = default;
Optional &operator=(T &&y) {
@@ -134,9 +235,7 @@
/// Create a new object by constructing it in place with the given arguments.
template <typename... ArgTypes> void emplace(ArgTypes &&... Args) {
- reset();
- Storage.hasVal = true;
- new (getPointer()) T(std::forward<ArgTypes>(Args)...);
+ Storage.emplace(std::forward<ArgTypes>(Args)...);
}
static inline Optional create(const T *y) {
@@ -151,23 +250,17 @@
void reset() { Storage.reset(); }
- const T *getPointer() const {
- assert(Storage.hasVal);
- return reinterpret_cast<const T *>(Storage.storage.buffer);
- }
- T *getPointer() {
- assert(Storage.hasVal);
- return reinterpret_cast<T *>(Storage.storage.buffer);
- }
- const T &getValue() const LLVM_LVALUE_FUNCTION { return *getPointer(); }
- T &getValue() LLVM_LVALUE_FUNCTION { return *getPointer(); }
+ const T *getPointer() const { return &Storage.getValue(); }
+ T *getPointer() { return &Storage.getValue(); }
+ const T &getValue() const LLVM_LVALUE_FUNCTION { return Storage.getValue(); }
+ T &getValue() LLVM_LVALUE_FUNCTION { return Storage.getValue(); }
- explicit operator bool() const { return Storage.hasVal; }
- bool hasValue() const { return Storage.hasVal; }
+ explicit operator bool() const { return hasValue(); }
+ bool hasValue() const { return Storage.hasValue(); }
const T *operator->() const { return getPointer(); }
T *operator->() { return getPointer(); }
- const T &operator*() const LLVM_LVALUE_FUNCTION { return *getPointer(); }
- T &operator*() LLVM_LVALUE_FUNCTION { return *getPointer(); }
+ const T &operator*() const LLVM_LVALUE_FUNCTION { return getValue(); }
+ T &operator*() LLVM_LVALUE_FUNCTION { return getValue(); }
template <typename U>
constexpr T getValueOr(U &&value) const LLVM_LVALUE_FUNCTION {
@@ -175,8 +268,8 @@
}
#if LLVM_HAS_RVALUE_REFERENCE_THIS
- T &&getValue() && { return std::move(*getPointer()); }
- T &&operator*() && { return std::move(*getPointer()); }
+ T &&getValue() && { return std::move(Storage.getValue()); }
+ T &&operator*() && { return std::move(Storage.getValue()); }
template <typename U>
T getValueOr(U &&value) && {
diff --git a/linux-x64/clang/include/llvm/ADT/PointerUnion.h b/linux-x64/clang/include/llvm/ADT/PointerUnion.h
index 0605429..2bcdf54 100644
--- a/linux-x64/clang/include/llvm/ADT/PointerUnion.h
+++ b/linux-x64/clang/include/llvm/ADT/PointerUnion.h
@@ -53,22 +53,98 @@
typename PointerUnionTypeSelector<T1, T2, RET_EQ, RET_NE>::Return;
};
-/// Provide PointerLikeTypeTraits for void* that is used by PointerUnion
-/// for the two template arguments.
-template <typename PT1, typename PT2> class PointerUnionUIntTraits {
-public:
- static inline void *getAsVoidPointer(void *P) { return P; }
- static inline void *getFromVoidPointer(void *P) { return P; }
+namespace pointer_union_detail {
+ constexpr int constexprMin(int a, int b) { return a < b ? a : b; }
+ /// Determine the number of bits required to store integers with values < n.
+ /// This is ceil(log2(n)).
+ constexpr int bitsRequired(unsigned n) {
+ return n > 1 ? 1 + bitsRequired((n + 1) / 2) : 0;
+ }
- enum {
- PT1BitsAv = (int)(PointerLikeTypeTraits<PT1>::NumLowBitsAvailable),
- PT2BitsAv = (int)(PointerLikeTypeTraits<PT2>::NumLowBitsAvailable),
- NumLowBitsAvailable = PT1BitsAv < PT2BitsAv ? PT1BitsAv : PT2BitsAv
+ // FIXME: In C++14, replace this with
+ // std::min({PointerLikeTypeTraits<Ts>::NumLowBitsAvailable...})
+ template <typename T> constexpr int lowBitsAvailable() {
+ return PointerLikeTypeTraits<T>::NumLowBitsAvailable;
+ }
+ template <typename T1, typename T2, typename... Ts>
+ constexpr int lowBitsAvailable() {
+ return constexprMin(lowBitsAvailable<T1>(), lowBitsAvailable<T2, Ts...>());
+ }
+
+ /// Find the index of a type in a list of types. TypeIndex<T, Us...>::Index
+ /// is the index of T in Us, or sizeof...(Us) if T does not appear in the
+ /// list.
+ template <typename T, typename ...Us> struct TypeIndex;
+ template <typename T, typename ...Us> struct TypeIndex<T, T, Us...> {
+ static constexpr int Index = 0;
};
-};
+ template <typename T, typename U, typename... Us>
+ struct TypeIndex<T, U, Us...> {
+ static constexpr int Index = 1 + TypeIndex<T, Us...>::Index;
+ };
+ template <typename T> struct TypeIndex<T> {
+ static constexpr int Index = 0;
+ };
-/// A discriminated union of two pointer types, with the discriminator in the
-/// low bit of the pointer.
+ /// Find the first type in a list of types.
+ template <typename T, typename...> struct GetFirstType {
+ using type = T;
+ };
+
+ /// Provide PointerLikeTypeTraits for void* that is used by PointerUnion
+ /// for the template arguments.
+ template <typename ...PTs> class PointerUnionUIntTraits {
+ public:
+ static inline void *getAsVoidPointer(void *P) { return P; }
+ static inline void *getFromVoidPointer(void *P) { return P; }
+ static constexpr int NumLowBitsAvailable = lowBitsAvailable<PTs...>();
+ };
+
+ /// Implement assigment in terms of construction.
+ template <typename Derived, typename T> struct AssignableFrom {
+ Derived &operator=(T t) {
+ return static_cast<Derived &>(*this) = Derived(t);
+ }
+ };
+
+ template <typename Derived, typename ValTy, int I, typename ...Types>
+ class PointerUnionMembers;
+
+ template <typename Derived, typename ValTy, int I>
+ class PointerUnionMembers<Derived, ValTy, I> {
+ protected:
+ ValTy Val;
+ PointerUnionMembers() = default;
+ PointerUnionMembers(ValTy Val) : Val(Val) {}
+
+ friend struct PointerLikeTypeTraits<Derived>;
+ };
+
+ template <typename Derived, typename ValTy, int I, typename Type,
+ typename ...Types>
+ class PointerUnionMembers<Derived, ValTy, I, Type, Types...>
+ : public PointerUnionMembers<Derived, ValTy, I + 1, Types...> {
+ using Base = PointerUnionMembers<Derived, ValTy, I + 1, Types...>;
+ public:
+ using Base::Base;
+ PointerUnionMembers() = default;
+ PointerUnionMembers(Type V)
+ : Base(ValTy(const_cast<void *>(
+ PointerLikeTypeTraits<Type>::getAsVoidPointer(V)),
+ I)) {}
+
+ using Base::operator=;
+ Derived &operator=(Type V) {
+ this->Val = ValTy(
+ const_cast<void *>(PointerLikeTypeTraits<Type>::getAsVoidPointer(V)),
+ I);
+ return static_cast<Derived &>(*this);
+ };
+ };
+}
+
+/// A discriminated union of two or more pointer types, with the discriminator
+/// in the low bit of the pointer.
///
/// This implementation is extremely efficient in space due to leveraging the
/// low bits of the pointer, while exposing a natural and type-safe API.
@@ -83,49 +159,44 @@
/// P = (float*)0;
/// Y = P.get<float*>(); // ok.
/// X = P.get<int*>(); // runtime assertion failure.
-template <typename PT1, typename PT2> class PointerUnion {
-public:
- using ValTy =
- PointerIntPair<void *, 1, bool, PointerUnionUIntTraits<PT1, PT2>>;
-
-private:
- ValTy Val;
-
- struct IsPT1 {
- static const int Num = 0;
- };
- struct IsPT2 {
- static const int Num = 1;
- };
- template <typename T> struct UNION_DOESNT_CONTAIN_TYPE {};
+template <typename... PTs>
+class PointerUnion
+ : public pointer_union_detail::PointerUnionMembers<
+ PointerUnion<PTs...>,
+ PointerIntPair<
+ void *, pointer_union_detail::bitsRequired(sizeof...(PTs)), int,
+ pointer_union_detail::PointerUnionUIntTraits<PTs...>>,
+ 0, PTs...> {
+ // The first type is special in some ways, but we don't want PointerUnion to
+ // be a 'template <typename First, typename ...Rest>' because it's much more
+ // convenient to have a name for the whole pack. So split off the first type
+ // here.
+ using First = typename pointer_union_detail::GetFirstType<PTs...>::type;
+ using Base = typename PointerUnion::PointerUnionMembers;
public:
PointerUnion() = default;
- PointerUnion(PT1 V)
- : Val(const_cast<void *>(
- PointerLikeTypeTraits<PT1>::getAsVoidPointer(V))) {}
- PointerUnion(PT2 V)
- : Val(const_cast<void *>(PointerLikeTypeTraits<PT2>::getAsVoidPointer(V)),
- 1) {}
+
+ PointerUnion(std::nullptr_t) : PointerUnion() {}
+ using Base::Base;
/// Test if the pointer held in the union is null, regardless of
/// which type it is.
bool isNull() const {
// Convert from the void* to one of the pointer types, to make sure that
// we recursively strip off low bits if we have a nested PointerUnion.
- return !PointerLikeTypeTraits<PT1>::getFromVoidPointer(Val.getPointer());
+ return !PointerLikeTypeTraits<First>::getFromVoidPointer(
+ this->Val.getPointer());
}
explicit operator bool() const { return !isNull(); }
/// Test if the Union currently holds the type matching T.
template <typename T> int is() const {
- using Ty = typename ::llvm::PointerUnionTypeSelector<
- PT1, T, IsPT1,
- ::llvm::PointerUnionTypeSelector<PT2, T, IsPT2,
- UNION_DOESNT_CONTAIN_TYPE<T>>>::Return;
- int TyNo = Ty::Num;
- return static_cast<int>(Val.getInt()) == TyNo;
+ constexpr int Index = pointer_union_detail::TypeIndex<T, PTs...>::Index;
+ static_assert(Index < sizeof...(PTs),
+ "PointerUnion::is<T> given type not in the union");
+ return this->Val.getInt() == Index;
}
/// Returns the value of the specified pointer type.
@@ -133,7 +204,7 @@
/// If the specified pointer type is incorrect, assert.
template <typename T> T get() const {
assert(is<T>() && "Invalid accessor called");
- return PointerLikeTypeTraits<T>::getFromVoidPointer(Val.getPointer());
+ return PointerLikeTypeTraits<T>::getFromVoidPointer(this->Val.getPointer());
}
/// Returns the current pointer if it is of the specified pointer type,
@@ -146,342 +217,100 @@
/// If the union is set to the first pointer type get an address pointing to
/// it.
- PT1 const *getAddrOfPtr1() const {
+ First const *getAddrOfPtr1() const {
return const_cast<PointerUnion *>(this)->getAddrOfPtr1();
}
/// If the union is set to the first pointer type get an address pointing to
/// it.
- PT1 *getAddrOfPtr1() {
- assert(is<PT1>() && "Val is not the first pointer");
+ First *getAddrOfPtr1() {
+ assert(is<First>() && "Val is not the first pointer");
assert(
- get<PT1>() == Val.getPointer() &&
+ get<First>() == this->Val.getPointer() &&
"Can't get the address because PointerLikeTypeTraits changes the ptr");
- return const_cast<PT1 *>(
- reinterpret_cast<const PT1 *>(Val.getAddrOfPointer()));
+ return const_cast<First *>(
+ reinterpret_cast<const First *>(this->Val.getAddrOfPointer()));
}
/// Assignment from nullptr which just clears the union.
const PointerUnion &operator=(std::nullptr_t) {
- Val.initWithPointer(nullptr);
+ this->Val.initWithPointer(nullptr);
return *this;
}
- /// Assignment operators - Allow assigning into this union from either
- /// pointer type, setting the discriminator to remember what it came from.
- const PointerUnion &operator=(const PT1 &RHS) {
- Val.initWithPointer(
- const_cast<void *>(PointerLikeTypeTraits<PT1>::getAsVoidPointer(RHS)));
- return *this;
- }
- const PointerUnion &operator=(const PT2 &RHS) {
- Val.setPointerAndInt(
- const_cast<void *>(PointerLikeTypeTraits<PT2>::getAsVoidPointer(RHS)),
- 1);
- return *this;
- }
+ /// Assignment from elements of the union.
+ using Base::operator=;
- void *getOpaqueValue() const { return Val.getOpaqueValue(); }
+ void *getOpaqueValue() const { return this->Val.getOpaqueValue(); }
static inline PointerUnion getFromOpaqueValue(void *VP) {
PointerUnion V;
- V.Val = ValTy::getFromOpaqueValue(VP);
+ V.Val = decltype(V.Val)::getFromOpaqueValue(VP);
return V;
}
};
-template <typename PT1, typename PT2>
-bool operator==(PointerUnion<PT1, PT2> lhs, PointerUnion<PT1, PT2> rhs) {
+template <typename ...PTs>
+bool operator==(PointerUnion<PTs...> lhs, PointerUnion<PTs...> rhs) {
return lhs.getOpaqueValue() == rhs.getOpaqueValue();
}
-template <typename PT1, typename PT2>
-bool operator!=(PointerUnion<PT1, PT2> lhs, PointerUnion<PT1, PT2> rhs) {
+template <typename ...PTs>
+bool operator!=(PointerUnion<PTs...> lhs, PointerUnion<PTs...> rhs) {
return lhs.getOpaqueValue() != rhs.getOpaqueValue();
}
-template <typename PT1, typename PT2>
-bool operator<(PointerUnion<PT1, PT2> lhs, PointerUnion<PT1, PT2> rhs) {
+template <typename ...PTs>
+bool operator<(PointerUnion<PTs...> lhs, PointerUnion<PTs...> rhs) {
return lhs.getOpaqueValue() < rhs.getOpaqueValue();
}
// Teach SmallPtrSet that PointerUnion is "basically a pointer", that has
// # low bits available = min(PT1bits,PT2bits)-1.
-template <typename PT1, typename PT2>
-struct PointerLikeTypeTraits<PointerUnion<PT1, PT2>> {
- static inline void *getAsVoidPointer(const PointerUnion<PT1, PT2> &P) {
+template <typename ...PTs>
+struct PointerLikeTypeTraits<PointerUnion<PTs...>> {
+ static inline void *getAsVoidPointer(const PointerUnion<PTs...> &P) {
return P.getOpaqueValue();
}
- static inline PointerUnion<PT1, PT2> getFromVoidPointer(void *P) {
- return PointerUnion<PT1, PT2>::getFromOpaqueValue(P);
+ static inline PointerUnion<PTs...> getFromVoidPointer(void *P) {
+ return PointerUnion<PTs...>::getFromOpaqueValue(P);
}
- // The number of bits available are the min of the two pointer types.
- enum {
- NumLowBitsAvailable = PointerLikeTypeTraits<
- typename PointerUnion<PT1, PT2>::ValTy>::NumLowBitsAvailable
- };
+ // The number of bits available are the min of the pointer types minus the
+ // bits needed for the discriminator.
+ static constexpr int NumLowBitsAvailable = PointerLikeTypeTraits<decltype(
+ PointerUnion<PTs...>::Val)>::NumLowBitsAvailable;
};
/// A pointer union of three pointer types. See documentation for PointerUnion
/// for usage.
-template <typename PT1, typename PT2, typename PT3> class PointerUnion3 {
-public:
- using InnerUnion = PointerUnion<PT1, PT2>;
- using ValTy = PointerUnion<InnerUnion, PT3>;
-
-private:
- ValTy Val;
-
- struct IsInnerUnion {
- ValTy Val;
-
- IsInnerUnion(ValTy val) : Val(val) {}
-
- template <typename T> int is() const {
- return Val.template is<InnerUnion>() &&
- Val.template get<InnerUnion>().template is<T>();
- }
-
- template <typename T> T get() const {
- return Val.template get<InnerUnion>().template get<T>();
- }
- };
-
- struct IsPT3 {
- ValTy Val;
-
- IsPT3(ValTy val) : Val(val) {}
-
- template <typename T> int is() const { return Val.template is<T>(); }
- template <typename T> T get() const { return Val.template get<T>(); }
- };
-
-public:
- PointerUnion3() = default;
- PointerUnion3(PT1 V) { Val = InnerUnion(V); }
- PointerUnion3(PT2 V) { Val = InnerUnion(V); }
- PointerUnion3(PT3 V) { Val = V; }
-
- /// Test if the pointer held in the union is null, regardless of
- /// which type it is.
- bool isNull() const { return Val.isNull(); }
- explicit operator bool() const { return !isNull(); }
-
- /// Test if the Union currently holds the type matching T.
- template <typename T> int is() const {
- // If T is PT1/PT2 choose IsInnerUnion otherwise choose IsPT3.
- using Ty = typename ::llvm::PointerUnionTypeSelector<
- PT1, T, IsInnerUnion,
- ::llvm::PointerUnionTypeSelector<PT2, T, IsInnerUnion, IsPT3>>::Return;
- return Ty(Val).template is<T>();
- }
-
- /// Returns the value of the specified pointer type.
- ///
- /// If the specified pointer type is incorrect, assert.
- template <typename T> T get() const {
- assert(is<T>() && "Invalid accessor called");
- // If T is PT1/PT2 choose IsInnerUnion otherwise choose IsPT3.
- using Ty = typename ::llvm::PointerUnionTypeSelector<
- PT1, T, IsInnerUnion,
- ::llvm::PointerUnionTypeSelector<PT2, T, IsInnerUnion, IsPT3>>::Return;
- return Ty(Val).template get<T>();
- }
-
- /// Returns the current pointer if it is of the specified pointer type,
- /// otherwises returns null.
- template <typename T> T dyn_cast() const {
- if (is<T>())
- return get<T>();
- return T();
- }
-
- /// Assignment from nullptr which just clears the union.
- const PointerUnion3 &operator=(std::nullptr_t) {
- Val = nullptr;
- return *this;
- }
-
- /// Assignment operators - Allow assigning into this union from either
- /// pointer type, setting the discriminator to remember what it came from.
- const PointerUnion3 &operator=(const PT1 &RHS) {
- Val = InnerUnion(RHS);
- return *this;
- }
- const PointerUnion3 &operator=(const PT2 &RHS) {
- Val = InnerUnion(RHS);
- return *this;
- }
- const PointerUnion3 &operator=(const PT3 &RHS) {
- Val = RHS;
- return *this;
- }
-
- void *getOpaqueValue() const { return Val.getOpaqueValue(); }
- static inline PointerUnion3 getFromOpaqueValue(void *VP) {
- PointerUnion3 V;
- V.Val = ValTy::getFromOpaqueValue(VP);
- return V;
- }
-};
-
-// Teach SmallPtrSet that PointerUnion3 is "basically a pointer", that has
-// # low bits available = min(PT1bits,PT2bits,PT2bits)-2.
template <typename PT1, typename PT2, typename PT3>
-struct PointerLikeTypeTraits<PointerUnion3<PT1, PT2, PT3>> {
- static inline void *getAsVoidPointer(const PointerUnion3<PT1, PT2, PT3> &P) {
- return P.getOpaqueValue();
- }
-
- static inline PointerUnion3<PT1, PT2, PT3> getFromVoidPointer(void *P) {
- return PointerUnion3<PT1, PT2, PT3>::getFromOpaqueValue(P);
- }
-
- // The number of bits available are the min of the two pointer types.
- enum {
- NumLowBitsAvailable = PointerLikeTypeTraits<
- typename PointerUnion3<PT1, PT2, PT3>::ValTy>::NumLowBitsAvailable
- };
-};
-
-template <typename PT1, typename PT2, typename PT3>
-bool operator<(PointerUnion3<PT1, PT2, PT3> lhs,
- PointerUnion3<PT1, PT2, PT3> rhs) {
- return lhs.getOpaqueValue() < rhs.getOpaqueValue();
-}
+using PointerUnion3 = PointerUnion<PT1, PT2, PT3>;
/// A pointer union of four pointer types. See documentation for PointerUnion
/// for usage.
template <typename PT1, typename PT2, typename PT3, typename PT4>
-class PointerUnion4 {
-public:
- using InnerUnion1 = PointerUnion<PT1, PT2>;
- using InnerUnion2 = PointerUnion<PT3, PT4>;
- using ValTy = PointerUnion<InnerUnion1, InnerUnion2>;
-
-private:
- ValTy Val;
-
-public:
- PointerUnion4() = default;
- PointerUnion4(PT1 V) { Val = InnerUnion1(V); }
- PointerUnion4(PT2 V) { Val = InnerUnion1(V); }
- PointerUnion4(PT3 V) { Val = InnerUnion2(V); }
- PointerUnion4(PT4 V) { Val = InnerUnion2(V); }
-
- /// Test if the pointer held in the union is null, regardless of
- /// which type it is.
- bool isNull() const { return Val.isNull(); }
- explicit operator bool() const { return !isNull(); }
-
- /// Test if the Union currently holds the type matching T.
- template <typename T> int is() const {
- // If T is PT1/PT2 choose InnerUnion1 otherwise choose InnerUnion2.
- using Ty = typename ::llvm::PointerUnionTypeSelector<
- PT1, T, InnerUnion1,
- ::llvm::PointerUnionTypeSelector<PT2, T, InnerUnion1,
- InnerUnion2>>::Return;
- return Val.template is<Ty>() && Val.template get<Ty>().template is<T>();
- }
-
- /// Returns the value of the specified pointer type.
- ///
- /// If the specified pointer type is incorrect, assert.
- template <typename T> T get() const {
- assert(is<T>() && "Invalid accessor called");
- // If T is PT1/PT2 choose InnerUnion1 otherwise choose InnerUnion2.
- using Ty = typename ::llvm::PointerUnionTypeSelector<
- PT1, T, InnerUnion1,
- ::llvm::PointerUnionTypeSelector<PT2, T, InnerUnion1,
- InnerUnion2>>::Return;
- return Val.template get<Ty>().template get<T>();
- }
-
- /// Returns the current pointer if it is of the specified pointer type,
- /// otherwises returns null.
- template <typename T> T dyn_cast() const {
- if (is<T>())
- return get<T>();
- return T();
- }
-
- /// Assignment from nullptr which just clears the union.
- const PointerUnion4 &operator=(std::nullptr_t) {
- Val = nullptr;
- return *this;
- }
-
- /// Assignment operators - Allow assigning into this union from either
- /// pointer type, setting the discriminator to remember what it came from.
- const PointerUnion4 &operator=(const PT1 &RHS) {
- Val = InnerUnion1(RHS);
- return *this;
- }
- const PointerUnion4 &operator=(const PT2 &RHS) {
- Val = InnerUnion1(RHS);
- return *this;
- }
- const PointerUnion4 &operator=(const PT3 &RHS) {
- Val = InnerUnion2(RHS);
- return *this;
- }
- const PointerUnion4 &operator=(const PT4 &RHS) {
- Val = InnerUnion2(RHS);
- return *this;
- }
-
- void *getOpaqueValue() const { return Val.getOpaqueValue(); }
- static inline PointerUnion4 getFromOpaqueValue(void *VP) {
- PointerUnion4 V;
- V.Val = ValTy::getFromOpaqueValue(VP);
- return V;
- }
-};
-
-// Teach SmallPtrSet that PointerUnion4 is "basically a pointer", that has
-// # low bits available = min(PT1bits,PT2bits,PT2bits)-2.
-template <typename PT1, typename PT2, typename PT3, typename PT4>
-struct PointerLikeTypeTraits<PointerUnion4<PT1, PT2, PT3, PT4>> {
- static inline void *
- getAsVoidPointer(const PointerUnion4<PT1, PT2, PT3, PT4> &P) {
- return P.getOpaqueValue();
- }
-
- static inline PointerUnion4<PT1, PT2, PT3, PT4> getFromVoidPointer(void *P) {
- return PointerUnion4<PT1, PT2, PT3, PT4>::getFromOpaqueValue(P);
- }
-
- // The number of bits available are the min of the two pointer types.
- enum {
- NumLowBitsAvailable = PointerLikeTypeTraits<
- typename PointerUnion4<PT1, PT2, PT3, PT4>::ValTy>::NumLowBitsAvailable
- };
-};
+using PointerUnion4 = PointerUnion<PT1, PT2, PT3, PT4>;
// Teach DenseMap how to use PointerUnions as keys.
-template <typename T, typename U> struct DenseMapInfo<PointerUnion<T, U>> {
- using Pair = PointerUnion<T, U>;
- using FirstInfo = DenseMapInfo<T>;
- using SecondInfo = DenseMapInfo<U>;
+template <typename ...PTs> struct DenseMapInfo<PointerUnion<PTs...>> {
+ using Union = PointerUnion<PTs...>;
+ using FirstInfo =
+ DenseMapInfo<typename pointer_union_detail::GetFirstType<PTs...>::type>;
- static inline Pair getEmptyKey() { return Pair(FirstInfo::getEmptyKey()); }
+ static inline Union getEmptyKey() { return Union(FirstInfo::getEmptyKey()); }
- static inline Pair getTombstoneKey() {
- return Pair(FirstInfo::getTombstoneKey());
+ static inline Union getTombstoneKey() {
+ return Union(FirstInfo::getTombstoneKey());
}
- static unsigned getHashValue(const Pair &PairVal) {
- intptr_t key = (intptr_t)PairVal.getOpaqueValue();
+ static unsigned getHashValue(const Union &UnionVal) {
+ intptr_t key = (intptr_t)UnionVal.getOpaqueValue();
return DenseMapInfo<intptr_t>::getHashValue(key);
}
- static bool isEqual(const Pair &LHS, const Pair &RHS) {
- return LHS.template is<T>() == RHS.template is<T>() &&
- (LHS.template is<T>() ? FirstInfo::isEqual(LHS.template get<T>(),
- RHS.template get<T>())
- : SecondInfo::isEqual(LHS.template get<U>(),
- RHS.template get<U>()));
+ static bool isEqual(const Union &LHS, const Union &RHS) {
+ return LHS == RHS;
}
};
diff --git a/linux-x64/clang/include/llvm/ADT/STLExtras.h b/linux-x64/clang/include/llvm/ADT/STLExtras.h
index 9a891d1..81dce01 100644
--- a/linux-x64/clang/include/llvm/ADT/STLExtras.h
+++ b/linux-x64/clang/include/llvm/ADT/STLExtras.h
@@ -240,6 +240,13 @@
return mapped_iterator<ItTy, FuncTy>(std::move(I), std::move(F));
}
+template <class ContainerTy, class FuncTy>
+auto map_range(ContainerTy &&C, FuncTy F)
+ -> decltype(make_range(map_iterator(C.begin(), F),
+ map_iterator(C.end(), F))) {
+ return make_range(map_iterator(C.begin(), F), map_iterator(C.end(), F));
+}
+
/// Helper to determine if type T has a member called rbegin().
template <typename Ty> class has_rbegin_impl {
using yes = char[1];
@@ -1277,29 +1284,52 @@
/// Provide wrappers to std::lower_bound which take ranges instead of having to
/// pass begin/end explicitly.
-template <typename R, typename ForwardIt>
-auto lower_bound(R &&Range, ForwardIt I) -> decltype(adl_begin(Range)) {
- return std::lower_bound(adl_begin(Range), adl_end(Range), I);
+template <typename R, typename T>
+auto lower_bound(R &&Range, T &&Value) -> decltype(adl_begin(Range)) {
+ return std::lower_bound(adl_begin(Range), adl_end(Range),
+ std::forward<T>(Value));
}
-template <typename R, typename ForwardIt, typename Compare>
-auto lower_bound(R &&Range, ForwardIt I, Compare C)
+template <typename R, typename T, typename Compare>
+auto lower_bound(R &&Range, T &&Value, Compare C)
-> decltype(adl_begin(Range)) {
- return std::lower_bound(adl_begin(Range), adl_end(Range), I, C);
+ return std::lower_bound(adl_begin(Range), adl_end(Range),
+ std::forward<T>(Value), C);
}
/// Provide wrappers to std::upper_bound which take ranges instead of having to
/// pass begin/end explicitly.
-template <typename R, typename ForwardIt>
-auto upper_bound(R &&Range, ForwardIt I) -> decltype(adl_begin(Range)) {
- return std::upper_bound(adl_begin(Range), adl_end(Range), I);
+template <typename R, typename T>
+auto upper_bound(R &&Range, T &&Value) -> decltype(adl_begin(Range)) {
+ return std::upper_bound(adl_begin(Range), adl_end(Range),
+ std::forward<T>(Value));
}
-template <typename R, typename ForwardIt, typename Compare>
-auto upper_bound(R &&Range, ForwardIt I, Compare C)
+template <typename R, typename T, typename Compare>
+auto upper_bound(R &&Range, T &&Value, Compare C)
-> decltype(adl_begin(Range)) {
- return std::upper_bound(adl_begin(Range), adl_end(Range), I, C);
+ return std::upper_bound(adl_begin(Range), adl_end(Range),
+ std::forward<T>(Value), C);
}
+
+template <typename R>
+void stable_sort(R &&Range) {
+ std::stable_sort(adl_begin(Range), adl_end(Range));
+}
+
+template <typename R, typename Compare>
+void stable_sort(R &&Range, Compare C) {
+ std::stable_sort(adl_begin(Range), adl_end(Range), C);
+}
+
+/// Binary search for the first iterator in a range where a predicate is false.
+/// Requires that C is always true below some limit, and always false above it.
+template <typename R, typename Predicate,
+ typename Val = decltype(*adl_begin(std::declval<R>()))>
+auto partition_point(R &&Range, Predicate P) -> decltype(adl_begin(Range)) {
+ return std::partition_point(adl_begin(Range), adl_end(Range), P);
+}
+
/// Wrapper function around std::equal to detect if all elements
/// in a container are same.
template <typename R>
@@ -1330,6 +1360,33 @@
C.erase(remove_if(C, P), C.end());
}
+/// Given a sequence container Cont, replace the range [ContIt, ContEnd) with
+/// the range [ValIt, ValEnd) (which is not from the same container).
+template<typename Container, typename RandomAccessIterator>
+void replace(Container &Cont, typename Container::iterator ContIt,
+ typename Container::iterator ContEnd, RandomAccessIterator ValIt,
+ RandomAccessIterator ValEnd) {
+ while (true) {
+ if (ValIt == ValEnd) {
+ Cont.erase(ContIt, ContEnd);
+ return;
+ } else if (ContIt == ContEnd) {
+ Cont.insert(ContIt, ValIt, ValEnd);
+ return;
+ }
+ *ContIt++ = *ValIt++;
+ }
+}
+
+/// Given a sequence container Cont, replace the range [ContIt, ContEnd) with
+/// the range R.
+template<typename Container, typename Range = std::initializer_list<
+ typename Container::value_type>>
+void replace(Container &Cont, typename Container::iterator ContIt,
+ typename Container::iterator ContEnd, Range R) {
+ replace(Cont, ContIt, ContEnd, R.begin(), R.end());
+}
+
//===----------------------------------------------------------------------===//
// Extra additions to <memory>
//===----------------------------------------------------------------------===//
@@ -1417,6 +1474,9 @@
template <typename R> class enumerator_iter;
template <typename R> struct result_pair {
+ using value_reference =
+ typename std::iterator_traits<IterOfRange<R>>::reference;
+
friend class enumerator_iter<R>;
result_pair() = default;
@@ -1430,8 +1490,8 @@
}
std::size_t index() const { return Index; }
- const ValueOfRange<R> &value() const { return *Iter; }
- ValueOfRange<R> &value() { return *Iter; }
+ const value_reference value() const { return *Iter; }
+ value_reference value() { return *Iter; }
private:
std::size_t Index = std::numeric_limits<std::size_t>::max();
@@ -1576,6 +1636,19 @@
return true;
}
+/// Returns a raw pointer that represents the same address as the argument.
+///
+/// The late bound return should be removed once we move to C++14 to better
+/// align with the C++20 declaration. Also, this implementation can be removed
+/// once we move to C++20 where it's defined as std::to_addres()
+///
+/// The std::pointer_traits<>::to_address(p) variations of these overloads has
+/// not been implemented.
+template <class Ptr> auto to_address(const Ptr &P) -> decltype(P.operator->()) {
+ return P.operator->();
+}
+template <class T> constexpr T *to_address(T *P) { return P; }
+
} // end namespace llvm
#endif // LLVM_ADT_STLEXTRAS_H
diff --git a/linux-x64/clang/include/llvm/ADT/SmallVector.h b/linux-x64/clang/include/llvm/ADT/SmallVector.h
index e3bfb90..1758690 100644
--- a/linux-x64/clang/include/llvm/ADT/SmallVector.h
+++ b/linux-x64/clang/include/llvm/ADT/SmallVector.h
@@ -41,8 +41,8 @@
unsigned Size = 0, Capacity;
SmallVectorBase() = delete;
- SmallVectorBase(void *FirstEl, size_t Capacity)
- : BeginX(FirstEl), Capacity(Capacity) {}
+ SmallVectorBase(void *FirstEl, size_t TotalCapacity)
+ : BeginX(FirstEl), Capacity(TotalCapacity) {}
/// This is an implementation of the grow() method which only works
/// on POD-like data types and is out of line to reduce code duplication.
@@ -63,9 +63,9 @@
/// of the buffer when they know that more elements are available, and only
/// update the size later. This avoids the cost of value initializing elements
/// which will only be overwritten.
- void set_size(size_t Size) {
- assert(Size <= capacity());
- this->Size = Size;
+ void set_size(size_t N) {
+ assert(N <= capacity());
+ Size = N;
}
};
@@ -318,6 +318,7 @@
public:
using iterator = typename SuperClass::iterator;
using const_iterator = typename SuperClass::const_iterator;
+ using reference = typename SuperClass::reference;
using size_type = typename SuperClass::size_type;
protected:
@@ -385,22 +386,18 @@
std::input_iterator_tag>::value>::type>
void append(in_iter in_start, in_iter in_end) {
size_type NumInputs = std::distance(in_start, in_end);
- // Grow allocated space if needed.
if (NumInputs > this->capacity() - this->size())
this->grow(this->size()+NumInputs);
- // Copy the new elements over.
this->uninitialized_copy(in_start, in_end, this->end());
this->set_size(this->size() + NumInputs);
}
- /// Add the specified range to the end of the SmallVector.
+ /// Append \p NumInputs copies of \p Elt to the end.
void append(size_type NumInputs, const T &Elt) {
- // Grow allocated space if needed.
if (NumInputs > this->capacity() - this->size())
this->grow(this->size()+NumInputs);
- // Copy the new elements over.
std::uninitialized_fill_n(this->end(), NumInputs, Elt);
this->set_size(this->size() + NumInputs);
}
@@ -641,11 +638,12 @@
insert(I, IL.begin(), IL.end());
}
- template <typename... ArgTypes> void emplace_back(ArgTypes &&... Args) {
+ template <typename... ArgTypes> reference emplace_back(ArgTypes &&... Args) {
if (LLVM_UNLIKELY(this->size() >= this->capacity()))
this->grow();
::new ((void *)this->end()) T(std::forward<ArgTypes>(Args)...);
this->set_size(this->size() + 1);
+ return this->back();
}
SmallVectorImpl &operator=(const SmallVectorImpl &RHS);
diff --git a/linux-x64/clang/include/llvm/ADT/StringMap.h b/linux-x64/clang/include/llvm/ADT/StringMap.h
index d94e483..8a586fc 100644
--- a/linux-x64/clang/include/llvm/ADT/StringMap.h
+++ b/linux-x64/clang/include/llvm/ADT/StringMap.h
@@ -359,6 +359,11 @@
return find(Key) == end() ? 0 : 1;
}
+ template <typename InputTy>
+ size_type count(const StringMapEntry<InputTy> &MapEntry) const {
+ return count(MapEntry.getKey());
+ }
+
/// insert - Insert the specified key/value pair into the map. If the key
/// already exists in the map, return false and ignore the request, otherwise
/// insert it and return true.
diff --git a/linux-x64/clang/include/llvm/ADT/StringSet.h b/linux-x64/clang/include/llvm/ADT/StringSet.h
index fcf9519..af3a44a 100644
--- a/linux-x64/clang/include/llvm/ADT/StringSet.h
+++ b/linux-x64/clang/include/llvm/ADT/StringSet.h
@@ -33,6 +33,7 @@
for (StringRef X : S)
insert(X);
}
+ explicit StringSet(AllocatorTy A) : base(A) {}
std::pair<typename base::iterator, bool> insert(StringRef Key) {
assert(!Key.empty());
@@ -44,6 +45,12 @@
for (auto It = Begin; It != End; ++It)
base::insert(std::make_pair(*It, '\0'));
}
+
+ template <typename ValueTy>
+ std::pair<typename base::iterator, bool>
+ insert(const StringMapEntry<ValueTy> &MapEntry) {
+ return insert(MapEntry.getKey());
+ }
};
} // end namespace llvm
diff --git a/linux-x64/clang/include/llvm/ADT/Triple.h b/linux-x64/clang/include/llvm/ADT/Triple.h
index 70d8879..edeb31e 100644
--- a/linux-x64/clang/include/llvm/ADT/Triple.h
+++ b/linux-x64/clang/include/llvm/ADT/Triple.h
@@ -49,6 +49,7 @@
armeb, // ARM (big endian): armeb
aarch64, // AArch64 (little endian): aarch64
aarch64_be, // AArch64 (big endian): aarch64_be
+ aarch64_32, // AArch64 (little endian) ILP32: aarch64_32
arc, // ARC: Synopsys ARC
avr, // AVR: Atmel AVR microcontroller
bpfel, // eBPF or extended BPF or 64-bit BPF (little endian)
@@ -108,6 +109,7 @@
ARMSubArch_v8r,
ARMSubArch_v8m_baseline,
ARMSubArch_v8m_mainline,
+ ARMSubArch_v8_1m_mainline,
ARMSubArch_v7,
ARMSubArch_v7em,
ARMSubArch_v7m,
@@ -186,7 +188,8 @@
HermitCore, // HermitCore Unikernel/Multikernel
Hurd, // GNU/Hurd
WASI, // Experimental WebAssembly OS
- LastOSType = WASI
+ Emscripten,
+ LastOSType = Emscripten
};
enum EnvironmentType {
UnknownEnvironment,
@@ -200,6 +203,8 @@
CODE16,
EABI,
EABIHF,
+ ELFv1,
+ ELFv2,
Android,
Musl,
MuslEABI,
@@ -209,8 +214,9 @@
Itanium,
Cygnus,
CoreCLR,
- Simulator, // Simulator variants of other systems, e.g., Apple's iOS
- LastEnvironmentType = Simulator
+ Simulator, // Simulator variants of other systems, e.g., Apple's iOS
+ MacABI, // Mac Catalyst variant of Apple's iOS deployment target.
+ LastEnvironmentType = MacABI
};
enum ObjectFormatType {
UnknownObjectFormat,
@@ -219,6 +225,7 @@
ELF,
MachO,
Wasm,
+ XCOFF,
};
private:
@@ -479,6 +486,10 @@
return getEnvironment() == Triple::Simulator;
}
+ bool isMacCatalystEnvironment() const {
+ return getEnvironment() == Triple::MacABI;
+ }
+
bool isOSNetBSD() const {
return getOS() == Triple::NetBSD;
}
@@ -591,6 +602,11 @@
return getOS() == Triple::WASI;
}
+ /// Tests whether the OS is Emscripten.
+ bool isOSEmscripten() const {
+ return getOS() == Triple::Emscripten;
+ }
+
/// Tests whether the OS uses glibc.
bool isOSGlibc() const {
return (getOS() == Triple::Linux || getOS() == Triple::KFreeBSD ||
@@ -598,6 +614,11 @@
!isAndroid();
}
+ /// Tests whether the OS is AIX.
+ bool isOSAIX() const {
+ return getOS() == Triple::AIX;
+ }
+
/// Tests whether the OS uses the ELF binary format.
bool isOSBinFormatELF() const {
return getObjectFormat() == Triple::ELF;
@@ -618,6 +639,11 @@
return getObjectFormat() == Triple::Wasm;
}
+ /// Tests whether the OS uses the XCOFF binary format.
+ bool isOSBinFormatXCOFF() const {
+ return getObjectFormat() == Triple::XCOFF;
+ }
+
/// Tests whether the target is the PS4 CPU
bool isPS4CPU() const {
return getArch() == Triple::x86_64 &&
@@ -654,6 +680,11 @@
getEnvironment() == Triple::MuslEABIHF;
}
+ /// Tests whether the target is SPIR (32- or 64-bit).
+ bool isSPIR() const {
+ return getArch() == Triple::spir || getArch() == Triple::spir64;
+ }
+
/// Tests whether the target is NVPTX (32- or 64-bit).
bool isNVPTX() const {
return getArch() == Triple::nvptx || getArch() == Triple::nvptx64;
@@ -689,6 +720,16 @@
return isMIPS32() || isMIPS64();
}
+ /// Tests whether the target is 64-bit PowerPC (little and big endian).
+ bool isPPC64() const {
+ return getArch() == Triple::ppc64 || getArch() == Triple::ppc64le;
+ }
+
+ /// Tests whether the target is RISC-V (32- and 64-bit).
+ bool isRISCV() const {
+ return getArch() == Triple::riscv32 || getArch() == Triple::riscv64;
+ }
+
/// Tests whether the target supports comdat
bool supportsCOMDAT() const {
return !isOSBinFormatMachO();