3PP: Bump submodules
This commit is contained in:
parent
13badbb4c0
commit
bb20ada9bf
|
@ -1 +1 @@
|
||||||
Subproject commit 79ec168f3c1e2fe27335cb8886439f7ef676fb49
|
Subproject commit fa24d868ac2f8fd558e4e914c9863411245db8fd
|
|
@ -1 +1 @@
|
||||||
Subproject commit 1c35ba99ce775f8342d87a83a3f0f696f99c2a39
|
Subproject commit 3bab6924988e5f19bf36586a496156cf72f70d9f
|
|
@ -1 +1 @@
|
||||||
Subproject commit af1ed2fb3d9d67926389a71e12531bef76f50482
|
Subproject commit 66b08439abd988e87b4542389b4937ce13bd0063
|
|
@ -1 +1 @@
|
||||||
Subproject commit 63d1b65a694cfceafc20863afa75df49dfbe6b2a
|
Subproject commit f029892dab60526184ee42ae63a7f6d19a6b0e49
|
|
@ -1 +1 @@
|
||||||
Subproject commit 51ce7e131079c061533d741be5fe7cca57f2faac
|
Subproject commit 5bdb7e6f31fac909c090a46dbd9fea27b6e609a4
|
|
@ -1 +1 @@
|
||||||
Subproject commit 0c9fce2ffefecfdce794e1859584e25877b7b592
|
Subproject commit e3ddede6c4ee818825c4e5a6dfa1d384860c27d9
|
|
@ -1,5 +1,5 @@
|
||||||
This is automated checker to make sure a C++ file follows Google's C++ style
|
This is automated checker to make sure a C++ file follows Google's C++ style
|
||||||
guide (http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml). As it
|
guide (https://google.github.io/styleguide/cppguide.html). As it
|
||||||
heavily relies on regular expressions, cpplint.py won't catch all violations of
|
heavily relies on regular expressions, cpplint.py won't catch all violations of
|
||||||
the style guide and will very occasionally report a false positive. There is a
|
the style guide and will very occasionally report a false positive. There is a
|
||||||
list of things we currently don't handle very well at the top of cpplint.py,
|
list of things we currently don't handle very well at the top of cpplint.py,
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -4,7 +4,7 @@ LLVM Release License
|
||||||
University of Illinois/NCSA
|
University of Illinois/NCSA
|
||||||
Open Source License
|
Open Source License
|
||||||
|
|
||||||
Copyright (c) 2003-2014 University of Illinois at Urbana-Champaign.
|
Copyright (c) 2003-2015 University of Illinois at Urbana-Champaign.
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Developed by:
|
Developed by:
|
||||||
|
@ -63,7 +63,6 @@ Program Directory
|
||||||
------- ---------
|
------- ---------
|
||||||
Autoconf llvm/autoconf
|
Autoconf llvm/autoconf
|
||||||
llvm/projects/ModuleMaker/autoconf
|
llvm/projects/ModuleMaker/autoconf
|
||||||
llvm/projects/sample/autoconf
|
|
||||||
Google Test llvm/utils/unittest/googletest
|
Google Test llvm/utils/unittest/googletest
|
||||||
OpenBSD regex llvm/lib/Support/{reg*, COPYRIGHT.regex}
|
OpenBSD regex llvm/lib/Support/{reg*, COPYRIGHT.regex}
|
||||||
pyyaml tests llvm/test/YAMLParser/{*.data, LICENSE.TXT}
|
pyyaml tests llvm/test/YAMLParser/{*.data, LICENSE.TXT}
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
// here just to keep gyp happy
|
|
|
@ -33,11 +33,15 @@ class BitVector {
|
||||||
|
|
||||||
enum { BITWORD_SIZE = (unsigned)sizeof(BitWord) * CHAR_BIT };
|
enum { BITWORD_SIZE = (unsigned)sizeof(BitWord) * CHAR_BIT };
|
||||||
|
|
||||||
|
static_assert(BITWORD_SIZE == 64 || BITWORD_SIZE == 32,
|
||||||
|
"Unsupported word size");
|
||||||
|
|
||||||
BitWord *Bits; // Actual bits.
|
BitWord *Bits; // Actual bits.
|
||||||
unsigned Size; // Size of bitvector in bits.
|
unsigned Size; // Size of bitvector in bits.
|
||||||
unsigned Capacity; // Size of allocated memory in BitWord.
|
unsigned Capacity; // Number of BitWords allocated in the Bits array.
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
typedef unsigned size_type;
|
||||||
// Encapsulation of a single bit.
|
// Encapsulation of a single bit.
|
||||||
class reference {
|
class reference {
|
||||||
friend class BitVector;
|
friend class BitVector;
|
||||||
|
@ -53,7 +57,7 @@ public:
|
||||||
BitPos = Idx % BITWORD_SIZE;
|
BitPos = Idx % BITWORD_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
~reference() {}
|
reference(const reference&) = default;
|
||||||
|
|
||||||
reference &operator=(reference t) {
|
reference &operator=(reference t) {
|
||||||
*this = bool(t);
|
*this = bool(t);
|
||||||
|
@ -62,21 +66,21 @@ public:
|
||||||
|
|
||||||
reference& operator=(bool t) {
|
reference& operator=(bool t) {
|
||||||
if (t)
|
if (t)
|
||||||
*WordRef |= 1L << BitPos;
|
*WordRef |= BitWord(1) << BitPos;
|
||||||
else
|
else
|
||||||
*WordRef &= ~(1L << BitPos);
|
*WordRef &= ~(BitWord(1) << BitPos);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
operator bool() const {
|
operator bool() const {
|
||||||
return ((*WordRef) & (1L << BitPos)) ? true : false;
|
return ((*WordRef) & (BitWord(1) << BitPos)) ? true : false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/// BitVector default ctor - Creates an empty bitvector.
|
/// BitVector default ctor - Creates an empty bitvector.
|
||||||
BitVector() : Size(0), Capacity(0) {
|
BitVector() : Size(0), Capacity(0) {
|
||||||
Bits = 0;
|
Bits = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// BitVector ctor - Creates a bitvector of specified number of bits. All
|
/// BitVector ctor - Creates a bitvector of specified number of bits. All
|
||||||
|
@ -92,7 +96,7 @@ public:
|
||||||
/// BitVector copy ctor.
|
/// BitVector copy ctor.
|
||||||
BitVector(const BitVector &RHS) : Size(RHS.size()) {
|
BitVector(const BitVector &RHS) : Size(RHS.size()) {
|
||||||
if (Size == 0) {
|
if (Size == 0) {
|
||||||
Bits = 0;
|
Bits = nullptr;
|
||||||
Capacity = 0;
|
Capacity = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -102,12 +106,10 @@ public:
|
||||||
std::memcpy(Bits, RHS.Bits, Capacity * sizeof(BitWord));
|
std::memcpy(Bits, RHS.Bits, Capacity * sizeof(BitWord));
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LLVM_HAS_RVALUE_REFERENCES
|
|
||||||
BitVector(BitVector &&RHS)
|
BitVector(BitVector &&RHS)
|
||||||
: Bits(RHS.Bits), Size(RHS.Size), Capacity(RHS.Capacity) {
|
: Bits(RHS.Bits), Size(RHS.Size), Capacity(RHS.Capacity) {
|
||||||
RHS.Bits = 0;
|
RHS.Bits = nullptr;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
~BitVector() {
|
~BitVector() {
|
||||||
std::free(Bits);
|
std::free(Bits);
|
||||||
|
@ -117,18 +119,13 @@ public:
|
||||||
bool empty() const { return Size == 0; }
|
bool empty() const { return Size == 0; }
|
||||||
|
|
||||||
/// size - Returns the number of bits in this bitvector.
|
/// size - Returns the number of bits in this bitvector.
|
||||||
unsigned size() const { return Size; }
|
size_type size() const { return Size; }
|
||||||
|
|
||||||
/// count - Returns the number of bits which are set.
|
/// count - Returns the number of bits which are set.
|
||||||
unsigned count() const {
|
size_type count() const {
|
||||||
unsigned NumBits = 0;
|
unsigned NumBits = 0;
|
||||||
for (unsigned i = 0; i < NumBitWords(size()); ++i)
|
for (unsigned i = 0; i < NumBitWords(size()); ++i)
|
||||||
if (sizeof(BitWord) == 4)
|
NumBits += countPopulation(Bits[i]);
|
||||||
NumBits += CountPopulation_32((uint32_t)Bits[i]);
|
|
||||||
else if (sizeof(BitWord) == 8)
|
|
||||||
NumBits += CountPopulation_64(Bits[i]);
|
|
||||||
else
|
|
||||||
llvm_unreachable("Unsupported!");
|
|
||||||
return NumBits;
|
return NumBits;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,13 +159,8 @@ public:
|
||||||
/// of the bits are set.
|
/// of the bits are set.
|
||||||
int find_first() const {
|
int find_first() const {
|
||||||
for (unsigned i = 0; i < NumBitWords(size()); ++i)
|
for (unsigned i = 0; i < NumBitWords(size()); ++i)
|
||||||
if (Bits[i] != 0) {
|
if (Bits[i] != 0)
|
||||||
if (sizeof(BitWord) == 4)
|
return i * BITWORD_SIZE + countTrailingZeros(Bits[i]);
|
||||||
return i * BITWORD_SIZE + countTrailingZeros((uint32_t)Bits[i]);
|
|
||||||
if (sizeof(BitWord) == 8)
|
|
||||||
return i * BITWORD_SIZE + countTrailingZeros(Bits[i]);
|
|
||||||
llvm_unreachable("Unsupported!");
|
|
||||||
}
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,23 +177,13 @@ public:
|
||||||
// Mask off previous bits.
|
// Mask off previous bits.
|
||||||
Copy &= ~0UL << BitPos;
|
Copy &= ~0UL << BitPos;
|
||||||
|
|
||||||
if (Copy != 0) {
|
if (Copy != 0)
|
||||||
if (sizeof(BitWord) == 4)
|
return WordPos * BITWORD_SIZE + countTrailingZeros(Copy);
|
||||||
return WordPos * BITWORD_SIZE + countTrailingZeros((uint32_t)Copy);
|
|
||||||
if (sizeof(BitWord) == 8)
|
|
||||||
return WordPos * BITWORD_SIZE + countTrailingZeros(Copy);
|
|
||||||
llvm_unreachable("Unsupported!");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check subsequent words.
|
// Check subsequent words.
|
||||||
for (unsigned i = WordPos+1; i < NumBitWords(size()); ++i)
|
for (unsigned i = WordPos+1; i < NumBitWords(size()); ++i)
|
||||||
if (Bits[i] != 0) {
|
if (Bits[i] != 0)
|
||||||
if (sizeof(BitWord) == 4)
|
return i * BITWORD_SIZE + countTrailingZeros(Bits[i]);
|
||||||
return i * BITWORD_SIZE + countTrailingZeros((uint32_t)Bits[i]);
|
|
||||||
if (sizeof(BitWord) == 8)
|
|
||||||
return i * BITWORD_SIZE + countTrailingZeros(Bits[i]);
|
|
||||||
llvm_unreachable("Unsupported!");
|
|
||||||
}
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -244,7 +226,8 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
BitVector &set(unsigned Idx) {
|
BitVector &set(unsigned Idx) {
|
||||||
Bits[Idx / BITWORD_SIZE] |= 1L << (Idx % BITWORD_SIZE);
|
assert(Bits && "Bits never allocated");
|
||||||
|
Bits[Idx / BITWORD_SIZE] |= BitWord(1) << (Idx % BITWORD_SIZE);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -283,7 +266,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
BitVector &reset(unsigned Idx) {
|
BitVector &reset(unsigned Idx) {
|
||||||
Bits[Idx / BITWORD_SIZE] &= ~(1L << (Idx % BITWORD_SIZE));
|
Bits[Idx / BITWORD_SIZE] &= ~(BitWord(1) << (Idx % BITWORD_SIZE));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -324,7 +307,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
BitVector &flip(unsigned Idx) {
|
BitVector &flip(unsigned Idx) {
|
||||||
Bits[Idx / BITWORD_SIZE] ^= 1L << (Idx % BITWORD_SIZE);
|
Bits[Idx / BITWORD_SIZE] ^= BitWord(1) << (Idx % BITWORD_SIZE);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -336,7 +319,7 @@ public:
|
||||||
|
|
||||||
bool operator[](unsigned Idx) const {
|
bool operator[](unsigned Idx) const {
|
||||||
assert (Idx < Size && "Out-of-bounds Bit access.");
|
assert (Idx < Size && "Out-of-bounds Bit access.");
|
||||||
BitWord Mask = 1L << (Idx % BITWORD_SIZE);
|
BitWord Mask = BitWord(1) << (Idx % BITWORD_SIZE);
|
||||||
return (Bits[Idx / BITWORD_SIZE] & Mask) != 0;
|
return (Bits[Idx / BITWORD_SIZE] & Mask) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -455,6 +438,7 @@ public:
|
||||||
|
|
||||||
// Grow the bitvector to have enough elements.
|
// Grow the bitvector to have enough elements.
|
||||||
Capacity = RHSWords;
|
Capacity = RHSWords;
|
||||||
|
assert(Capacity > 0 && "negative capacity?");
|
||||||
BitWord *NewBits = (BitWord *)std::malloc(Capacity * sizeof(BitWord));
|
BitWord *NewBits = (BitWord *)std::malloc(Capacity * sizeof(BitWord));
|
||||||
std::memcpy(NewBits, RHS.Bits, Capacity * sizeof(BitWord));
|
std::memcpy(NewBits, RHS.Bits, Capacity * sizeof(BitWord));
|
||||||
|
|
||||||
|
@ -465,7 +449,6 @@ public:
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LLVM_HAS_RVALUE_REFERENCES
|
|
||||||
const BitVector &operator=(BitVector &&RHS) {
|
const BitVector &operator=(BitVector &&RHS) {
|
||||||
if (this == &RHS) return *this;
|
if (this == &RHS) return *this;
|
||||||
|
|
||||||
|
@ -474,11 +457,10 @@ public:
|
||||||
Size = RHS.Size;
|
Size = RHS.Size;
|
||||||
Capacity = RHS.Capacity;
|
Capacity = RHS.Capacity;
|
||||||
|
|
||||||
RHS.Bits = 0;
|
RHS.Bits = nullptr;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
void swap(BitVector &RHS) {
|
void swap(BitVector &RHS) {
|
||||||
std::swap(Bits, RHS.Bits);
|
std::swap(Bits, RHS.Bits);
|
||||||
|
@ -552,6 +534,7 @@ private:
|
||||||
|
|
||||||
void grow(unsigned NewSize) {
|
void grow(unsigned NewSize) {
|
||||||
Capacity = std::max(NumBitWords(NewSize), Capacity * 2);
|
Capacity = std::max(NumBitWords(NewSize), Capacity * 2);
|
||||||
|
assert(Capacity > 0 && "realloc-ing zero space");
|
||||||
Bits = (BitWord *)std::realloc(Bits, Capacity * sizeof(BitWord));
|
Bits = (BitWord *)std::realloc(Bits, Capacity * sizeof(BitWord));
|
||||||
|
|
||||||
clear_unused_bits();
|
clear_unused_bits();
|
||||||
|
@ -563,7 +546,7 @@ private:
|
||||||
|
|
||||||
template<bool AddBits, bool InvertMask>
|
template<bool AddBits, bool InvertMask>
|
||||||
void applyMask(const uint32_t *Mask, unsigned MaskWords) {
|
void applyMask(const uint32_t *Mask, unsigned MaskWords) {
|
||||||
assert(BITWORD_SIZE % 32 == 0 && "Unsupported BitWord size.");
|
static_assert(BITWORD_SIZE % 32 == 0, "Unsupported BitWord size.");
|
||||||
MaskWords = std::min(MaskWords, (size() + 31) / 32);
|
MaskWords = std::min(MaskWords, (size() + 31) / 32);
|
||||||
const unsigned Scale = BITWORD_SIZE / 32;
|
const unsigned Scale = BITWORD_SIZE / 32;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
@ -587,8 +570,16 @@ private:
|
||||||
if (AddBits)
|
if (AddBits)
|
||||||
clear_unused_bits();
|
clear_unused_bits();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/// Return the size (in bytes) of the bit vector.
|
||||||
|
size_t getMemorySize() const { return Capacity * sizeof(BitWord); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static inline size_t capacity_in_bytes(const BitVector &X) {
|
||||||
|
return X.getMemorySize();
|
||||||
|
}
|
||||||
|
|
||||||
} // End llvm namespace
|
} // End llvm namespace
|
||||||
|
|
||||||
namespace std {
|
namespace std {
|
||||||
|
|
|
@ -33,140 +33,65 @@
|
||||||
# define __has_builtin(x) 0
|
# define __has_builtin(x) 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/// \macro __GNUC_PREREQ
|
/// \macro LLVM_GNUC_PREREQ
|
||||||
/// \brief Defines __GNUC_PREREQ if glibc's features.h isn't available.
|
/// \brief Extend the default __GNUC_PREREQ even if glibc's features.h isn't
|
||||||
#ifndef __GNUC_PREREQ
|
/// available.
|
||||||
# if defined(__GNUC__) && defined(__GNUC_MINOR__)
|
#ifndef LLVM_GNUC_PREREQ
|
||||||
# define __GNUC_PREREQ(maj, min) \
|
# if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__)
|
||||||
((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
|
# define LLVM_GNUC_PREREQ(maj, min, patch) \
|
||||||
|
((__GNUC__ << 20) + (__GNUC_MINOR__ << 10) + __GNUC_PATCHLEVEL__ >= \
|
||||||
|
((maj) << 20) + ((min) << 10) + (patch))
|
||||||
|
# elif defined(__GNUC__) && defined(__GNUC_MINOR__)
|
||||||
|
# define LLVM_GNUC_PREREQ(maj, min, patch) \
|
||||||
|
((__GNUC__ << 20) + (__GNUC_MINOR__ << 10) >= ((maj) << 20) + ((min) << 10))
|
||||||
# else
|
# else
|
||||||
# define __GNUC_PREREQ(maj, min) 0
|
# define LLVM_GNUC_PREREQ(maj, min, patch) 0
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/// \macro LLVM_MSC_PREREQ
|
/// \macro LLVM_MSC_PREREQ
|
||||||
/// \brief Is the compiler MSVC of at least the specified version?
|
/// \brief Is the compiler MSVC of at least the specified version?
|
||||||
/// The common \param version values to check for are:
|
/// The common \param version values to check for are:
|
||||||
/// * 1600: Microsoft Visual Studio 2010 / 10.0
|
|
||||||
/// * 1700: Microsoft Visual Studio 2012 / 11.0
|
|
||||||
/// * 1800: Microsoft Visual Studio 2013 / 12.0
|
/// * 1800: Microsoft Visual Studio 2013 / 12.0
|
||||||
|
/// * 1900: Microsoft Visual Studio 2015 / 14.0
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#define LLVM_MSC_PREREQ(version) (_MSC_VER >= (version))
|
#define LLVM_MSC_PREREQ(version) (_MSC_VER >= (version))
|
||||||
|
|
||||||
|
// We require at least MSVC 2013.
|
||||||
|
#if !LLVM_MSC_PREREQ(1800)
|
||||||
|
#error LLVM requires at least MSVC 2013.
|
||||||
|
#endif
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#define LLVM_MSC_PREREQ(version) 0
|
#define LLVM_MSC_PREREQ(version) 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/// \brief Does the compiler support r-value references?
|
#if !defined(_MSC_VER) || defined(__clang__) || LLVM_MSC_PREREQ(1900)
|
||||||
/// This implies that <utility> provides the one-argument std::move; it
|
#define LLVM_NOEXCEPT noexcept
|
||||||
/// does not imply the existence of any other C++ library features.
|
|
||||||
#if __has_feature(cxx_rvalue_references) || \
|
|
||||||
defined(__GXX_EXPERIMENTAL_CXX0X__) || LLVM_MSC_PREREQ(1600)
|
|
||||||
#define LLVM_HAS_RVALUE_REFERENCES 1
|
|
||||||
#else
|
#else
|
||||||
#define LLVM_HAS_RVALUE_REFERENCES 0
|
#define LLVM_NOEXCEPT throw()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/// \brief Does the compiler support r-value reference *this?
|
/// \brief Does the compiler support ref-qualifiers for *this?
|
||||||
///
|
///
|
||||||
/// Sadly, this is separate from just r-value reference support because GCC
|
/// Sadly, this is separate from just rvalue reference support because GCC
|
||||||
/// implemented everything but this thus far. No release of GCC yet has support
|
/// and MSVC implemented this later than everything else.
|
||||||
/// for this feature so it is enabled with Clang only.
|
#if __has_feature(cxx_rvalue_references) || LLVM_GNUC_PREREQ(4, 8, 1)
|
||||||
/// FIXME: This should change to a version check when GCC grows support for it.
|
|
||||||
#if __has_feature(cxx_rvalue_references)
|
|
||||||
#define LLVM_HAS_RVALUE_REFERENCE_THIS 1
|
#define LLVM_HAS_RVALUE_REFERENCE_THIS 1
|
||||||
#else
|
#else
|
||||||
#define LLVM_HAS_RVALUE_REFERENCE_THIS 0
|
#define LLVM_HAS_RVALUE_REFERENCE_THIS 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/// \macro LLVM_HAS_CXX11_TYPETRAITS
|
/// Expands to '&' if ref-qualifiers for *this are supported.
|
||||||
/// \brief Does the compiler have the C++11 type traits.
|
|
||||||
///
|
///
|
||||||
/// #include <type_traits>
|
/// This can be used to provide lvalue/rvalue overrides of member functions.
|
||||||
///
|
/// The rvalue override should be guarded by LLVM_HAS_RVALUE_REFERENCE_THIS
|
||||||
/// * enable_if
|
|
||||||
/// * {true,false}_type
|
|
||||||
/// * is_constructible
|
|
||||||
/// * etc...
|
|
||||||
#if defined(__GXX_EXPERIMENTAL_CXX0X__) || LLVM_MSC_PREREQ(1700)
|
|
||||||
#define LLVM_HAS_CXX11_TYPETRAITS 1
|
|
||||||
#else
|
|
||||||
#define LLVM_HAS_CXX11_TYPETRAITS 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// \macro LLVM_HAS_CXX11_STDLIB
|
|
||||||
/// \brief Does the compiler have the C++11 standard library.
|
|
||||||
///
|
|
||||||
/// Implies LLVM_HAS_RVALUE_REFERENCES, LLVM_HAS_CXX11_TYPETRAITS
|
|
||||||
#if defined(__GXX_EXPERIMENTAL_CXX0X__) || LLVM_MSC_PREREQ(1700)
|
|
||||||
#define LLVM_HAS_CXX11_STDLIB 1
|
|
||||||
#else
|
|
||||||
#define LLVM_HAS_CXX11_STDLIB 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// \macro LLVM_HAS_VARIADIC_TEMPLATES
|
|
||||||
/// \brief Does this compiler support variadic templates.
|
|
||||||
///
|
|
||||||
/// Implies LLVM_HAS_RVALUE_REFERENCES and the existence of std::forward.
|
|
||||||
#if __has_feature(cxx_variadic_templates) || LLVM_MSC_PREREQ(1800)
|
|
||||||
# define LLVM_HAS_VARIADIC_TEMPLATES 1
|
|
||||||
#else
|
|
||||||
# define LLVM_HAS_VARIADIC_TEMPLATES 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// llvm_move - Expands to ::std::move if the compiler supports
|
|
||||||
/// r-value references; otherwise, expands to the argument.
|
|
||||||
#if LLVM_HAS_RVALUE_REFERENCES
|
|
||||||
#define llvm_move(value) (::std::move(value))
|
|
||||||
#else
|
|
||||||
#define llvm_move(value) (value)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// Expands to '&' if r-value references are supported.
|
|
||||||
///
|
|
||||||
/// This can be used to provide l-value/r-value overrides of member functions.
|
|
||||||
/// The r-value override should be guarded by LLVM_HAS_RVALUE_REFERENCE_THIS
|
|
||||||
#if LLVM_HAS_RVALUE_REFERENCE_THIS
|
#if LLVM_HAS_RVALUE_REFERENCE_THIS
|
||||||
#define LLVM_LVALUE_FUNCTION &
|
#define LLVM_LVALUE_FUNCTION &
|
||||||
#else
|
#else
|
||||||
#define LLVM_LVALUE_FUNCTION
|
#define LLVM_LVALUE_FUNCTION
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/// LLVM_DELETED_FUNCTION - Expands to = delete if the compiler supports it.
|
|
||||||
/// Use to mark functions as uncallable. Member functions with this should
|
|
||||||
/// be declared private so that some behavior is kept in C++03 mode.
|
|
||||||
///
|
|
||||||
/// class DontCopy {
|
|
||||||
/// private:
|
|
||||||
/// DontCopy(const DontCopy&) LLVM_DELETED_FUNCTION;
|
|
||||||
/// DontCopy &operator =(const DontCopy&) LLVM_DELETED_FUNCTION;
|
|
||||||
/// public:
|
|
||||||
/// ...
|
|
||||||
/// };
|
|
||||||
#if __has_feature(cxx_deleted_functions) || \
|
|
||||||
defined(__GXX_EXPERIMENTAL_CXX0X__) || LLVM_MSC_PREREQ(1800)
|
|
||||||
#define LLVM_DELETED_FUNCTION = delete
|
|
||||||
#else
|
|
||||||
#define LLVM_DELETED_FUNCTION
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// LLVM_FINAL - Expands to 'final' if the compiler supports it.
|
|
||||||
/// Use to mark classes or virtual methods as final.
|
|
||||||
#if __has_feature(cxx_override_control) || \
|
|
||||||
defined(__GXX_EXPERIMENTAL_CXX0X__) || LLVM_MSC_PREREQ(1700)
|
|
||||||
#define LLVM_FINAL final
|
|
||||||
#else
|
|
||||||
#define LLVM_FINAL
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// LLVM_OVERRIDE - Expands to 'override' if the compiler supports it.
|
|
||||||
/// Use to mark virtual methods as overriding a base class method.
|
|
||||||
#if __has_feature(cxx_override_control) || \
|
|
||||||
defined(__GXX_EXPERIMENTAL_CXX0X__) || LLVM_MSC_PREREQ(1700)
|
|
||||||
#define LLVM_OVERRIDE override
|
|
||||||
#else
|
|
||||||
#define LLVM_OVERRIDE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if __has_feature(cxx_constexpr) || defined(__GXX_EXPERIMENTAL_CXX0X__)
|
#if __has_feature(cxx_constexpr) || defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||||
# define LLVM_CONSTEXPR constexpr
|
# define LLVM_CONSTEXPR constexpr
|
||||||
#else
|
#else
|
||||||
|
@ -178,20 +103,26 @@
|
||||||
/// not accessible from outside it. Can also be used to mark variables and
|
/// not accessible from outside it. Can also be used to mark variables and
|
||||||
/// functions, making them private to any shared library they are linked into.
|
/// functions, making them private to any shared library they are linked into.
|
||||||
/// On PE/COFF targets, library visibility is the default, so this isn't needed.
|
/// On PE/COFF targets, library visibility is the default, so this isn't needed.
|
||||||
#if (__has_attribute(visibility) || __GNUC_PREREQ(4, 0)) && \
|
#if (__has_attribute(visibility) || LLVM_GNUC_PREREQ(4, 0, 0)) && \
|
||||||
!defined(__MINGW32__) && !defined(__CYGWIN__) && !defined(LLVM_ON_WIN32)
|
!defined(__MINGW32__) && !defined(__CYGWIN__) && !defined(LLVM_ON_WIN32)
|
||||||
#define LLVM_LIBRARY_VISIBILITY __attribute__ ((visibility("hidden")))
|
#define LLVM_LIBRARY_VISIBILITY __attribute__ ((visibility("hidden")))
|
||||||
#else
|
#else
|
||||||
#define LLVM_LIBRARY_VISIBILITY
|
#define LLVM_LIBRARY_VISIBILITY
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if __has_attribute(used) || __GNUC_PREREQ(3, 1)
|
#if __has_attribute(sentinel) || LLVM_GNUC_PREREQ(3, 0, 0)
|
||||||
|
#define LLVM_END_WITH_NULL __attribute__((sentinel))
|
||||||
|
#else
|
||||||
|
#define LLVM_END_WITH_NULL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if __has_attribute(used) || LLVM_GNUC_PREREQ(3, 1, 0)
|
||||||
#define LLVM_ATTRIBUTE_USED __attribute__((__used__))
|
#define LLVM_ATTRIBUTE_USED __attribute__((__used__))
|
||||||
#else
|
#else
|
||||||
#define LLVM_ATTRIBUTE_USED
|
#define LLVM_ATTRIBUTE_USED
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if __has_attribute(warn_unused_result) || __GNUC_PREREQ(3, 4)
|
#if __has_attribute(warn_unused_result) || LLVM_GNUC_PREREQ(3, 4, 0)
|
||||||
#define LLVM_ATTRIBUTE_UNUSED_RESULT __attribute__((__warn_unused_result__))
|
#define LLVM_ATTRIBUTE_UNUSED_RESULT __attribute__((__warn_unused_result__))
|
||||||
#else
|
#else
|
||||||
#define LLVM_ATTRIBUTE_UNUSED_RESULT
|
#define LLVM_ATTRIBUTE_UNUSED_RESULT
|
||||||
|
@ -205,14 +136,14 @@
|
||||||
// more portable solution:
|
// more portable solution:
|
||||||
// (void)unused_var_name;
|
// (void)unused_var_name;
|
||||||
// Prefer cast-to-void wherever it is sufficient.
|
// Prefer cast-to-void wherever it is sufficient.
|
||||||
#if __has_attribute(unused) || __GNUC_PREREQ(3, 1)
|
#if __has_attribute(unused) || LLVM_GNUC_PREREQ(3, 1, 0)
|
||||||
#define LLVM_ATTRIBUTE_UNUSED __attribute__((__unused__))
|
#define LLVM_ATTRIBUTE_UNUSED __attribute__((__unused__))
|
||||||
#else
|
#else
|
||||||
#define LLVM_ATTRIBUTE_UNUSED
|
#define LLVM_ATTRIBUTE_UNUSED
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// FIXME: Provide this for PE/COFF targets.
|
// FIXME: Provide this for PE/COFF targets.
|
||||||
#if (__has_attribute(weak) || __GNUC_PREREQ(4, 0)) && \
|
#if (__has_attribute(weak) || LLVM_GNUC_PREREQ(4, 0, 0)) && \
|
||||||
(!defined(__MINGW32__) && !defined(__CYGWIN__) && !defined(LLVM_ON_WIN32))
|
(!defined(__MINGW32__) && !defined(__CYGWIN__) && !defined(LLVM_ON_WIN32))
|
||||||
#define LLVM_ATTRIBUTE_WEAK __attribute__((__weak__))
|
#define LLVM_ATTRIBUTE_WEAK __attribute__((__weak__))
|
||||||
#else
|
#else
|
||||||
|
@ -235,7 +166,7 @@
|
||||||
#define LLVM_READONLY
|
#define LLVM_READONLY
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if __has_builtin(__builtin_expect) || __GNUC_PREREQ(4, 0)
|
#if __has_builtin(__builtin_expect) || LLVM_GNUC_PREREQ(4, 0, 0)
|
||||||
#define LLVM_LIKELY(EXPR) __builtin_expect((bool)(EXPR), true)
|
#define LLVM_LIKELY(EXPR) __builtin_expect((bool)(EXPR), true)
|
||||||
#define LLVM_UNLIKELY(EXPR) __builtin_expect((bool)(EXPR), false)
|
#define LLVM_UNLIKELY(EXPR) __builtin_expect((bool)(EXPR), false)
|
||||||
#else
|
#else
|
||||||
|
@ -243,22 +174,9 @@
|
||||||
#define LLVM_UNLIKELY(EXPR) (EXPR)
|
#define LLVM_UNLIKELY(EXPR) (EXPR)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// C++ doesn't support 'extern template' of template specializations. GCC does,
|
|
||||||
// but requires __extension__ before it. In the header, use this:
|
|
||||||
// EXTERN_TEMPLATE_INSTANTIATION(class foo<bar>);
|
|
||||||
// in the .cpp file, use this:
|
|
||||||
// TEMPLATE_INSTANTIATION(class foo<bar>);
|
|
||||||
#ifdef __GNUC__
|
|
||||||
#define EXTERN_TEMPLATE_INSTANTIATION(X) __extension__ extern template X
|
|
||||||
#define TEMPLATE_INSTANTIATION(X) template X
|
|
||||||
#else
|
|
||||||
#define EXTERN_TEMPLATE_INSTANTIATION(X)
|
|
||||||
#define TEMPLATE_INSTANTIATION(X)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// LLVM_ATTRIBUTE_NOINLINE - On compilers where we have a directive to do so,
|
/// LLVM_ATTRIBUTE_NOINLINE - On compilers where we have a directive to do so,
|
||||||
/// mark a method "not for inlining".
|
/// mark a method "not for inlining".
|
||||||
#if __has_attribute(noinline) || __GNUC_PREREQ(3, 4)
|
#if __has_attribute(noinline) || LLVM_GNUC_PREREQ(3, 4, 0)
|
||||||
#define LLVM_ATTRIBUTE_NOINLINE __attribute__((noinline))
|
#define LLVM_ATTRIBUTE_NOINLINE __attribute__((noinline))
|
||||||
#elif defined(_MSC_VER)
|
#elif defined(_MSC_VER)
|
||||||
#define LLVM_ATTRIBUTE_NOINLINE __declspec(noinline)
|
#define LLVM_ATTRIBUTE_NOINLINE __declspec(noinline)
|
||||||
|
@ -270,8 +188,8 @@
|
||||||
/// so, mark a method "always inline" because it is performance sensitive. GCC
|
/// so, mark a method "always inline" because it is performance sensitive. GCC
|
||||||
/// 3.4 supported this but is buggy in various cases and produces unimplemented
|
/// 3.4 supported this but is buggy in various cases and produces unimplemented
|
||||||
/// errors, just use it in GCC 4.0 and later.
|
/// errors, just use it in GCC 4.0 and later.
|
||||||
#if __has_attribute(always_inline) || __GNUC_PREREQ(4, 0)
|
#if __has_attribute(always_inline) || LLVM_GNUC_PREREQ(4, 0, 0)
|
||||||
#define LLVM_ATTRIBUTE_ALWAYS_INLINE inline __attribute__((always_inline))
|
#define LLVM_ATTRIBUTE_ALWAYS_INLINE __attribute__((always_inline))
|
||||||
#elif defined(_MSC_VER)
|
#elif defined(_MSC_VER)
|
||||||
#define LLVM_ATTRIBUTE_ALWAYS_INLINE __forceinline
|
#define LLVM_ATTRIBUTE_ALWAYS_INLINE __forceinline
|
||||||
#else
|
#else
|
||||||
|
@ -286,6 +204,22 @@
|
||||||
#define LLVM_ATTRIBUTE_NORETURN
|
#define LLVM_ATTRIBUTE_NORETURN
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if __has_attribute(returns_nonnull) || LLVM_GNUC_PREREQ(4, 9, 0)
|
||||||
|
#define LLVM_ATTRIBUTE_RETURNS_NONNULL __attribute__((returns_nonnull))
|
||||||
|
#else
|
||||||
|
#define LLVM_ATTRIBUTE_RETURNS_NONNULL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// \macro LLVM_ATTRIBUTE_RETURNS_NOALIAS Used to mark a function as returning a
|
||||||
|
/// pointer that does not alias any other valid pointer.
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#define LLVM_ATTRIBUTE_RETURNS_NOALIAS __attribute__((__malloc__))
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
#define LLVM_ATTRIBUTE_RETURNS_NOALIAS __declspec(restrict)
|
||||||
|
#else
|
||||||
|
#define LLVM_ATTRIBUTE_RETURNS_NOALIAS
|
||||||
|
#endif
|
||||||
|
|
||||||
/// LLVM_EXTENSION - Support compilers where we have a keyword to suppress
|
/// LLVM_EXTENSION - Support compilers where we have a keyword to suppress
|
||||||
/// pedantic diagnostics.
|
/// pedantic diagnostics.
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
|
@ -312,7 +246,7 @@
|
||||||
/// LLVM_BUILTIN_UNREACHABLE - On compilers which support it, expands
|
/// LLVM_BUILTIN_UNREACHABLE - On compilers which support it, expands
|
||||||
/// to an expression which states that it is undefined behavior for the
|
/// to an expression which states that it is undefined behavior for the
|
||||||
/// compiler to reach this point. Otherwise is not defined.
|
/// compiler to reach this point. Otherwise is not defined.
|
||||||
#if __has_builtin(__builtin_unreachable) || __GNUC_PREREQ(4, 5)
|
#if __has_builtin(__builtin_unreachable) || LLVM_GNUC_PREREQ(4, 5, 0)
|
||||||
# define LLVM_BUILTIN_UNREACHABLE __builtin_unreachable()
|
# define LLVM_BUILTIN_UNREACHABLE __builtin_unreachable()
|
||||||
#elif defined(_MSC_VER)
|
#elif defined(_MSC_VER)
|
||||||
# define LLVM_BUILTIN_UNREACHABLE __assume(false)
|
# define LLVM_BUILTIN_UNREACHABLE __assume(false)
|
||||||
|
@ -320,15 +254,21 @@
|
||||||
|
|
||||||
/// LLVM_BUILTIN_TRAP - On compilers which support it, expands to an expression
|
/// LLVM_BUILTIN_TRAP - On compilers which support it, expands to an expression
|
||||||
/// which causes the program to exit abnormally.
|
/// which causes the program to exit abnormally.
|
||||||
#if __has_builtin(__builtin_trap) || __GNUC_PREREQ(4, 3)
|
#if __has_builtin(__builtin_trap) || LLVM_GNUC_PREREQ(4, 3, 0)
|
||||||
# define LLVM_BUILTIN_TRAP __builtin_trap()
|
# define LLVM_BUILTIN_TRAP __builtin_trap()
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
// The __debugbreak intrinsic is supported by MSVC, does not require forward
|
||||||
|
// declarations involving platform-specific typedefs (unlike RaiseException),
|
||||||
|
// results in a call to vectored exception handlers, and encodes to a short
|
||||||
|
// instruction that still causes the trapping behavior we want.
|
||||||
|
# define LLVM_BUILTIN_TRAP __debugbreak()
|
||||||
#else
|
#else
|
||||||
# define LLVM_BUILTIN_TRAP *(volatile int*)0x11 = 0
|
# define LLVM_BUILTIN_TRAP *(volatile int*)0x11 = 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/// \macro LLVM_ASSUME_ALIGNED
|
/// \macro LLVM_ASSUME_ALIGNED
|
||||||
/// \brief Returns a pointer with an assumed alignment.
|
/// \brief Returns a pointer with an assumed alignment.
|
||||||
#if __has_builtin(__builtin_assume_aligned) && __GNUC_PREREQ(4, 7)
|
#if __has_builtin(__builtin_assume_aligned) || LLVM_GNUC_PREREQ(4, 7, 0)
|
||||||
# define LLVM_ASSUME_ALIGNED(p, a) __builtin_assume_aligned(p, a)
|
# define LLVM_ASSUME_ALIGNED(p, a) __builtin_assume_aligned(p, a)
|
||||||
#elif defined(LLVM_BUILTIN_UNREACHABLE)
|
#elif defined(LLVM_BUILTIN_UNREACHABLE)
|
||||||
// As of today, clang does not support __builtin_assume_aligned.
|
// As of today, clang does not support __builtin_assume_aligned.
|
||||||
|
@ -338,6 +278,65 @@
|
||||||
# define LLVM_ASSUME_ALIGNED(p, a) (p)
|
# define LLVM_ASSUME_ALIGNED(p, a) (p)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/// \macro LLVM_ALIGNAS
|
||||||
|
/// \brief Used to specify a minimum alignment for a structure or variable. The
|
||||||
|
/// alignment must be a constant integer. Use LLVM_PTR_SIZE to compute
|
||||||
|
/// alignments in terms of the size of a pointer.
|
||||||
|
///
|
||||||
|
/// Note that __declspec(align) has special quirks, it's not legal to pass a
|
||||||
|
/// structure with __declspec(align) as a formal parameter.
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
# define LLVM_ALIGNAS(x) __declspec(align(x))
|
||||||
|
#elif __GNUC__ && !__has_feature(cxx_alignas) && !LLVM_GNUC_PREREQ(4, 8, 0)
|
||||||
|
# define LLVM_ALIGNAS(x) __attribute__((aligned(x)))
|
||||||
|
#else
|
||||||
|
# define LLVM_ALIGNAS(x) alignas(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// \macro LLVM_PACKED
|
||||||
|
/// \brief Used to specify a packed structure.
|
||||||
|
/// LLVM_PACKED(
|
||||||
|
/// struct A {
|
||||||
|
/// int i;
|
||||||
|
/// int j;
|
||||||
|
/// int k;
|
||||||
|
/// long long l;
|
||||||
|
/// });
|
||||||
|
///
|
||||||
|
/// LLVM_PACKED_START
|
||||||
|
/// struct B {
|
||||||
|
/// int i;
|
||||||
|
/// int j;
|
||||||
|
/// int k;
|
||||||
|
/// long long l;
|
||||||
|
/// };
|
||||||
|
/// LLVM_PACKED_END
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
# define LLVM_PACKED(d) __pragma(pack(push, 1)) d __pragma(pack(pop))
|
||||||
|
# define LLVM_PACKED_START __pragma(pack(push, 1))
|
||||||
|
# define LLVM_PACKED_END __pragma(pack(pop))
|
||||||
|
#else
|
||||||
|
# define LLVM_PACKED(d) d __attribute__((packed))
|
||||||
|
# define LLVM_PACKED_START _Pragma("pack(push, 1)")
|
||||||
|
# define LLVM_PACKED_END _Pragma("pack(pop)")
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// \macro LLVM_PTR_SIZE
|
||||||
|
/// \brief A constant integer equivalent to the value of sizeof(void*).
|
||||||
|
/// Generally used in combination with LLVM_ALIGNAS or when doing computation in
|
||||||
|
/// the preprocessor.
|
||||||
|
#ifdef __SIZEOF_POINTER__
|
||||||
|
# define LLVM_PTR_SIZE __SIZEOF_POINTER__
|
||||||
|
#elif defined(_WIN64)
|
||||||
|
# define LLVM_PTR_SIZE 8
|
||||||
|
#elif defined(_WIN32)
|
||||||
|
# define LLVM_PTR_SIZE 4
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
# error "could not determine LLVM_PTR_SIZE as a constant int for MSVC"
|
||||||
|
#else
|
||||||
|
# define LLVM_PTR_SIZE sizeof(void *)
|
||||||
|
#endif
|
||||||
|
|
||||||
/// \macro LLVM_FUNCTION_NAME
|
/// \macro LLVM_FUNCTION_NAME
|
||||||
/// \brief Expands to __func__ on compilers which support it. Otherwise,
|
/// \brief Expands to __func__ on compilers which support it. Otherwise,
|
||||||
/// expands to a compiler-dependent replacement.
|
/// expands to a compiler-dependent replacement.
|
||||||
|
@ -347,91 +346,65 @@
|
||||||
# define LLVM_FUNCTION_NAME __func__
|
# define LLVM_FUNCTION_NAME __func__
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(HAVE_SANITIZER_MSAN_INTERFACE_H)
|
|
||||||
# include <sanitizer/msan_interface.h>
|
|
||||||
#else
|
|
||||||
# define __msan_allocated_memory(p, size)
|
|
||||||
# define __msan_unpoison(p, size)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// \macro LLVM_MEMORY_SANITIZER_BUILD
|
/// \macro LLVM_MEMORY_SANITIZER_BUILD
|
||||||
/// \brief Whether LLVM itself is built with MemorySanitizer instrumentation.
|
/// \brief Whether LLVM itself is built with MemorySanitizer instrumentation.
|
||||||
#if __has_feature(memory_sanitizer)
|
#if __has_feature(memory_sanitizer)
|
||||||
# define LLVM_MEMORY_SANITIZER_BUILD 1
|
# define LLVM_MEMORY_SANITIZER_BUILD 1
|
||||||
|
# include <sanitizer/msan_interface.h>
|
||||||
#else
|
#else
|
||||||
# define LLVM_MEMORY_SANITIZER_BUILD 0
|
# define LLVM_MEMORY_SANITIZER_BUILD 0
|
||||||
|
# define __msan_allocated_memory(p, size)
|
||||||
|
# define __msan_unpoison(p, size)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/// \macro LLVM_ADDRESS_SANITIZER_BUILD
|
/// \macro LLVM_ADDRESS_SANITIZER_BUILD
|
||||||
/// \brief Whether LLVM itself is built with AddressSanitizer instrumentation.
|
/// \brief Whether LLVM itself is built with AddressSanitizer instrumentation.
|
||||||
#if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
|
#if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
|
||||||
# define LLVM_ADDRESS_SANITIZER_BUILD 1
|
# define LLVM_ADDRESS_SANITIZER_BUILD 1
|
||||||
|
# include <sanitizer/asan_interface.h>
|
||||||
#else
|
#else
|
||||||
# define LLVM_ADDRESS_SANITIZER_BUILD 0
|
# define LLVM_ADDRESS_SANITIZER_BUILD 0
|
||||||
|
# define __asan_poison_memory_region(p, size)
|
||||||
|
# define __asan_unpoison_memory_region(p, size)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/// \macro LLVM_IS_UNALIGNED_ACCESS_FAST
|
/// \macro LLVM_THREAD_SANITIZER_BUILD
|
||||||
/// \brief Is unaligned memory access fast on the host machine.
|
/// \brief Whether LLVM itself is built with ThreadSanitizer instrumentation.
|
||||||
///
|
#if __has_feature(thread_sanitizer) || defined(__SANITIZE_THREAD__)
|
||||||
/// Don't specialize on alignment for platforms where unaligned memory accesses
|
# define LLVM_THREAD_SANITIZER_BUILD 1
|
||||||
/// generates the same code as aligned memory accesses for common types.
|
|
||||||
#if defined(_M_AMD64) || defined(_M_IX86) || defined(__amd64) || \
|
|
||||||
defined(__amd64__) || defined(__x86_64) || defined(__x86_64__) || \
|
|
||||||
defined(_X86_) || defined(__i386) || defined(__i386__)
|
|
||||||
# define LLVM_IS_UNALIGNED_ACCESS_FAST 1
|
|
||||||
#else
|
#else
|
||||||
# define LLVM_IS_UNALIGNED_ACCESS_FAST 0
|
# define LLVM_THREAD_SANITIZER_BUILD 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/// \macro LLVM_EXPLICIT
|
#if LLVM_THREAD_SANITIZER_BUILD
|
||||||
/// \brief Expands to explicit on compilers which support explicit conversion
|
// Thread Sanitizer is a tool that finds races in code.
|
||||||
/// operators. Otherwise expands to nothing.
|
// See http://code.google.com/p/data-race-test/wiki/DynamicAnnotations .
|
||||||
#if __has_feature(cxx_explicit_conversions) || \
|
// tsan detects these exact functions by name.
|
||||||
defined(__GXX_EXPERIMENTAL_CXX0X__) || LLVM_MSC_PREREQ(1800)
|
extern "C" {
|
||||||
#define LLVM_EXPLICIT explicit
|
void AnnotateHappensAfter(const char *file, int line, const volatile void *cv);
|
||||||
#else
|
void AnnotateHappensBefore(const char *file, int line, const volatile void *cv);
|
||||||
#define LLVM_EXPLICIT
|
void AnnotateIgnoreWritesBegin(const char *file, int line);
|
||||||
#endif
|
void AnnotateIgnoreWritesEnd(const char *file, int line);
|
||||||
|
}
|
||||||
|
|
||||||
/// \macro LLVM_STATIC_ASSERT
|
// This marker is used to define a happens-before arc. The race detector will
|
||||||
/// \brief Expands to C/C++'s static_assert on compilers which support it.
|
// infer an arc from the begin to the end when they share the same pointer
|
||||||
#if __has_feature(cxx_static_assert) || \
|
// argument.
|
||||||
defined(__GXX_EXPERIMENTAL_CXX0X__) || LLVM_MSC_PREREQ(1600)
|
# define TsanHappensBefore(cv) AnnotateHappensBefore(__FILE__, __LINE__, cv)
|
||||||
# define LLVM_STATIC_ASSERT(expr, msg) static_assert(expr, msg)
|
|
||||||
#elif __has_feature(c_static_assert)
|
|
||||||
# define LLVM_STATIC_ASSERT(expr, msg) _Static_assert(expr, msg)
|
|
||||||
#elif __has_extension(c_static_assert)
|
|
||||||
# define LLVM_STATIC_ASSERT(expr, msg) LLVM_EXTENSION _Static_assert(expr, msg)
|
|
||||||
#else
|
|
||||||
# define LLVM_STATIC_ASSERT(expr, msg)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// \macro LLVM_ENUM_INT_TYPE
|
// This marker defines the destination of a happens-before arc.
|
||||||
/// \brief Expands to colon followed by the given integral type on compilers
|
# define TsanHappensAfter(cv) AnnotateHappensAfter(__FILE__, __LINE__, cv)
|
||||||
/// which support C++11 strong enums. This can be used to make enums unsigned
|
|
||||||
/// with MSVC.
|
|
||||||
#if __has_feature(cxx_strong_enums) || LLVM_MSC_PREREQ(1600)
|
|
||||||
# define LLVM_ENUM_INT_TYPE(intty) : intty
|
|
||||||
#else
|
|
||||||
# define LLVM_ENUM_INT_TYPE(intty)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// \brief Does the compiler support C++11 semantics for strongly typed forward
|
// Ignore any races on writes between here and the next TsanIgnoreWritesEnd.
|
||||||
/// declared enums?
|
# define TsanIgnoreWritesBegin() AnnotateIgnoreWritesBegin(__FILE__, __LINE__)
|
||||||
#if __has_feature(cxx_strong_enums) || LLVM_MSC_PREREQ(1700)
|
|
||||||
#define LLVM_HAS_STRONG_ENUMS 1
|
|
||||||
#else
|
|
||||||
#define LLVM_HAS_STRONG_ENUMS 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// \brief Does the compiler support generalized initializers (using braced
|
// Resume checking for racy writes.
|
||||||
/// lists and std::initializer_list). While clang may claim it supports general
|
# define TsanIgnoreWritesEnd() AnnotateIgnoreWritesEnd(__FILE__, __LINE__)
|
||||||
/// initializers, if we're using MSVC's headers, we might not have a usable
|
|
||||||
/// std::initializer list type from the STL. Disable this for now.
|
|
||||||
#if __has_feature(cxx_generalized_initializers) && !defined(_MSC_VER)
|
|
||||||
#define LLVM_HAS_INITIALIZER_LISTS 1
|
|
||||||
#else
|
#else
|
||||||
#define LLVM_HAS_INITIALIZER_LISTS 0
|
# define TsanHappensBefore(cv)
|
||||||
|
# define TsanHappensAfter(cv)
|
||||||
|
# define TsanIgnoreWritesBegin()
|
||||||
|
# define TsanIgnoreWritesEnd()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/// \brief Mark debug helper function definitions like dump() that should not be
|
/// \brief Mark debug helper function definitions like dump() that should not be
|
||||||
|
@ -443,4 +416,33 @@
|
||||||
#define LLVM_DUMP_METHOD LLVM_ATTRIBUTE_NOINLINE
|
#define LLVM_DUMP_METHOD LLVM_ATTRIBUTE_NOINLINE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/// \macro LLVM_THREAD_LOCAL
|
||||||
|
/// \brief A thread-local storage specifier which can be used with globals,
|
||||||
|
/// extern globals, and static globals.
|
||||||
|
///
|
||||||
|
/// This is essentially an extremely restricted analog to C++11's thread_local
|
||||||
|
/// support, and uses that when available. However, it falls back on
|
||||||
|
/// platform-specific or vendor-provided extensions when necessary. These
|
||||||
|
/// extensions don't support many of the C++11 thread_local's features. You
|
||||||
|
/// should only use this for PODs that you can statically initialize to
|
||||||
|
/// some constant value. In almost all circumstances this is most appropriate
|
||||||
|
/// for use with a pointer, integer, or small aggregation of pointers and
|
||||||
|
/// integers.
|
||||||
|
#if LLVM_ENABLE_THREADS
|
||||||
|
#if __has_feature(cxx_thread_local)
|
||||||
|
#define LLVM_THREAD_LOCAL thread_local
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
// MSVC supports this with a __declspec.
|
||||||
|
#define LLVM_THREAD_LOCAL __declspec(thread)
|
||||||
|
#else
|
||||||
|
// Clang, GCC, and other compatible compilers used __thread prior to C++11 and
|
||||||
|
// we only need the restricted functionality that provides.
|
||||||
|
#define LLVM_THREAD_LOCAL __thread
|
||||||
|
#endif
|
||||||
|
#else // !LLVM_ENABLE_THREADS
|
||||||
|
// If threading is disabled entirely, this compiles to nothing and you get
|
||||||
|
// a normal global variable.
|
||||||
|
#define LLVM_THREAD_LOCAL
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -18,13 +18,16 @@
|
||||||
#ifdef IGNORED_LLVM_XENIA
|
#ifdef IGNORED_LLVM_XENIA
|
||||||
#include "llvm/Support/SwapByteOrder.h"
|
#include "llvm/Support/SwapByteOrder.h"
|
||||||
#endif // IGNORED_LLVM_XENIA
|
#endif // IGNORED_LLVM_XENIA
|
||||||
#include <cmath>
|
#include <cassert>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include "llvm/Support/type_traits.h"
|
#include <type_traits>
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#include <intrin.h>
|
#include <intrin.h>
|
||||||
#include <limits>
|
#endif
|
||||||
|
|
||||||
|
#ifdef __ANDROID_NDK__
|
||||||
|
#include <android/api-level.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
@ -38,6 +41,65 @@ enum ZeroBehavior {
|
||||||
ZB_Width
|
ZB_Width
|
||||||
};
|
};
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
template <typename T, std::size_t SizeOfT> struct TrailingZerosCounter {
|
||||||
|
static std::size_t count(T Val, ZeroBehavior) {
|
||||||
|
if (!Val)
|
||||||
|
return std::numeric_limits<T>::digits;
|
||||||
|
if (Val & 0x1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// Bisection method.
|
||||||
|
std::size_t ZeroBits = 0;
|
||||||
|
T Shift = std::numeric_limits<T>::digits >> 1;
|
||||||
|
T Mask = std::numeric_limits<T>::max() >> Shift;
|
||||||
|
while (Shift) {
|
||||||
|
if ((Val & Mask) == 0) {
|
||||||
|
Val >>= Shift;
|
||||||
|
ZeroBits |= Shift;
|
||||||
|
}
|
||||||
|
Shift >>= 1;
|
||||||
|
Mask >>= Shift;
|
||||||
|
}
|
||||||
|
return ZeroBits;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#if __GNUC__ >= 4 || defined(_MSC_VER)
|
||||||
|
template <typename T> struct TrailingZerosCounter<T, 4> {
|
||||||
|
static std::size_t count(T Val, ZeroBehavior ZB) {
|
||||||
|
if (ZB != ZB_Undefined && Val == 0)
|
||||||
|
return 32;
|
||||||
|
|
||||||
|
#if __has_builtin(__builtin_ctz) || LLVM_GNUC_PREREQ(4, 0, 0)
|
||||||
|
return __builtin_ctz(Val);
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
unsigned long Index;
|
||||||
|
_BitScanForward(&Index, Val);
|
||||||
|
return Index;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#if !defined(_MSC_VER) || defined(_M_X64)
|
||||||
|
template <typename T> struct TrailingZerosCounter<T, 8> {
|
||||||
|
static std::size_t count(T Val, ZeroBehavior ZB) {
|
||||||
|
if (ZB != ZB_Undefined && Val == 0)
|
||||||
|
return 64;
|
||||||
|
|
||||||
|
#if __has_builtin(__builtin_ctzll) || LLVM_GNUC_PREREQ(4, 0, 0)
|
||||||
|
return __builtin_ctzll(Val);
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
unsigned long Index;
|
||||||
|
_BitScanForward64(&Index, Val);
|
||||||
|
return Index;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
/// \brief Count number of 0's from the least significant bit to the most
|
/// \brief Count number of 0's from the least significant bit to the most
|
||||||
/// stopping at the first 1.
|
/// stopping at the first 1.
|
||||||
///
|
///
|
||||||
|
@ -46,68 +108,66 @@ enum ZeroBehavior {
|
||||||
/// \param ZB the behavior on an input of 0. Only ZB_Width and ZB_Undefined are
|
/// \param ZB the behavior on an input of 0. Only ZB_Width and ZB_Undefined are
|
||||||
/// valid arguments.
|
/// valid arguments.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
typename enable_if_c<std::numeric_limits<T>::is_integer &&
|
std::size_t countTrailingZeros(T Val, ZeroBehavior ZB = ZB_Width) {
|
||||||
!std::numeric_limits<T>::is_signed, std::size_t>::type
|
static_assert(std::numeric_limits<T>::is_integer &&
|
||||||
countTrailingZeros(T Val, ZeroBehavior ZB = ZB_Width) {
|
!std::numeric_limits<T>::is_signed,
|
||||||
(void)ZB;
|
"Only unsigned integral types are allowed.");
|
||||||
|
return detail::TrailingZerosCounter<T, sizeof(T)>::count(Val, ZB);
|
||||||
|
}
|
||||||
|
|
||||||
if (!Val)
|
namespace detail {
|
||||||
return std::numeric_limits<T>::digits;
|
template <typename T, std::size_t SizeOfT> struct LeadingZerosCounter {
|
||||||
if (Val & 0x1)
|
static std::size_t count(T Val, ZeroBehavior) {
|
||||||
return 0;
|
if (!Val)
|
||||||
|
return std::numeric_limits<T>::digits;
|
||||||
|
|
||||||
// Bisection method.
|
// Bisection method.
|
||||||
std::size_t ZeroBits = 0;
|
std::size_t ZeroBits = 0;
|
||||||
T Shift = std::numeric_limits<T>::digits >> 1;
|
for (T Shift = std::numeric_limits<T>::digits >> 1; Shift; Shift >>= 1) {
|
||||||
T Mask = std::numeric_limits<T>::max() >> Shift;
|
T Tmp = Val >> Shift;
|
||||||
while (Shift) {
|
if (Tmp)
|
||||||
if ((Val & Mask) == 0) {
|
Val = Tmp;
|
||||||
Val >>= Shift;
|
else
|
||||||
ZeroBits |= Shift;
|
ZeroBits |= Shift;
|
||||||
}
|
}
|
||||||
Shift >>= 1;
|
return ZeroBits;
|
||||||
Mask >>= Shift;
|
|
||||||
}
|
}
|
||||||
return ZeroBits;
|
};
|
||||||
}
|
|
||||||
|
|
||||||
// Disable signed.
|
#if __GNUC__ >= 4 || defined(_MSC_VER)
|
||||||
template <typename T>
|
template <typename T> struct LeadingZerosCounter<T, 4> {
|
||||||
typename enable_if_c<std::numeric_limits<T>::is_integer &&
|
static std::size_t count(T Val, ZeroBehavior ZB) {
|
||||||
std::numeric_limits<T>::is_signed, std::size_t>::type
|
if (ZB != ZB_Undefined && Val == 0)
|
||||||
countTrailingZeros(T Val, ZeroBehavior ZB = ZB_Width) LLVM_DELETED_FUNCTION;
|
return 32;
|
||||||
|
|
||||||
#if __GNUC__ >= 4 || _MSC_VER
|
#if __has_builtin(__builtin_clz) || LLVM_GNUC_PREREQ(4, 0, 0)
|
||||||
template <>
|
return __builtin_clz(Val);
|
||||||
inline std::size_t countTrailingZeros<uint32_t>(uint32_t Val, ZeroBehavior ZB) {
|
#elif defined(_MSC_VER)
|
||||||
if (ZB != ZB_Undefined && Val == 0)
|
unsigned long Index;
|
||||||
return 32;
|
_BitScanReverse(&Index, Val);
|
||||||
|
return Index ^ 31;
|
||||||
#if __has_builtin(__builtin_ctz) || __GNUC_PREREQ(4, 0)
|
|
||||||
return __builtin_ctz(Val);
|
|
||||||
#elif _MSC_VER
|
|
||||||
unsigned long Index;
|
|
||||||
_BitScanForward(&Index, Val);
|
|
||||||
return Index;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
#if !defined(_MSC_VER) || defined(_M_X64)
|
#if !defined(_MSC_VER) || defined(_M_X64)
|
||||||
template <>
|
template <typename T> struct LeadingZerosCounter<T, 8> {
|
||||||
inline std::size_t countTrailingZeros<uint64_t>(uint64_t Val, ZeroBehavior ZB) {
|
static std::size_t count(T Val, ZeroBehavior ZB) {
|
||||||
if (ZB != ZB_Undefined && Val == 0)
|
if (ZB != ZB_Undefined && Val == 0)
|
||||||
return 64;
|
return 64;
|
||||||
|
|
||||||
#if __has_builtin(__builtin_ctzll) || __GNUC_PREREQ(4, 0)
|
#if __has_builtin(__builtin_clzll) || LLVM_GNUC_PREREQ(4, 0, 0)
|
||||||
return __builtin_ctzll(Val);
|
return __builtin_clzll(Val);
|
||||||
#elif _MSC_VER
|
#elif defined(_MSC_VER)
|
||||||
unsigned long Index;
|
unsigned long Index;
|
||||||
_BitScanForward64(&Index, Val);
|
_BitScanReverse64(&Index, Val);
|
||||||
return Index;
|
return Index ^ 63;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
};
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
/// \brief Count number of 0's from the most significant bit to the least
|
/// \brief Count number of 0's from the most significant bit to the least
|
||||||
/// stopping at the first 1.
|
/// stopping at the first 1.
|
||||||
|
@ -117,64 +177,13 @@ inline std::size_t countTrailingZeros<uint64_t>(uint64_t Val, ZeroBehavior ZB) {
|
||||||
/// \param ZB the behavior on an input of 0. Only ZB_Width and ZB_Undefined are
|
/// \param ZB the behavior on an input of 0. Only ZB_Width and ZB_Undefined are
|
||||||
/// valid arguments.
|
/// valid arguments.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
typename enable_if_c<std::numeric_limits<T>::is_integer &&
|
std::size_t countLeadingZeros(T Val, ZeroBehavior ZB = ZB_Width) {
|
||||||
!std::numeric_limits<T>::is_signed, std::size_t>::type
|
static_assert(std::numeric_limits<T>::is_integer &&
|
||||||
countLeadingZeros(T Val, ZeroBehavior ZB = ZB_Width) {
|
!std::numeric_limits<T>::is_signed,
|
||||||
(void)ZB;
|
"Only unsigned integral types are allowed.");
|
||||||
|
return detail::LeadingZerosCounter<T, sizeof(T)>::count(Val, ZB);
|
||||||
if (!Val)
|
|
||||||
return std::numeric_limits<T>::digits;
|
|
||||||
|
|
||||||
// Bisection method.
|
|
||||||
std::size_t ZeroBits = 0;
|
|
||||||
for (T Shift = std::numeric_limits<T>::digits >> 1; Shift; Shift >>= 1) {
|
|
||||||
T Tmp = Val >> Shift;
|
|
||||||
if (Tmp)
|
|
||||||
Val = Tmp;
|
|
||||||
else
|
|
||||||
ZeroBits |= Shift;
|
|
||||||
}
|
|
||||||
return ZeroBits;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disable signed.
|
|
||||||
template <typename T>
|
|
||||||
typename enable_if_c<std::numeric_limits<T>::is_integer &&
|
|
||||||
std::numeric_limits<T>::is_signed, std::size_t>::type
|
|
||||||
countLeadingZeros(T Val, ZeroBehavior ZB = ZB_Width) LLVM_DELETED_FUNCTION;
|
|
||||||
|
|
||||||
#if __GNUC__ >= 4 || _MSC_VER
|
|
||||||
template <>
|
|
||||||
inline std::size_t countLeadingZeros<uint32_t>(uint32_t Val, ZeroBehavior ZB) {
|
|
||||||
if (ZB != ZB_Undefined && Val == 0)
|
|
||||||
return 32;
|
|
||||||
|
|
||||||
#if __has_builtin(__builtin_clz) || __GNUC_PREREQ(4, 0)
|
|
||||||
return __builtin_clz(Val);
|
|
||||||
#elif _MSC_VER
|
|
||||||
unsigned long Index;
|
|
||||||
_BitScanReverse(&Index, Val);
|
|
||||||
return Index ^ 31;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !defined(_MSC_VER) || defined(_M_X64)
|
|
||||||
template <>
|
|
||||||
inline std::size_t countLeadingZeros<uint64_t>(uint64_t Val, ZeroBehavior ZB) {
|
|
||||||
if (ZB != ZB_Undefined && Val == 0)
|
|
||||||
return 64;
|
|
||||||
|
|
||||||
#if __has_builtin(__builtin_clzll) || __GNUC_PREREQ(4, 0)
|
|
||||||
return __builtin_clzll(Val);
|
|
||||||
#elif _MSC_VER
|
|
||||||
unsigned long Index;
|
|
||||||
_BitScanReverse64(&Index, Val);
|
|
||||||
return Index ^ 63;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// \brief Get the index of the first set bit starting from the least
|
/// \brief Get the index of the first set bit starting from the least
|
||||||
/// significant bit.
|
/// significant bit.
|
||||||
///
|
///
|
||||||
|
@ -182,22 +191,13 @@ inline std::size_t countLeadingZeros<uint64_t>(uint64_t Val, ZeroBehavior ZB) {
|
||||||
///
|
///
|
||||||
/// \param ZB the behavior on an input of 0. Only ZB_Max and ZB_Undefined are
|
/// \param ZB the behavior on an input of 0. Only ZB_Max and ZB_Undefined are
|
||||||
/// valid arguments.
|
/// valid arguments.
|
||||||
template <typename T>
|
template <typename T> T findFirstSet(T Val, ZeroBehavior ZB = ZB_Max) {
|
||||||
typename enable_if_c<std::numeric_limits<T>::is_integer &&
|
|
||||||
!std::numeric_limits<T>::is_signed, T>::type
|
|
||||||
findFirstSet(T Val, ZeroBehavior ZB = ZB_Max) {
|
|
||||||
if (ZB == ZB_Max && Val == 0)
|
if (ZB == ZB_Max && Val == 0)
|
||||||
return std::numeric_limits<T>::max();
|
return std::numeric_limits<T>::max();
|
||||||
|
|
||||||
return countTrailingZeros(Val, ZB_Undefined);
|
return countTrailingZeros(Val, ZB_Undefined);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disable signed.
|
|
||||||
template <typename T>
|
|
||||||
typename enable_if_c<std::numeric_limits<T>::is_integer &&
|
|
||||||
std::numeric_limits<T>::is_signed, T>::type
|
|
||||||
findFirstSet(T Val, ZeroBehavior ZB = ZB_Max) LLVM_DELETED_FUNCTION;
|
|
||||||
|
|
||||||
/// \brief Get the index of the last set bit starting from the least
|
/// \brief Get the index of the last set bit starting from the least
|
||||||
/// significant bit.
|
/// significant bit.
|
||||||
///
|
///
|
||||||
|
@ -205,10 +205,7 @@ findFirstSet(T Val, ZeroBehavior ZB = ZB_Max) LLVM_DELETED_FUNCTION;
|
||||||
///
|
///
|
||||||
/// \param ZB the behavior on an input of 0. Only ZB_Max and ZB_Undefined are
|
/// \param ZB the behavior on an input of 0. Only ZB_Max and ZB_Undefined are
|
||||||
/// valid arguments.
|
/// valid arguments.
|
||||||
template <typename T>
|
template <typename T> T findLastSet(T Val, ZeroBehavior ZB = ZB_Max) {
|
||||||
typename enable_if_c<std::numeric_limits<T>::is_integer &&
|
|
||||||
!std::numeric_limits<T>::is_signed, T>::type
|
|
||||||
findLastSet(T Val, ZeroBehavior ZB = ZB_Max) {
|
|
||||||
if (ZB == ZB_Max && Val == 0)
|
if (ZB == ZB_Max && Val == 0)
|
||||||
return std::numeric_limits<T>::max();
|
return std::numeric_limits<T>::max();
|
||||||
|
|
||||||
|
@ -218,12 +215,6 @@ findLastSet(T Val, ZeroBehavior ZB = ZB_Max) {
|
||||||
(std::numeric_limits<T>::digits - 1);
|
(std::numeric_limits<T>::digits - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disable signed.
|
|
||||||
template <typename T>
|
|
||||||
typename enable_if_c<std::numeric_limits<T>::is_integer &&
|
|
||||||
std::numeric_limits<T>::is_signed, T>::type
|
|
||||||
findLastSet(T Val, ZeroBehavior ZB = ZB_Max) LLVM_DELETED_FUNCTION;
|
|
||||||
|
|
||||||
/// \brief Macro compressed bit reversal table for 256 bits.
|
/// \brief Macro compressed bit reversal table for 256 bits.
|
||||||
///
|
///
|
||||||
/// http://graphics.stanford.edu/~seander/bithacks.html#BitReverseTable
|
/// http://graphics.stanford.edu/~seander/bithacks.html#BitReverseTable
|
||||||
|
@ -232,6 +223,9 @@ static const unsigned char BitReverseTable256[256] = {
|
||||||
#define R4(n) R2(n), R2(n + 2 * 16), R2(n + 1 * 16), R2(n + 3 * 16)
|
#define R4(n) R2(n), R2(n + 2 * 16), R2(n + 1 * 16), R2(n + 3 * 16)
|
||||||
#define R6(n) R4(n), R4(n + 2 * 4), R4(n + 1 * 4), R4(n + 3 * 4)
|
#define R6(n) R4(n), R4(n + 2 * 4), R4(n + 1 * 4), R4(n + 3 * 4)
|
||||||
R6(0), R6(2), R6(1), R6(3)
|
R6(0), R6(2), R6(1), R6(3)
|
||||||
|
#undef R2
|
||||||
|
#undef R4
|
||||||
|
#undef R6
|
||||||
};
|
};
|
||||||
|
|
||||||
/// \brief Reverse the bits in \p Val.
|
/// \brief Reverse the bits in \p Val.
|
||||||
|
@ -260,6 +254,12 @@ inline uint32_t Lo_32(uint64_t Value) {
|
||||||
return static_cast<uint32_t>(Value);
|
return static_cast<uint32_t>(Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Make_64 - This functions makes a 64-bit integer from a high / low pair of
|
||||||
|
/// 32-bit integers.
|
||||||
|
inline uint64_t Make_64(uint32_t High, uint32_t Low) {
|
||||||
|
return ((uint64_t)High << 32) | (uint64_t)Low;
|
||||||
|
}
|
||||||
|
|
||||||
/// isInt - Checks if an integer fits into the given bit width.
|
/// isInt - Checks if an integer fits into the given bit width.
|
||||||
template<unsigned N>
|
template<unsigned N>
|
||||||
inline bool isInt(int64_t x) {
|
inline bool isInt(int64_t x) {
|
||||||
|
@ -315,7 +315,7 @@ inline bool isShiftedUInt(uint64_t x) {
|
||||||
/// isUIntN - Checks if an unsigned integer fits into the given (dynamic)
|
/// isUIntN - Checks if an unsigned integer fits into the given (dynamic)
|
||||||
/// bit width.
|
/// bit width.
|
||||||
inline bool isUIntN(unsigned N, uint64_t x) {
|
inline bool isUIntN(unsigned N, uint64_t x) {
|
||||||
return x == (x & (~0ULL >> (64 - N)));
|
return N >= 64 || x < (UINT64_C(1)<<(N));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// isIntN - Checks if an signed integer fits into the given (dynamic)
|
/// isIntN - Checks if an signed integer fits into the given (dynamic)
|
||||||
|
@ -324,31 +324,31 @@ inline bool isIntN(unsigned N, int64_t x) {
|
||||||
return N >= 64 || (-(INT64_C(1)<<(N-1)) <= x && x < (INT64_C(1)<<(N-1)));
|
return N >= 64 || (-(INT64_C(1)<<(N-1)) <= x && x < (INT64_C(1)<<(N-1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// isMask_32 - This function returns true if the argument is a sequence of ones
|
/// isMask_32 - This function returns true if the argument is a non-empty
|
||||||
/// starting at the least significant bit with the remainder zero (32 bit
|
/// sequence of ones starting at the least significant bit with the remainder
|
||||||
/// version). Ex. isMask_32(0x0000FFFFU) == true.
|
/// zero (32 bit version). Ex. isMask_32(0x0000FFFFU) == true.
|
||||||
inline bool isMask_32(uint32_t Value) {
|
inline bool isMask_32(uint32_t Value) {
|
||||||
return Value && ((Value + 1) & Value) == 0;
|
return Value && ((Value + 1) & Value) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// isMask_64 - This function returns true if the argument is a sequence of ones
|
/// isMask_64 - This function returns true if the argument is a non-empty
|
||||||
/// starting at the least significant bit with the remainder zero (64 bit
|
/// sequence of ones starting at the least significant bit with the remainder
|
||||||
/// version).
|
/// zero (64 bit version).
|
||||||
inline bool isMask_64(uint64_t Value) {
|
inline bool isMask_64(uint64_t Value) {
|
||||||
return Value && ((Value + 1) & Value) == 0;
|
return Value && ((Value + 1) & Value) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// isShiftedMask_32 - This function returns true if the argument contains a
|
/// isShiftedMask_32 - This function returns true if the argument contains a
|
||||||
/// sequence of ones with the remainder zero (32 bit version.)
|
/// non-empty sequence of ones with the remainder zero (32 bit version.)
|
||||||
/// Ex. isShiftedMask_32(0x0000FF00U) == true.
|
/// Ex. isShiftedMask_32(0x0000FF00U) == true.
|
||||||
inline bool isShiftedMask_32(uint32_t Value) {
|
inline bool isShiftedMask_32(uint32_t Value) {
|
||||||
return isMask_32((Value - 1) | Value);
|
return Value && isMask_32((Value - 1) | Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// isShiftedMask_64 - This function returns true if the argument contains a
|
/// isShiftedMask_64 - This function returns true if the argument contains a
|
||||||
/// sequence of ones with the remainder zero (64 bit version.)
|
/// non-empty sequence of ones with the remainder zero (64 bit version.)
|
||||||
inline bool isShiftedMask_64(uint64_t Value) {
|
inline bool isShiftedMask_64(uint64_t Value) {
|
||||||
return isMask_64((Value - 1) | Value);
|
return Value && isMask_64((Value - 1) | Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// isPowerOf2_32 - This function returns true if the argument is a power of
|
/// isPowerOf2_32 - This function returns true if the argument is a power of
|
||||||
|
@ -383,61 +383,86 @@ inline uint64_t ByteSwap_64(uint64_t Value) {
|
||||||
}
|
}
|
||||||
#endif // IGNORED_LLVM_XENIA
|
#endif // IGNORED_LLVM_XENIA
|
||||||
|
|
||||||
/// CountLeadingOnes_32 - this function performs the operation of
|
/// \brief Count the number of ones from the most significant bit to the first
|
||||||
/// counting the number of ones from the most significant bit to the first zero
|
/// zero bit.
|
||||||
/// bit. Ex. CountLeadingOnes_32(0xFF0FFF00) == 8.
|
///
|
||||||
/// Returns 32 if the word is all ones.
|
/// Ex. CountLeadingOnes(0xFF0FFF00) == 8.
|
||||||
inline unsigned CountLeadingOnes_32(uint32_t Value) {
|
/// Only unsigned integral types are allowed.
|
||||||
return countLeadingZeros(~Value);
|
///
|
||||||
|
/// \param ZB the behavior on an input of all ones. Only ZB_Width and
|
||||||
|
/// ZB_Undefined are valid arguments.
|
||||||
|
template <typename T>
|
||||||
|
std::size_t countLeadingOnes(T Value, ZeroBehavior ZB = ZB_Width) {
|
||||||
|
static_assert(std::numeric_limits<T>::is_integer &&
|
||||||
|
!std::numeric_limits<T>::is_signed,
|
||||||
|
"Only unsigned integral types are allowed.");
|
||||||
|
return countLeadingZeros(~Value, ZB);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// CountLeadingOnes_64 - This function performs the operation
|
/// \brief Count the number of ones from the least significant bit to the first
|
||||||
/// of counting the number of ones from the most significant bit to the first
|
/// zero bit.
|
||||||
/// zero bit (64 bit edition.)
|
///
|
||||||
/// Returns 64 if the word is all ones.
|
/// Ex. countTrailingOnes(0x00FF00FF) == 8.
|
||||||
inline unsigned CountLeadingOnes_64(uint64_t Value) {
|
/// Only unsigned integral types are allowed.
|
||||||
return countLeadingZeros(~Value);
|
///
|
||||||
|
/// \param ZB the behavior on an input of all ones. Only ZB_Width and
|
||||||
|
/// ZB_Undefined are valid arguments.
|
||||||
|
template <typename T>
|
||||||
|
std::size_t countTrailingOnes(T Value, ZeroBehavior ZB = ZB_Width) {
|
||||||
|
static_assert(std::numeric_limits<T>::is_integer &&
|
||||||
|
!std::numeric_limits<T>::is_signed,
|
||||||
|
"Only unsigned integral types are allowed.");
|
||||||
|
return countTrailingZeros(~Value, ZB);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// CountTrailingOnes_32 - this function performs the operation of
|
namespace detail {
|
||||||
/// counting the number of ones from the least significant bit to the first zero
|
template <typename T, std::size_t SizeOfT> struct PopulationCounter {
|
||||||
/// bit. Ex. CountTrailingOnes_32(0x00FF00FF) == 8.
|
static unsigned count(T Value) {
|
||||||
/// Returns 32 if the word is all ones.
|
// Generic version, forward to 32 bits.
|
||||||
inline unsigned CountTrailingOnes_32(uint32_t Value) {
|
static_assert(SizeOfT <= 4, "Not implemented!");
|
||||||
return countTrailingZeros(~Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// CountTrailingOnes_64 - This function performs the operation
|
|
||||||
/// of counting the number of ones from the least significant bit to the first
|
|
||||||
/// zero bit (64 bit edition.)
|
|
||||||
/// Returns 64 if the word is all ones.
|
|
||||||
inline unsigned CountTrailingOnes_64(uint64_t Value) {
|
|
||||||
return countTrailingZeros(~Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// CountPopulation_32 - this function counts the number of set bits in a value.
|
|
||||||
/// Ex. CountPopulation(0xF000F000) = 8
|
|
||||||
/// Returns 0 if the word is zero.
|
|
||||||
inline unsigned CountPopulation_32(uint32_t Value) {
|
|
||||||
#if __GNUC__ >= 4
|
#if __GNUC__ >= 4
|
||||||
return __builtin_popcount(Value);
|
return __builtin_popcount(Value);
|
||||||
#else
|
#else
|
||||||
uint32_t v = Value - ((Value >> 1) & 0x55555555);
|
uint32_t v = Value;
|
||||||
v = (v & 0x33333333) + ((v >> 2) & 0x33333333);
|
v = v - ((v >> 1) & 0x55555555);
|
||||||
return ((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24;
|
v = (v & 0x33333333) + ((v >> 2) & 0x33333333);
|
||||||
|
return ((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24;
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T> struct PopulationCounter<T, 8> {
|
||||||
|
static unsigned count(T Value) {
|
||||||
|
#if __GNUC__ >= 4
|
||||||
|
return __builtin_popcountll(Value);
|
||||||
|
#else
|
||||||
|
uint64_t v = Value;
|
||||||
|
v = v - ((v >> 1) & 0x5555555555555555ULL);
|
||||||
|
v = (v & 0x3333333333333333ULL) + ((v >> 2) & 0x3333333333333333ULL);
|
||||||
|
v = (v + (v >> 4)) & 0x0F0F0F0F0F0F0F0FULL;
|
||||||
|
return unsigned((uint64_t)(v * 0x0101010101010101ULL) >> 56);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
/// \brief Count the number of set bits in a value.
|
||||||
|
/// Ex. countPopulation(0xF000F000) = 8
|
||||||
|
/// Returns 0 if the word is zero.
|
||||||
|
template <typename T>
|
||||||
|
inline unsigned countPopulation(T Value) {
|
||||||
|
static_assert(std::numeric_limits<T>::is_integer &&
|
||||||
|
!std::numeric_limits<T>::is_signed,
|
||||||
|
"Only unsigned integral types are allowed.");
|
||||||
|
return detail::PopulationCounter<T, sizeof(T)>::count(Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// CountPopulation_64 - this function counts the number of set bits in a value,
|
/// Log2 - This function returns the log base 2 of the specified value
|
||||||
/// (64 bit edition.)
|
inline double Log2(double Value) {
|
||||||
inline unsigned CountPopulation_64(uint64_t Value) {
|
#if defined(__ANDROID_API__) && __ANDROID_API__ < 18
|
||||||
#if __GNUC__ >= 4
|
return __builtin_log(Value) / __builtin_log(2.0);
|
||||||
return __builtin_popcountll(Value);
|
|
||||||
#else
|
#else
|
||||||
uint64_t v = Value - ((Value >> 1) & 0x5555555555555555ULL);
|
return log2(Value);
|
||||||
v = (v & 0x3333333333333333ULL) + ((v >> 2) & 0x3333333333333333ULL);
|
|
||||||
v = (v + (v >> 4)) & 0x0F0F0F0F0F0F0F0FULL;
|
|
||||||
return unsigned((uint64_t)(v * 0x0101010101010101ULL) >> 56);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -526,14 +551,6 @@ inline uint32_t FloatToBits(float Float) {
|
||||||
return T.I;
|
return T.I;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Platform-independent wrappers for the C99 isnan() function.
|
|
||||||
int IsNAN(float f);
|
|
||||||
int IsNAN(double d);
|
|
||||||
|
|
||||||
/// Platform-independent wrappers for the C99 isinf() function.
|
|
||||||
int IsInf(float f);
|
|
||||||
int IsInf(double d);
|
|
||||||
|
|
||||||
/// MinAlign - A and B are either alignments or offsets. Return the minimum
|
/// MinAlign - A and B are either alignments or offsets. Return the minimum
|
||||||
/// alignment that may be assumed after adding the two together.
|
/// alignment that may be assumed after adding the two together.
|
||||||
inline uint64_t MinAlign(uint64_t A, uint64_t B) {
|
inline uint64_t MinAlign(uint64_t A, uint64_t B) {
|
||||||
|
@ -545,6 +562,25 @@ inline uint64_t MinAlign(uint64_t A, uint64_t B) {
|
||||||
return (A | B) & (1 + ~(A | B));
|
return (A | B) & (1 + ~(A | B));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// \brief Aligns \c Addr to \c Alignment bytes, rounding up.
|
||||||
|
///
|
||||||
|
/// Alignment should be a power of two. This method rounds up, so
|
||||||
|
/// alignAddr(7, 4) == 8 and alignAddr(8, 4) == 8.
|
||||||
|
inline uintptr_t alignAddr(const void *Addr, size_t Alignment) {
|
||||||
|
assert(Alignment && isPowerOf2_64((uint64_t)Alignment) &&
|
||||||
|
"Alignment is not a power of two!");
|
||||||
|
|
||||||
|
assert((uintptr_t)Addr + Alignment - 1 >= (uintptr_t)Addr);
|
||||||
|
|
||||||
|
return (((uintptr_t)Addr + Alignment - 1) & ~(uintptr_t)(Alignment - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Returns the necessary adjustment for aligning \c Ptr to \c Alignment
|
||||||
|
/// bytes, rounding up.
|
||||||
|
inline size_t alignmentAdjustment(const void *Ptr, size_t Alignment) {
|
||||||
|
return alignAddr(Ptr, Alignment) - (uintptr_t)Ptr;
|
||||||
|
}
|
||||||
|
|
||||||
/// NextPowerOf2 - Returns the next power of two (in 64-bits)
|
/// NextPowerOf2 - Returns the next power of two (in 64-bits)
|
||||||
/// that is strictly greater than A. Returns zero on overflow.
|
/// that is strictly greater than A. Returns zero on overflow.
|
||||||
inline uint64_t NextPowerOf2(uint64_t A) {
|
inline uint64_t NextPowerOf2(uint64_t A) {
|
||||||
|
@ -567,14 +603,27 @@ inline uint64_t PowerOf2Floor(uint64_t A) {
|
||||||
/// Returns the next integer (mod 2**64) that is greater than or equal to
|
/// Returns the next integer (mod 2**64) that is greater than or equal to
|
||||||
/// \p Value and is a multiple of \p Align. \p Align must be non-zero.
|
/// \p Value and is a multiple of \p Align. \p Align must be non-zero.
|
||||||
///
|
///
|
||||||
|
/// If non-zero \p Skew is specified, the return value will be a minimal
|
||||||
|
/// integer that is greater than or equal to \p Value and equal to
|
||||||
|
/// \p Align * N + \p Skew for some integer N. If \p Skew is larger than
|
||||||
|
/// \p Align, its value is adjusted to '\p Skew mod \p Align'.
|
||||||
|
///
|
||||||
/// Examples:
|
/// Examples:
|
||||||
/// \code
|
/// \code
|
||||||
/// RoundUpToAlignment(5, 8) = 8
|
/// RoundUpToAlignment(5, 8) = 8
|
||||||
/// RoundUpToAlignment(17, 8) = 24
|
/// RoundUpToAlignment(17, 8) = 24
|
||||||
/// RoundUpToAlignment(~0LL, 8) = 0
|
/// RoundUpToAlignment(~0LL, 8) = 0
|
||||||
|
/// RoundUpToAlignment(321, 255) = 510
|
||||||
|
///
|
||||||
|
/// RoundUpToAlignment(5, 8, 7) = 7
|
||||||
|
/// RoundUpToAlignment(17, 8, 1) = 17
|
||||||
|
/// RoundUpToAlignment(~0LL, 8, 3) = 3
|
||||||
|
/// RoundUpToAlignment(321, 255, 42) = 552
|
||||||
/// \endcode
|
/// \endcode
|
||||||
inline uint64_t RoundUpToAlignment(uint64_t Value, uint64_t Align) {
|
inline uint64_t RoundUpToAlignment(uint64_t Value, uint64_t Align,
|
||||||
return ((Value + Align - 1) / Align) * Align;
|
uint64_t Skew = 0) {
|
||||||
|
Skew %= Align;
|
||||||
|
return (Value + Align - 1 - Skew) / Align * Align + Skew;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the offset to the next integer (mod 2**64) that is greater than
|
/// Returns the offset to the next integer (mod 2**64) that is greater than
|
||||||
|
@ -584,13 +633,6 @@ inline uint64_t OffsetToAlignment(uint64_t Value, uint64_t Align) {
|
||||||
return RoundUpToAlignment(Value, Align) - Value;
|
return RoundUpToAlignment(Value, Align) - Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// abs64 - absolute value of a 64-bit int. Not all environments support
|
|
||||||
/// "abs" on whatever their name for the 64-bit int type is. The absolute
|
|
||||||
/// value of the largest negative number is undefined, as with "abs".
|
|
||||||
inline int64_t abs64(int64_t x) {
|
|
||||||
return (x < 0) ? -x : x;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// SignExtend32 - Sign extend B-bit number x to 32-bit int.
|
/// SignExtend32 - Sign extend B-bit number x to 32-bit int.
|
||||||
/// Usage int32_t r = SignExtend32<5>(x);
|
/// Usage int32_t r = SignExtend32<5>(x);
|
||||||
template <unsigned B> inline int32_t SignExtend32(uint32_t x) {
|
template <unsigned B> inline int32_t SignExtend32(uint32_t x) {
|
||||||
|
@ -615,13 +657,90 @@ inline int64_t SignExtend64(uint64_t X, unsigned B) {
|
||||||
return int64_t(X << (64 - B)) >> (64 - B);
|
return int64_t(X << (64 - B)) >> (64 - B);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
/// \brief Add two unsigned integers, X and Y, of type T.
|
||||||
// Visual Studio defines the HUGE_VAL class of macros using purposeful
|
/// Clamp the result to the maximum representable value of T on overflow.
|
||||||
// constant arithmetic overflow, which it then warns on when encountered.
|
/// ResultOverflowed indicates if the result is larger than the maximum
|
||||||
const float huge_valf = std::numeric_limits<float>::infinity();
|
/// representable value of type T.
|
||||||
#else
|
template <typename T>
|
||||||
const float huge_valf = HUGE_VALF;
|
typename std::enable_if<std::is_unsigned<T>::value, T>::type
|
||||||
#endif
|
SaturatingAdd(T X, T Y, bool *ResultOverflowed = nullptr) {
|
||||||
|
bool Dummy;
|
||||||
|
bool &Overflowed = ResultOverflowed ? *ResultOverflowed : Dummy;
|
||||||
|
// Hacker's Delight, p. 29
|
||||||
|
T Z = X + Y;
|
||||||
|
Overflowed = (Z < X || Z < Y);
|
||||||
|
if (Overflowed)
|
||||||
|
return std::numeric_limits<T>::max();
|
||||||
|
else
|
||||||
|
return Z;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Multiply two unsigned integers, X and Y, of type T.
|
||||||
|
/// Clamp the result to the maximum representable value of T on overflow.
|
||||||
|
/// ResultOverflowed indicates if the result is larger than the maximum
|
||||||
|
/// representable value of type T.
|
||||||
|
template <typename T>
|
||||||
|
typename std::enable_if<std::is_unsigned<T>::value, T>::type
|
||||||
|
SaturatingMultiply(T X, T Y, bool *ResultOverflowed = nullptr) {
|
||||||
|
bool Dummy;
|
||||||
|
bool &Overflowed = ResultOverflowed ? *ResultOverflowed : Dummy;
|
||||||
|
|
||||||
|
// Hacker's Delight, p. 30 has a different algorithm, but we don't use that
|
||||||
|
// because it fails for uint16_t (where multiplication can have undefined
|
||||||
|
// behavior due to promotion to int), and requires a division in addition
|
||||||
|
// to the multiplication.
|
||||||
|
|
||||||
|
Overflowed = false;
|
||||||
|
|
||||||
|
// Log2(Z) would be either Log2Z or Log2Z + 1.
|
||||||
|
// Special case: if X or Y is 0, Log2_64 gives -1, and Log2Z
|
||||||
|
// will necessarily be less than Log2Max as desired.
|
||||||
|
int Log2Z = Log2_64(X) + Log2_64(Y);
|
||||||
|
const T Max = std::numeric_limits<T>::max();
|
||||||
|
int Log2Max = Log2_64(Max);
|
||||||
|
if (Log2Z < Log2Max) {
|
||||||
|
return X * Y;
|
||||||
|
}
|
||||||
|
if (Log2Z > Log2Max) {
|
||||||
|
Overflowed = true;
|
||||||
|
return Max;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We're going to use the top bit, and maybe overflow one
|
||||||
|
// bit past it. Multiply all but the bottom bit then add
|
||||||
|
// that on at the end.
|
||||||
|
T Z = (X >> 1) * Y;
|
||||||
|
if (Z & ~(Max >> 1)) {
|
||||||
|
Overflowed = true;
|
||||||
|
return Max;
|
||||||
|
}
|
||||||
|
Z <<= 1;
|
||||||
|
if (X & 1)
|
||||||
|
return SaturatingAdd(Z, Y, ResultOverflowed);
|
||||||
|
|
||||||
|
return Z;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Multiply two unsigned integers, X and Y, and add the unsigned
|
||||||
|
/// integer, A to the product. Clamp the result to the maximum representable
|
||||||
|
/// value of T on overflow. ResultOverflowed indicates if the result is larger
|
||||||
|
/// than the maximum representable value of type T.
|
||||||
|
/// Note that this is purely a convenience function as there is no distinction
|
||||||
|
/// where overflow occurred in a 'fused' multiply-add for unsigned numbers.
|
||||||
|
template <typename T>
|
||||||
|
typename std::enable_if<std::is_unsigned<T>::value, T>::type
|
||||||
|
SaturatingMultiplyAdd(T X, T Y, T A, bool *ResultOverflowed = nullptr) {
|
||||||
|
bool Dummy;
|
||||||
|
bool &Overflowed = ResultOverflowed ? *ResultOverflowed : Dummy;
|
||||||
|
|
||||||
|
T Product = SaturatingMultiply(X, Y, &Overflowed);
|
||||||
|
if (Overflowed)
|
||||||
|
return Product;
|
||||||
|
|
||||||
|
return SaturatingAdd(A, Product, &Overflowed);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern const float huge_valf;
|
||||||
} // End llvm namespace
|
} // End llvm namespace
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,244 +0,0 @@
|
||||||
//===- llvm/Support/type_traits.h - Simplfied type traits -------*- C++ -*-===//
|
|
||||||
//
|
|
||||||
// The LLVM Compiler Infrastructure
|
|
||||||
//
|
|
||||||
// This file is distributed under the University of Illinois Open Source
|
|
||||||
// License. See LICENSE.TXT for details.
|
|
||||||
//
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
//
|
|
||||||
// This file provides a template class that determines if a type is a class or
|
|
||||||
// not. The basic mechanism, based on using the pointer to member function of
|
|
||||||
// a zero argument to a function was "boosted" from the boost type_traits
|
|
||||||
// library. See http://www.boost.org/ for all the gory details.
|
|
||||||
//
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
|
|
||||||
#ifndef LLVM_SUPPORT_TYPE_TRAITS_H
|
|
||||||
#define LLVM_SUPPORT_TYPE_TRAITS_H
|
|
||||||
|
|
||||||
//#include "llvm/Support/DataTypes.h"
|
|
||||||
#include <cstddef>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
#ifndef __has_feature
|
|
||||||
#define LLVM_DEFINED_HAS_FEATURE
|
|
||||||
#define __has_feature(x) 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// This is actually the conforming implementation which works with abstract
|
|
||||||
// classes. However, enough compilers have trouble with it that most will use
|
|
||||||
// the one in boost/type_traits/object_traits.hpp. This implementation actually
|
|
||||||
// works with VC7.0, but other interactions seem to fail when we use it.
|
|
||||||
|
|
||||||
namespace llvm {
|
|
||||||
|
|
||||||
namespace dont_use
|
|
||||||
{
|
|
||||||
// These two functions should never be used. They are helpers to
|
|
||||||
// the is_class template below. They cannot be located inside
|
|
||||||
// is_class because doing so causes at least GCC to think that
|
|
||||||
// the value of the "value" enumerator is not constant. Placing
|
|
||||||
// them out here (for some strange reason) allows the sizeof
|
|
||||||
// operator against them to magically be constant. This is
|
|
||||||
// important to make the is_class<T>::value idiom zero cost. it
|
|
||||||
// evaluates to a constant 1 or 0 depending on whether the
|
|
||||||
// parameter T is a class or not (respectively).
|
|
||||||
template<typename T> char is_class_helper(void(T::*)());
|
|
||||||
template<typename T> double is_class_helper(...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct is_class
|
|
||||||
{
|
|
||||||
// is_class<> metafunction due to Paul Mensonides (leavings@attbi.com). For
|
|
||||||
// more details:
|
|
||||||
// http://groups.google.com/groups?hl=en&selm=000001c1cc83%24e154d5e0%247772e50c%40c161550a&rnum=1
|
|
||||||
public:
|
|
||||||
static const bool value =
|
|
||||||
sizeof(char) == sizeof(dont_use::is_class_helper<T>(0));
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/// isPodLike - This is a type trait that is used to determine whether a given
|
|
||||||
/// type can be copied around with memcpy instead of running ctors etc.
|
|
||||||
template <typename T>
|
|
||||||
struct isPodLike {
|
|
||||||
#if __has_feature(is_trivially_copyable)
|
|
||||||
// If the compiler supports the is_trivially_copyable trait use it, as it
|
|
||||||
// matches the definition of isPodLike closely.
|
|
||||||
static const bool value = __is_trivially_copyable(T);
|
|
||||||
#else
|
|
||||||
// If we don't know anything else, we can (at least) assume that all non-class
|
|
||||||
// types are PODs.
|
|
||||||
static const bool value = !is_class<T>::value;
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
// std::pair's are pod-like if their elements are.
|
|
||||||
template<typename T, typename U>
|
|
||||||
struct isPodLike<std::pair<T, U> > {
|
|
||||||
static const bool value = isPodLike<T>::value && isPodLike<U>::value;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template <class T, T v>
|
|
||||||
struct integral_constant {
|
|
||||||
typedef T value_type;
|
|
||||||
static const value_type value = v;
|
|
||||||
typedef integral_constant<T,v> type;
|
|
||||||
operator value_type() { return value; }
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef integral_constant<bool, true> true_type;
|
|
||||||
typedef integral_constant<bool, false> false_type;
|
|
||||||
|
|
||||||
/// \brief Metafunction that determines whether the two given types are
|
|
||||||
/// equivalent.
|
|
||||||
template<typename T, typename U> struct is_same : public false_type {};
|
|
||||||
template<typename T> struct is_same<T, T> : public true_type {};
|
|
||||||
|
|
||||||
/// \brief Metafunction that removes const qualification from a type.
|
|
||||||
template <typename T> struct remove_const { typedef T type; };
|
|
||||||
template <typename T> struct remove_const<const T> { typedef T type; };
|
|
||||||
|
|
||||||
/// \brief Metafunction that removes volatile qualification from a type.
|
|
||||||
template <typename T> struct remove_volatile { typedef T type; };
|
|
||||||
template <typename T> struct remove_volatile<volatile T> { typedef T type; };
|
|
||||||
|
|
||||||
/// \brief Metafunction that removes both const and volatile qualification from
|
|
||||||
/// a type.
|
|
||||||
template <typename T> struct remove_cv {
|
|
||||||
typedef typename remove_const<typename remove_volatile<T>::type>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
/// \brief Helper to implement is_integral metafunction.
|
|
||||||
template <typename T> struct is_integral_impl : false_type {};
|
|
||||||
template <> struct is_integral_impl< bool> : true_type {};
|
|
||||||
template <> struct is_integral_impl< char> : true_type {};
|
|
||||||
template <> struct is_integral_impl< signed char> : true_type {};
|
|
||||||
template <> struct is_integral_impl<unsigned char> : true_type {};
|
|
||||||
template <> struct is_integral_impl< wchar_t> : true_type {};
|
|
||||||
template <> struct is_integral_impl< short> : true_type {};
|
|
||||||
template <> struct is_integral_impl<unsigned short> : true_type {};
|
|
||||||
template <> struct is_integral_impl< int> : true_type {};
|
|
||||||
template <> struct is_integral_impl<unsigned int> : true_type {};
|
|
||||||
template <> struct is_integral_impl< long> : true_type {};
|
|
||||||
template <> struct is_integral_impl<unsigned long> : true_type {};
|
|
||||||
template <> struct is_integral_impl< long long> : true_type {};
|
|
||||||
template <> struct is_integral_impl<unsigned long long> : true_type {};
|
|
||||||
|
|
||||||
/// \brief Metafunction that determines whether the given type is an integral
|
|
||||||
/// type.
|
|
||||||
template <typename T>
|
|
||||||
struct is_integral : is_integral_impl<T> {};
|
|
||||||
|
|
||||||
/// \brief Metafunction to remove reference from a type.
|
|
||||||
template <typename T> struct remove_reference { typedef T type; };
|
|
||||||
template <typename T> struct remove_reference<T&> { typedef T type; };
|
|
||||||
|
|
||||||
/// \brief Metafunction that determines whether the given type is a pointer
|
|
||||||
/// type.
|
|
||||||
template <typename T> struct is_pointer : false_type {};
|
|
||||||
template <typename T> struct is_pointer<T*> : true_type {};
|
|
||||||
template <typename T> struct is_pointer<T* const> : true_type {};
|
|
||||||
template <typename T> struct is_pointer<T* volatile> : true_type {};
|
|
||||||
template <typename T> struct is_pointer<T* const volatile> : true_type {};
|
|
||||||
|
|
||||||
/// \brief Metafunction that determines wheather the given type is a reference.
|
|
||||||
template <typename T> struct is_reference : false_type {};
|
|
||||||
template <typename T> struct is_reference<T&> : true_type {};
|
|
||||||
|
|
||||||
/// \brief Metafunction that determines whether the given type is either an
|
|
||||||
/// integral type or an enumeration type.
|
|
||||||
///
|
|
||||||
/// Note that this accepts potentially more integral types than we whitelist
|
|
||||||
/// above for is_integral because it is based on merely being convertible
|
|
||||||
/// implicitly to an integral type.
|
|
||||||
template <typename T> class is_integral_or_enum {
|
|
||||||
// Provide an overload which can be called with anything implicitly
|
|
||||||
// convertible to an unsigned long long. This should catch integer types and
|
|
||||||
// enumeration types at least. We blacklist classes with conversion operators
|
|
||||||
// below.
|
|
||||||
static double check_int_convertible(unsigned long long);
|
|
||||||
static char check_int_convertible(...);
|
|
||||||
|
|
||||||
typedef typename remove_reference<T>::type UnderlyingT;
|
|
||||||
static UnderlyingT &nonce_instance;
|
|
||||||
|
|
||||||
public:
|
|
||||||
static const bool
|
|
||||||
value = (!is_class<UnderlyingT>::value && !is_pointer<UnderlyingT>::value &&
|
|
||||||
!is_same<UnderlyingT, float>::value &&
|
|
||||||
!is_same<UnderlyingT, double>::value &&
|
|
||||||
sizeof(char) != sizeof(check_int_convertible(nonce_instance)));
|
|
||||||
};
|
|
||||||
|
|
||||||
// enable_if_c - Enable/disable a template based on a metafunction
|
|
||||||
template<bool Cond, typename T = void>
|
|
||||||
struct enable_if_c {
|
|
||||||
typedef T type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T> struct enable_if_c<false, T> { };
|
|
||||||
|
|
||||||
// enable_if - Enable/disable a template based on a metafunction
|
|
||||||
template<typename Cond, typename T = void>
|
|
||||||
struct enable_if : public enable_if_c<Cond::value, T> { };
|
|
||||||
|
|
||||||
namespace dont_use {
|
|
||||||
template<typename Base> char base_of_helper(const volatile Base*);
|
|
||||||
template<typename Base> double base_of_helper(...);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// is_base_of - Metafunction to determine whether one type is a base class of
|
|
||||||
/// (or identical to) another type.
|
|
||||||
template<typename Base, typename Derived>
|
|
||||||
struct is_base_of {
|
|
||||||
static const bool value
|
|
||||||
= is_class<Base>::value && is_class<Derived>::value &&
|
|
||||||
sizeof(char) == sizeof(dont_use::base_of_helper<Base>((Derived*)0));
|
|
||||||
};
|
|
||||||
|
|
||||||
// remove_pointer - Metafunction to turn Foo* into Foo. Defined in
|
|
||||||
// C++0x [meta.trans.ptr].
|
|
||||||
template <typename T> struct remove_pointer { typedef T type; };
|
|
||||||
template <typename T> struct remove_pointer<T*> { typedef T type; };
|
|
||||||
template <typename T> struct remove_pointer<T*const> { typedef T type; };
|
|
||||||
template <typename T> struct remove_pointer<T*volatile> { typedef T type; };
|
|
||||||
template <typename T> struct remove_pointer<T*const volatile> {
|
|
||||||
typedef T type; };
|
|
||||||
|
|
||||||
// If T is a pointer, just return it. If it is not, return T&.
|
|
||||||
template<typename T, typename Enable = void>
|
|
||||||
struct add_lvalue_reference_if_not_pointer { typedef T &type; };
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct add_lvalue_reference_if_not_pointer<T,
|
|
||||||
typename enable_if<is_pointer<T> >::type> {
|
|
||||||
typedef T type;
|
|
||||||
};
|
|
||||||
|
|
||||||
// If T is a pointer to X, return a pointer to const X. If it is not, return
|
|
||||||
// const T.
|
|
||||||
template<typename T, typename Enable = void>
|
|
||||||
struct add_const_past_pointer { typedef const T type; };
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct add_const_past_pointer<T, typename enable_if<is_pointer<T> >::type> {
|
|
||||||
typedef const typename remove_pointer<T>::type *type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <bool, typename T, typename F>
|
|
||||||
struct conditional { typedef T type; };
|
|
||||||
|
|
||||||
template <typename T, typename F>
|
|
||||||
struct conditional<false, T, F> { typedef F type; };
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef LLVM_DEFINED_HAS_FEATURE
|
|
||||||
#undef __has_feature
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit cf209c915b849141ed9821fea883fd04bcc34859
|
Subproject commit 4e44f4614ddbf038f2a6296f5b906d5c72691e0f
|
|
@ -1 +1 @@
|
||||||
Subproject commit 3e321b4407318ac1348c0b80fb6fbae8c81ad5fa
|
Subproject commit e626a72bc2321cd320e953a0ccf1584cad60f363
|
Loading…
Reference in New Issue