initial
This commit is contained in:
25
thirdparty/clang/include/llvm/Support/AIXDataTypesFix.h
vendored
Normal file
25
thirdparty/clang/include/llvm/Support/AIXDataTypesFix.h
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
//===-- llvm/Support/AIXDataTypesFix.h - Fix datatype defs ------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file overrides default system-defined types and limits which cannot be
|
||||
// done in DataTypes.h.in because it is processed by autoheader first, which
|
||||
// comments out any #undef statement
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// No include guards desired!
|
||||
|
||||
#ifndef SUPPORT_DATATYPES_H
|
||||
#error "AIXDataTypesFix.h must only be included via DataTypes.h!"
|
||||
#endif
|
||||
|
||||
// GCC is strict about defining large constants: they must have LL modifier.
|
||||
// These will be defined properly at the end of DataTypes.h
|
||||
#undef INT64_MAX
|
||||
#undef INT64_MIN
|
||||
204
thirdparty/clang/include/llvm/Support/AlignOf.h
vendored
Normal file
204
thirdparty/clang/include/llvm/Support/AlignOf.h
vendored
Normal file
@@ -0,0 +1,204 @@
|
||||
//===--- AlignOf.h - Portable calculation of type alignment -----*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the AlignOf function that computes alignments for
|
||||
// arbitrary types.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_ALIGNOF_H
|
||||
#define LLVM_SUPPORT_ALIGNOF_H
|
||||
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include <cstddef>
|
||||
|
||||
namespace llvm {
|
||||
template <typename T>
|
||||
struct AlignmentCalcImpl {
|
||||
char x;
|
||||
T t;
|
||||
private:
|
||||
AlignmentCalcImpl() {} // Never instantiate.
|
||||
};
|
||||
|
||||
/// AlignOf - A templated class that contains an enum value representing
|
||||
/// the alignment of the template argument. For example,
|
||||
/// AlignOf<int>::Alignment represents the alignment of type "int". The
|
||||
/// alignment calculated is the minimum alignment, and not necessarily
|
||||
/// the "desired" alignment returned by GCC's __alignof__ (for example). Note
|
||||
/// that because the alignment is an enum value, it can be used as a
|
||||
/// compile-time constant (e.g., for template instantiation).
|
||||
template <typename T>
|
||||
struct AlignOf {
|
||||
enum { Alignment =
|
||||
static_cast<unsigned int>(sizeof(AlignmentCalcImpl<T>) - sizeof(T)) };
|
||||
|
||||
enum { Alignment_GreaterEqual_2Bytes = Alignment >= 2 ? 1 : 0 };
|
||||
enum { Alignment_GreaterEqual_4Bytes = Alignment >= 4 ? 1 : 0 };
|
||||
enum { Alignment_GreaterEqual_8Bytes = Alignment >= 8 ? 1 : 0 };
|
||||
enum { Alignment_GreaterEqual_16Bytes = Alignment >= 16 ? 1 : 0 };
|
||||
|
||||
enum { Alignment_LessEqual_2Bytes = Alignment <= 2 ? 1 : 0 };
|
||||
enum { Alignment_LessEqual_4Bytes = Alignment <= 4 ? 1 : 0 };
|
||||
enum { Alignment_LessEqual_8Bytes = Alignment <= 8 ? 1 : 0 };
|
||||
enum { Alignment_LessEqual_16Bytes = Alignment <= 16 ? 1 : 0 };
|
||||
};
|
||||
|
||||
/// alignOf - A templated function that returns the minimum alignment of
|
||||
/// of a type. This provides no extra functionality beyond the AlignOf
|
||||
/// class besides some cosmetic cleanliness. Example usage:
|
||||
/// alignOf<int>() returns the alignment of an int.
|
||||
template <typename T>
|
||||
inline unsigned alignOf() { return AlignOf<T>::Alignment; }
|
||||
|
||||
/// \struct AlignedCharArray
|
||||
/// \brief Helper for building an aligned character array type.
|
||||
///
|
||||
/// This template is used to explicitly build up a collection of aligned
|
||||
/// character array types. We have to build these up using a macro and explicit
|
||||
/// specialization to cope with old versions of MSVC and GCC where only an
|
||||
/// integer literal can be used to specify an alignment constraint. Once built
|
||||
/// up here, we can then begin to indirect between these using normal C++
|
||||
/// template parameters.
|
||||
|
||||
// MSVC requires special handling here.
|
||||
#ifndef _MSC_VER
|
||||
|
||||
#if __has_feature(cxx_alignas)
|
||||
template<std::size_t Alignment, std::size_t Size>
|
||||
struct AlignedCharArray {
|
||||
alignas(Alignment) char buffer[Size];
|
||||
};
|
||||
|
||||
#elif defined(__GNUC__) || defined(__IBM_ATTRIBUTES)
|
||||
/// \brief Create a type with an aligned char buffer.
|
||||
template<std::size_t Alignment, std::size_t Size>
|
||||
struct AlignedCharArray;
|
||||
|
||||
#define LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(x) \
|
||||
template<std::size_t Size> \
|
||||
struct AlignedCharArray<x, Size> { \
|
||||
__attribute__((aligned(x))) char buffer[Size]; \
|
||||
};
|
||||
|
||||
LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(1)
|
||||
LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(2)
|
||||
LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(4)
|
||||
LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(8)
|
||||
LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(16)
|
||||
LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(32)
|
||||
LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(64)
|
||||
LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(128)
|
||||
|
||||
#undef LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT
|
||||
|
||||
#else
|
||||
# error No supported align as directive.
|
||||
#endif
|
||||
|
||||
#else // _MSC_VER
|
||||
|
||||
/// \brief Create a type with an aligned char buffer.
|
||||
template<std::size_t Alignment, std::size_t Size>
|
||||
struct AlignedCharArray;
|
||||
|
||||
// We provide special variations of this template for the most common
|
||||
// alignments because __declspec(align(...)) doesn't actually work when it is
|
||||
// a member of a by-value function argument in MSVC, even if the alignment
|
||||
// request is something reasonably like 8-byte or 16-byte. Note that we can't
|
||||
// even include the declspec with the union that forces the alignment because
|
||||
// MSVC warns on the existence of the declspec despite the union member forcing
|
||||
// proper alignment.
|
||||
|
||||
template<std::size_t Size>
|
||||
struct AlignedCharArray<1, Size> {
|
||||
union {
|
||||
char aligned;
|
||||
char buffer[Size];
|
||||
};
|
||||
};
|
||||
|
||||
template<std::size_t Size>
|
||||
struct AlignedCharArray<2, Size> {
|
||||
union {
|
||||
short aligned;
|
||||
char buffer[Size];
|
||||
};
|
||||
};
|
||||
|
||||
template<std::size_t Size>
|
||||
struct AlignedCharArray<4, Size> {
|
||||
union {
|
||||
int aligned;
|
||||
char buffer[Size];
|
||||
};
|
||||
};
|
||||
|
||||
template<std::size_t Size>
|
||||
struct AlignedCharArray<8, Size> {
|
||||
union {
|
||||
double aligned;
|
||||
char buffer[Size];
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
// The rest of these are provided with a __declspec(align(...)) and we simply
|
||||
// can't pass them by-value as function arguments on MSVC.
|
||||
|
||||
#define LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(x) \
|
||||
template<std::size_t Size> \
|
||||
struct AlignedCharArray<x, Size> { \
|
||||
__declspec(align(x)) char buffer[Size]; \
|
||||
};
|
||||
|
||||
LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(16)
|
||||
LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(32)
|
||||
LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(64)
|
||||
LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(128)
|
||||
|
||||
#undef LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT
|
||||
|
||||
#endif // _MSC_VER
|
||||
|
||||
namespace detail {
|
||||
template <typename T1,
|
||||
typename T2 = char, typename T3 = char, typename T4 = char,
|
||||
typename T5 = char, typename T6 = char, typename T7 = char>
|
||||
class AlignerImpl {
|
||||
T1 t1; T2 t2; T3 t3; T4 t4; T5 t5; T6 t6; T7 t7;
|
||||
|
||||
AlignerImpl(); // Never defined or instantiated.
|
||||
};
|
||||
|
||||
template <typename T1,
|
||||
typename T2 = char, typename T3 = char, typename T4 = char,
|
||||
typename T5 = char, typename T6 = char, typename T7 = char>
|
||||
union SizerImpl {
|
||||
char arr1[sizeof(T1)], arr2[sizeof(T2)], arr3[sizeof(T3)], arr4[sizeof(T4)],
|
||||
arr5[sizeof(T5)], arr6[sizeof(T6)], arr7[sizeof(T7)];
|
||||
};
|
||||
} // end namespace detail
|
||||
|
||||
/// \brief This union template exposes a suitably aligned and sized character
|
||||
/// array member which can hold elements of any of up to four types.
|
||||
///
|
||||
/// These types may be arrays, structs, or any other types. The goal is to
|
||||
/// expose a char array buffer member which can be used as suitable storage for
|
||||
/// a placement new of any of these types. Support for more than seven types can
|
||||
/// be added at the cost of more boiler plate.
|
||||
template <typename T1,
|
||||
typename T2 = char, typename T3 = char, typename T4 = char,
|
||||
typename T5 = char, typename T6 = char, typename T7 = char>
|
||||
struct AlignedCharArrayUnion : llvm::AlignedCharArray<
|
||||
AlignOf<detail::AlignerImpl<T1, T2, T3, T4, T5, T6, T7> >::Alignment,
|
||||
sizeof(detail::SizerImpl<T1, T2, T3, T4, T5, T6, T7>)> {
|
||||
};
|
||||
} // end namespace llvm
|
||||
#endif
|
||||
242
thirdparty/clang/include/llvm/Support/Allocator.h
vendored
Normal file
242
thirdparty/clang/include/llvm/Support/Allocator.h
vendored
Normal file
@@ -0,0 +1,242 @@
|
||||
//===--- Allocator.h - Simple memory allocation abstraction -----*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the MallocAllocator and BumpPtrAllocator interfaces.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_ALLOCATOR_H
|
||||
#define LLVM_SUPPORT_ALLOCATOR_H
|
||||
|
||||
#include "llvm/Support/AlignOf.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
|
||||
namespace llvm {
|
||||
template <typename T> struct ReferenceAdder { typedef T& result; };
|
||||
template <typename T> struct ReferenceAdder<T&> { typedef T result; };
|
||||
|
||||
class MallocAllocator {
|
||||
public:
|
||||
MallocAllocator() {}
|
||||
~MallocAllocator() {}
|
||||
|
||||
void Reset() {}
|
||||
|
||||
void *Allocate(size_t Size, size_t /*Alignment*/) { return malloc(Size); }
|
||||
|
||||
template <typename T>
|
||||
T *Allocate() { return static_cast<T*>(malloc(sizeof(T))); }
|
||||
|
||||
template <typename T>
|
||||
T *Allocate(size_t Num) {
|
||||
return static_cast<T*>(malloc(sizeof(T)*Num));
|
||||
}
|
||||
|
||||
void Deallocate(const void *Ptr) { free(const_cast<void*>(Ptr)); }
|
||||
|
||||
void PrintStats() const {}
|
||||
};
|
||||
|
||||
/// MemSlab - This structure lives at the beginning of every slab allocated by
|
||||
/// the bump allocator.
|
||||
class MemSlab {
|
||||
public:
|
||||
size_t Size;
|
||||
MemSlab *NextPtr;
|
||||
};
|
||||
|
||||
/// SlabAllocator - This class can be used to parameterize the underlying
|
||||
/// allocation strategy for the bump allocator. In particular, this is used
|
||||
/// by the JIT to allocate contiguous swathes of executable memory. The
|
||||
/// interface uses MemSlab's instead of void *'s so that the allocator
|
||||
/// doesn't have to remember the size of the pointer it allocated.
|
||||
class SlabAllocator {
|
||||
public:
|
||||
virtual ~SlabAllocator();
|
||||
virtual MemSlab *Allocate(size_t Size) = 0;
|
||||
virtual void Deallocate(MemSlab *Slab) = 0;
|
||||
};
|
||||
|
||||
/// MallocSlabAllocator - The default slab allocator for the bump allocator
|
||||
/// is an adapter class for MallocAllocator that just forwards the method
|
||||
/// calls and translates the arguments.
|
||||
class MallocSlabAllocator : public SlabAllocator {
|
||||
/// Allocator - The underlying allocator that we forward to.
|
||||
///
|
||||
MallocAllocator Allocator;
|
||||
|
||||
public:
|
||||
MallocSlabAllocator() : Allocator() { }
|
||||
virtual ~MallocSlabAllocator();
|
||||
virtual MemSlab *Allocate(size_t Size) LLVM_OVERRIDE;
|
||||
virtual void Deallocate(MemSlab *Slab) LLVM_OVERRIDE;
|
||||
};
|
||||
|
||||
/// BumpPtrAllocator - This allocator is useful for containers that need
|
||||
/// very simple memory allocation strategies. In particular, this just keeps
|
||||
/// allocating memory, and never deletes it until the entire block is dead. This
|
||||
/// makes allocation speedy, but must only be used when the trade-off is ok.
|
||||
class BumpPtrAllocator {
|
||||
BumpPtrAllocator(const BumpPtrAllocator &) LLVM_DELETED_FUNCTION;
|
||||
void operator=(const BumpPtrAllocator &) LLVM_DELETED_FUNCTION;
|
||||
|
||||
/// SlabSize - Allocate data into slabs of this size unless we get an
|
||||
/// allocation above SizeThreshold.
|
||||
size_t SlabSize;
|
||||
|
||||
/// SizeThreshold - For any allocation larger than this threshold, we should
|
||||
/// allocate a separate slab.
|
||||
size_t SizeThreshold;
|
||||
|
||||
/// Allocator - The underlying allocator we use to get slabs of memory. This
|
||||
/// defaults to MallocSlabAllocator, which wraps malloc, but it could be
|
||||
/// changed to use a custom allocator.
|
||||
SlabAllocator &Allocator;
|
||||
|
||||
/// CurSlab - The slab that we are currently allocating into.
|
||||
///
|
||||
MemSlab *CurSlab;
|
||||
|
||||
/// CurPtr - The current pointer into the current slab. This points to the
|
||||
/// next free byte in the slab.
|
||||
char *CurPtr;
|
||||
|
||||
/// End - The end of the current slab.
|
||||
///
|
||||
char *End;
|
||||
|
||||
/// BytesAllocated - This field tracks how many bytes we've allocated, so
|
||||
/// that we can compute how much space was wasted.
|
||||
size_t BytesAllocated;
|
||||
|
||||
/// AlignPtr - Align Ptr to Alignment bytes, rounding up. Alignment should
|
||||
/// be a power of two. This method rounds up, so AlignPtr(7, 4) == 8 and
|
||||
/// AlignPtr(8, 4) == 8.
|
||||
static char *AlignPtr(char *Ptr, size_t Alignment);
|
||||
|
||||
/// StartNewSlab - Allocate a new slab and move the bump pointers over into
|
||||
/// the new slab. Modifies CurPtr and End.
|
||||
void StartNewSlab();
|
||||
|
||||
/// DeallocateSlabs - Deallocate all memory slabs after and including this
|
||||
/// one.
|
||||
void DeallocateSlabs(MemSlab *Slab);
|
||||
|
||||
static MallocSlabAllocator DefaultSlabAllocator;
|
||||
|
||||
template<typename T> friend class SpecificBumpPtrAllocator;
|
||||
public:
|
||||
BumpPtrAllocator(size_t size = 4096, size_t threshold = 4096,
|
||||
SlabAllocator &allocator = DefaultSlabAllocator);
|
||||
~BumpPtrAllocator();
|
||||
|
||||
/// Reset - Deallocate all but the current slab and reset the current pointer
|
||||
/// to the beginning of it, freeing all memory allocated so far.
|
||||
void Reset();
|
||||
|
||||
/// Allocate - Allocate space at the specified alignment.
|
||||
///
|
||||
void *Allocate(size_t Size, size_t Alignment);
|
||||
|
||||
/// Allocate space, but do not construct, one object.
|
||||
///
|
||||
template <typename T>
|
||||
T *Allocate() {
|
||||
return static_cast<T*>(Allocate(sizeof(T),AlignOf<T>::Alignment));
|
||||
}
|
||||
|
||||
/// Allocate space for an array of objects. This does not construct the
|
||||
/// objects though.
|
||||
template <typename T>
|
||||
T *Allocate(size_t Num) {
|
||||
return static_cast<T*>(Allocate(Num * sizeof(T), AlignOf<T>::Alignment));
|
||||
}
|
||||
|
||||
/// Allocate space for a specific count of elements and with a specified
|
||||
/// alignment.
|
||||
template <typename T>
|
||||
T *Allocate(size_t Num, size_t Alignment) {
|
||||
// Round EltSize up to the specified alignment.
|
||||
size_t EltSize = (sizeof(T)+Alignment-1)&(-Alignment);
|
||||
return static_cast<T*>(Allocate(Num * EltSize, Alignment));
|
||||
}
|
||||
|
||||
void Deallocate(const void * /*Ptr*/) {}
|
||||
|
||||
unsigned GetNumSlabs() const;
|
||||
|
||||
void PrintStats() const;
|
||||
|
||||
/// Compute the total physical memory allocated by this allocator.
|
||||
size_t getTotalMemory() const;
|
||||
};
|
||||
|
||||
/// SpecificBumpPtrAllocator - Same as BumpPtrAllocator but allows only
|
||||
/// elements of one type to be allocated. This allows calling the destructor
|
||||
/// in DestroyAll() and when the allocator is destroyed.
|
||||
template <typename T>
|
||||
class SpecificBumpPtrAllocator {
|
||||
BumpPtrAllocator Allocator;
|
||||
public:
|
||||
SpecificBumpPtrAllocator(size_t size = 4096, size_t threshold = 4096,
|
||||
SlabAllocator &allocator = BumpPtrAllocator::DefaultSlabAllocator)
|
||||
: Allocator(size, threshold, allocator) {}
|
||||
|
||||
~SpecificBumpPtrAllocator() {
|
||||
DestroyAll();
|
||||
}
|
||||
|
||||
/// Call the destructor of each allocated object and deallocate all but the
|
||||
/// current slab and reset the current pointer to the beginning of it, freeing
|
||||
/// all memory allocated so far.
|
||||
void DestroyAll() {
|
||||
MemSlab *Slab = Allocator.CurSlab;
|
||||
while (Slab) {
|
||||
char *End = Slab == Allocator.CurSlab ? Allocator.CurPtr :
|
||||
(char *)Slab + Slab->Size;
|
||||
for (char *Ptr = (char*)(Slab+1); Ptr < End; Ptr += sizeof(T)) {
|
||||
Ptr = Allocator.AlignPtr(Ptr, alignOf<T>());
|
||||
if (Ptr + sizeof(T) <= End)
|
||||
reinterpret_cast<T*>(Ptr)->~T();
|
||||
}
|
||||
Slab = Slab->NextPtr;
|
||||
}
|
||||
Allocator.Reset();
|
||||
}
|
||||
|
||||
/// Allocate space for a specific count of elements.
|
||||
T *Allocate(size_t num = 1) {
|
||||
return Allocator.Allocate<T>(num);
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
inline void *operator new(size_t Size, llvm::BumpPtrAllocator &Allocator) {
|
||||
struct S {
|
||||
char c;
|
||||
union {
|
||||
double D;
|
||||
long double LD;
|
||||
long long L;
|
||||
void *P;
|
||||
} x;
|
||||
};
|
||||
return Allocator.Allocate(Size, std::min((size_t)llvm::NextPowerOf2(Size),
|
||||
offsetof(S, x)));
|
||||
}
|
||||
|
||||
inline void operator delete(void *, llvm::BumpPtrAllocator &) {}
|
||||
|
||||
#endif // LLVM_SUPPORT_ALLOCATOR_H
|
||||
143
thirdparty/clang/include/llvm/Support/ArrayRecycler.h
vendored
Normal file
143
thirdparty/clang/include/llvm/Support/ArrayRecycler.h
vendored
Normal file
@@ -0,0 +1,143 @@
|
||||
//==- llvm/Support/ArrayRecycler.h - Recycling of Arrays ---------*- C++ -*-==//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the ArrayRecycler class template which can recycle small
|
||||
// arrays allocated from one of the allocators in Allocator.h
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_ARRAYRECYCLER_H
|
||||
#define LLVM_SUPPORT_ARRAYRECYCLER_H
|
||||
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class BumpPtrAllocator;
|
||||
|
||||
/// Recycle small arrays allocated from a BumpPtrAllocator.
|
||||
///
|
||||
/// Arrays are allocated in a small number of fixed sizes. For each supported
|
||||
/// array size, the ArrayRecycler keeps a free list of available arrays.
|
||||
///
|
||||
template<class T, size_t Align = AlignOf<T>::Alignment>
|
||||
class ArrayRecycler {
|
||||
// The free list for a given array size is a simple singly linked list.
|
||||
// We can't use iplist or Recycler here since those classes can't be copied.
|
||||
struct FreeList {
|
||||
FreeList *Next;
|
||||
};
|
||||
|
||||
// Keep a free list for each array size.
|
||||
SmallVector<FreeList*, 8> Bucket;
|
||||
|
||||
// Remove an entry from the free list in Bucket[Idx] and return it.
|
||||
// Return NULL if no entries are available.
|
||||
T *pop(unsigned Idx) {
|
||||
if (Idx >= Bucket.size())
|
||||
return 0;
|
||||
FreeList *Entry = Bucket[Idx];
|
||||
if (!Entry)
|
||||
return 0;
|
||||
Bucket[Idx] = Entry->Next;
|
||||
return reinterpret_cast<T*>(Entry);
|
||||
}
|
||||
|
||||
// Add an entry to the free list at Bucket[Idx].
|
||||
void push(unsigned Idx, T *Ptr) {
|
||||
assert(Ptr && "Cannot recycle NULL pointer");
|
||||
assert(sizeof(T) >= sizeof(FreeList) && "Objects are too small");
|
||||
assert(Align >= AlignOf<FreeList>::Alignment && "Object underaligned");
|
||||
FreeList *Entry = reinterpret_cast<FreeList*>(Ptr);
|
||||
if (Idx >= Bucket.size())
|
||||
Bucket.resize(size_t(Idx) + 1);
|
||||
Entry->Next = Bucket[Idx];
|
||||
Bucket[Idx] = Entry;
|
||||
}
|
||||
|
||||
public:
|
||||
/// The size of an allocated array is represented by a Capacity instance.
|
||||
///
|
||||
/// This class is much smaller than a size_t, and it provides methods to work
|
||||
/// with the set of legal array capacities.
|
||||
class Capacity {
|
||||
uint8_t Index;
|
||||
explicit Capacity(uint8_t idx) : Index(idx) {}
|
||||
|
||||
public:
|
||||
Capacity() : Index(0) {}
|
||||
|
||||
/// Get the capacity of an array that can hold at least N elements.
|
||||
static Capacity get(size_t N) {
|
||||
return Capacity(N ? Log2_64_Ceil(N) : 0);
|
||||
}
|
||||
|
||||
/// Get the number of elements in an array with this capacity.
|
||||
size_t getSize() const { return size_t(1u) << Index; }
|
||||
|
||||
/// Get the bucket number for this capacity.
|
||||
unsigned getBucket() const { return Index; }
|
||||
|
||||
/// Get the next larger capacity. Large capacities grow exponentially, so
|
||||
/// this function can be used to reallocate incrementally growing vectors
|
||||
/// in amortized linear time.
|
||||
Capacity getNext() const { return Capacity(Index + 1); }
|
||||
};
|
||||
|
||||
~ArrayRecycler() {
|
||||
// The client should always call clear() so recycled arrays can be returned
|
||||
// to the allocator.
|
||||
assert(Bucket.empty() && "Non-empty ArrayRecycler deleted!");
|
||||
}
|
||||
|
||||
/// Release all the tracked allocations to the allocator. The recycler must
|
||||
/// be free of any tracked allocations before being deleted.
|
||||
template<class AllocatorType>
|
||||
void clear(AllocatorType &Allocator) {
|
||||
for (; !Bucket.empty(); Bucket.pop_back())
|
||||
while (T *Ptr = pop(Bucket.size() - 1))
|
||||
Allocator.Deallocate(Ptr);
|
||||
}
|
||||
|
||||
/// Special case for BumpPtrAllocator which has an empty Deallocate()
|
||||
/// function.
|
||||
///
|
||||
/// There is no need to traverse the free lists, pulling all the objects into
|
||||
/// cache.
|
||||
void clear(BumpPtrAllocator&) {
|
||||
Bucket.clear();
|
||||
}
|
||||
|
||||
/// Allocate an array of at least the requested capacity.
|
||||
///
|
||||
/// Return an existing recycled array, or allocate one from Allocator if
|
||||
/// none are available for recycling.
|
||||
///
|
||||
template<class AllocatorType>
|
||||
T *allocate(Capacity Cap, AllocatorType &Allocator) {
|
||||
// Try to recycle an existing array.
|
||||
if (T *Ptr = pop(Cap.getBucket()))
|
||||
return Ptr;
|
||||
// Nope, get more memory.
|
||||
return static_cast<T*>(Allocator.Allocate(sizeof(T)*Cap.getSize(), Align));
|
||||
}
|
||||
|
||||
/// Deallocate an array with the specified Capacity.
|
||||
///
|
||||
/// Cap must be the same capacity that was given to allocate().
|
||||
///
|
||||
void deallocate(Capacity Cap, T *Ptr) {
|
||||
push(Cap.getBucket(), Ptr);
|
||||
}
|
||||
};
|
||||
|
||||
} // end llvm namespace
|
||||
|
||||
#endif
|
||||
39
thirdparty/clang/include/llvm/Support/Atomic.h
vendored
Normal file
39
thirdparty/clang/include/llvm/Support/Atomic.h
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
//===- llvm/Support/Atomic.h - Atomic Operations -----------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file declares the llvm::sys atomic operations.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_ATOMIC_H
|
||||
#define LLVM_SUPPORT_ATOMIC_H
|
||||
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
|
||||
namespace llvm {
|
||||
namespace sys {
|
||||
void MemoryFence();
|
||||
|
||||
#ifdef _MSC_VER
|
||||
typedef long cas_flag;
|
||||
#else
|
||||
typedef uint32_t cas_flag;
|
||||
#endif
|
||||
cas_flag CompareAndSwap(volatile cas_flag* ptr,
|
||||
cas_flag new_value,
|
||||
cas_flag old_value);
|
||||
cas_flag AtomicIncrement(volatile cas_flag* ptr);
|
||||
cas_flag AtomicDecrement(volatile cas_flag* ptr);
|
||||
cas_flag AtomicAdd(volatile cas_flag* ptr, cas_flag val);
|
||||
cas_flag AtomicMul(volatile cas_flag* ptr, cas_flag val);
|
||||
cas_flag AtomicDiv(volatile cas_flag* ptr, cas_flag val);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
65
thirdparty/clang/include/llvm/Support/BlockFrequency.h
vendored
Normal file
65
thirdparty/clang/include/llvm/Support/BlockFrequency.h
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
//===-------- BlockFrequency.h - Block Frequency Wrapper --------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements Block Frequency class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_BLOCKFREQUENCY_H
|
||||
#define LLVM_SUPPORT_BLOCKFREQUENCY_H
|
||||
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class raw_ostream;
|
||||
class BranchProbability;
|
||||
|
||||
// This class represents Block Frequency as a 64-bit value.
|
||||
class BlockFrequency {
|
||||
|
||||
uint64_t Frequency;
|
||||
static const int64_t ENTRY_FREQ = 1024;
|
||||
|
||||
public:
|
||||
BlockFrequency(uint64_t Freq = 0) : Frequency(Freq) { }
|
||||
|
||||
static uint64_t getEntryFrequency() { return ENTRY_FREQ; }
|
||||
uint64_t getFrequency() const { return Frequency; }
|
||||
|
||||
BlockFrequency &operator*=(const BranchProbability &Prob);
|
||||
const BlockFrequency operator*(const BranchProbability &Prob) const;
|
||||
|
||||
BlockFrequency &operator+=(const BlockFrequency &Freq);
|
||||
const BlockFrequency operator+(const BlockFrequency &Freq) const;
|
||||
|
||||
bool operator<(const BlockFrequency &RHS) const {
|
||||
return Frequency < RHS.Frequency;
|
||||
}
|
||||
|
||||
bool operator<=(const BlockFrequency &RHS) const {
|
||||
return Frequency <= RHS.Frequency;
|
||||
}
|
||||
|
||||
bool operator>(const BlockFrequency &RHS) const {
|
||||
return Frequency > RHS.Frequency;
|
||||
}
|
||||
|
||||
bool operator>=(const BlockFrequency &RHS) const {
|
||||
return Frequency >= RHS.Frequency;
|
||||
}
|
||||
|
||||
void print(raw_ostream &OS) const;
|
||||
};
|
||||
|
||||
raw_ostream &operator<<(raw_ostream &OS, const BlockFrequency &Freq);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
77
thirdparty/clang/include/llvm/Support/BranchProbability.h
vendored
Normal file
77
thirdparty/clang/include/llvm/Support/BranchProbability.h
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
//===- BranchProbability.h - Branch Probability Wrapper ---------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Definition of BranchProbability shared by IR and Machine Instructions.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_BRANCHPROBABILITY_H
|
||||
#define LLVM_SUPPORT_BRANCHPROBABILITY_H
|
||||
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include <cassert>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class raw_ostream;
|
||||
|
||||
// This class represents Branch Probability as a non-negative fraction.
|
||||
class BranchProbability {
|
||||
// Numerator
|
||||
uint32_t N;
|
||||
|
||||
// Denominator
|
||||
uint32_t D;
|
||||
|
||||
public:
|
||||
BranchProbability(uint32_t n, uint32_t d) : N(n), D(d) {
|
||||
assert(d > 0 && "Denomiator cannot be 0!");
|
||||
assert(n <= d && "Probability cannot be bigger than 1!");
|
||||
}
|
||||
|
||||
static BranchProbability getZero() { return BranchProbability(0, 1); }
|
||||
static BranchProbability getOne() { return BranchProbability(1, 1); }
|
||||
|
||||
uint32_t getNumerator() const { return N; }
|
||||
uint32_t getDenominator() const { return D; }
|
||||
|
||||
// Return (1 - Probability).
|
||||
BranchProbability getCompl() const {
|
||||
return BranchProbability(D - N, D);
|
||||
}
|
||||
|
||||
void print(raw_ostream &OS) const;
|
||||
|
||||
void dump() const;
|
||||
|
||||
bool operator==(BranchProbability RHS) const {
|
||||
return (uint64_t)N * RHS.D == (uint64_t)D * RHS.N;
|
||||
}
|
||||
bool operator!=(BranchProbability RHS) const {
|
||||
return !(*this == RHS);
|
||||
}
|
||||
bool operator<(BranchProbability RHS) const {
|
||||
return (uint64_t)N * RHS.D < (uint64_t)D * RHS.N;
|
||||
}
|
||||
bool operator>(BranchProbability RHS) const {
|
||||
return RHS < *this;
|
||||
}
|
||||
bool operator<=(BranchProbability RHS) const {
|
||||
return (uint64_t)N * RHS.D <= (uint64_t)D * RHS.N;
|
||||
}
|
||||
bool operator>=(BranchProbability RHS) const {
|
||||
return RHS <= *this;
|
||||
}
|
||||
};
|
||||
|
||||
raw_ostream &operator<<(raw_ostream &OS, const BranchProbability &Prob);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
361
thirdparty/clang/include/llvm/Support/CFG.h
vendored
Normal file
361
thirdparty/clang/include/llvm/Support/CFG.h
vendored
Normal file
@@ -0,0 +1,361 @@
|
||||
//===-- llvm/Support/CFG.h - Process LLVM structures as graphs --*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines specializations of GraphTraits that allow Function and
|
||||
// BasicBlock graphs to be treated as proper graphs for generic algorithms.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_CFG_H
|
||||
#define LLVM_SUPPORT_CFG_H
|
||||
|
||||
#include "llvm/ADT/GraphTraits.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/IR/InstrTypes.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// BasicBlock pred_iterator definition
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
template <class Ptr, class USE_iterator> // Predecessor Iterator
|
||||
class PredIterator : public std::iterator<std::forward_iterator_tag,
|
||||
Ptr, ptrdiff_t, Ptr*, Ptr*> {
|
||||
typedef std::iterator<std::forward_iterator_tag, Ptr, ptrdiff_t, Ptr*,
|
||||
Ptr*> super;
|
||||
typedef PredIterator<Ptr, USE_iterator> Self;
|
||||
USE_iterator It;
|
||||
|
||||
inline void advancePastNonTerminators() {
|
||||
// Loop to ignore non terminator uses (for example BlockAddresses).
|
||||
while (!It.atEnd() && !isa<TerminatorInst>(*It))
|
||||
++It;
|
||||
}
|
||||
|
||||
public:
|
||||
typedef typename super::pointer pointer;
|
||||
typedef typename super::reference reference;
|
||||
|
||||
PredIterator() {}
|
||||
explicit inline PredIterator(Ptr *bb) : It(bb->use_begin()) {
|
||||
advancePastNonTerminators();
|
||||
}
|
||||
inline PredIterator(Ptr *bb, bool) : It(bb->use_end()) {}
|
||||
|
||||
inline bool operator==(const Self& x) const { return It == x.It; }
|
||||
inline bool operator!=(const Self& x) const { return !operator==(x); }
|
||||
|
||||
inline reference operator*() const {
|
||||
assert(!It.atEnd() && "pred_iterator out of range!");
|
||||
return cast<TerminatorInst>(*It)->getParent();
|
||||
}
|
||||
inline pointer *operator->() const { return &operator*(); }
|
||||
|
||||
inline Self& operator++() { // Preincrement
|
||||
assert(!It.atEnd() && "pred_iterator out of range!");
|
||||
++It; advancePastNonTerminators();
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Self operator++(int) { // Postincrement
|
||||
Self tmp = *this; ++*this; return tmp;
|
||||
}
|
||||
|
||||
/// getOperandNo - Return the operand number in the predecessor's
|
||||
/// terminator of the successor.
|
||||
unsigned getOperandNo() const {
|
||||
return It.getOperandNo();
|
||||
}
|
||||
|
||||
/// getUse - Return the operand Use in the predecessor's terminator
|
||||
/// of the successor.
|
||||
Use &getUse() const {
|
||||
return It.getUse();
|
||||
}
|
||||
};
|
||||
|
||||
typedef PredIterator<BasicBlock, Value::use_iterator> pred_iterator;
|
||||
typedef PredIterator<const BasicBlock,
|
||||
Value::const_use_iterator> const_pred_iterator;
|
||||
|
||||
inline pred_iterator pred_begin(BasicBlock *BB) { return pred_iterator(BB); }
|
||||
inline const_pred_iterator pred_begin(const BasicBlock *BB) {
|
||||
return const_pred_iterator(BB);
|
||||
}
|
||||
inline pred_iterator pred_end(BasicBlock *BB) { return pred_iterator(BB, true);}
|
||||
inline const_pred_iterator pred_end(const BasicBlock *BB) {
|
||||
return const_pred_iterator(BB, true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// BasicBlock succ_iterator definition
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
template <class Term_, class BB_> // Successor Iterator
|
||||
class SuccIterator : public std::iterator<std::bidirectional_iterator_tag,
|
||||
BB_, ptrdiff_t, BB_*, BB_*> {
|
||||
const Term_ Term;
|
||||
unsigned idx;
|
||||
typedef std::iterator<std::bidirectional_iterator_tag, BB_, ptrdiff_t, BB_*,
|
||||
BB_*> super;
|
||||
typedef SuccIterator<Term_, BB_> Self;
|
||||
|
||||
inline bool index_is_valid(int idx) {
|
||||
return idx >= 0 && (unsigned) idx < Term->getNumSuccessors();
|
||||
}
|
||||
|
||||
public:
|
||||
typedef typename super::pointer pointer;
|
||||
typedef typename super::reference reference;
|
||||
// TODO: This can be random access iterator, only operator[] missing.
|
||||
|
||||
explicit inline SuccIterator(Term_ T) : Term(T), idx(0) {// begin iterator
|
||||
}
|
||||
inline SuccIterator(Term_ T, bool) // end iterator
|
||||
: Term(T) {
|
||||
if (Term)
|
||||
idx = Term->getNumSuccessors();
|
||||
else
|
||||
// Term == NULL happens, if a basic block is not fully constructed and
|
||||
// consequently getTerminator() returns NULL. In this case we construct a
|
||||
// SuccIterator which describes a basic block that has zero successors.
|
||||
// Defining SuccIterator for incomplete and malformed CFGs is especially
|
||||
// useful for debugging.
|
||||
idx = 0;
|
||||
}
|
||||
|
||||
inline const Self &operator=(const Self &I) {
|
||||
assert(Term == I.Term &&"Cannot assign iterators to two different blocks!");
|
||||
idx = I.idx;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// getSuccessorIndex - This is used to interface between code that wants to
|
||||
/// operate on terminator instructions directly.
|
||||
unsigned getSuccessorIndex() const { return idx; }
|
||||
|
||||
inline bool operator==(const Self& x) const { return idx == x.idx; }
|
||||
inline bool operator!=(const Self& x) const { return !operator==(x); }
|
||||
|
||||
inline reference operator*() const { return Term->getSuccessor(idx); }
|
||||
inline pointer operator->() const { return operator*(); }
|
||||
|
||||
inline Self& operator++() { ++idx; return *this; } // Preincrement
|
||||
|
||||
inline Self operator++(int) { // Postincrement
|
||||
Self tmp = *this; ++*this; return tmp;
|
||||
}
|
||||
|
||||
inline Self& operator--() { --idx; return *this; } // Predecrement
|
||||
inline Self operator--(int) { // Postdecrement
|
||||
Self tmp = *this; --*this; return tmp;
|
||||
}
|
||||
|
||||
inline bool operator<(const Self& x) const {
|
||||
assert(Term == x.Term && "Cannot compare iterators of different blocks!");
|
||||
return idx < x.idx;
|
||||
}
|
||||
|
||||
inline bool operator<=(const Self& x) const {
|
||||
assert(Term == x.Term && "Cannot compare iterators of different blocks!");
|
||||
return idx <= x.idx;
|
||||
}
|
||||
inline bool operator>=(const Self& x) const {
|
||||
assert(Term == x.Term && "Cannot compare iterators of different blocks!");
|
||||
return idx >= x.idx;
|
||||
}
|
||||
|
||||
inline bool operator>(const Self& x) const {
|
||||
assert(Term == x.Term && "Cannot compare iterators of different blocks!");
|
||||
return idx > x.idx;
|
||||
}
|
||||
|
||||
inline Self& operator+=(int Right) {
|
||||
unsigned new_idx = idx + Right;
|
||||
assert(index_is_valid(new_idx) && "Iterator index out of bound");
|
||||
idx = new_idx;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Self operator+(int Right) {
|
||||
Self tmp = *this;
|
||||
tmp += Right;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
inline Self& operator-=(int Right) {
|
||||
return operator+=(-Right);
|
||||
}
|
||||
|
||||
inline Self operator-(int Right) {
|
||||
return operator+(-Right);
|
||||
}
|
||||
|
||||
inline int operator-(const Self& x) {
|
||||
assert(Term == x.Term && "Cannot work on iterators of different blocks!");
|
||||
int distance = idx - x.idx;
|
||||
return distance;
|
||||
}
|
||||
|
||||
// This works for read access, however write access is difficult as changes
|
||||
// to Term are only possible with Term->setSuccessor(idx). Pointers that can
|
||||
// be modified are not available.
|
||||
//
|
||||
// inline pointer operator[](int offset) {
|
||||
// Self tmp = *this;
|
||||
// tmp += offset;
|
||||
// return tmp.operator*();
|
||||
// }
|
||||
|
||||
/// Get the source BB of this iterator.
|
||||
inline BB_ *getSource() {
|
||||
assert(Term && "Source not available, if basic block was malformed");
|
||||
return Term->getParent();
|
||||
}
|
||||
};
|
||||
|
||||
typedef SuccIterator<TerminatorInst*, BasicBlock> succ_iterator;
|
||||
typedef SuccIterator<const TerminatorInst*,
|
||||
const BasicBlock> succ_const_iterator;
|
||||
|
||||
inline succ_iterator succ_begin(BasicBlock *BB) {
|
||||
return succ_iterator(BB->getTerminator());
|
||||
}
|
||||
inline succ_const_iterator succ_begin(const BasicBlock *BB) {
|
||||
return succ_const_iterator(BB->getTerminator());
|
||||
}
|
||||
inline succ_iterator succ_end(BasicBlock *BB) {
|
||||
return succ_iterator(BB->getTerminator(), true);
|
||||
}
|
||||
inline succ_const_iterator succ_end(const BasicBlock *BB) {
|
||||
return succ_const_iterator(BB->getTerminator(), true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// GraphTraits specializations for basic block graphs (CFGs)
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
||||
// Provide specializations of GraphTraits to be able to treat a function as a
|
||||
// graph of basic blocks...
|
||||
|
||||
template <> struct GraphTraits<BasicBlock*> {
|
||||
typedef BasicBlock NodeType;
|
||||
typedef succ_iterator ChildIteratorType;
|
||||
|
||||
static NodeType *getEntryNode(BasicBlock *BB) { return BB; }
|
||||
static inline ChildIteratorType child_begin(NodeType *N) {
|
||||
return succ_begin(N);
|
||||
}
|
||||
static inline ChildIteratorType child_end(NodeType *N) {
|
||||
return succ_end(N);
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct GraphTraits<const BasicBlock*> {
|
||||
typedef const BasicBlock NodeType;
|
||||
typedef succ_const_iterator ChildIteratorType;
|
||||
|
||||
static NodeType *getEntryNode(const BasicBlock *BB) { return BB; }
|
||||
|
||||
static inline ChildIteratorType child_begin(NodeType *N) {
|
||||
return succ_begin(N);
|
||||
}
|
||||
static inline ChildIteratorType child_end(NodeType *N) {
|
||||
return succ_end(N);
|
||||
}
|
||||
};
|
||||
|
||||
// Provide specializations of GraphTraits to be able to treat a function as a
|
||||
// graph of basic blocks... and to walk it in inverse order. Inverse order for
|
||||
// a function is considered to be when traversing the predecessor edges of a BB
|
||||
// instead of the successor edges.
|
||||
//
|
||||
template <> struct GraphTraits<Inverse<BasicBlock*> > {
|
||||
typedef BasicBlock NodeType;
|
||||
typedef pred_iterator ChildIteratorType;
|
||||
static NodeType *getEntryNode(Inverse<BasicBlock *> G) { return G.Graph; }
|
||||
static inline ChildIteratorType child_begin(NodeType *N) {
|
||||
return pred_begin(N);
|
||||
}
|
||||
static inline ChildIteratorType child_end(NodeType *N) {
|
||||
return pred_end(N);
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct GraphTraits<Inverse<const BasicBlock*> > {
|
||||
typedef const BasicBlock NodeType;
|
||||
typedef const_pred_iterator ChildIteratorType;
|
||||
static NodeType *getEntryNode(Inverse<const BasicBlock*> G) {
|
||||
return G.Graph;
|
||||
}
|
||||
static inline ChildIteratorType child_begin(NodeType *N) {
|
||||
return pred_begin(N);
|
||||
}
|
||||
static inline ChildIteratorType child_end(NodeType *N) {
|
||||
return pred_end(N);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// GraphTraits specializations for function basic block graphs (CFGs)
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
||||
// Provide specializations of GraphTraits to be able to treat a function as a
|
||||
// graph of basic blocks... these are the same as the basic block iterators,
|
||||
// except that the root node is implicitly the first node of the function.
|
||||
//
|
||||
template <> struct GraphTraits<Function*> : public GraphTraits<BasicBlock*> {
|
||||
static NodeType *getEntryNode(Function *F) { return &F->getEntryBlock(); }
|
||||
|
||||
// nodes_iterator/begin/end - Allow iteration over all nodes in the graph
|
||||
typedef Function::iterator nodes_iterator;
|
||||
static nodes_iterator nodes_begin(Function *F) { return F->begin(); }
|
||||
static nodes_iterator nodes_end (Function *F) { return F->end(); }
|
||||
static unsigned size (Function *F) { return F->size(); }
|
||||
};
|
||||
template <> struct GraphTraits<const Function*> :
|
||||
public GraphTraits<const BasicBlock*> {
|
||||
static NodeType *getEntryNode(const Function *F) {return &F->getEntryBlock();}
|
||||
|
||||
// nodes_iterator/begin/end - Allow iteration over all nodes in the graph
|
||||
typedef Function::const_iterator nodes_iterator;
|
||||
static nodes_iterator nodes_begin(const Function *F) { return F->begin(); }
|
||||
static nodes_iterator nodes_end (const Function *F) { return F->end(); }
|
||||
static unsigned size (const Function *F) { return F->size(); }
|
||||
};
|
||||
|
||||
|
||||
// Provide specializations of GraphTraits to be able to treat a function as a
|
||||
// graph of basic blocks... and to walk it in inverse order. Inverse order for
|
||||
// a function is considered to be when traversing the predecessor edges of a BB
|
||||
// instead of the successor edges.
|
||||
//
|
||||
template <> struct GraphTraits<Inverse<Function*> > :
|
||||
public GraphTraits<Inverse<BasicBlock*> > {
|
||||
static NodeType *getEntryNode(Inverse<Function*> G) {
|
||||
return &G.Graph->getEntryBlock();
|
||||
}
|
||||
};
|
||||
template <> struct GraphTraits<Inverse<const Function*> > :
|
||||
public GraphTraits<Inverse<const BasicBlock*> > {
|
||||
static NodeType *getEntryNode(Inverse<const Function *> G) {
|
||||
return &G.Graph->getEntryBlock();
|
||||
}
|
||||
};
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
||||
595
thirdparty/clang/include/llvm/Support/COFF.h
vendored
Normal file
595
thirdparty/clang/include/llvm/Support/COFF.h
vendored
Normal file
@@ -0,0 +1,595 @@
|
||||
//===-- llvm/Support/COFF.h -------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file contains an definitions used in Windows COFF Files.
|
||||
//
|
||||
// Structures and enums defined within this file where created using
|
||||
// information from Microsoft's publicly available PE/COFF format document:
|
||||
//
|
||||
// Microsoft Portable Executable and Common Object File Format Specification
|
||||
// Revision 8.1 - February 15, 2008
|
||||
//
|
||||
// As of 5/2/2010, hosted by Microsoft at:
|
||||
// http://www.microsoft.com/whdc/system/platform/firmware/pecoff.mspx
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_COFF_H
|
||||
#define LLVM_SUPPORT_COFF_H
|
||||
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
namespace llvm {
|
||||
namespace COFF {
|
||||
|
||||
// Sizes in bytes of various things in the COFF format.
|
||||
enum {
|
||||
HeaderSize = 20,
|
||||
NameSize = 8,
|
||||
SymbolSize = 18,
|
||||
SectionSize = 40,
|
||||
RelocationSize = 10
|
||||
};
|
||||
|
||||
struct header {
|
||||
uint16_t Machine;
|
||||
uint16_t NumberOfSections;
|
||||
uint32_t TimeDateStamp;
|
||||
uint32_t PointerToSymbolTable;
|
||||
uint32_t NumberOfSymbols;
|
||||
uint16_t SizeOfOptionalHeader;
|
||||
uint16_t Characteristics;
|
||||
};
|
||||
|
||||
enum MachineTypes {
|
||||
MT_Invalid = 0xffff,
|
||||
|
||||
IMAGE_FILE_MACHINE_UNKNOWN = 0x0,
|
||||
IMAGE_FILE_MACHINE_AM33 = 0x13,
|
||||
IMAGE_FILE_MACHINE_AMD64 = 0x8664,
|
||||
IMAGE_FILE_MACHINE_ARM = 0x1C0,
|
||||
IMAGE_FILE_MACHINE_ARMV7 = 0x1C4,
|
||||
IMAGE_FILE_MACHINE_EBC = 0xEBC,
|
||||
IMAGE_FILE_MACHINE_I386 = 0x14C,
|
||||
IMAGE_FILE_MACHINE_IA64 = 0x200,
|
||||
IMAGE_FILE_MACHINE_M32R = 0x9041,
|
||||
IMAGE_FILE_MACHINE_MIPS16 = 0x266,
|
||||
IMAGE_FILE_MACHINE_MIPSFPU = 0x366,
|
||||
IMAGE_FILE_MACHINE_MIPSFPU16 = 0x466,
|
||||
IMAGE_FILE_MACHINE_POWERPC = 0x1F0,
|
||||
IMAGE_FILE_MACHINE_POWERPCFP = 0x1F1,
|
||||
IMAGE_FILE_MACHINE_R4000 = 0x166,
|
||||
IMAGE_FILE_MACHINE_SH3 = 0x1A2,
|
||||
IMAGE_FILE_MACHINE_SH3DSP = 0x1A3,
|
||||
IMAGE_FILE_MACHINE_SH4 = 0x1A6,
|
||||
IMAGE_FILE_MACHINE_SH5 = 0x1A8,
|
||||
IMAGE_FILE_MACHINE_THUMB = 0x1C2,
|
||||
IMAGE_FILE_MACHINE_WCEMIPSV2 = 0x169
|
||||
};
|
||||
|
||||
enum Characteristics {
|
||||
C_Invalid = 0,
|
||||
|
||||
/// The file does not contain base relocations and must be loaded at its
|
||||
/// preferred base. If this cannot be done, the loader will error.
|
||||
IMAGE_FILE_RELOCS_STRIPPED = 0x0001,
|
||||
/// The file is valid and can be run.
|
||||
IMAGE_FILE_EXECUTABLE_IMAGE = 0x0002,
|
||||
/// COFF line numbers have been stripped. This is deprecated and should be
|
||||
/// 0.
|
||||
IMAGE_FILE_LINE_NUMS_STRIPPED = 0x0004,
|
||||
/// COFF symbol table entries for local symbols have been removed. This is
|
||||
/// deprecated and should be 0.
|
||||
IMAGE_FILE_LOCAL_SYMS_STRIPPED = 0x0008,
|
||||
/// Aggressively trim working set. This is deprecated and must be 0.
|
||||
IMAGE_FILE_AGGRESSIVE_WS_TRIM = 0x0010,
|
||||
/// Image can handle > 2GiB addresses.
|
||||
IMAGE_FILE_LARGE_ADDRESS_AWARE = 0x0020,
|
||||
/// Little endian: the LSB precedes the MSB in memory. This is deprecated
|
||||
/// and should be 0.
|
||||
IMAGE_FILE_BYTES_REVERSED_LO = 0x0080,
|
||||
/// Machine is based on a 32bit word architecture.
|
||||
IMAGE_FILE_32BIT_MACHINE = 0x0100,
|
||||
/// Debugging info has been removed.
|
||||
IMAGE_FILE_DEBUG_STRIPPED = 0x0200,
|
||||
/// If the image is on removable media, fully load it and copy it to swap.
|
||||
IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP = 0x0400,
|
||||
/// If the image is on network media, fully load it and copy it to swap.
|
||||
IMAGE_FILE_NET_RUN_FROM_SWAP = 0x0800,
|
||||
/// The image file is a system file, not a user program.
|
||||
IMAGE_FILE_SYSTEM = 0x1000,
|
||||
/// The image file is a DLL.
|
||||
IMAGE_FILE_DLL = 0x2000,
|
||||
/// This file should only be run on a uniprocessor machine.
|
||||
IMAGE_FILE_UP_SYSTEM_ONLY = 0x4000,
|
||||
/// Big endian: the MSB precedes the LSB in memory. This is deprecated
|
||||
/// and should be 0.
|
||||
IMAGE_FILE_BYTES_REVERSED_HI = 0x8000
|
||||
};
|
||||
|
||||
struct symbol {
|
||||
char Name[NameSize];
|
||||
uint32_t Value;
|
||||
uint16_t SectionNumber;
|
||||
uint16_t Type;
|
||||
uint8_t StorageClass;
|
||||
uint8_t NumberOfAuxSymbols;
|
||||
};
|
||||
|
||||
enum SymbolFlags {
|
||||
SF_TypeMask = 0x0000FFFF,
|
||||
SF_TypeShift = 0,
|
||||
|
||||
SF_ClassMask = 0x00FF0000,
|
||||
SF_ClassShift = 16,
|
||||
|
||||
SF_WeakExternal = 0x01000000
|
||||
};
|
||||
|
||||
enum SymbolSectionNumber {
|
||||
IMAGE_SYM_DEBUG = -2,
|
||||
IMAGE_SYM_ABSOLUTE = -1,
|
||||
IMAGE_SYM_UNDEFINED = 0
|
||||
};
|
||||
|
||||
/// Storage class tells where and what the symbol represents
|
||||
enum SymbolStorageClass {
|
||||
SSC_Invalid = 0xff,
|
||||
|
||||
IMAGE_SYM_CLASS_END_OF_FUNCTION = -1, ///< Physical end of function
|
||||
IMAGE_SYM_CLASS_NULL = 0, ///< No symbol
|
||||
IMAGE_SYM_CLASS_AUTOMATIC = 1, ///< Stack variable
|
||||
IMAGE_SYM_CLASS_EXTERNAL = 2, ///< External symbol
|
||||
IMAGE_SYM_CLASS_STATIC = 3, ///< Static
|
||||
IMAGE_SYM_CLASS_REGISTER = 4, ///< Register variable
|
||||
IMAGE_SYM_CLASS_EXTERNAL_DEF = 5, ///< External definition
|
||||
IMAGE_SYM_CLASS_LABEL = 6, ///< Label
|
||||
IMAGE_SYM_CLASS_UNDEFINED_LABEL = 7, ///< Undefined label
|
||||
IMAGE_SYM_CLASS_MEMBER_OF_STRUCT = 8, ///< Member of structure
|
||||
IMAGE_SYM_CLASS_ARGUMENT = 9, ///< Function argument
|
||||
IMAGE_SYM_CLASS_STRUCT_TAG = 10, ///< Structure tag
|
||||
IMAGE_SYM_CLASS_MEMBER_OF_UNION = 11, ///< Member of union
|
||||
IMAGE_SYM_CLASS_UNION_TAG = 12, ///< Union tag
|
||||
IMAGE_SYM_CLASS_TYPE_DEFINITION = 13, ///< Type definition
|
||||
IMAGE_SYM_CLASS_UNDEFINED_STATIC = 14, ///< Undefined static
|
||||
IMAGE_SYM_CLASS_ENUM_TAG = 15, ///< Enumeration tag
|
||||
IMAGE_SYM_CLASS_MEMBER_OF_ENUM = 16, ///< Member of enumeration
|
||||
IMAGE_SYM_CLASS_REGISTER_PARAM = 17, ///< Register parameter
|
||||
IMAGE_SYM_CLASS_BIT_FIELD = 18, ///< Bit field
|
||||
/// ".bb" or ".eb" - beginning or end of block
|
||||
IMAGE_SYM_CLASS_BLOCK = 100,
|
||||
/// ".bf" or ".ef" - beginning or end of function
|
||||
IMAGE_SYM_CLASS_FUNCTION = 101,
|
||||
IMAGE_SYM_CLASS_END_OF_STRUCT = 102, ///< End of structure
|
||||
IMAGE_SYM_CLASS_FILE = 103, ///< File name
|
||||
/// Line number, reformatted as symbol
|
||||
IMAGE_SYM_CLASS_SECTION = 104,
|
||||
IMAGE_SYM_CLASS_WEAK_EXTERNAL = 105, ///< Duplicate tag
|
||||
/// External symbol in dmert public lib
|
||||
IMAGE_SYM_CLASS_CLR_TOKEN = 107
|
||||
};
|
||||
|
||||
enum SymbolBaseType {
|
||||
IMAGE_SYM_TYPE_NULL = 0, ///< No type information or unknown base type.
|
||||
IMAGE_SYM_TYPE_VOID = 1, ///< Used with void pointers and functions.
|
||||
IMAGE_SYM_TYPE_CHAR = 2, ///< A character (signed byte).
|
||||
IMAGE_SYM_TYPE_SHORT = 3, ///< A 2-byte signed integer.
|
||||
IMAGE_SYM_TYPE_INT = 4, ///< A natural integer type on the target.
|
||||
IMAGE_SYM_TYPE_LONG = 5, ///< A 4-byte signed integer.
|
||||
IMAGE_SYM_TYPE_FLOAT = 6, ///< A 4-byte floating-point number.
|
||||
IMAGE_SYM_TYPE_DOUBLE = 7, ///< An 8-byte floating-point number.
|
||||
IMAGE_SYM_TYPE_STRUCT = 8, ///< A structure.
|
||||
IMAGE_SYM_TYPE_UNION = 9, ///< An union.
|
||||
IMAGE_SYM_TYPE_ENUM = 10, ///< An enumerated type.
|
||||
IMAGE_SYM_TYPE_MOE = 11, ///< A member of enumeration (a specific value).
|
||||
IMAGE_SYM_TYPE_BYTE = 12, ///< A byte; unsigned 1-byte integer.
|
||||
IMAGE_SYM_TYPE_WORD = 13, ///< A word; unsigned 2-byte integer.
|
||||
IMAGE_SYM_TYPE_UINT = 14, ///< An unsigned integer of natural size.
|
||||
IMAGE_SYM_TYPE_DWORD = 15 ///< An unsigned 4-byte integer.
|
||||
};
|
||||
|
||||
enum SymbolComplexType {
|
||||
IMAGE_SYM_DTYPE_NULL = 0, ///< No complex type; simple scalar variable.
|
||||
IMAGE_SYM_DTYPE_POINTER = 1, ///< A pointer to base type.
|
||||
IMAGE_SYM_DTYPE_FUNCTION = 2, ///< A function that returns a base type.
|
||||
IMAGE_SYM_DTYPE_ARRAY = 3, ///< An array of base type.
|
||||
|
||||
/// Type is formed as (base + (derived << SCT_COMPLEX_TYPE_SHIFT))
|
||||
SCT_COMPLEX_TYPE_SHIFT = 4
|
||||
};
|
||||
|
||||
struct section {
|
||||
char Name[NameSize];
|
||||
uint32_t VirtualSize;
|
||||
uint32_t VirtualAddress;
|
||||
uint32_t SizeOfRawData;
|
||||
uint32_t PointerToRawData;
|
||||
uint32_t PointerToRelocations;
|
||||
uint32_t PointerToLineNumbers;
|
||||
uint16_t NumberOfRelocations;
|
||||
uint16_t NumberOfLineNumbers;
|
||||
uint32_t Characteristics;
|
||||
};
|
||||
|
||||
enum SectionCharacteristics {
|
||||
SC_Invalid = 0xffffffff,
|
||||
|
||||
IMAGE_SCN_TYPE_NO_PAD = 0x00000008,
|
||||
IMAGE_SCN_CNT_CODE = 0x00000020,
|
||||
IMAGE_SCN_CNT_INITIALIZED_DATA = 0x00000040,
|
||||
IMAGE_SCN_CNT_UNINITIALIZED_DATA = 0x00000080,
|
||||
IMAGE_SCN_LNK_OTHER = 0x00000100,
|
||||
IMAGE_SCN_LNK_INFO = 0x00000200,
|
||||
IMAGE_SCN_LNK_REMOVE = 0x00000800,
|
||||
IMAGE_SCN_LNK_COMDAT = 0x00001000,
|
||||
IMAGE_SCN_GPREL = 0x00008000,
|
||||
IMAGE_SCN_MEM_PURGEABLE = 0x00020000,
|
||||
IMAGE_SCN_MEM_16BIT = 0x00020000,
|
||||
IMAGE_SCN_MEM_LOCKED = 0x00040000,
|
||||
IMAGE_SCN_MEM_PRELOAD = 0x00080000,
|
||||
IMAGE_SCN_ALIGN_1BYTES = 0x00100000,
|
||||
IMAGE_SCN_ALIGN_2BYTES = 0x00200000,
|
||||
IMAGE_SCN_ALIGN_4BYTES = 0x00300000,
|
||||
IMAGE_SCN_ALIGN_8BYTES = 0x00400000,
|
||||
IMAGE_SCN_ALIGN_16BYTES = 0x00500000,
|
||||
IMAGE_SCN_ALIGN_32BYTES = 0x00600000,
|
||||
IMAGE_SCN_ALIGN_64BYTES = 0x00700000,
|
||||
IMAGE_SCN_ALIGN_128BYTES = 0x00800000,
|
||||
IMAGE_SCN_ALIGN_256BYTES = 0x00900000,
|
||||
IMAGE_SCN_ALIGN_512BYTES = 0x00A00000,
|
||||
IMAGE_SCN_ALIGN_1024BYTES = 0x00B00000,
|
||||
IMAGE_SCN_ALIGN_2048BYTES = 0x00C00000,
|
||||
IMAGE_SCN_ALIGN_4096BYTES = 0x00D00000,
|
||||
IMAGE_SCN_ALIGN_8192BYTES = 0x00E00000,
|
||||
IMAGE_SCN_LNK_NRELOC_OVFL = 0x01000000,
|
||||
IMAGE_SCN_MEM_DISCARDABLE = 0x02000000,
|
||||
IMAGE_SCN_MEM_NOT_CACHED = 0x04000000,
|
||||
IMAGE_SCN_MEM_NOT_PAGED = 0x08000000,
|
||||
IMAGE_SCN_MEM_SHARED = 0x10000000,
|
||||
IMAGE_SCN_MEM_EXECUTE = 0x20000000,
|
||||
IMAGE_SCN_MEM_READ = 0x40000000,
|
||||
IMAGE_SCN_MEM_WRITE = 0x80000000
|
||||
};
|
||||
|
||||
struct relocation {
|
||||
uint32_t VirtualAddress;
|
||||
uint32_t SymbolTableIndex;
|
||||
uint16_t Type;
|
||||
};
|
||||
|
||||
enum RelocationTypeX86 {
|
||||
IMAGE_REL_I386_ABSOLUTE = 0x0000,
|
||||
IMAGE_REL_I386_DIR16 = 0x0001,
|
||||
IMAGE_REL_I386_REL16 = 0x0002,
|
||||
IMAGE_REL_I386_DIR32 = 0x0006,
|
||||
IMAGE_REL_I386_DIR32NB = 0x0007,
|
||||
IMAGE_REL_I386_SEG12 = 0x0009,
|
||||
IMAGE_REL_I386_SECTION = 0x000A,
|
||||
IMAGE_REL_I386_SECREL = 0x000B,
|
||||
IMAGE_REL_I386_TOKEN = 0x000C,
|
||||
IMAGE_REL_I386_SECREL7 = 0x000D,
|
||||
IMAGE_REL_I386_REL32 = 0x0014,
|
||||
|
||||
IMAGE_REL_AMD64_ABSOLUTE = 0x0000,
|
||||
IMAGE_REL_AMD64_ADDR64 = 0x0001,
|
||||
IMAGE_REL_AMD64_ADDR32 = 0x0002,
|
||||
IMAGE_REL_AMD64_ADDR32NB = 0x0003,
|
||||
IMAGE_REL_AMD64_REL32 = 0x0004,
|
||||
IMAGE_REL_AMD64_REL32_1 = 0x0005,
|
||||
IMAGE_REL_AMD64_REL32_2 = 0x0006,
|
||||
IMAGE_REL_AMD64_REL32_3 = 0x0007,
|
||||
IMAGE_REL_AMD64_REL32_4 = 0x0008,
|
||||
IMAGE_REL_AMD64_REL32_5 = 0x0009,
|
||||
IMAGE_REL_AMD64_SECTION = 0x000A,
|
||||
IMAGE_REL_AMD64_SECREL = 0x000B,
|
||||
IMAGE_REL_AMD64_SECREL7 = 0x000C,
|
||||
IMAGE_REL_AMD64_TOKEN = 0x000D,
|
||||
IMAGE_REL_AMD64_SREL32 = 0x000E,
|
||||
IMAGE_REL_AMD64_PAIR = 0x000F,
|
||||
IMAGE_REL_AMD64_SSPAN32 = 0x0010
|
||||
};
|
||||
|
||||
enum RelocationTypesARM {
|
||||
IMAGE_REL_ARM_ABSOLUTE = 0x0000,
|
||||
IMAGE_REL_ARM_ADDR32 = 0x0001,
|
||||
IMAGE_REL_ARM_ADDR32NB = 0x0002,
|
||||
IMAGE_REL_ARM_BRANCH24 = 0x0003,
|
||||
IMAGE_REL_ARM_BRANCH11 = 0x0004,
|
||||
IMAGE_REL_ARM_TOKEN = 0x0005,
|
||||
IMAGE_REL_ARM_BLX24 = 0x0008,
|
||||
IMAGE_REL_ARM_BLX11 = 0x0009,
|
||||
IMAGE_REL_ARM_SECTION = 0x000E,
|
||||
IMAGE_REL_ARM_SECREL = 0x000F,
|
||||
IMAGE_REL_ARM_MOV32A = 0x0010,
|
||||
IMAGE_REL_ARM_MOV32T = 0x0011,
|
||||
IMAGE_REL_ARM_BRANCH20T = 0x0012,
|
||||
IMAGE_REL_ARM_BRANCH24T = 0x0014,
|
||||
IMAGE_REL_ARM_BLX23T = 0x0015
|
||||
};
|
||||
|
||||
enum COMDATType {
|
||||
IMAGE_COMDAT_SELECT_NODUPLICATES = 1,
|
||||
IMAGE_COMDAT_SELECT_ANY,
|
||||
IMAGE_COMDAT_SELECT_SAME_SIZE,
|
||||
IMAGE_COMDAT_SELECT_EXACT_MATCH,
|
||||
IMAGE_COMDAT_SELECT_ASSOCIATIVE,
|
||||
IMAGE_COMDAT_SELECT_LARGEST,
|
||||
IMAGE_COMDAT_SELECT_NEWEST
|
||||
};
|
||||
|
||||
// Auxiliary Symbol Formats
|
||||
struct AuxiliaryFunctionDefinition {
|
||||
uint32_t TagIndex;
|
||||
uint32_t TotalSize;
|
||||
uint32_t PointerToLinenumber;
|
||||
uint32_t PointerToNextFunction;
|
||||
uint8_t unused[2];
|
||||
};
|
||||
|
||||
struct AuxiliarybfAndefSymbol {
|
||||
uint8_t unused1[4];
|
||||
uint16_t Linenumber;
|
||||
uint8_t unused2[6];
|
||||
uint32_t PointerToNextFunction;
|
||||
uint8_t unused3[2];
|
||||
};
|
||||
|
||||
struct AuxiliaryWeakExternal {
|
||||
uint32_t TagIndex;
|
||||
uint32_t Characteristics;
|
||||
uint8_t unused[10];
|
||||
};
|
||||
|
||||
/// These are not documented in the spec, but are located in WinNT.h.
|
||||
enum WeakExternalCharacteristics {
|
||||
IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY = 1,
|
||||
IMAGE_WEAK_EXTERN_SEARCH_LIBRARY = 2,
|
||||
IMAGE_WEAK_EXTERN_SEARCH_ALIAS = 3
|
||||
};
|
||||
|
||||
struct AuxiliaryFile {
|
||||
uint8_t FileName[18];
|
||||
};
|
||||
|
||||
struct AuxiliarySectionDefinition {
|
||||
uint32_t Length;
|
||||
uint16_t NumberOfRelocations;
|
||||
uint16_t NumberOfLinenumbers;
|
||||
uint32_t CheckSum;
|
||||
uint16_t Number;
|
||||
uint8_t Selection;
|
||||
uint8_t unused[3];
|
||||
};
|
||||
|
||||
union Auxiliary {
|
||||
AuxiliaryFunctionDefinition FunctionDefinition;
|
||||
AuxiliarybfAndefSymbol bfAndefSymbol;
|
||||
AuxiliaryWeakExternal WeakExternal;
|
||||
AuxiliaryFile File;
|
||||
AuxiliarySectionDefinition SectionDefinition;
|
||||
};
|
||||
|
||||
/// @brief The Import Directory Table.
|
||||
///
|
||||
/// There is a single array of these and one entry per imported DLL.
|
||||
struct ImportDirectoryTableEntry {
|
||||
uint32_t ImportLookupTableRVA;
|
||||
uint32_t TimeDateStamp;
|
||||
uint32_t ForwarderChain;
|
||||
uint32_t NameRVA;
|
||||
uint32_t ImportAddressTableRVA;
|
||||
};
|
||||
|
||||
/// @brief The PE32 Import Lookup Table.
|
||||
///
|
||||
/// There is an array of these for each imported DLL. It represents either
|
||||
/// the ordinal to import from the target DLL, or a name to lookup and import
|
||||
/// from the target DLL.
|
||||
///
|
||||
/// This also happens to be the same format used by the Import Address Table
|
||||
/// when it is initially written out to the image.
|
||||
struct ImportLookupTableEntry32 {
|
||||
uint32_t data;
|
||||
|
||||
/// @brief Is this entry specified by ordinal, or name?
|
||||
bool isOrdinal() const { return data & 0x80000000; }
|
||||
|
||||
/// @brief Get the ordinal value of this entry. isOrdinal must be true.
|
||||
uint16_t getOrdinal() const {
|
||||
assert(isOrdinal() && "ILT entry is not an ordinal!");
|
||||
return data & 0xFFFF;
|
||||
}
|
||||
|
||||
/// @brief Set the ordinal value and set isOrdinal to true.
|
||||
void setOrdinal(uint16_t o) {
|
||||
data = o;
|
||||
data |= 0x80000000;
|
||||
}
|
||||
|
||||
/// @brief Get the Hint/Name entry RVA. isOrdinal must be false.
|
||||
uint32_t getHintNameRVA() const {
|
||||
assert(!isOrdinal() && "ILT entry is not a Hint/Name RVA!");
|
||||
return data;
|
||||
}
|
||||
|
||||
/// @brief Set the Hint/Name entry RVA and set isOrdinal to false.
|
||||
void setHintNameRVA(uint32_t rva) { data = rva; }
|
||||
};
|
||||
|
||||
/// @brief The DOS compatible header at the front of all PEs.
|
||||
struct DOSHeader {
|
||||
uint16_t Magic;
|
||||
uint16_t UsedBytesInTheLastPage;
|
||||
uint16_t FileSizeInPages;
|
||||
uint16_t NumberOfRelocationItems;
|
||||
uint16_t HeaderSizeInParagraphs;
|
||||
uint16_t MinimumExtraParagraphs;
|
||||
uint16_t MaximumExtraParagraphs;
|
||||
uint16_t InitialRelativeSS;
|
||||
uint16_t InitialSP;
|
||||
uint16_t Checksum;
|
||||
uint16_t InitialIP;
|
||||
uint16_t InitialRelativeCS;
|
||||
uint16_t AddressOfRelocationTable;
|
||||
uint16_t OverlayNumber;
|
||||
uint16_t Reserved[4];
|
||||
uint16_t OEMid;
|
||||
uint16_t OEMinfo;
|
||||
uint16_t Reserved2[10];
|
||||
uint32_t AddressOfNewExeHeader;
|
||||
};
|
||||
|
||||
struct PEHeader {
|
||||
uint32_t Signature;
|
||||
header COFFHeader;
|
||||
uint16_t Magic;
|
||||
uint8_t MajorLinkerVersion;
|
||||
uint8_t MinorLinkerVersion;
|
||||
uint32_t SizeOfCode;
|
||||
uint32_t SizeOfInitializedData;
|
||||
uint32_t SizeOfUninitializedData;
|
||||
uint32_t AddressOfEntryPoint; // RVA
|
||||
uint32_t BaseOfCode; // RVA
|
||||
uint32_t BaseOfData; // RVA
|
||||
uint64_t ImageBase;
|
||||
uint32_t SectionAlignment;
|
||||
uint32_t FileAlignment;
|
||||
uint16_t MajorOperatingSystemVersion;
|
||||
uint16_t MinorOperatingSystemVersion;
|
||||
uint16_t MajorImageVersion;
|
||||
uint16_t MinorImageVersion;
|
||||
uint16_t MajorSubsystemVersion;
|
||||
uint16_t MinorSubsystemVersion;
|
||||
uint32_t Win32VersionValue;
|
||||
uint32_t SizeOfImage;
|
||||
uint32_t SizeOfHeaders;
|
||||
uint32_t CheckSum;
|
||||
uint16_t Subsystem;
|
||||
uint16_t DLLCharacteristics;
|
||||
uint64_t SizeOfStackReserve;
|
||||
uint64_t SizeOfStackCommit;
|
||||
uint64_t SizeOfHeapReserve;
|
||||
uint64_t SizeOfHeapCommit;
|
||||
uint32_t LoaderFlags;
|
||||
uint32_t NumberOfRvaAndSize;
|
||||
};
|
||||
|
||||
struct DataDirectory {
|
||||
uint32_t RelativeVirtualAddress;
|
||||
uint32_t Size;
|
||||
};
|
||||
|
||||
enum WindowsSubsystem {
|
||||
IMAGE_SUBSYSTEM_UNKNOWN = 0, ///< An unknown subsystem.
|
||||
IMAGE_SUBSYSTEM_NATIVE = 1, ///< Device drivers and native Windows processes
|
||||
IMAGE_SUBSYSTEM_WINDOWS_GUI = 2, ///< The Windows GUI subsystem.
|
||||
IMAGE_SUBSYSTEM_WINDOWS_CUI = 3, ///< The Windows character subsystem.
|
||||
IMAGE_SUBSYSTEM_POSIX_CUI = 7, ///< The POSIX character subsystem.
|
||||
IMAGE_SUBSYSTEM_WINDOWS_CE_GUI = 9, ///< Windows CE.
|
||||
IMAGE_SUBSYSTEM_EFI_APPLICATION = 10, ///< An EFI application.
|
||||
IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER = 11, ///< An EFI driver with boot
|
||||
/// services.
|
||||
IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER = 12, ///< An EFI driver with run-time
|
||||
/// services.
|
||||
IMAGE_SUBSYSTEM_EFI_ROM = 13, ///< An EFI ROM image.
|
||||
IMAGE_SUBSYSTEM_XBOX = 14 ///< XBOX.
|
||||
};
|
||||
|
||||
enum DLLCharacteristics {
|
||||
/// DLL can be relocated at load time.
|
||||
IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE = 0x0040,
|
||||
/// Code integrity checks are enforced.
|
||||
IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY = 0x0080,
|
||||
IMAGE_DLL_CHARACTERISTICS_NX_COMPAT = 0x0100, ///< Image is NX compatible.
|
||||
/// Isolation aware, but do not isolate the image.
|
||||
IMAGE_DLL_CHARACTERISTICS_NO_ISOLATION = 0x0200,
|
||||
/// Does not use structured exception handling (SEH). No SEH handler may be
|
||||
/// called in this image.
|
||||
IMAGE_DLL_CHARACTERISTICS_NO_SEH = 0x0400,
|
||||
/// Do not bind the image.
|
||||
IMAGE_DLL_CHARACTERISTICS_NO_BIND = 0x0800,
|
||||
IMAGE_DLL_CHARACTERISTICS_WDM_DRIVER = 0x2000, ///< A WDM driver.
|
||||
/// Terminal Server aware.
|
||||
IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE = 0x8000
|
||||
};
|
||||
|
||||
enum DebugType {
|
||||
IMAGE_DEBUG_TYPE_UNKNOWN = 0,
|
||||
IMAGE_DEBUG_TYPE_COFF = 1,
|
||||
IMAGE_DEBUG_TYPE_CODEVIEW = 2,
|
||||
IMAGE_DEBUG_TYPE_FPO = 3,
|
||||
IMAGE_DEBUG_TYPE_MISC = 4,
|
||||
IMAGE_DEBUG_TYPE_EXCEPTION = 5,
|
||||
IMAGE_DEBUG_TYPE_FIXUP = 6,
|
||||
IMAGE_DEBUG_TYPE_OMAP_TO_SRC = 7,
|
||||
IMAGE_DEBUG_TYPE_OMAP_FROM_SRC = 8,
|
||||
IMAGE_DEBUG_TYPE_BORLAND = 9,
|
||||
IMAGE_DEBUG_TYPE_CLSID = 11
|
||||
};
|
||||
|
||||
enum BaseRelocationType {
|
||||
IMAGE_REL_BASED_ABSOLUTE = 0,
|
||||
IMAGE_REL_BASED_HIGH = 1,
|
||||
IMAGE_REL_BASED_LOW = 2,
|
||||
IMAGE_REL_BASED_HIGHLOW = 3,
|
||||
IMAGE_REL_BASED_HIGHADJ = 4,
|
||||
IMAGE_REL_BASED_MIPS_JMPADDR = 5,
|
||||
IMAGE_REL_BASED_ARM_MOV32A = 5,
|
||||
IMAGE_REL_BASED_ARM_MOV32T = 7,
|
||||
IMAGE_REL_BASED_MIPS_JMPADDR16 = 9,
|
||||
IMAGE_REL_BASED_DIR64 = 10
|
||||
};
|
||||
|
||||
enum ImportType {
|
||||
IMPORT_CODE = 0,
|
||||
IMPORT_DATA = 1,
|
||||
IMPORT_CONST = 2
|
||||
};
|
||||
|
||||
enum ImportNameType {
|
||||
/// Import is by ordinal. This indicates that the value in the Ordinal/Hint
|
||||
/// field of the import header is the import's ordinal. If this constant is
|
||||
/// not specified, then the Ordinal/Hint field should always be interpreted
|
||||
/// as the import's hint.
|
||||
IMPORT_ORDINAL = 0,
|
||||
/// The import name is identical to the public symbol name
|
||||
IMPORT_NAME = 1,
|
||||
/// The import name is the public symbol name, but skipping the leading ?,
|
||||
/// @, or optionally _.
|
||||
IMPORT_NAME_NOPREFIX = 2,
|
||||
/// The import name is the public symbol name, but skipping the leading ?,
|
||||
/// @, or optionally _, and truncating at the first @.
|
||||
IMPORT_NAME_UNDECORATE = 3
|
||||
};
|
||||
|
||||
struct ImportHeader {
|
||||
uint16_t Sig1; ///< Must be IMAGE_FILE_MACHINE_UNKNOWN (0).
|
||||
uint16_t Sig2; ///< Must be 0xFFFF.
|
||||
uint16_t Version;
|
||||
uint16_t Machine;
|
||||
uint32_t TimeDateStamp;
|
||||
uint32_t SizeOfData;
|
||||
uint16_t OrdinalHint;
|
||||
uint16_t TypeInfo;
|
||||
|
||||
ImportType getType() const {
|
||||
return static_cast<ImportType>(TypeInfo & 0x3);
|
||||
}
|
||||
|
||||
ImportNameType getNameType() const {
|
||||
return static_cast<ImportNameType>((TypeInfo & 0x1C) >> 3);
|
||||
}
|
||||
};
|
||||
|
||||
} // End namespace COFF.
|
||||
} // End namespace llvm.
|
||||
|
||||
#endif
|
||||
315
thirdparty/clang/include/llvm/Support/CallSite.h
vendored
Normal file
315
thirdparty/clang/include/llvm/Support/CallSite.h
vendored
Normal file
@@ -0,0 +1,315 @@
|
||||
//===-- llvm/Support/CallSite.h - Abstract Call & Invoke instrs -*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the CallSite class, which is a handy wrapper for code that
|
||||
// wants to treat Call and Invoke instructions in a generic way. When in non-
|
||||
// mutation context (e.g. an analysis) ImmutableCallSite should be used.
|
||||
// Finally, when some degree of customization is necessary between these two
|
||||
// extremes, CallSiteBase<> can be supplied with fine-tuned parameters.
|
||||
//
|
||||
// NOTE: These classes are supposed to have "value semantics". So they should be
|
||||
// passed by value, not by reference; they should not be "new"ed or "delete"d.
|
||||
// They are efficiently copyable, assignable and constructable, with cost
|
||||
// equivalent to copying a pointer (notice that they have only a single data
|
||||
// member). The internal representation carries a flag which indicates which of
|
||||
// the two variants is enclosed. This allows for cheaper checks when various
|
||||
// accessors of CallSite are employed.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_CALLSITE_H
|
||||
#define LLVM_SUPPORT_CALLSITE_H
|
||||
|
||||
#include "llvm/ADT/PointerIntPair.h"
|
||||
#include "llvm/IR/Attributes.h"
|
||||
#include "llvm/IR/CallingConv.h"
|
||||
#include "llvm/IR/Instructions.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class CallInst;
|
||||
class InvokeInst;
|
||||
|
||||
template <typename FunTy = const Function,
|
||||
typename ValTy = const Value,
|
||||
typename UserTy = const User,
|
||||
typename InstrTy = const Instruction,
|
||||
typename CallTy = const CallInst,
|
||||
typename InvokeTy = const InvokeInst,
|
||||
typename IterTy = User::const_op_iterator>
|
||||
class CallSiteBase {
|
||||
protected:
|
||||
PointerIntPair<InstrTy*, 1, bool> I;
|
||||
public:
|
||||
CallSiteBase() : I(0, false) {}
|
||||
CallSiteBase(CallTy *CI) : I(CI, true) { assert(CI); }
|
||||
CallSiteBase(InvokeTy *II) : I(II, false) { assert(II); }
|
||||
CallSiteBase(ValTy *II) { *this = get(II); }
|
||||
protected:
|
||||
/// CallSiteBase::get - This static method is sort of like a constructor. It
|
||||
/// will create an appropriate call site for a Call or Invoke instruction, but
|
||||
/// it can also create a null initialized CallSiteBase object for something
|
||||
/// which is NOT a call site.
|
||||
///
|
||||
static CallSiteBase get(ValTy *V) {
|
||||
if (InstrTy *II = dyn_cast<InstrTy>(V)) {
|
||||
if (II->getOpcode() == Instruction::Call)
|
||||
return CallSiteBase(static_cast<CallTy*>(II));
|
||||
else if (II->getOpcode() == Instruction::Invoke)
|
||||
return CallSiteBase(static_cast<InvokeTy*>(II));
|
||||
}
|
||||
return CallSiteBase();
|
||||
}
|
||||
public:
|
||||
/// isCall - true if a CallInst is enclosed.
|
||||
/// Note that !isCall() does not mean it is an InvokeInst enclosed,
|
||||
/// it also could signify a NULL Instruction pointer.
|
||||
bool isCall() const { return I.getInt(); }
|
||||
|
||||
/// isInvoke - true if a InvokeInst is enclosed.
|
||||
///
|
||||
bool isInvoke() const { return getInstruction() && !I.getInt(); }
|
||||
|
||||
InstrTy *getInstruction() const { return I.getPointer(); }
|
||||
InstrTy *operator->() const { return I.getPointer(); }
|
||||
operator bool() const { return I.getPointer(); }
|
||||
|
||||
/// getCalledValue - Return the pointer to function that is being called.
|
||||
///
|
||||
ValTy *getCalledValue() const {
|
||||
assert(getInstruction() && "Not a call or invoke instruction!");
|
||||
return *getCallee();
|
||||
}
|
||||
|
||||
/// getCalledFunction - Return the function being called if this is a direct
|
||||
/// call, otherwise return null (if it's an indirect call).
|
||||
///
|
||||
FunTy *getCalledFunction() const {
|
||||
return dyn_cast<FunTy>(getCalledValue());
|
||||
}
|
||||
|
||||
/// setCalledFunction - Set the callee to the specified value.
|
||||
///
|
||||
void setCalledFunction(Value *V) {
|
||||
assert(getInstruction() && "Not a call or invoke instruction!");
|
||||
*getCallee() = V;
|
||||
}
|
||||
|
||||
/// isCallee - Determine whether the passed iterator points to the
|
||||
/// callee operand's Use.
|
||||
///
|
||||
bool isCallee(value_use_iterator<UserTy> UI) const {
|
||||
return getCallee() == &UI.getUse();
|
||||
}
|
||||
|
||||
ValTy *getArgument(unsigned ArgNo) const {
|
||||
assert(arg_begin() + ArgNo < arg_end() && "Argument # out of range!");
|
||||
return *(arg_begin() + ArgNo);
|
||||
}
|
||||
|
||||
void setArgument(unsigned ArgNo, Value* newVal) {
|
||||
assert(getInstruction() && "Not a call or invoke instruction!");
|
||||
assert(arg_begin() + ArgNo < arg_end() && "Argument # out of range!");
|
||||
getInstruction()->setOperand(ArgNo, newVal);
|
||||
}
|
||||
|
||||
/// Given a value use iterator, returns the argument that corresponds to it.
|
||||
/// Iterator must actually correspond to an argument.
|
||||
unsigned getArgumentNo(value_use_iterator<UserTy> I) const {
|
||||
assert(getInstruction() && "Not a call or invoke instruction!");
|
||||
assert(arg_begin() <= &I.getUse() && &I.getUse() < arg_end()
|
||||
&& "Argument # out of range!");
|
||||
return &I.getUse() - arg_begin();
|
||||
}
|
||||
|
||||
/// arg_iterator - The type of iterator to use when looping over actual
|
||||
/// arguments at this call site.
|
||||
typedef IterTy arg_iterator;
|
||||
|
||||
/// arg_begin/arg_end - Return iterators corresponding to the actual argument
|
||||
/// list for a call site.
|
||||
IterTy arg_begin() const {
|
||||
assert(getInstruction() && "Not a call or invoke instruction!");
|
||||
// Skip non-arguments
|
||||
return (*this)->op_begin();
|
||||
}
|
||||
|
||||
IterTy arg_end() const { return (*this)->op_end() - getArgumentEndOffset(); }
|
||||
bool arg_empty() const { return arg_end() == arg_begin(); }
|
||||
unsigned arg_size() const { return unsigned(arg_end() - arg_begin()); }
|
||||
|
||||
/// getType - Return the type of the instruction that generated this call site
|
||||
///
|
||||
Type *getType() const { return (*this)->getType(); }
|
||||
|
||||
/// getCaller - Return the caller function for this call site
|
||||
///
|
||||
FunTy *getCaller() const { return (*this)->getParent()->getParent(); }
|
||||
|
||||
#define CALLSITE_DELEGATE_GETTER(METHOD) \
|
||||
InstrTy *II = getInstruction(); \
|
||||
return isCall() \
|
||||
? cast<CallInst>(II)->METHOD \
|
||||
: cast<InvokeInst>(II)->METHOD
|
||||
|
||||
#define CALLSITE_DELEGATE_SETTER(METHOD) \
|
||||
InstrTy *II = getInstruction(); \
|
||||
if (isCall()) \
|
||||
cast<CallInst>(II)->METHOD; \
|
||||
else \
|
||||
cast<InvokeInst>(II)->METHOD
|
||||
|
||||
/// getCallingConv/setCallingConv - get or set the calling convention of the
|
||||
/// call.
|
||||
CallingConv::ID getCallingConv() const {
|
||||
CALLSITE_DELEGATE_GETTER(getCallingConv());
|
||||
}
|
||||
void setCallingConv(CallingConv::ID CC) {
|
||||
CALLSITE_DELEGATE_SETTER(setCallingConv(CC));
|
||||
}
|
||||
|
||||
/// getAttributes/setAttributes - get or set the parameter attributes of
|
||||
/// the call.
|
||||
const AttributeSet &getAttributes() const {
|
||||
CALLSITE_DELEGATE_GETTER(getAttributes());
|
||||
}
|
||||
void setAttributes(const AttributeSet &PAL) {
|
||||
CALLSITE_DELEGATE_SETTER(setAttributes(PAL));
|
||||
}
|
||||
|
||||
/// \brief Return true if this function has the given attribute.
|
||||
bool hasFnAttr(Attribute::AttrKind A) const {
|
||||
CALLSITE_DELEGATE_GETTER(hasFnAttr(A));
|
||||
}
|
||||
|
||||
/// \brief Return true if the call or the callee has the given attribute.
|
||||
bool paramHasAttr(unsigned i, Attribute::AttrKind A) const {
|
||||
CALLSITE_DELEGATE_GETTER(paramHasAttr(i, A));
|
||||
}
|
||||
|
||||
/// @brief Extract the alignment for a call or parameter (0=unknown).
|
||||
uint16_t getParamAlignment(uint16_t i) const {
|
||||
CALLSITE_DELEGATE_GETTER(getParamAlignment(i));
|
||||
}
|
||||
|
||||
/// @brief Return true if the call should not be inlined.
|
||||
bool isNoInline() const {
|
||||
CALLSITE_DELEGATE_GETTER(isNoInline());
|
||||
}
|
||||
void setIsNoInline(bool Value = true) {
|
||||
CALLSITE_DELEGATE_SETTER(setIsNoInline(Value));
|
||||
}
|
||||
|
||||
/// @brief Determine if the call does not access memory.
|
||||
bool doesNotAccessMemory() const {
|
||||
CALLSITE_DELEGATE_GETTER(doesNotAccessMemory());
|
||||
}
|
||||
void setDoesNotAccessMemory() {
|
||||
CALLSITE_DELEGATE_SETTER(setDoesNotAccessMemory());
|
||||
}
|
||||
|
||||
/// @brief Determine if the call does not access or only reads memory.
|
||||
bool onlyReadsMemory() const {
|
||||
CALLSITE_DELEGATE_GETTER(onlyReadsMemory());
|
||||
}
|
||||
void setOnlyReadsMemory() {
|
||||
CALLSITE_DELEGATE_SETTER(setOnlyReadsMemory());
|
||||
}
|
||||
|
||||
/// @brief Determine if the call cannot return.
|
||||
bool doesNotReturn() const {
|
||||
CALLSITE_DELEGATE_GETTER(doesNotReturn());
|
||||
}
|
||||
void setDoesNotReturn() {
|
||||
CALLSITE_DELEGATE_SETTER(setDoesNotReturn());
|
||||
}
|
||||
|
||||
/// @brief Determine if the call cannot unwind.
|
||||
bool doesNotThrow() const {
|
||||
CALLSITE_DELEGATE_GETTER(doesNotThrow());
|
||||
}
|
||||
void setDoesNotThrow() {
|
||||
CALLSITE_DELEGATE_SETTER(setDoesNotThrow());
|
||||
}
|
||||
|
||||
#undef CALLSITE_DELEGATE_GETTER
|
||||
#undef CALLSITE_DELEGATE_SETTER
|
||||
|
||||
/// @brief Determine whether this argument is not captured.
|
||||
bool doesNotCapture(unsigned ArgNo) const {
|
||||
return paramHasAttr(ArgNo + 1, Attribute::NoCapture);
|
||||
}
|
||||
|
||||
/// @brief Determine whether this argument is passed by value.
|
||||
bool isByValArgument(unsigned ArgNo) const {
|
||||
return paramHasAttr(ArgNo + 1, Attribute::ByVal);
|
||||
}
|
||||
|
||||
/// hasArgument - Returns true if this CallSite passes the given Value* as an
|
||||
/// argument to the called function.
|
||||
bool hasArgument(const Value *Arg) const {
|
||||
for (arg_iterator AI = this->arg_begin(), E = this->arg_end(); AI != E;
|
||||
++AI)
|
||||
if (AI->get() == Arg)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned getArgumentEndOffset() const {
|
||||
if (isCall())
|
||||
return 1; // Skip Callee
|
||||
else
|
||||
return 3; // Skip BB, BB, Callee
|
||||
}
|
||||
|
||||
IterTy getCallee() const {
|
||||
if (isCall()) // Skip Callee
|
||||
return cast<CallInst>(getInstruction())->op_end() - 1;
|
||||
else // Skip BB, BB, Callee
|
||||
return cast<InvokeInst>(getInstruction())->op_end() - 3;
|
||||
}
|
||||
};
|
||||
|
||||
class CallSite : public CallSiteBase<Function, Value, User, Instruction,
|
||||
CallInst, InvokeInst, User::op_iterator> {
|
||||
typedef CallSiteBase<Function, Value, User, Instruction,
|
||||
CallInst, InvokeInst, User::op_iterator> Base;
|
||||
public:
|
||||
CallSite() {}
|
||||
CallSite(Base B) : Base(B) {}
|
||||
CallSite(Value* V) : Base(V) {}
|
||||
CallSite(CallInst *CI) : Base(CI) {}
|
||||
CallSite(InvokeInst *II) : Base(II) {}
|
||||
CallSite(Instruction *II) : Base(II) {}
|
||||
|
||||
bool operator==(const CallSite &CS) const { return I == CS.I; }
|
||||
bool operator!=(const CallSite &CS) const { return I != CS.I; }
|
||||
bool operator<(const CallSite &CS) const {
|
||||
return getInstruction() < CS.getInstruction();
|
||||
}
|
||||
|
||||
private:
|
||||
User::op_iterator getCallee() const;
|
||||
};
|
||||
|
||||
/// ImmutableCallSite - establish a view to a call site for examination
|
||||
class ImmutableCallSite : public CallSiteBase<> {
|
||||
typedef CallSiteBase<> Base;
|
||||
public:
|
||||
ImmutableCallSite(const Value* V) : Base(V) {}
|
||||
ImmutableCallSite(const CallInst *CI) : Base(CI) {}
|
||||
ImmutableCallSite(const InvokeInst *II) : Base(II) {}
|
||||
ImmutableCallSite(const Instruction *II) : Base(II) {}
|
||||
ImmutableCallSite(CallSite CS) : Base(CS.getInstruction()) {}
|
||||
};
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
||||
32
thirdparty/clang/include/llvm/Support/Capacity.h
vendored
Normal file
32
thirdparty/clang/include/llvm/Support/Capacity.h
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
//===--- Capacity.h - Generic computation of ADT memory use -----*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the capacity function that computes the amount of
|
||||
// memory used by an ADT.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_CAPACITY_H
|
||||
#define LLVM_SUPPORT_CAPACITY_H
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
template <typename T>
|
||||
static inline size_t capacity_in_bytes(const T &x) {
|
||||
// This default definition of capacity should work for things like std::vector
|
||||
// and friends. More specialized versions will work for others.
|
||||
return x.capacity() * sizeof(typename T::value_type);
|
||||
}
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
|
||||
289
thirdparty/clang/include/llvm/Support/Casting.h
vendored
Normal file
289
thirdparty/clang/include/llvm/Support/Casting.h
vendored
Normal file
@@ -0,0 +1,289 @@
|
||||
//===-- llvm/Support/Casting.h - Allow flexible, checked, casts -*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the isa<X>(), cast<X>(), dyn_cast<X>(), cast_or_null<X>(),
|
||||
// and dyn_cast_or_null<X>() templates.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_CASTING_H
|
||||
#define LLVM_SUPPORT_CASTING_H
|
||||
|
||||
#include "llvm/Support/type_traits.h"
|
||||
#include <cassert>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// isa<x> Support Templates
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// Define a template that can be specialized by smart pointers to reflect the
|
||||
// fact that they are automatically dereferenced, and are not involved with the
|
||||
// template selection process... the default implementation is a noop.
|
||||
//
|
||||
template<typename From> struct simplify_type {
|
||||
typedef From SimpleType; // The real type this represents...
|
||||
|
||||
// An accessor to get the real value...
|
||||
static SimpleType &getSimplifiedValue(From &Val) { return Val; }
|
||||
};
|
||||
|
||||
template<typename From> struct simplify_type<const From> {
|
||||
typedef typename simplify_type<From>::SimpleType NonConstSimpleType;
|
||||
typedef typename add_const_past_pointer<NonConstSimpleType>::type
|
||||
SimpleType;
|
||||
typedef typename add_lvalue_reference_if_not_pointer<SimpleType>::type
|
||||
RetType;
|
||||
static RetType getSimplifiedValue(const From& Val) {
|
||||
return simplify_type<From>::getSimplifiedValue(const_cast<From&>(Val));
|
||||
}
|
||||
};
|
||||
|
||||
// The core of the implementation of isa<X> is here; To and From should be
|
||||
// the names of classes. This template can be specialized to customize the
|
||||
// implementation of isa<> without rewriting it from scratch.
|
||||
template <typename To, typename From, typename Enabler = void>
|
||||
struct isa_impl {
|
||||
static inline bool doit(const From &Val) {
|
||||
return To::classof(&Val);
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Always allow upcasts, and perform no dynamic check for them.
|
||||
template <typename To, typename From>
|
||||
struct isa_impl<To, From,
|
||||
typename enable_if<
|
||||
llvm::is_base_of<To, From>
|
||||
>::type
|
||||
> {
|
||||
static inline bool doit(const From &) { return true; }
|
||||
};
|
||||
|
||||
template <typename To, typename From> struct isa_impl_cl {
|
||||
static inline bool doit(const From &Val) {
|
||||
return isa_impl<To, From>::doit(Val);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename To, typename From> struct isa_impl_cl<To, const From> {
|
||||
static inline bool doit(const From &Val) {
|
||||
return isa_impl<To, From>::doit(Val);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename To, typename From> struct isa_impl_cl<To, From*> {
|
||||
static inline bool doit(const From *Val) {
|
||||
assert(Val && "isa<> used on a null pointer");
|
||||
return isa_impl<To, From>::doit(*Val);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename To, typename From> struct isa_impl_cl<To, From*const> {
|
||||
static inline bool doit(const From *Val) {
|
||||
assert(Val && "isa<> used on a null pointer");
|
||||
return isa_impl<To, From>::doit(*Val);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename To, typename From> struct isa_impl_cl<To, const From*> {
|
||||
static inline bool doit(const From *Val) {
|
||||
assert(Val && "isa<> used on a null pointer");
|
||||
return isa_impl<To, From>::doit(*Val);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename To, typename From> struct isa_impl_cl<To, const From*const> {
|
||||
static inline bool doit(const From *Val) {
|
||||
assert(Val && "isa<> used on a null pointer");
|
||||
return isa_impl<To, From>::doit(*Val);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename To, typename From, typename SimpleFrom>
|
||||
struct isa_impl_wrap {
|
||||
// When From != SimplifiedType, we can simplify the type some more by using
|
||||
// the simplify_type template.
|
||||
static bool doit(const From &Val) {
|
||||
return isa_impl_wrap<To, SimpleFrom,
|
||||
typename simplify_type<SimpleFrom>::SimpleType>::doit(
|
||||
simplify_type<const From>::getSimplifiedValue(Val));
|
||||
}
|
||||
};
|
||||
|
||||
template<typename To, typename FromTy>
|
||||
struct isa_impl_wrap<To, FromTy, FromTy> {
|
||||
// When From == SimpleType, we are as simple as we are going to get.
|
||||
static bool doit(const FromTy &Val) {
|
||||
return isa_impl_cl<To,FromTy>::doit(Val);
|
||||
}
|
||||
};
|
||||
|
||||
// isa<X> - Return true if the parameter to the template is an instance of the
|
||||
// template type argument. Used like this:
|
||||
//
|
||||
// if (isa<Type>(myVal)) { ... }
|
||||
//
|
||||
template <class X, class Y>
|
||||
inline bool isa(const Y &Val) {
|
||||
return isa_impl_wrap<X, const Y,
|
||||
typename simplify_type<const Y>::SimpleType>::doit(Val);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// cast<x> Support Templates
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
template<class To, class From> struct cast_retty;
|
||||
|
||||
|
||||
// Calculate what type the 'cast' function should return, based on a requested
|
||||
// type of To and a source type of From.
|
||||
template<class To, class From> struct cast_retty_impl {
|
||||
typedef To& ret_type; // Normal case, return Ty&
|
||||
};
|
||||
template<class To, class From> struct cast_retty_impl<To, const From> {
|
||||
typedef const To &ret_type; // Normal case, return Ty&
|
||||
};
|
||||
|
||||
template<class To, class From> struct cast_retty_impl<To, From*> {
|
||||
typedef To* ret_type; // Pointer arg case, return Ty*
|
||||
};
|
||||
|
||||
template<class To, class From> struct cast_retty_impl<To, const From*> {
|
||||
typedef const To* ret_type; // Constant pointer arg case, return const Ty*
|
||||
};
|
||||
|
||||
template<class To, class From> struct cast_retty_impl<To, const From*const> {
|
||||
typedef const To* ret_type; // Constant pointer arg case, return const Ty*
|
||||
};
|
||||
|
||||
|
||||
template<class To, class From, class SimpleFrom>
|
||||
struct cast_retty_wrap {
|
||||
// When the simplified type and the from type are not the same, use the type
|
||||
// simplifier to reduce the type, then reuse cast_retty_impl to get the
|
||||
// resultant type.
|
||||
typedef typename cast_retty<To, SimpleFrom>::ret_type ret_type;
|
||||
};
|
||||
|
||||
template<class To, class FromTy>
|
||||
struct cast_retty_wrap<To, FromTy, FromTy> {
|
||||
// When the simplified type is equal to the from type, use it directly.
|
||||
typedef typename cast_retty_impl<To,FromTy>::ret_type ret_type;
|
||||
};
|
||||
|
||||
template<class To, class From>
|
||||
struct cast_retty {
|
||||
typedef typename cast_retty_wrap<To, From,
|
||||
typename simplify_type<From>::SimpleType>::ret_type ret_type;
|
||||
};
|
||||
|
||||
// Ensure the non-simple values are converted using the simplify_type template
|
||||
// that may be specialized by smart pointers...
|
||||
//
|
||||
template<class To, class From, class SimpleFrom> struct cast_convert_val {
|
||||
// This is not a simple type, use the template to simplify it...
|
||||
static typename cast_retty<To, From>::ret_type doit(From &Val) {
|
||||
return cast_convert_val<To, SimpleFrom,
|
||||
typename simplify_type<SimpleFrom>::SimpleType>::doit(
|
||||
simplify_type<From>::getSimplifiedValue(Val));
|
||||
}
|
||||
};
|
||||
|
||||
template<class To, class FromTy> struct cast_convert_val<To,FromTy,FromTy> {
|
||||
// This _is_ a simple type, just cast it.
|
||||
static typename cast_retty<To, FromTy>::ret_type doit(const FromTy &Val) {
|
||||
typename cast_retty<To, FromTy>::ret_type Res2
|
||||
= (typename cast_retty<To, FromTy>::ret_type)const_cast<FromTy&>(Val);
|
||||
return Res2;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
// cast<X> - Return the argument parameter cast to the specified type. This
|
||||
// casting operator asserts that the type is correct, so it does not return null
|
||||
// on failure. It does not allow a null argument (use cast_or_null for that).
|
||||
// It is typically used like this:
|
||||
//
|
||||
// cast<Instruction>(myVal)->getParent()
|
||||
//
|
||||
template <class X, class Y>
|
||||
inline typename cast_retty<X, const Y>::ret_type cast(const Y &Val) {
|
||||
assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!");
|
||||
return cast_convert_val<X, const Y,
|
||||
typename simplify_type<const Y>::SimpleType>::doit(Val);
|
||||
}
|
||||
|
||||
template <class X, class Y>
|
||||
inline typename cast_retty<X, Y>::ret_type cast(Y &Val) {
|
||||
assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!");
|
||||
return cast_convert_val<X, Y,
|
||||
typename simplify_type<Y>::SimpleType>::doit(Val);
|
||||
}
|
||||
|
||||
template <class X, class Y>
|
||||
inline typename enable_if<
|
||||
is_same<Y, typename simplify_type<Y>::SimpleType>,
|
||||
typename cast_retty<X, Y*>::ret_type
|
||||
>::type cast(Y *Val) {
|
||||
assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!");
|
||||
return cast_convert_val<X, Y*,
|
||||
typename simplify_type<Y*>::SimpleType>::doit(Val);
|
||||
}
|
||||
|
||||
// cast_or_null<X> - Functionally identical to cast, except that a null value is
|
||||
// accepted.
|
||||
//
|
||||
template <class X, class Y>
|
||||
inline typename cast_retty<X, Y*>::ret_type cast_or_null(Y *Val) {
|
||||
if (Val == 0) return 0;
|
||||
assert(isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!");
|
||||
return cast<X>(Val);
|
||||
}
|
||||
|
||||
|
||||
// dyn_cast<X> - Return the argument parameter cast to the specified type. This
|
||||
// casting operator returns null if the argument is of the wrong type, so it can
|
||||
// be used to test for a type as well as cast if successful. This should be
|
||||
// used in the context of an if statement like this:
|
||||
//
|
||||
// if (const Instruction *I = dyn_cast<Instruction>(myVal)) { ... }
|
||||
//
|
||||
|
||||
template <class X, class Y>
|
||||
inline typename cast_retty<X, const Y>::ret_type dyn_cast(const Y &Val) {
|
||||
return isa<X>(Val) ? cast<X>(Val) : 0;
|
||||
}
|
||||
|
||||
template <class X, class Y>
|
||||
inline typename cast_retty<X, Y>::ret_type dyn_cast(Y &Val) {
|
||||
return isa<X>(Val) ? cast<X>(Val) : 0;
|
||||
}
|
||||
|
||||
template <class X, class Y>
|
||||
inline typename enable_if<
|
||||
is_same<Y, typename simplify_type<Y>::SimpleType>,
|
||||
typename cast_retty<X, Y*>::ret_type
|
||||
>::type dyn_cast(Y *Val) {
|
||||
return isa<X>(Val) ? cast<X>(Val) : 0;
|
||||
}
|
||||
|
||||
// dyn_cast_or_null<X> - Functionally identical to dyn_cast, except that a null
|
||||
// value is accepted.
|
||||
//
|
||||
template <class X, class Y>
|
||||
inline typename cast_retty<X, Y*>::ret_type dyn_cast_or_null(Y *Val) {
|
||||
return (Val && isa<X>(Val)) ? cast<X>(Val) : 0;
|
||||
}
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
||||
52
thirdparty/clang/include/llvm/Support/CodeGen.h
vendored
Normal file
52
thirdparty/clang/include/llvm/Support/CodeGen.h
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
//===-- llvm/Support/CodeGen.h - CodeGen Concepts ---------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file define some types which define code generation concepts. For
|
||||
// example, relocation model.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_CODEGEN_H
|
||||
#define LLVM_SUPPORT_CODEGEN_H
|
||||
|
||||
namespace llvm {
|
||||
|
||||
// Relocation model types.
|
||||
namespace Reloc {
|
||||
enum Model { Default, Static, PIC_, DynamicNoPIC };
|
||||
}
|
||||
|
||||
// Code model types.
|
||||
namespace CodeModel {
|
||||
enum Model { Default, JITDefault, Small, Kernel, Medium, Large };
|
||||
}
|
||||
|
||||
// TLS models.
|
||||
namespace TLSModel {
|
||||
enum Model {
|
||||
GeneralDynamic,
|
||||
LocalDynamic,
|
||||
InitialExec,
|
||||
LocalExec
|
||||
};
|
||||
}
|
||||
|
||||
// Code generation optimization level.
|
||||
namespace CodeGenOpt {
|
||||
enum Level {
|
||||
None, // -O0
|
||||
Less, // -O1
|
||||
Default, // -O2, -Os
|
||||
Aggressive // -O3
|
||||
};
|
||||
}
|
||||
|
||||
} // end llvm namespace
|
||||
|
||||
#endif
|
||||
1686
thirdparty/clang/include/llvm/Support/CommandLine.h
vendored
Normal file
1686
thirdparty/clang/include/llvm/Support/CommandLine.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
364
thirdparty/clang/include/llvm/Support/Compiler.h
vendored
Normal file
364
thirdparty/clang/include/llvm/Support/Compiler.h
vendored
Normal file
@@ -0,0 +1,364 @@
|
||||
//===-- llvm/Support/Compiler.h - Compiler abstraction support --*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines several macros, based on the current compiler. This allows
|
||||
// use of compiler-specific features in a way that remains portable.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_COMPILER_H
|
||||
#define LLVM_SUPPORT_COMPILER_H
|
||||
|
||||
#include "llvm/Config/llvm-config.h"
|
||||
|
||||
#ifndef __has_feature
|
||||
# define __has_feature(x) 0
|
||||
#endif
|
||||
|
||||
/// \brief Does the compiler support r-value references?
|
||||
/// This implies that <utility> provides the one-argument std::move; it
|
||||
/// does not imply the existence of any other C++ library features.
|
||||
#if (__has_feature(cxx_rvalue_references) \
|
||||
|| defined(__GXX_EXPERIMENTAL_CXX0X__) \
|
||||
|| (defined(_MSC_VER) && _MSC_VER >= 1600))
|
||||
#define LLVM_HAS_RVALUE_REFERENCES 1
|
||||
#else
|
||||
#define LLVM_HAS_RVALUE_REFERENCES 0
|
||||
#endif
|
||||
|
||||
/// \brief Does the compiler support r-value reference *this?
|
||||
///
|
||||
/// Sadly, this is separate from just r-value reference support because GCC
|
||||
/// implemented everything but this thus far. No release of GCC yet has support
|
||||
/// for this feature so it is enabled with Clang only.
|
||||
/// 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
|
||||
#else
|
||||
#define LLVM_HAS_RVALUE_REFERENCE_THIS 0
|
||||
#endif
|
||||
|
||||
/// \macro LLVM_HAS_CXX11_TYPETRAITS
|
||||
/// \brief Does the compiler have the C++11 type traits.
|
||||
///
|
||||
/// #include <type_traits>
|
||||
///
|
||||
/// * enable_if
|
||||
/// * {true,false}_type
|
||||
/// * is_constructible
|
||||
/// * etc...
|
||||
#if defined(__GXX_EXPERIMENTAL_CXX0X__) \
|
||||
|| (defined(_MSC_VER) && _MSC_VER >= 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__) \
|
||||
|| (defined(_MSC_VER) && _MSC_VER >= 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)
|
||||
# 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
|
||||
#define LLVM_LVALUE_FUNCTION &
|
||||
#else
|
||||
#define LLVM_LVALUE_FUNCTION
|
||||
#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__))
|
||||
// No version of MSVC currently supports this.
|
||||
#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(_MSC_VER) && _MSC_VER >= 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(_MSC_VER) && _MSC_VER >= 1700)
|
||||
#define LLVM_OVERRIDE override
|
||||
#else
|
||||
#define LLVM_OVERRIDE
|
||||
#endif
|
||||
|
||||
#if __has_feature(cxx_constexpr) || defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||
# define LLVM_CONSTEXPR constexpr
|
||||
#else
|
||||
# define LLVM_CONSTEXPR
|
||||
#endif
|
||||
|
||||
/// LLVM_LIBRARY_VISIBILITY - If a class marked with this attribute is linked
|
||||
/// into a shared library, then the class should be private to the library 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.
|
||||
#if (__GNUC__ >= 4) && !defined(__MINGW32__) && !defined(__CYGWIN__)
|
||||
#define LLVM_LIBRARY_VISIBILITY __attribute__ ((visibility("hidden")))
|
||||
#else
|
||||
#define LLVM_LIBRARY_VISIBILITY
|
||||
#endif
|
||||
|
||||
#if (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
|
||||
#define LLVM_ATTRIBUTE_USED __attribute__((__used__))
|
||||
#else
|
||||
#define LLVM_ATTRIBUTE_USED
|
||||
#endif
|
||||
|
||||
// Some compilers warn about unused functions. When a function is sometimes
|
||||
// used or not depending on build settings (e.g. a function only called from
|
||||
// within "assert"), this attribute can be used to suppress such warnings.
|
||||
//
|
||||
// However, it shouldn't be used for unused *variables*, as those have a much
|
||||
// more portable solution:
|
||||
// (void)unused_var_name;
|
||||
// Prefer cast-to-void wherever it is sufficient.
|
||||
#if (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
|
||||
#define LLVM_ATTRIBUTE_UNUSED __attribute__((__unused__))
|
||||
#else
|
||||
#define LLVM_ATTRIBUTE_UNUSED
|
||||
#endif
|
||||
|
||||
#if (__GNUC__ >= 4) && !defined(__MINGW32__) && !defined(__CYGWIN__)
|
||||
#define LLVM_ATTRIBUTE_WEAK __attribute__((__weak__))
|
||||
#else
|
||||
#define LLVM_ATTRIBUTE_WEAK
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__ // aka 'CONST' but following LLVM Conventions.
|
||||
#define LLVM_READNONE __attribute__((__const__))
|
||||
#else
|
||||
#define LLVM_READNONE
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__ // aka 'PURE' but following LLVM Conventions.
|
||||
#define LLVM_READONLY __attribute__((__pure__))
|
||||
#else
|
||||
#define LLVM_READONLY
|
||||
#endif
|
||||
|
||||
#if (__GNUC__ >= 4)
|
||||
#define LLVM_LIKELY(EXPR) __builtin_expect((bool)(EXPR), true)
|
||||
#define LLVM_UNLIKELY(EXPR) __builtin_expect((bool)(EXPR), false)
|
||||
#else
|
||||
#define LLVM_LIKELY(EXPR) (EXPR)
|
||||
#define LLVM_UNLIKELY(EXPR) (EXPR)
|
||||
#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,
|
||||
/// mark a method "not for inlining".
|
||||
#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
|
||||
#define LLVM_ATTRIBUTE_NOINLINE __attribute__((noinline))
|
||||
#elif defined(_MSC_VER)
|
||||
#define LLVM_ATTRIBUTE_NOINLINE __declspec(noinline)
|
||||
#else
|
||||
#define LLVM_ATTRIBUTE_NOINLINE
|
||||
#endif
|
||||
|
||||
/// LLVM_ATTRIBUTE_ALWAYS_INLINE - On compilers where we have a directive to do
|
||||
/// 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
|
||||
/// errors, just use it in GCC 4.0 and later.
|
||||
#if __GNUC__ > 3
|
||||
#define LLVM_ATTRIBUTE_ALWAYS_INLINE inline __attribute__((always_inline))
|
||||
#elif defined(_MSC_VER)
|
||||
#define LLVM_ATTRIBUTE_ALWAYS_INLINE __forceinline
|
||||
#else
|
||||
#define LLVM_ATTRIBUTE_ALWAYS_INLINE
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define LLVM_ATTRIBUTE_NORETURN __attribute__((noreturn))
|
||||
#elif defined(_MSC_VER)
|
||||
#define LLVM_ATTRIBUTE_NORETURN __declspec(noreturn)
|
||||
#else
|
||||
#define LLVM_ATTRIBUTE_NORETURN
|
||||
#endif
|
||||
|
||||
/// LLVM_EXTENSION - Support compilers where we have a keyword to suppress
|
||||
/// pedantic diagnostics.
|
||||
#ifdef __GNUC__
|
||||
#define LLVM_EXTENSION __extension__
|
||||
#else
|
||||
#define LLVM_EXTENSION
|
||||
#endif
|
||||
|
||||
// LLVM_ATTRIBUTE_DEPRECATED(decl, "message")
|
||||
#if __has_feature(attribute_deprecated_with_message)
|
||||
# define LLVM_ATTRIBUTE_DEPRECATED(decl, message) \
|
||||
decl __attribute__((deprecated(message)))
|
||||
#elif defined(__GNUC__)
|
||||
# define LLVM_ATTRIBUTE_DEPRECATED(decl, message) \
|
||||
decl __attribute__((deprecated))
|
||||
#elif defined(_MSC_VER)
|
||||
# define LLVM_ATTRIBUTE_DEPRECATED(decl, message) \
|
||||
__declspec(deprecated(message)) decl
|
||||
#else
|
||||
# define LLVM_ATTRIBUTE_DEPRECATED(decl, message) \
|
||||
decl
|
||||
#endif
|
||||
|
||||
/// LLVM_BUILTIN_UNREACHABLE - On compilers which support it, expands
|
||||
/// to an expression which states that it is undefined behavior for the
|
||||
/// compiler to reach this point. Otherwise is not defined.
|
||||
#if defined(__clang__) || (__GNUC__ > 4) \
|
||||
|| (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
|
||||
# define LLVM_BUILTIN_UNREACHABLE __builtin_unreachable()
|
||||
#elif defined(_MSC_VER)
|
||||
# define LLVM_BUILTIN_UNREACHABLE __assume(false)
|
||||
#endif
|
||||
|
||||
/// LLVM_BUILTIN_TRAP - On compilers which support it, expands to an expression
|
||||
/// which causes the program to exit abnormally.
|
||||
#if defined(__clang__) || (__GNUC__ > 4) \
|
||||
|| (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
|
||||
# define LLVM_BUILTIN_TRAP __builtin_trap()
|
||||
#else
|
||||
# define LLVM_BUILTIN_TRAP *(volatile int*)0x11 = 0
|
||||
#endif
|
||||
|
||||
/// \macro LLVM_ASSUME_ALIGNED
|
||||
/// \brief Returns a pointer with an assumed alignment.
|
||||
#if !defined(__clang__) && ((__GNUC__ > 4) \
|
||||
|| (__GNUC__ == 4 && __GNUC_MINOR__ >= 7))
|
||||
// FIXME: Enable on clang when it supports it.
|
||||
# define LLVM_ASSUME_ALIGNED(p, a) __builtin_assume_aligned(p, a)
|
||||
#elif defined(LLVM_BUILTIN_UNREACHABLE)
|
||||
# define LLVM_ASSUME_ALIGNED(p, a) \
|
||||
(((uintptr_t(p) % (a)) == 0) ? (p) : (LLVM_BUILTIN_UNREACHABLE, (p)))
|
||||
#else
|
||||
# define LLVM_ASSUME_ALIGNED(p, a) (p)
|
||||
#endif
|
||||
|
||||
/// \macro LLVM_FUNCTION_NAME
|
||||
/// \brief Expands to __func__ on compilers which support it. Otherwise,
|
||||
/// expands to a compiler-dependent replacement.
|
||||
#if defined(_MSC_VER)
|
||||
# define LLVM_FUNCTION_NAME __FUNCTION__
|
||||
#else
|
||||
# define LLVM_FUNCTION_NAME __func__
|
||||
#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
|
||||
/// \brief Whether LLVM itself is built with MemorySanitizer instrumentation.
|
||||
#if __has_feature(memory_sanitizer)
|
||||
# define LLVM_MEMORY_SANITIZER_BUILD 1
|
||||
#else
|
||||
# define LLVM_MEMORY_SANITIZER_BUILD 0
|
||||
#endif
|
||||
|
||||
/// \macro LLVM_ADDRESS_SANITIZER_BUILD
|
||||
/// \brief Whether LLVM itself is built with AddressSanitizer instrumentation.
|
||||
#if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
|
||||
# define LLVM_ADDRESS_SANITIZER_BUILD 1
|
||||
#else
|
||||
# define LLVM_ADDRESS_SANITIZER_BUILD 0
|
||||
#endif
|
||||
|
||||
/// \macro LLVM_IS_UNALIGNED_ACCESS_FAST
|
||||
/// \brief Is unaligned memory access fast on the host machine.
|
||||
///
|
||||
/// Don't specialize on alignment for platforms where unaligned memory accesses
|
||||
/// 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
|
||||
# define LLVM_IS_UNALIGNED_ACCESS_FAST 0
|
||||
#endif
|
||||
|
||||
/// \macro LLVM_EXPLICIT
|
||||
/// \brief Expands to explicit on compilers which support explicit conversion
|
||||
/// operators. Otherwise expands to nothing.
|
||||
#if (__has_feature(cxx_explicit_conversions) \
|
||||
|| defined(__GXX_EXPERIMENTAL_CXX0X__))
|
||||
#define LLVM_EXPLICIT explicit
|
||||
#else
|
||||
#define LLVM_EXPLICIT
|
||||
#endif
|
||||
|
||||
/// \macro LLVM_STATIC_ASSERT
|
||||
/// \brief Expands to C/C++'s static_assert on compilers which support it.
|
||||
#if __has_feature(cxx_static_assert)
|
||||
# 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)
|
||||
#else
|
||||
# define LLVM_STATIC_ASSERT(expr, msg)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
238
thirdparty/clang/include/llvm/Support/ConstantFolder.h
vendored
Normal file
238
thirdparty/clang/include/llvm/Support/ConstantFolder.h
vendored
Normal file
@@ -0,0 +1,238 @@
|
||||
//===-- llvm/Support/ConstantFolder.h - Constant folding helper -*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the ConstantFolder class, a helper for IRBuilder.
|
||||
// It provides IRBuilder with a set of methods for creating constants
|
||||
// with minimal folding. For general constant creation and folding,
|
||||
// use ConstantExpr and the routines in llvm/Analysis/ConstantFolding.h.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_CONSTANTFOLDER_H
|
||||
#define LLVM_SUPPORT_CONSTANTFOLDER_H
|
||||
|
||||
#include "llvm/IR/Constants.h"
|
||||
#include "llvm/IR/InstrTypes.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
/// ConstantFolder - Create constants with minimum, target independent, folding.
|
||||
class ConstantFolder {
|
||||
public:
|
||||
explicit ConstantFolder() {}
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Binary Operators
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
||||
Constant *CreateAdd(Constant *LHS, Constant *RHS,
|
||||
bool HasNUW = false, bool HasNSW = false) const {
|
||||
return ConstantExpr::getAdd(LHS, RHS, HasNUW, HasNSW);
|
||||
}
|
||||
Constant *CreateFAdd(Constant *LHS, Constant *RHS) const {
|
||||
return ConstantExpr::getFAdd(LHS, RHS);
|
||||
}
|
||||
Constant *CreateSub(Constant *LHS, Constant *RHS,
|
||||
bool HasNUW = false, bool HasNSW = false) const {
|
||||
return ConstantExpr::getSub(LHS, RHS, HasNUW, HasNSW);
|
||||
}
|
||||
Constant *CreateFSub(Constant *LHS, Constant *RHS) const {
|
||||
return ConstantExpr::getFSub(LHS, RHS);
|
||||
}
|
||||
Constant *CreateMul(Constant *LHS, Constant *RHS,
|
||||
bool HasNUW = false, bool HasNSW = false) const {
|
||||
return ConstantExpr::getMul(LHS, RHS, HasNUW, HasNSW);
|
||||
}
|
||||
Constant *CreateFMul(Constant *LHS, Constant *RHS) const {
|
||||
return ConstantExpr::getFMul(LHS, RHS);
|
||||
}
|
||||
Constant *CreateUDiv(Constant *LHS, Constant *RHS,
|
||||
bool isExact = false) const {
|
||||
return ConstantExpr::getUDiv(LHS, RHS, isExact);
|
||||
}
|
||||
Constant *CreateSDiv(Constant *LHS, Constant *RHS,
|
||||
bool isExact = false) const {
|
||||
return ConstantExpr::getSDiv(LHS, RHS, isExact);
|
||||
}
|
||||
Constant *CreateFDiv(Constant *LHS, Constant *RHS) const {
|
||||
return ConstantExpr::getFDiv(LHS, RHS);
|
||||
}
|
||||
Constant *CreateURem(Constant *LHS, Constant *RHS) const {
|
||||
return ConstantExpr::getURem(LHS, RHS);
|
||||
}
|
||||
Constant *CreateSRem(Constant *LHS, Constant *RHS) const {
|
||||
return ConstantExpr::getSRem(LHS, RHS);
|
||||
}
|
||||
Constant *CreateFRem(Constant *LHS, Constant *RHS) const {
|
||||
return ConstantExpr::getFRem(LHS, RHS);
|
||||
}
|
||||
Constant *CreateShl(Constant *LHS, Constant *RHS,
|
||||
bool HasNUW = false, bool HasNSW = false) const {
|
||||
return ConstantExpr::getShl(LHS, RHS, HasNUW, HasNSW);
|
||||
}
|
||||
Constant *CreateLShr(Constant *LHS, Constant *RHS,
|
||||
bool isExact = false) const {
|
||||
return ConstantExpr::getLShr(LHS, RHS, isExact);
|
||||
}
|
||||
Constant *CreateAShr(Constant *LHS, Constant *RHS,
|
||||
bool isExact = false) const {
|
||||
return ConstantExpr::getAShr(LHS, RHS, isExact);
|
||||
}
|
||||
Constant *CreateAnd(Constant *LHS, Constant *RHS) const {
|
||||
return ConstantExpr::getAnd(LHS, RHS);
|
||||
}
|
||||
Constant *CreateOr(Constant *LHS, Constant *RHS) const {
|
||||
return ConstantExpr::getOr(LHS, RHS);
|
||||
}
|
||||
Constant *CreateXor(Constant *LHS, Constant *RHS) const {
|
||||
return ConstantExpr::getXor(LHS, RHS);
|
||||
}
|
||||
|
||||
Constant *CreateBinOp(Instruction::BinaryOps Opc,
|
||||
Constant *LHS, Constant *RHS) const {
|
||||
return ConstantExpr::get(Opc, LHS, RHS);
|
||||
}
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Unary Operators
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
||||
Constant *CreateNeg(Constant *C,
|
||||
bool HasNUW = false, bool HasNSW = false) const {
|
||||
return ConstantExpr::getNeg(C, HasNUW, HasNSW);
|
||||
}
|
||||
Constant *CreateFNeg(Constant *C) const {
|
||||
return ConstantExpr::getFNeg(C);
|
||||
}
|
||||
Constant *CreateNot(Constant *C) const {
|
||||
return ConstantExpr::getNot(C);
|
||||
}
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Memory Instructions
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
||||
Constant *CreateGetElementPtr(Constant *C,
|
||||
ArrayRef<Constant *> IdxList) const {
|
||||
return ConstantExpr::getGetElementPtr(C, IdxList);
|
||||
}
|
||||
Constant *CreateGetElementPtr(Constant *C, Constant *Idx) const {
|
||||
// This form of the function only exists to avoid ambiguous overload
|
||||
// warnings about whether to convert Idx to ArrayRef<Constant *> or
|
||||
// ArrayRef<Value *>.
|
||||
return ConstantExpr::getGetElementPtr(C, Idx);
|
||||
}
|
||||
Constant *CreateGetElementPtr(Constant *C,
|
||||
ArrayRef<Value *> IdxList) const {
|
||||
return ConstantExpr::getGetElementPtr(C, IdxList);
|
||||
}
|
||||
|
||||
Constant *CreateInBoundsGetElementPtr(Constant *C,
|
||||
ArrayRef<Constant *> IdxList) const {
|
||||
return ConstantExpr::getInBoundsGetElementPtr(C, IdxList);
|
||||
}
|
||||
Constant *CreateInBoundsGetElementPtr(Constant *C, Constant *Idx) const {
|
||||
// This form of the function only exists to avoid ambiguous overload
|
||||
// warnings about whether to convert Idx to ArrayRef<Constant *> or
|
||||
// ArrayRef<Value *>.
|
||||
return ConstantExpr::getInBoundsGetElementPtr(C, Idx);
|
||||
}
|
||||
Constant *CreateInBoundsGetElementPtr(Constant *C,
|
||||
ArrayRef<Value *> IdxList) const {
|
||||
return ConstantExpr::getInBoundsGetElementPtr(C, IdxList);
|
||||
}
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Cast/Conversion Operators
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
||||
Constant *CreateCast(Instruction::CastOps Op, Constant *C,
|
||||
Type *DestTy) const {
|
||||
return ConstantExpr::getCast(Op, C, DestTy);
|
||||
}
|
||||
Constant *CreatePointerCast(Constant *C, Type *DestTy) const {
|
||||
return ConstantExpr::getPointerCast(C, DestTy);
|
||||
}
|
||||
Constant *CreateIntCast(Constant *C, Type *DestTy,
|
||||
bool isSigned) const {
|
||||
return ConstantExpr::getIntegerCast(C, DestTy, isSigned);
|
||||
}
|
||||
Constant *CreateFPCast(Constant *C, Type *DestTy) const {
|
||||
return ConstantExpr::getFPCast(C, DestTy);
|
||||
}
|
||||
|
||||
Constant *CreateBitCast(Constant *C, Type *DestTy) const {
|
||||
return CreateCast(Instruction::BitCast, C, DestTy);
|
||||
}
|
||||
Constant *CreateIntToPtr(Constant *C, Type *DestTy) const {
|
||||
return CreateCast(Instruction::IntToPtr, C, DestTy);
|
||||
}
|
||||
Constant *CreatePtrToInt(Constant *C, Type *DestTy) const {
|
||||
return CreateCast(Instruction::PtrToInt, C, DestTy);
|
||||
}
|
||||
Constant *CreateZExtOrBitCast(Constant *C, Type *DestTy) const {
|
||||
return ConstantExpr::getZExtOrBitCast(C, DestTy);
|
||||
}
|
||||
Constant *CreateSExtOrBitCast(Constant *C, Type *DestTy) const {
|
||||
return ConstantExpr::getSExtOrBitCast(C, DestTy);
|
||||
}
|
||||
|
||||
Constant *CreateTruncOrBitCast(Constant *C, Type *DestTy) const {
|
||||
return ConstantExpr::getTruncOrBitCast(C, DestTy);
|
||||
}
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Compare Instructions
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
||||
Constant *CreateICmp(CmpInst::Predicate P, Constant *LHS,
|
||||
Constant *RHS) const {
|
||||
return ConstantExpr::getCompare(P, LHS, RHS);
|
||||
}
|
||||
Constant *CreateFCmp(CmpInst::Predicate P, Constant *LHS,
|
||||
Constant *RHS) const {
|
||||
return ConstantExpr::getCompare(P, LHS, RHS);
|
||||
}
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Other Instructions
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
||||
Constant *CreateSelect(Constant *C, Constant *True, Constant *False) const {
|
||||
return ConstantExpr::getSelect(C, True, False);
|
||||
}
|
||||
|
||||
Constant *CreateExtractElement(Constant *Vec, Constant *Idx) const {
|
||||
return ConstantExpr::getExtractElement(Vec, Idx);
|
||||
}
|
||||
|
||||
Constant *CreateInsertElement(Constant *Vec, Constant *NewElt,
|
||||
Constant *Idx) const {
|
||||
return ConstantExpr::getInsertElement(Vec, NewElt, Idx);
|
||||
}
|
||||
|
||||
Constant *CreateShuffleVector(Constant *V1, Constant *V2,
|
||||
Constant *Mask) const {
|
||||
return ConstantExpr::getShuffleVector(V1, V2, Mask);
|
||||
}
|
||||
|
||||
Constant *CreateExtractValue(Constant *Agg,
|
||||
ArrayRef<unsigned> IdxList) const {
|
||||
return ConstantExpr::getExtractValue(Agg, IdxList);
|
||||
}
|
||||
|
||||
Constant *CreateInsertValue(Constant *Agg, Constant *Val,
|
||||
ArrayRef<unsigned> IdxList) const {
|
||||
return ConstantExpr::getInsertValue(Agg, Val, IdxList);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
269
thirdparty/clang/include/llvm/Support/ConstantRange.h
vendored
Normal file
269
thirdparty/clang/include/llvm/Support/ConstantRange.h
vendored
Normal file
@@ -0,0 +1,269 @@
|
||||
//===-- llvm/Support/ConstantRange.h - Represent a range --------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Represent a range of possible values that may occur when the program is run
|
||||
// for an integral value. This keeps track of a lower and upper bound for the
|
||||
// constant, which MAY wrap around the end of the numeric range. To do this, it
|
||||
// keeps track of a [lower, upper) bound, which specifies an interval just like
|
||||
// STL iterators. When used with boolean values, the following are important
|
||||
// ranges: :
|
||||
//
|
||||
// [F, F) = {} = Empty set
|
||||
// [T, F) = {T}
|
||||
// [F, T) = {F}
|
||||
// [T, T) = {F, T} = Full set
|
||||
//
|
||||
// The other integral ranges use min/max values for special range values. For
|
||||
// example, for 8-bit types, it uses:
|
||||
// [0, 0) = {} = Empty set
|
||||
// [255, 255) = {0..255} = Full Set
|
||||
//
|
||||
// Note that ConstantRange can be used to represent either signed or
|
||||
// unsigned ranges.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_CONSTANTRANGE_H
|
||||
#define LLVM_SUPPORT_CONSTANTRANGE_H
|
||||
|
||||
#include "llvm/ADT/APInt.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
/// ConstantRange - This class represents an range of values.
|
||||
///
|
||||
class ConstantRange {
|
||||
APInt Lower, Upper;
|
||||
|
||||
public:
|
||||
/// Initialize a full (the default) or empty set for the specified bit width.
|
||||
///
|
||||
explicit ConstantRange(uint32_t BitWidth, bool isFullSet = true);
|
||||
|
||||
/// Initialize a range to hold the single specified value.
|
||||
///
|
||||
ConstantRange(const APInt &Value);
|
||||
|
||||
/// @brief Initialize a range of values explicitly. This will assert out if
|
||||
/// Lower==Upper and Lower != Min or Max value for its type. It will also
|
||||
/// assert out if the two APInt's are not the same bit width.
|
||||
ConstantRange(const APInt &Lower, const APInt &Upper);
|
||||
|
||||
/// makeICmpRegion - Produce the smallest range that contains all values that
|
||||
/// might satisfy the comparison specified by Pred when compared to any value
|
||||
/// contained within Other.
|
||||
///
|
||||
/// Solves for range X in 'for all x in X, there exists a y in Y such that
|
||||
/// icmp op x, y is true'. Every value that might make the comparison true
|
||||
/// is included in the resulting range.
|
||||
static ConstantRange makeICmpRegion(unsigned Pred,
|
||||
const ConstantRange &Other);
|
||||
|
||||
/// getLower - Return the lower value for this range...
|
||||
///
|
||||
const APInt &getLower() const { return Lower; }
|
||||
|
||||
/// getUpper - Return the upper value for this range...
|
||||
///
|
||||
const APInt &getUpper() const { return Upper; }
|
||||
|
||||
/// getBitWidth - get the bit width of this ConstantRange
|
||||
///
|
||||
uint32_t getBitWidth() const { return Lower.getBitWidth(); }
|
||||
|
||||
/// isFullSet - Return true if this set contains all of the elements possible
|
||||
/// for this data-type
|
||||
///
|
||||
bool isFullSet() const;
|
||||
|
||||
/// isEmptySet - Return true if this set contains no members.
|
||||
///
|
||||
bool isEmptySet() const;
|
||||
|
||||
/// isWrappedSet - Return true if this set wraps around the top of the range,
|
||||
/// for example: [100, 8)
|
||||
///
|
||||
bool isWrappedSet() const;
|
||||
|
||||
/// isSignWrappedSet - Return true if this set wraps around the INT_MIN of
|
||||
/// its bitwidth, for example: i8 [120, 140).
|
||||
///
|
||||
bool isSignWrappedSet() const;
|
||||
|
||||
/// contains - Return true if the specified value is in the set.
|
||||
///
|
||||
bool contains(const APInt &Val) const;
|
||||
|
||||
/// contains - Return true if the other range is a subset of this one.
|
||||
///
|
||||
bool contains(const ConstantRange &CR) const;
|
||||
|
||||
/// getSingleElement - If this set contains a single element, return it,
|
||||
/// otherwise return null.
|
||||
///
|
||||
const APInt *getSingleElement() const {
|
||||
if (Upper == Lower + 1)
|
||||
return &Lower;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// isSingleElement - Return true if this set contains exactly one member.
|
||||
///
|
||||
bool isSingleElement() const { return getSingleElement() != 0; }
|
||||
|
||||
/// getSetSize - Return the number of elements in this set.
|
||||
///
|
||||
APInt getSetSize() const;
|
||||
|
||||
/// getUnsignedMax - Return the largest unsigned value contained in the
|
||||
/// ConstantRange.
|
||||
///
|
||||
APInt getUnsignedMax() const;
|
||||
|
||||
/// getUnsignedMin - Return the smallest unsigned value contained in the
|
||||
/// ConstantRange.
|
||||
///
|
||||
APInt getUnsignedMin() const;
|
||||
|
||||
/// getSignedMax - Return the largest signed value contained in the
|
||||
/// ConstantRange.
|
||||
///
|
||||
APInt getSignedMax() const;
|
||||
|
||||
/// getSignedMin - Return the smallest signed value contained in the
|
||||
/// ConstantRange.
|
||||
///
|
||||
APInt getSignedMin() const;
|
||||
|
||||
/// operator== - Return true if this range is equal to another range.
|
||||
///
|
||||
bool operator==(const ConstantRange &CR) const {
|
||||
return Lower == CR.Lower && Upper == CR.Upper;
|
||||
}
|
||||
bool operator!=(const ConstantRange &CR) const {
|
||||
return !operator==(CR);
|
||||
}
|
||||
|
||||
/// subtract - Subtract the specified constant from the endpoints of this
|
||||
/// constant range.
|
||||
ConstantRange subtract(const APInt &CI) const;
|
||||
|
||||
/// \brief Subtract the specified range from this range (aka relative
|
||||
/// complement of the sets).
|
||||
ConstantRange difference(const ConstantRange &CR) const;
|
||||
|
||||
/// intersectWith - Return the range that results from the intersection of
|
||||
/// this range with another range. The resultant range is guaranteed to
|
||||
/// include all elements contained in both input ranges, and to have the
|
||||
/// smallest possible set size that does so. Because there may be two
|
||||
/// intersections with the same set size, A.intersectWith(B) might not
|
||||
/// be equal to B.intersectWith(A).
|
||||
///
|
||||
ConstantRange intersectWith(const ConstantRange &CR) const;
|
||||
|
||||
/// unionWith - Return the range that results from the union of this range
|
||||
/// with another range. The resultant range is guaranteed to include the
|
||||
/// elements of both sets, but may contain more. For example, [3, 9) union
|
||||
/// [12,15) is [3, 15), which includes 9, 10, and 11, which were not included
|
||||
/// in either set before.
|
||||
///
|
||||
ConstantRange unionWith(const ConstantRange &CR) const;
|
||||
|
||||
/// zeroExtend - Return a new range in the specified integer type, which must
|
||||
/// be strictly larger than the current type. The returned range will
|
||||
/// correspond to the possible range of values if the source range had been
|
||||
/// zero extended to BitWidth.
|
||||
ConstantRange zeroExtend(uint32_t BitWidth) const;
|
||||
|
||||
/// signExtend - Return a new range in the specified integer type, which must
|
||||
/// be strictly larger than the current type. The returned range will
|
||||
/// correspond to the possible range of values if the source range had been
|
||||
/// sign extended to BitWidth.
|
||||
ConstantRange signExtend(uint32_t BitWidth) const;
|
||||
|
||||
/// truncate - Return a new range in the specified integer type, which must be
|
||||
/// strictly smaller than the current type. The returned range will
|
||||
/// correspond to the possible range of values if the source range had been
|
||||
/// truncated to the specified type.
|
||||
ConstantRange truncate(uint32_t BitWidth) const;
|
||||
|
||||
/// zextOrTrunc - make this range have the bit width given by \p BitWidth. The
|
||||
/// value is zero extended, truncated, or left alone to make it that width.
|
||||
ConstantRange zextOrTrunc(uint32_t BitWidth) const;
|
||||
|
||||
/// sextOrTrunc - make this range have the bit width given by \p BitWidth. The
|
||||
/// value is sign extended, truncated, or left alone to make it that width.
|
||||
ConstantRange sextOrTrunc(uint32_t BitWidth) const;
|
||||
|
||||
/// add - Return a new range representing the possible values resulting
|
||||
/// from an addition of a value in this range and a value in \p Other.
|
||||
ConstantRange add(const ConstantRange &Other) const;
|
||||
|
||||
/// sub - Return a new range representing the possible values resulting
|
||||
/// from a subtraction of a value in this range and a value in \p Other.
|
||||
ConstantRange sub(const ConstantRange &Other) const;
|
||||
|
||||
/// multiply - Return a new range representing the possible values resulting
|
||||
/// from a multiplication of a value in this range and a value in \p Other.
|
||||
/// TODO: This isn't fully implemented yet.
|
||||
ConstantRange multiply(const ConstantRange &Other) const;
|
||||
|
||||
/// smax - Return a new range representing the possible values resulting
|
||||
/// from a signed maximum of a value in this range and a value in \p Other.
|
||||
ConstantRange smax(const ConstantRange &Other) const;
|
||||
|
||||
/// umax - Return a new range representing the possible values resulting
|
||||
/// from an unsigned maximum of a value in this range and a value in \p Other.
|
||||
ConstantRange umax(const ConstantRange &Other) const;
|
||||
|
||||
/// udiv - Return a new range representing the possible values resulting
|
||||
/// from an unsigned division of a value in this range and a value in
|
||||
/// \p Other.
|
||||
ConstantRange udiv(const ConstantRange &Other) const;
|
||||
|
||||
/// binaryAnd - return a new range representing the possible values resulting
|
||||
/// from a binary-and of a value in this range by a value in \p Other.
|
||||
ConstantRange binaryAnd(const ConstantRange &Other) const;
|
||||
|
||||
/// binaryOr - return a new range representing the possible values resulting
|
||||
/// from a binary-or of a value in this range by a value in \p Other.
|
||||
ConstantRange binaryOr(const ConstantRange &Other) const;
|
||||
|
||||
/// shl - Return a new range representing the possible values resulting
|
||||
/// from a left shift of a value in this range by a value in \p Other.
|
||||
/// TODO: This isn't fully implemented yet.
|
||||
ConstantRange shl(const ConstantRange &Other) const;
|
||||
|
||||
/// lshr - Return a new range representing the possible values resulting
|
||||
/// from a logical right shift of a value in this range and a value in
|
||||
/// \p Other.
|
||||
ConstantRange lshr(const ConstantRange &Other) const;
|
||||
|
||||
/// inverse - Return a new range that is the logical not of the current set.
|
||||
///
|
||||
ConstantRange inverse() const;
|
||||
|
||||
/// print - Print out the bounds to a stream...
|
||||
///
|
||||
void print(raw_ostream &OS) const;
|
||||
|
||||
/// dump - Allow printing from a debugger easily...
|
||||
///
|
||||
void dump() const;
|
||||
};
|
||||
|
||||
inline raw_ostream &operator<<(raw_ostream &OS, const ConstantRange &CR) {
|
||||
CR.print(OS);
|
||||
return OS;
|
||||
}
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
||||
228
thirdparty/clang/include/llvm/Support/ConvertUTF.h
vendored
Normal file
228
thirdparty/clang/include/llvm/Support/ConvertUTF.h
vendored
Normal file
@@ -0,0 +1,228 @@
|
||||
/*===--- ConvertUTF.h - Universal Character Names conversions ---------------===
|
||||
*
|
||||
* The LLVM Compiler Infrastructure
|
||||
*
|
||||
* This file is distributed under the University of Illinois Open Source
|
||||
* License. See LICENSE.TXT for details.
|
||||
*
|
||||
*==------------------------------------------------------------------------==*/
|
||||
/*
|
||||
* Copyright 2001-2004 Unicode, Inc.
|
||||
*
|
||||
* Disclaimer
|
||||
*
|
||||
* This source code is provided as is by Unicode, Inc. No claims are
|
||||
* made as to fitness for any particular purpose. No warranties of any
|
||||
* kind are expressed or implied. The recipient agrees to determine
|
||||
* applicability of information provided. If this file has been
|
||||
* purchased on magnetic or optical media from Unicode, Inc., the
|
||||
* sole remedy for any claim will be exchange of defective media
|
||||
* within 90 days of receipt.
|
||||
*
|
||||
* Limitations on Rights to Redistribute This Code
|
||||
*
|
||||
* Unicode, Inc. hereby grants the right to freely use the information
|
||||
* supplied in this file in the creation of products supporting the
|
||||
* Unicode Standard, and to make copies of this file in any form
|
||||
* for internal or external distribution as long as this notice
|
||||
* remains attached.
|
||||
*/
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
|
||||
Conversions between UTF32, UTF-16, and UTF-8. Header file.
|
||||
|
||||
Several funtions are included here, forming a complete set of
|
||||
conversions between the three formats. UTF-7 is not included
|
||||
here, but is handled in a separate source file.
|
||||
|
||||
Each of these routines takes pointers to input buffers and output
|
||||
buffers. The input buffers are const.
|
||||
|
||||
Each routine converts the text between *sourceStart and sourceEnd,
|
||||
putting the result into the buffer between *targetStart and
|
||||
targetEnd. Note: the end pointers are *after* the last item: e.g.
|
||||
*(sourceEnd - 1) is the last item.
|
||||
|
||||
The return result indicates whether the conversion was successful,
|
||||
and if not, whether the problem was in the source or target buffers.
|
||||
(Only the first encountered problem is indicated.)
|
||||
|
||||
After the conversion, *sourceStart and *targetStart are both
|
||||
updated to point to the end of last text successfully converted in
|
||||
the respective buffers.
|
||||
|
||||
Input parameters:
|
||||
sourceStart - pointer to a pointer to the source buffer.
|
||||
The contents of this are modified on return so that
|
||||
it points at the next thing to be converted.
|
||||
targetStart - similarly, pointer to pointer to the target buffer.
|
||||
sourceEnd, targetEnd - respectively pointers to the ends of the
|
||||
two buffers, for overflow checking only.
|
||||
|
||||
These conversion functions take a ConversionFlags argument. When this
|
||||
flag is set to strict, both irregular sequences and isolated surrogates
|
||||
will cause an error. When the flag is set to lenient, both irregular
|
||||
sequences and isolated surrogates are converted.
|
||||
|
||||
Whether the flag is strict or lenient, all illegal sequences will cause
|
||||
an error return. This includes sequences such as: <F4 90 80 80>, <C0 80>,
|
||||
or <A0> in UTF-8, and values above 0x10FFFF in UTF-32. Conformant code
|
||||
must check for illegal sequences.
|
||||
|
||||
When the flag is set to lenient, characters over 0x10FFFF are converted
|
||||
to the replacement character; otherwise (when the flag is set to strict)
|
||||
they constitute an error.
|
||||
|
||||
Output parameters:
|
||||
The value "sourceIllegal" is returned from some routines if the input
|
||||
sequence is malformed. When "sourceIllegal" is returned, the source
|
||||
value will point to the illegal value that caused the problem. E.g.,
|
||||
in UTF-8 when a sequence is malformed, it points to the start of the
|
||||
malformed sequence.
|
||||
|
||||
Author: Mark E. Davis, 1994.
|
||||
Rev History: Rick McGowan, fixes & updates May 2001.
|
||||
Fixes & updates, Sept 2001.
|
||||
|
||||
------------------------------------------------------------------------ */
|
||||
|
||||
#ifndef CLANG_BASIC_CONVERTUTF_H
|
||||
#define CLANG_BASIC_CONVERTUTF_H
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
The following 4 definitions are compiler-specific.
|
||||
The C standard does not guarantee that wchar_t has at least
|
||||
16 bits, so wchar_t is no less portable than unsigned short!
|
||||
All should be unsigned values to avoid sign extension during
|
||||
bit mask & shift operations.
|
||||
------------------------------------------------------------------------ */
|
||||
|
||||
typedef unsigned int UTF32; /* at least 32 bits */
|
||||
typedef unsigned short UTF16; /* at least 16 bits */
|
||||
typedef unsigned char UTF8; /* typically 8 bits */
|
||||
typedef unsigned char Boolean; /* 0 or 1 */
|
||||
|
||||
/* Some fundamental constants */
|
||||
#define UNI_REPLACEMENT_CHAR (UTF32)0x0000FFFD
|
||||
#define UNI_MAX_BMP (UTF32)0x0000FFFF
|
||||
#define UNI_MAX_UTF16 (UTF32)0x0010FFFF
|
||||
#define UNI_MAX_UTF32 (UTF32)0x7FFFFFFF
|
||||
#define UNI_MAX_LEGAL_UTF32 (UTF32)0x0010FFFF
|
||||
|
||||
#define UNI_MAX_UTF8_BYTES_PER_CODE_POINT 4
|
||||
|
||||
typedef enum {
|
||||
conversionOK, /* conversion successful */
|
||||
sourceExhausted, /* partial character in source, but hit end */
|
||||
targetExhausted, /* insuff. room in target for conversion */
|
||||
sourceIllegal /* source sequence is illegal/malformed */
|
||||
} ConversionResult;
|
||||
|
||||
typedef enum {
|
||||
strictConversion = 0,
|
||||
lenientConversion
|
||||
} ConversionFlags;
|
||||
|
||||
/* This is for C++ and does no harm in C */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
ConversionResult ConvertUTF8toUTF16 (
|
||||
const UTF8** sourceStart, const UTF8* sourceEnd,
|
||||
UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags);
|
||||
|
||||
ConversionResult ConvertUTF8toUTF32 (
|
||||
const UTF8** sourceStart, const UTF8* sourceEnd,
|
||||
UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags);
|
||||
|
||||
ConversionResult ConvertUTF16toUTF8 (
|
||||
const UTF16** sourceStart, const UTF16* sourceEnd,
|
||||
UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags);
|
||||
|
||||
ConversionResult ConvertUTF32toUTF8 (
|
||||
const UTF32** sourceStart, const UTF32* sourceEnd,
|
||||
UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags);
|
||||
|
||||
ConversionResult ConvertUTF16toUTF32 (
|
||||
const UTF16** sourceStart, const UTF16* sourceEnd,
|
||||
UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags);
|
||||
|
||||
ConversionResult ConvertUTF32toUTF16 (
|
||||
const UTF32** sourceStart, const UTF32* sourceEnd,
|
||||
UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags);
|
||||
|
||||
Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd);
|
||||
|
||||
Boolean isLegalUTF8String(const UTF8 **source, const UTF8 *sourceEnd);
|
||||
|
||||
unsigned getNumBytesForUTF8(UTF8 firstByte);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
/* Below are LLVM-specific wrappers of the functions above. */
|
||||
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
/**
|
||||
* Convert an UTF8 StringRef to UTF8, UTF16, or UTF32 depending on
|
||||
* WideCharWidth. The converted data is written to ResultPtr, which needs to
|
||||
* point to at least WideCharWidth * (Source.Size() + 1) bytes. On success,
|
||||
* ResultPtr will point one after the end of the copied string. On failure,
|
||||
* ResultPtr will not be changed, and ErrorPtr will be set to the location of
|
||||
* the first character which could not be converted.
|
||||
* \return true on success.
|
||||
*/
|
||||
bool ConvertUTF8toWide(unsigned WideCharWidth, llvm::StringRef Source,
|
||||
char *&ResultPtr, const UTF8 *&ErrorPtr);
|
||||
|
||||
/**
|
||||
* Convert an Unicode code point to UTF8 sequence.
|
||||
*
|
||||
* \param Source a Unicode code point.
|
||||
* \param [in,out] ResultPtr pointer to the output buffer, needs to be at least
|
||||
* \c UNI_MAX_UTF8_BYTES_PER_CODE_POINT bytes. On success \c ResultPtr is
|
||||
* updated one past end of the converted sequence.
|
||||
*
|
||||
* \returns true on success.
|
||||
*/
|
||||
bool ConvertCodePointToUTF8(unsigned Source, char *&ResultPtr);
|
||||
|
||||
/**
|
||||
* Convert the first UTF8 sequence in the given source buffer to a UTF32
|
||||
* code point.
|
||||
*
|
||||
* \param [in,out] source A pointer to the source buffer. If the conversion
|
||||
* succeeds, this pointer will be updated to point to the byte just past the
|
||||
* end of the converted sequence.
|
||||
* \param sourceEnd A pointer just past the end of the source buffer.
|
||||
* \param [out] target The converted code
|
||||
* \param flags Whether the conversion is strict or lenient.
|
||||
*
|
||||
* \returns conversionOK on success
|
||||
*
|
||||
* \sa ConvertUTF8toUTF32
|
||||
*/
|
||||
static inline ConversionResult convertUTF8Sequence(const UTF8 **source,
|
||||
const UTF8 *sourceEnd,
|
||||
UTF32 *target,
|
||||
ConversionFlags flags) {
|
||||
if (*source == sourceEnd)
|
||||
return sourceExhausted;
|
||||
unsigned size = getNumBytesForUTF8(**source);
|
||||
if ((ptrdiff_t)size > sourceEnd - *source)
|
||||
return sourceExhausted;
|
||||
return ConvertUTF8toUTF32(source, *source + size, &target, target + 1, flags);
|
||||
}
|
||||
} /* end namespace llvm */
|
||||
|
||||
#endif
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
#endif
|
||||
200
thirdparty/clang/include/llvm/Support/CrashRecoveryContext.h
vendored
Normal file
200
thirdparty/clang/include/llvm/Support/CrashRecoveryContext.h
vendored
Normal file
@@ -0,0 +1,200 @@
|
||||
//===--- CrashRecoveryContext.h - Crash Recovery ----------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_CRASHRECOVERYCONTEXT_H
|
||||
#define LLVM_SUPPORT_CRASHRECOVERYCONTEXT_H
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace llvm {
|
||||
class StringRef;
|
||||
|
||||
class CrashRecoveryContextCleanup;
|
||||
|
||||
/// \brief Crash recovery helper object.
|
||||
///
|
||||
/// This class implements support for running operations in a safe context so
|
||||
/// that crashes (memory errors, stack overflow, assertion violations) can be
|
||||
/// detected and control restored to the crashing thread. Crash detection is
|
||||
/// purely "best effort", the exact set of failures which can be recovered from
|
||||
/// is platform dependent.
|
||||
///
|
||||
/// Clients make use of this code by first calling
|
||||
/// CrashRecoveryContext::Enable(), and then executing unsafe operations via a
|
||||
/// CrashRecoveryContext object. For example:
|
||||
///
|
||||
/// void actual_work(void *);
|
||||
///
|
||||
/// void foo() {
|
||||
/// CrashRecoveryContext CRC;
|
||||
///
|
||||
/// if (!CRC.RunSafely(actual_work, 0)) {
|
||||
/// ... a crash was detected, report error to user ...
|
||||
/// }
|
||||
///
|
||||
/// ... no crash was detected ...
|
||||
/// }
|
||||
///
|
||||
/// Crash recovery contexts may not be nested.
|
||||
class CrashRecoveryContext {
|
||||
void *Impl;
|
||||
CrashRecoveryContextCleanup *head;
|
||||
|
||||
public:
|
||||
CrashRecoveryContext() : Impl(0), head(0) {}
|
||||
~CrashRecoveryContext();
|
||||
|
||||
void registerCleanup(CrashRecoveryContextCleanup *cleanup);
|
||||
void unregisterCleanup(CrashRecoveryContextCleanup *cleanup);
|
||||
|
||||
/// \brief Enable crash recovery.
|
||||
static void Enable();
|
||||
|
||||
/// \brief Disable crash recovery.
|
||||
static void Disable();
|
||||
|
||||
/// \brief Return the active context, if the code is currently executing in a
|
||||
/// thread which is in a protected context.
|
||||
static CrashRecoveryContext *GetCurrent();
|
||||
|
||||
/// \brief Return true if the current thread is recovering from a
|
||||
/// crash.
|
||||
static bool isRecoveringFromCrash();
|
||||
|
||||
/// \brief Execute the provide callback function (with the given arguments) in
|
||||
/// a protected context.
|
||||
///
|
||||
/// \return True if the function completed successfully, and false if the
|
||||
/// function crashed (or HandleCrash was called explicitly). Clients should
|
||||
/// make as little assumptions as possible about the program state when
|
||||
/// RunSafely has returned false. Clients can use getBacktrace() to retrieve
|
||||
/// the backtrace of the crash on failures.
|
||||
bool RunSafely(void (*Fn)(void*), void *UserData);
|
||||
|
||||
/// \brief Execute the provide callback function (with the given arguments) in
|
||||
/// a protected context which is run in another thread (optionally with a
|
||||
/// requested stack size).
|
||||
///
|
||||
/// See RunSafely() and llvm_execute_on_thread().
|
||||
bool RunSafelyOnThread(void (*Fn)(void*), void *UserData,
|
||||
unsigned RequestedStackSize = 0);
|
||||
|
||||
/// \brief Explicitly trigger a crash recovery in the current process, and
|
||||
/// return failure from RunSafely(). This function does not return.
|
||||
void HandleCrash();
|
||||
|
||||
/// \brief Return a string containing the backtrace where the crash was
|
||||
/// detected; or empty if the backtrace wasn't recovered.
|
||||
///
|
||||
/// This function is only valid when a crash has been detected (i.e.,
|
||||
/// RunSafely() has returned false.
|
||||
const std::string &getBacktrace() const;
|
||||
};
|
||||
|
||||
class CrashRecoveryContextCleanup {
|
||||
protected:
|
||||
CrashRecoveryContext *context;
|
||||
CrashRecoveryContextCleanup(CrashRecoveryContext *context)
|
||||
: context(context), cleanupFired(false) {}
|
||||
public:
|
||||
bool cleanupFired;
|
||||
|
||||
virtual ~CrashRecoveryContextCleanup();
|
||||
virtual void recoverResources() = 0;
|
||||
|
||||
CrashRecoveryContext *getContext() const {
|
||||
return context;
|
||||
}
|
||||
|
||||
private:
|
||||
friend class CrashRecoveryContext;
|
||||
CrashRecoveryContextCleanup *prev, *next;
|
||||
};
|
||||
|
||||
template<typename DERIVED, typename T>
|
||||
class CrashRecoveryContextCleanupBase : public CrashRecoveryContextCleanup {
|
||||
protected:
|
||||
T *resource;
|
||||
CrashRecoveryContextCleanupBase(CrashRecoveryContext *context, T* resource)
|
||||
: CrashRecoveryContextCleanup(context), resource(resource) {}
|
||||
public:
|
||||
static DERIVED *create(T *x) {
|
||||
if (x) {
|
||||
if (CrashRecoveryContext *context = CrashRecoveryContext::GetCurrent())
|
||||
return new DERIVED(context, x);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class CrashRecoveryContextDestructorCleanup : public
|
||||
CrashRecoveryContextCleanupBase<CrashRecoveryContextDestructorCleanup<T>, T> {
|
||||
public:
|
||||
CrashRecoveryContextDestructorCleanup(CrashRecoveryContext *context,
|
||||
T *resource)
|
||||
: CrashRecoveryContextCleanupBase<
|
||||
CrashRecoveryContextDestructorCleanup<T>, T>(context, resource) {}
|
||||
|
||||
virtual void recoverResources() {
|
||||
this->resource->~T();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class CrashRecoveryContextDeleteCleanup : public
|
||||
CrashRecoveryContextCleanupBase<CrashRecoveryContextDeleteCleanup<T>, T> {
|
||||
public:
|
||||
CrashRecoveryContextDeleteCleanup(CrashRecoveryContext *context, T *resource)
|
||||
: CrashRecoveryContextCleanupBase<
|
||||
CrashRecoveryContextDeleteCleanup<T>, T>(context, resource) {}
|
||||
|
||||
virtual void recoverResources() {
|
||||
delete this->resource;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class CrashRecoveryContextReleaseRefCleanup : public
|
||||
CrashRecoveryContextCleanupBase<CrashRecoveryContextReleaseRefCleanup<T>, T>
|
||||
{
|
||||
public:
|
||||
CrashRecoveryContextReleaseRefCleanup(CrashRecoveryContext *context,
|
||||
T *resource)
|
||||
: CrashRecoveryContextCleanupBase<CrashRecoveryContextReleaseRefCleanup<T>,
|
||||
T>(context, resource) {}
|
||||
|
||||
virtual void recoverResources() {
|
||||
this->resource->Release();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename Cleanup = CrashRecoveryContextDeleteCleanup<T> >
|
||||
class CrashRecoveryContextCleanupRegistrar {
|
||||
CrashRecoveryContextCleanup *cleanup;
|
||||
public:
|
||||
CrashRecoveryContextCleanupRegistrar(T *x)
|
||||
: cleanup(Cleanup::create(x)) {
|
||||
if (cleanup)
|
||||
cleanup->getContext()->registerCleanup(cleanup);
|
||||
}
|
||||
|
||||
~CrashRecoveryContextCleanupRegistrar() {
|
||||
unregister();
|
||||
}
|
||||
|
||||
void unregister() {
|
||||
if (cleanup && !cleanup->cleanupFired)
|
||||
cleanup->getContext()->unregisterCleanup(cleanup);
|
||||
cleanup = 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
166
thirdparty/clang/include/llvm/Support/DOTGraphTraits.h
vendored
Normal file
166
thirdparty/clang/include/llvm/Support/DOTGraphTraits.h
vendored
Normal file
@@ -0,0 +1,166 @@
|
||||
//===-- llvm/Support/DotGraphTraits.h - Customize .dot output ---*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines a template class that can be used to customize dot output
|
||||
// graphs generated by the GraphWriter.h file. The default implementation of
|
||||
// this file will produce a simple, but not very polished graph. By
|
||||
// specializing this template, lots of customization opportunities are possible.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_DOTGRAPHTRAITS_H
|
||||
#define LLVM_SUPPORT_DOTGRAPHTRAITS_H
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
/// DefaultDOTGraphTraits - This class provides the default implementations of
|
||||
/// all of the DOTGraphTraits methods. If a specialization does not need to
|
||||
/// override all methods here it should inherit so that it can get the default
|
||||
/// implementations.
|
||||
///
|
||||
struct DefaultDOTGraphTraits {
|
||||
private:
|
||||
bool IsSimple;
|
||||
|
||||
protected:
|
||||
bool isSimple() {
|
||||
return IsSimple;
|
||||
}
|
||||
|
||||
public:
|
||||
explicit DefaultDOTGraphTraits(bool simple=false) : IsSimple (simple) {}
|
||||
|
||||
/// getGraphName - Return the label for the graph as a whole. Printed at the
|
||||
/// top of the graph.
|
||||
///
|
||||
template<typename GraphType>
|
||||
static std::string getGraphName(const GraphType &) { return ""; }
|
||||
|
||||
/// getGraphProperties - Return any custom properties that should be included
|
||||
/// in the top level graph structure for dot.
|
||||
///
|
||||
template<typename GraphType>
|
||||
static std::string getGraphProperties(const GraphType &) {
|
||||
return "";
|
||||
}
|
||||
|
||||
/// renderGraphFromBottomUp - If this function returns true, the graph is
|
||||
/// emitted bottom-up instead of top-down. This requires graphviz 2.0 to work
|
||||
/// though.
|
||||
static bool renderGraphFromBottomUp() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/// isNodeHidden - If the function returns true, the given node is not
|
||||
/// displayed in the graph.
|
||||
static bool isNodeHidden(const void *) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/// getNodeLabel - Given a node and a pointer to the top level graph, return
|
||||
/// the label to print in the node.
|
||||
template<typename GraphType>
|
||||
std::string getNodeLabel(const void *, const GraphType &) {
|
||||
return "";
|
||||
}
|
||||
|
||||
/// hasNodeAddressLabel - If this method returns true, the address of the node
|
||||
/// is added to the label of the node.
|
||||
template<typename GraphType>
|
||||
static bool hasNodeAddressLabel(const void *, const GraphType &) {
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename GraphType>
|
||||
static std::string getNodeDescription(const void *, const GraphType &) {
|
||||
return "";
|
||||
}
|
||||
|
||||
/// If you want to specify custom node attributes, this is the place to do so
|
||||
///
|
||||
template<typename GraphType>
|
||||
static std::string getNodeAttributes(const void *,
|
||||
const GraphType &) {
|
||||
return "";
|
||||
}
|
||||
|
||||
/// If you want to override the dot attributes printed for a particular edge,
|
||||
/// override this method.
|
||||
template<typename EdgeIter, typename GraphType>
|
||||
static std::string getEdgeAttributes(const void *, EdgeIter,
|
||||
const GraphType &) {
|
||||
return "";
|
||||
}
|
||||
|
||||
/// getEdgeSourceLabel - If you want to label the edge source itself,
|
||||
/// implement this method.
|
||||
template<typename EdgeIter>
|
||||
static std::string getEdgeSourceLabel(const void *, EdgeIter) {
|
||||
return "";
|
||||
}
|
||||
|
||||
/// edgeTargetsEdgeSource - This method returns true if this outgoing edge
|
||||
/// should actually target another edge source, not a node. If this method is
|
||||
/// implemented, getEdgeTarget should be implemented.
|
||||
template<typename EdgeIter>
|
||||
static bool edgeTargetsEdgeSource(const void *, EdgeIter) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/// getEdgeTarget - If edgeTargetsEdgeSource returns true, this method is
|
||||
/// called to determine which outgoing edge of Node is the target of this
|
||||
/// edge.
|
||||
template<typename EdgeIter>
|
||||
static EdgeIter getEdgeTarget(const void *, EdgeIter I) {
|
||||
return I;
|
||||
}
|
||||
|
||||
/// hasEdgeDestLabels - If this function returns true, the graph is able
|
||||
/// to provide labels for edge destinations.
|
||||
static bool hasEdgeDestLabels() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/// numEdgeDestLabels - If hasEdgeDestLabels, this function returns the
|
||||
/// number of incoming edge labels the given node has.
|
||||
static unsigned numEdgeDestLabels(const void *) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// getEdgeDestLabel - If hasEdgeDestLabels, this function returns the
|
||||
/// incoming edge label with the given index in the given node.
|
||||
static std::string getEdgeDestLabel(const void *, unsigned) {
|
||||
return "";
|
||||
}
|
||||
|
||||
/// addCustomGraphFeatures - If a graph is made up of more than just
|
||||
/// straight-forward nodes and edges, this is the place to put all of the
|
||||
/// custom stuff necessary. The GraphWriter object, instantiated with your
|
||||
/// GraphType is passed in as an argument. You may call arbitrary methods on
|
||||
/// it to add things to the output graph.
|
||||
///
|
||||
template<typename GraphType, typename GraphWriter>
|
||||
static void addCustomGraphFeatures(const GraphType &, GraphWriter &) {}
|
||||
};
|
||||
|
||||
|
||||
/// DOTGraphTraits - Template class that can be specialized to customize how
|
||||
/// graphs are converted to 'dot' graphs. When specializing, you may inherit
|
||||
/// from DefaultDOTGraphTraits if you don't need to override everything.
|
||||
///
|
||||
template <typename Ty>
|
||||
struct DOTGraphTraits : public DefaultDOTGraphTraits {
|
||||
DOTGraphTraits (bool simple=false) : DefaultDOTGraphTraits (simple) {}
|
||||
};
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
||||
355
thirdparty/clang/include/llvm/Support/DataExtractor.h
vendored
Normal file
355
thirdparty/clang/include/llvm/Support/DataExtractor.h
vendored
Normal file
@@ -0,0 +1,355 @@
|
||||
//===-- DataExtractor.h -----------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_DATAEXTRACTOR_H
|
||||
#define LLVM_SUPPORT_DATAEXTRACTOR_H
|
||||
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
|
||||
namespace llvm {
|
||||
class DataExtractor {
|
||||
StringRef Data;
|
||||
uint8_t IsLittleEndian;
|
||||
uint8_t AddressSize;
|
||||
public:
|
||||
/// Construct with a buffer that is owned by the caller.
|
||||
///
|
||||
/// This constructor allows us to use data that is owned by the
|
||||
/// caller. The data must stay around as long as this object is
|
||||
/// valid.
|
||||
DataExtractor(StringRef Data, bool IsLittleEndian, uint8_t AddressSize)
|
||||
: Data(Data), IsLittleEndian(IsLittleEndian), AddressSize(AddressSize) {}
|
||||
|
||||
/// \brief Get the data pointed to by this extractor.
|
||||
StringRef getData() const { return Data; }
|
||||
/// \brief Get the endianess for this extractor.
|
||||
bool isLittleEndian() const { return IsLittleEndian; }
|
||||
/// \brief Get the address size for this extractor.
|
||||
uint8_t getAddressSize() const { return AddressSize; }
|
||||
/// \brief Set the address size for this extractor.
|
||||
void setAddressSize(uint8_t Size) { AddressSize = Size; }
|
||||
|
||||
/// Extract a C string from \a *offset_ptr.
|
||||
///
|
||||
/// Returns a pointer to a C String from the data at the offset
|
||||
/// pointed to by \a offset_ptr. A variable length NULL terminated C
|
||||
/// string will be extracted and the \a offset_ptr will be
|
||||
/// updated with the offset of the byte that follows the NULL
|
||||
/// terminator byte.
|
||||
///
|
||||
/// @param[in,out] offset_ptr
|
||||
/// A pointer to an offset within the data that will be advanced
|
||||
/// by the appropriate number of bytes if the value is extracted
|
||||
/// correctly. If the offset is out of bounds or there are not
|
||||
/// enough bytes to extract this value, the offset will be left
|
||||
/// unmodified.
|
||||
///
|
||||
/// @return
|
||||
/// A pointer to the C string value in the data. If the offset
|
||||
/// pointed to by \a offset_ptr is out of bounds, or if the
|
||||
/// offset plus the length of the C string is out of bounds,
|
||||
/// NULL will be returned.
|
||||
const char *getCStr(uint32_t *offset_ptr) const;
|
||||
|
||||
/// Extract an unsigned integer of size \a byte_size from \a
|
||||
/// *offset_ptr.
|
||||
///
|
||||
/// Extract a single unsigned integer value and update the offset
|
||||
/// pointed to by \a offset_ptr. The size of the extracted integer
|
||||
/// is specified by the \a byte_size argument. \a byte_size should
|
||||
/// have a value greater than or equal to one and less than or equal
|
||||
/// to eight since the return value is 64 bits wide. Any
|
||||
/// \a byte_size values less than 1 or greater than 8 will result in
|
||||
/// nothing being extracted, and zero being returned.
|
||||
///
|
||||
/// @param[in,out] offset_ptr
|
||||
/// A pointer to an offset within the data that will be advanced
|
||||
/// by the appropriate number of bytes if the value is extracted
|
||||
/// correctly. If the offset is out of bounds or there are not
|
||||
/// enough bytes to extract this value, the offset will be left
|
||||
/// unmodified.
|
||||
///
|
||||
/// @param[in] byte_size
|
||||
/// The size in byte of the integer to extract.
|
||||
///
|
||||
/// @return
|
||||
/// The unsigned integer value that was extracted, or zero on
|
||||
/// failure.
|
||||
uint64_t getUnsigned(uint32_t *offset_ptr, uint32_t byte_size) const;
|
||||
|
||||
/// Extract an signed integer of size \a byte_size from \a *offset_ptr.
|
||||
///
|
||||
/// Extract a single signed integer value (sign extending if required)
|
||||
/// and update the offset pointed to by \a offset_ptr. The size of
|
||||
/// the extracted integer is specified by the \a byte_size argument.
|
||||
/// \a byte_size should have a value greater than or equal to one
|
||||
/// and less than or equal to eight since the return value is 64
|
||||
/// bits wide. Any \a byte_size values less than 1 or greater than
|
||||
/// 8 will result in nothing being extracted, and zero being returned.
|
||||
///
|
||||
/// @param[in,out] offset_ptr
|
||||
/// A pointer to an offset within the data that will be advanced
|
||||
/// by the appropriate number of bytes if the value is extracted
|
||||
/// correctly. If the offset is out of bounds or there are not
|
||||
/// enough bytes to extract this value, the offset will be left
|
||||
/// unmodified.
|
||||
///
|
||||
/// @param[in] size
|
||||
/// The size in bytes of the integer to extract.
|
||||
///
|
||||
/// @return
|
||||
/// The sign extended signed integer value that was extracted,
|
||||
/// or zero on failure.
|
||||
int64_t getSigned(uint32_t *offset_ptr, uint32_t size) const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Extract an pointer from \a *offset_ptr.
|
||||
///
|
||||
/// Extract a single pointer from the data and update the offset
|
||||
/// pointed to by \a offset_ptr. The size of the extracted pointer
|
||||
/// is \a getAddressSize(), so the address size has to be
|
||||
/// set correctly prior to extracting any pointer values.
|
||||
///
|
||||
/// @param[in,out] offset_ptr
|
||||
/// A pointer to an offset within the data that will be advanced
|
||||
/// by the appropriate number of bytes if the value is extracted
|
||||
/// correctly. If the offset is out of bounds or there are not
|
||||
/// enough bytes to extract this value, the offset will be left
|
||||
/// unmodified.
|
||||
///
|
||||
/// @return
|
||||
/// The extracted pointer value as a 64 integer.
|
||||
uint64_t getAddress(uint32_t *offset_ptr) const {
|
||||
return getUnsigned(offset_ptr, AddressSize);
|
||||
}
|
||||
|
||||
/// Extract a uint8_t value from \a *offset_ptr.
|
||||
///
|
||||
/// Extract a single uint8_t from the binary data at the offset
|
||||
/// pointed to by \a offset_ptr, and advance the offset on success.
|
||||
///
|
||||
/// @param[in,out] offset_ptr
|
||||
/// A pointer to an offset within the data that will be advanced
|
||||
/// by the appropriate number of bytes if the value is extracted
|
||||
/// correctly. If the offset is out of bounds or there are not
|
||||
/// enough bytes to extract this value, the offset will be left
|
||||
/// unmodified.
|
||||
///
|
||||
/// @return
|
||||
/// The extracted uint8_t value.
|
||||
uint8_t getU8(uint32_t *offset_ptr) const;
|
||||
|
||||
/// Extract \a count uint8_t values from \a *offset_ptr.
|
||||
///
|
||||
/// Extract \a count uint8_t values from the binary data at the
|
||||
/// offset pointed to by \a offset_ptr, and advance the offset on
|
||||
/// success. The extracted values are copied into \a dst.
|
||||
///
|
||||
/// @param[in,out] offset_ptr
|
||||
/// A pointer to an offset within the data that will be advanced
|
||||
/// by the appropriate number of bytes if the value is extracted
|
||||
/// correctly. If the offset is out of bounds or there are not
|
||||
/// enough bytes to extract this value, the offset will be left
|
||||
/// unmodified.
|
||||
///
|
||||
/// @param[out] dst
|
||||
/// A buffer to copy \a count uint8_t values into. \a dst must
|
||||
/// be large enough to hold all requested data.
|
||||
///
|
||||
/// @param[in] count
|
||||
/// The number of uint8_t values to extract.
|
||||
///
|
||||
/// @return
|
||||
/// \a dst if all values were properly extracted and copied,
|
||||
/// NULL otherise.
|
||||
uint8_t *getU8(uint32_t *offset_ptr, uint8_t *dst, uint32_t count) const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Extract a uint16_t value from \a *offset_ptr.
|
||||
///
|
||||
/// Extract a single uint16_t from the binary data at the offset
|
||||
/// pointed to by \a offset_ptr, and update the offset on success.
|
||||
///
|
||||
/// @param[in,out] offset_ptr
|
||||
/// A pointer to an offset within the data that will be advanced
|
||||
/// by the appropriate number of bytes if the value is extracted
|
||||
/// correctly. If the offset is out of bounds or there are not
|
||||
/// enough bytes to extract this value, the offset will be left
|
||||
/// unmodified.
|
||||
///
|
||||
/// @return
|
||||
/// The extracted uint16_t value.
|
||||
//------------------------------------------------------------------
|
||||
uint16_t getU16(uint32_t *offset_ptr) const;
|
||||
|
||||
/// Extract \a count uint16_t values from \a *offset_ptr.
|
||||
///
|
||||
/// Extract \a count uint16_t values from the binary data at the
|
||||
/// offset pointed to by \a offset_ptr, and advance the offset on
|
||||
/// success. The extracted values are copied into \a dst.
|
||||
///
|
||||
/// @param[in,out] offset_ptr
|
||||
/// A pointer to an offset within the data that will be advanced
|
||||
/// by the appropriate number of bytes if the value is extracted
|
||||
/// correctly. If the offset is out of bounds or there are not
|
||||
/// enough bytes to extract this value, the offset will be left
|
||||
/// unmodified.
|
||||
///
|
||||
/// @param[out] dst
|
||||
/// A buffer to copy \a count uint16_t values into. \a dst must
|
||||
/// be large enough to hold all requested data.
|
||||
///
|
||||
/// @param[in] count
|
||||
/// The number of uint16_t values to extract.
|
||||
///
|
||||
/// @return
|
||||
/// \a dst if all values were properly extracted and copied,
|
||||
/// NULL otherise.
|
||||
uint16_t *getU16(uint32_t *offset_ptr, uint16_t *dst, uint32_t count) const;
|
||||
|
||||
/// Extract a uint32_t value from \a *offset_ptr.
|
||||
///
|
||||
/// Extract a single uint32_t from the binary data at the offset
|
||||
/// pointed to by \a offset_ptr, and update the offset on success.
|
||||
///
|
||||
/// @param[in,out] offset_ptr
|
||||
/// A pointer to an offset within the data that will be advanced
|
||||
/// by the appropriate number of bytes if the value is extracted
|
||||
/// correctly. If the offset is out of bounds or there are not
|
||||
/// enough bytes to extract this value, the offset will be left
|
||||
/// unmodified.
|
||||
///
|
||||
/// @return
|
||||
/// The extracted uint32_t value.
|
||||
uint32_t getU32(uint32_t *offset_ptr) const;
|
||||
|
||||
/// Extract \a count uint32_t values from \a *offset_ptr.
|
||||
///
|
||||
/// Extract \a count uint32_t values from the binary data at the
|
||||
/// offset pointed to by \a offset_ptr, and advance the offset on
|
||||
/// success. The extracted values are copied into \a dst.
|
||||
///
|
||||
/// @param[in,out] offset_ptr
|
||||
/// A pointer to an offset within the data that will be advanced
|
||||
/// by the appropriate number of bytes if the value is extracted
|
||||
/// correctly. If the offset is out of bounds or there are not
|
||||
/// enough bytes to extract this value, the offset will be left
|
||||
/// unmodified.
|
||||
///
|
||||
/// @param[out] dst
|
||||
/// A buffer to copy \a count uint32_t values into. \a dst must
|
||||
/// be large enough to hold all requested data.
|
||||
///
|
||||
/// @param[in] count
|
||||
/// The number of uint32_t values to extract.
|
||||
///
|
||||
/// @return
|
||||
/// \a dst if all values were properly extracted and copied,
|
||||
/// NULL otherise.
|
||||
uint32_t *getU32(uint32_t *offset_ptr, uint32_t *dst, uint32_t count) const;
|
||||
|
||||
/// Extract a uint64_t value from \a *offset_ptr.
|
||||
///
|
||||
/// Extract a single uint64_t from the binary data at the offset
|
||||
/// pointed to by \a offset_ptr, and update the offset on success.
|
||||
///
|
||||
/// @param[in,out] offset_ptr
|
||||
/// A pointer to an offset within the data that will be advanced
|
||||
/// by the appropriate number of bytes if the value is extracted
|
||||
/// correctly. If the offset is out of bounds or there are not
|
||||
/// enough bytes to extract this value, the offset will be left
|
||||
/// unmodified.
|
||||
///
|
||||
/// @return
|
||||
/// The extracted uint64_t value.
|
||||
uint64_t getU64(uint32_t *offset_ptr) const;
|
||||
|
||||
/// Extract \a count uint64_t values from \a *offset_ptr.
|
||||
///
|
||||
/// Extract \a count uint64_t values from the binary data at the
|
||||
/// offset pointed to by \a offset_ptr, and advance the offset on
|
||||
/// success. The extracted values are copied into \a dst.
|
||||
///
|
||||
/// @param[in,out] offset_ptr
|
||||
/// A pointer to an offset within the data that will be advanced
|
||||
/// by the appropriate number of bytes if the value is extracted
|
||||
/// correctly. If the offset is out of bounds or there are not
|
||||
/// enough bytes to extract this value, the offset will be left
|
||||
/// unmodified.
|
||||
///
|
||||
/// @param[out] dst
|
||||
/// A buffer to copy \a count uint64_t values into. \a dst must
|
||||
/// be large enough to hold all requested data.
|
||||
///
|
||||
/// @param[in] count
|
||||
/// The number of uint64_t values to extract.
|
||||
///
|
||||
/// @return
|
||||
/// \a dst if all values were properly extracted and copied,
|
||||
/// NULL otherise.
|
||||
uint64_t *getU64(uint32_t *offset_ptr, uint64_t *dst, uint32_t count) const;
|
||||
|
||||
/// Extract a signed LEB128 value from \a *offset_ptr.
|
||||
///
|
||||
/// Extracts an signed LEB128 number from this object's data
|
||||
/// starting at the offset pointed to by \a offset_ptr. The offset
|
||||
/// pointed to by \a offset_ptr will be updated with the offset of
|
||||
/// the byte following the last extracted byte.
|
||||
///
|
||||
/// @param[in,out] offset_ptr
|
||||
/// A pointer to an offset within the data that will be advanced
|
||||
/// by the appropriate number of bytes if the value is extracted
|
||||
/// correctly. If the offset is out of bounds or there are not
|
||||
/// enough bytes to extract this value, the offset will be left
|
||||
/// unmodified.
|
||||
///
|
||||
/// @return
|
||||
/// The extracted signed integer value.
|
||||
int64_t getSLEB128(uint32_t *offset_ptr) const;
|
||||
|
||||
/// Extract a unsigned LEB128 value from \a *offset_ptr.
|
||||
///
|
||||
/// Extracts an unsigned LEB128 number from this object's data
|
||||
/// starting at the offset pointed to by \a offset_ptr. The offset
|
||||
/// pointed to by \a offset_ptr will be updated with the offset of
|
||||
/// the byte following the last extracted byte.
|
||||
///
|
||||
/// @param[in,out] offset_ptr
|
||||
/// A pointer to an offset within the data that will be advanced
|
||||
/// by the appropriate number of bytes if the value is extracted
|
||||
/// correctly. If the offset is out of bounds or there are not
|
||||
/// enough bytes to extract this value, the offset will be left
|
||||
/// unmodified.
|
||||
///
|
||||
/// @return
|
||||
/// The extracted unsigned integer value.
|
||||
uint64_t getULEB128(uint32_t *offset_ptr) const;
|
||||
|
||||
/// Test the validity of \a offset.
|
||||
///
|
||||
/// @return
|
||||
/// \b true if \a offset is a valid offset into the data in this
|
||||
/// object, \b false otherwise.
|
||||
bool isValidOffset(uint32_t offset) const { return Data.size() > offset; }
|
||||
|
||||
/// Test the availability of \a length bytes of data from \a offset.
|
||||
///
|
||||
/// @return
|
||||
/// \b true if \a offset is a valid offset and there are \a
|
||||
/// length bytes available at that offset, \b false otherwise.
|
||||
bool isValidOffsetForDataOfSize(uint32_t offset, uint32_t length) const {
|
||||
return offset + length >= offset && isValidOffset(offset + length - 1);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace llvm
|
||||
|
||||
#endif
|
||||
103
thirdparty/clang/include/llvm/Support/DataFlow.h
vendored
Normal file
103
thirdparty/clang/include/llvm/Support/DataFlow.h
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
//===-- llvm/Support/DataFlow.h - dataflow as graphs ------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines specializations of GraphTraits that allows Use-Def and
|
||||
// Def-Use relations to be treated as proper graphs for generic algorithms.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_DATAFLOW_H
|
||||
#define LLVM_SUPPORT_DATAFLOW_H
|
||||
|
||||
#include "llvm/ADT/GraphTraits.h"
|
||||
#include "llvm/IR/User.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Provide specializations of GraphTraits to be able to treat def-use/use-def
|
||||
// chains as graphs
|
||||
|
||||
template <> struct GraphTraits<const Value*> {
|
||||
typedef const Value NodeType;
|
||||
typedef Value::const_use_iterator ChildIteratorType;
|
||||
|
||||
static NodeType *getEntryNode(const Value *G) {
|
||||
return G;
|
||||
}
|
||||
|
||||
static inline ChildIteratorType child_begin(NodeType *N) {
|
||||
return N->use_begin();
|
||||
}
|
||||
|
||||
static inline ChildIteratorType child_end(NodeType *N) {
|
||||
return N->use_end();
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct GraphTraits<Value*> {
|
||||
typedef Value NodeType;
|
||||
typedef Value::use_iterator ChildIteratorType;
|
||||
|
||||
static NodeType *getEntryNode(Value *G) {
|
||||
return G;
|
||||
}
|
||||
|
||||
static inline ChildIteratorType child_begin(NodeType *N) {
|
||||
return N->use_begin();
|
||||
}
|
||||
|
||||
static inline ChildIteratorType child_end(NodeType *N) {
|
||||
return N->use_end();
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct GraphTraits<Inverse<const User*> > {
|
||||
typedef const Value NodeType;
|
||||
typedef User::const_op_iterator ChildIteratorType;
|
||||
|
||||
static NodeType *getEntryNode(Inverse<const User*> G) {
|
||||
return G.Graph;
|
||||
}
|
||||
|
||||
static inline ChildIteratorType child_begin(NodeType *N) {
|
||||
if (const User *U = dyn_cast<User>(N))
|
||||
return U->op_begin();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline ChildIteratorType child_end(NodeType *N) {
|
||||
if(const User *U = dyn_cast<User>(N))
|
||||
return U->op_end();
|
||||
return NULL;
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct GraphTraits<Inverse<User*> > {
|
||||
typedef Value NodeType;
|
||||
typedef User::op_iterator ChildIteratorType;
|
||||
|
||||
static NodeType *getEntryNode(Inverse<User*> G) {
|
||||
return G.Graph;
|
||||
}
|
||||
|
||||
static inline ChildIteratorType child_begin(NodeType *N) {
|
||||
if (User *U = dyn_cast<User>(N))
|
||||
return U->op_begin();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline ChildIteratorType child_end(NodeType *N) {
|
||||
if (User *U = dyn_cast<User>(N))
|
||||
return U->op_end();
|
||||
return NULL;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
38
thirdparty/clang/include/llvm/Support/DataStream.h
vendored
Normal file
38
thirdparty/clang/include/llvm/Support/DataStream.h
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
//===---- llvm/Support/DataStream.h - Lazy bitcode streaming ----*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This header defines DataStreamer, which fetches bytes of data from
|
||||
// a stream source. It provides support for streaming (lazy reading) of
|
||||
// data, e.g. bitcode
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
||||
#ifndef LLVM_SUPPORT_DATASTREAM_H
|
||||
#define LLVM_SUPPORT_DATASTREAM_H
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class DataStreamer {
|
||||
public:
|
||||
/// Fetch bytes [start-end) from the stream, and write them to the
|
||||
/// buffer pointed to by buf. Returns the number of bytes actually written.
|
||||
virtual size_t GetBytes(unsigned char *buf, size_t len) = 0;
|
||||
|
||||
virtual ~DataStreamer();
|
||||
};
|
||||
|
||||
DataStreamer *getDataFileStreamer(const std::string &Filename,
|
||||
std::string *Err);
|
||||
|
||||
}
|
||||
|
||||
#endif // LLVM_SUPPORT_DATASTREAM_H_
|
||||
101
thirdparty/clang/include/llvm/Support/Debug.h
vendored
Normal file
101
thirdparty/clang/include/llvm/Support/Debug.h
vendored
Normal file
@@ -0,0 +1,101 @@
|
||||
//===- llvm/Support/Debug.h - Easy way to add debug output ------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements a handy way of adding debugging information to your
|
||||
// code, without it being enabled all of the time, and without having to add
|
||||
// command line options to enable it.
|
||||
//
|
||||
// In particular, just wrap your code with the DEBUG() macro, and it will be
|
||||
// enabled automatically if you specify '-debug' on the command-line.
|
||||
// Alternatively, you can also use the SET_DEBUG_TYPE("foo") macro to specify
|
||||
// that your debug code belongs to class "foo". Then, on the command line, you
|
||||
// can specify '-debug-only=foo' to enable JUST the debug information for the
|
||||
// foo class.
|
||||
//
|
||||
// When compiling without assertions, the -debug-* options and all code in
|
||||
// DEBUG() statements disappears, so it does not affect the runtime of the code.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_DEBUG_H
|
||||
#define LLVM_SUPPORT_DEBUG_H
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class raw_ostream;
|
||||
|
||||
/// DEBUG_TYPE macro - Files can specify a DEBUG_TYPE as a string, which causes
|
||||
/// all of their DEBUG statements to be activatable with -debug-only=thatstring.
|
||||
#ifndef DEBUG_TYPE
|
||||
#define DEBUG_TYPE ""
|
||||
#endif
|
||||
|
||||
#ifndef NDEBUG
|
||||
/// DebugFlag - This boolean is set to true if the '-debug' command line option
|
||||
/// is specified. This should probably not be referenced directly, instead, use
|
||||
/// the DEBUG macro below.
|
||||
///
|
||||
extern bool DebugFlag;
|
||||
|
||||
/// isCurrentDebugType - Return true if the specified string is the debug type
|
||||
/// specified on the command line, or if none was specified on the command line
|
||||
/// with the -debug-only=X option.
|
||||
///
|
||||
bool isCurrentDebugType(const char *Type);
|
||||
|
||||
/// setCurrentDebugType - Set the current debug type, as if the -debug-only=X
|
||||
/// option were specified. Note that DebugFlag also needs to be set to true for
|
||||
/// debug output to be produced.
|
||||
///
|
||||
void setCurrentDebugType(const char *Type);
|
||||
|
||||
/// DEBUG_WITH_TYPE macro - This macro should be used by passes to emit debug
|
||||
/// information. In the '-debug' option is specified on the commandline, and if
|
||||
/// this is a debug build, then the code specified as the option to the macro
|
||||
/// will be executed. Otherwise it will not be. Example:
|
||||
///
|
||||
/// DEBUG_WITH_TYPE("bitset", dbgs() << "Bitset contains: " << Bitset << "\n");
|
||||
///
|
||||
/// This will emit the debug information if -debug is present, and -debug-only
|
||||
/// is not specified, or is specified as "bitset".
|
||||
#define DEBUG_WITH_TYPE(TYPE, X) \
|
||||
do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType(TYPE)) { X; } \
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
#define isCurrentDebugType(X) (false)
|
||||
#define setCurrentDebugType(X)
|
||||
#define DEBUG_WITH_TYPE(TYPE, X) do { } while (0)
|
||||
#endif
|
||||
|
||||
/// EnableDebugBuffering - This defaults to false. If true, the debug
|
||||
/// stream will install signal handlers to dump any buffered debug
|
||||
/// output. It allows clients to selectively allow the debug stream
|
||||
/// to install signal handlers if they are certain there will be no
|
||||
/// conflict.
|
||||
///
|
||||
extern bool EnableDebugBuffering;
|
||||
|
||||
/// dbgs() - This returns a reference to a raw_ostream for debugging
|
||||
/// messages. If debugging is disabled it returns errs(). Use it
|
||||
/// like: dbgs() << "foo" << "bar";
|
||||
raw_ostream &dbgs();
|
||||
|
||||
// DEBUG macro - This macro should be used by passes to emit debug information.
|
||||
// In the '-debug' option is specified on the commandline, and if this is a
|
||||
// debug build, then the code specified as the option to the macro will be
|
||||
// executed. Otherwise it will not be. Example:
|
||||
//
|
||||
// DEBUG(dbgs() << "Bitset contains: " << Bitset << "\n");
|
||||
//
|
||||
#define DEBUG(X) DEBUG_WITH_TYPE(DEBUG_TYPE, X)
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
||||
112
thirdparty/clang/include/llvm/Support/DebugLoc.h
vendored
Normal file
112
thirdparty/clang/include/llvm/Support/DebugLoc.h
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
//===---- llvm/Support/DebugLoc.h - Debug Location Information --*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines a number of light weight data structures used
|
||||
// to describe and track debug location information.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_DEBUGLOC_H
|
||||
#define LLVM_SUPPORT_DEBUGLOC_H
|
||||
|
||||
namespace llvm {
|
||||
template <typename T> struct DenseMapInfo;
|
||||
class MDNode;
|
||||
class LLVMContext;
|
||||
|
||||
/// DebugLoc - Debug location id. This is carried by Instruction, SDNode,
|
||||
/// and MachineInstr to compactly encode file/line/scope information for an
|
||||
/// operation.
|
||||
class DebugLoc {
|
||||
friend struct DenseMapInfo<DebugLoc>;
|
||||
|
||||
/// getEmptyKey() - A private constructor that returns an unknown that is
|
||||
/// not equal to the tombstone key or DebugLoc().
|
||||
static DebugLoc getEmptyKey() {
|
||||
DebugLoc DL;
|
||||
DL.LineCol = 1;
|
||||
return DL;
|
||||
}
|
||||
|
||||
/// getTombstoneKey() - A private constructor that returns an unknown that
|
||||
/// is not equal to the empty key or DebugLoc().
|
||||
static DebugLoc getTombstoneKey() {
|
||||
DebugLoc DL;
|
||||
DL.LineCol = 2;
|
||||
return DL;
|
||||
}
|
||||
|
||||
/// LineCol - This 32-bit value encodes the line and column number for the
|
||||
/// location, encoded as 24-bits for line and 8 bits for col. A value of 0
|
||||
/// for either means unknown.
|
||||
unsigned LineCol;
|
||||
|
||||
/// ScopeIdx - This is an opaque ID# for Scope/InlinedAt information,
|
||||
/// decoded by LLVMContext. 0 is unknown.
|
||||
int ScopeIdx;
|
||||
public:
|
||||
DebugLoc() : LineCol(0), ScopeIdx(0) {} // Defaults to unknown.
|
||||
|
||||
/// get - Get a new DebugLoc that corresponds to the specified line/col
|
||||
/// scope/inline location.
|
||||
static DebugLoc get(unsigned Line, unsigned Col,
|
||||
MDNode *Scope, MDNode *InlinedAt = 0);
|
||||
|
||||
/// getFromDILocation - Translate the DILocation quad into a DebugLoc.
|
||||
static DebugLoc getFromDILocation(MDNode *N);
|
||||
|
||||
/// getFromDILexicalBlock - Translate the DILexicalBlock into a DebugLoc.
|
||||
static DebugLoc getFromDILexicalBlock(MDNode *N);
|
||||
|
||||
/// isUnknown - Return true if this is an unknown location.
|
||||
bool isUnknown() const { return ScopeIdx == 0; }
|
||||
|
||||
unsigned getLine() const {
|
||||
return (LineCol << 8) >> 8; // Mask out column.
|
||||
}
|
||||
|
||||
unsigned getCol() const {
|
||||
return LineCol >> 24;
|
||||
}
|
||||
|
||||
/// getScope - This returns the scope pointer for this DebugLoc, or null if
|
||||
/// invalid.
|
||||
MDNode *getScope(const LLVMContext &Ctx) const;
|
||||
|
||||
/// getInlinedAt - This returns the InlinedAt pointer for this DebugLoc, or
|
||||
/// null if invalid or not present.
|
||||
MDNode *getInlinedAt(const LLVMContext &Ctx) const;
|
||||
|
||||
/// getScopeAndInlinedAt - Return both the Scope and the InlinedAt values.
|
||||
void getScopeAndInlinedAt(MDNode *&Scope, MDNode *&IA,
|
||||
const LLVMContext &Ctx) const;
|
||||
|
||||
|
||||
/// getAsMDNode - This method converts the compressed DebugLoc node into a
|
||||
/// DILocation compatible MDNode.
|
||||
MDNode *getAsMDNode(const LLVMContext &Ctx) const;
|
||||
|
||||
bool operator==(const DebugLoc &DL) const {
|
||||
return LineCol == DL.LineCol && ScopeIdx == DL.ScopeIdx;
|
||||
}
|
||||
bool operator!=(const DebugLoc &DL) const { return !(*this == DL); }
|
||||
|
||||
void dump(const LLVMContext &Ctx) const;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct DenseMapInfo<DebugLoc> {
|
||||
static DebugLoc getEmptyKey() { return DebugLoc::getEmptyKey(); }
|
||||
static DebugLoc getTombstoneKey() { return DebugLoc::getTombstoneKey(); }
|
||||
static unsigned getHashValue(const DebugLoc &Key);
|
||||
static bool isEqual(DebugLoc LHS, DebugLoc RHS) { return LHS == RHS; }
|
||||
};
|
||||
} // end namespace llvm
|
||||
|
||||
#endif /* LLVM_SUPPORT_DEBUGLOC_H */
|
||||
35
thirdparty/clang/include/llvm/Support/Disassembler.h
vendored
Normal file
35
thirdparty/clang/include/llvm/Support/Disassembler.h
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
//===- llvm/Support/Disassembler.h ------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements the necessary glue to call external disassembler
|
||||
// libraries.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SYSTEM_DISASSEMBLER_H
|
||||
#define LLVM_SYSTEM_DISASSEMBLER_H
|
||||
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include <string>
|
||||
|
||||
namespace llvm {
|
||||
namespace sys {
|
||||
|
||||
/// This function returns true, if there is possible to use some external
|
||||
/// disassembler library. False otherwise.
|
||||
bool hasDisassembler();
|
||||
|
||||
/// This function provides some "glue" code to call external disassembler
|
||||
/// libraries.
|
||||
std::string disassembleBuffer(uint8_t* start, size_t length, uint64_t pc = 0);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif // LLVM_SYSTEM_DISASSEMBLER_H
|
||||
770
thirdparty/clang/include/llvm/Support/Dwarf.h
vendored
Normal file
770
thirdparty/clang/include/llvm/Support/Dwarf.h
vendored
Normal file
@@ -0,0 +1,770 @@
|
||||
//===-- llvm/Support/Dwarf.h ---Dwarf Constants------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file contains constants used for implementing Dwarf debug support. For
|
||||
// Details on the Dwarf 3 specfication see DWARF Debugging Information Format
|
||||
// V.3 reference manual http://dwarf.freestandards.org ,
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_DWARF_H
|
||||
#define LLVM_SUPPORT_DWARF_H
|
||||
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
|
||||
|
||||
namespace llvm {
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Debug info constants.
|
||||
|
||||
enum {
|
||||
LLVMDebugVersion = (12 << 16), // Current version of debug information.
|
||||
LLVMDebugVersion11 = (11 << 16), // Constant for version 11.
|
||||
LLVMDebugVersion10 = (10 << 16), // Constant for version 10.
|
||||
LLVMDebugVersion9 = (9 << 16), // Constant for version 9.
|
||||
LLVMDebugVersion8 = (8 << 16), // Constant for version 8.
|
||||
LLVMDebugVersion7 = (7 << 16), // Constant for version 7.
|
||||
LLVMDebugVersion6 = (6 << 16), // Constant for version 6.
|
||||
LLVMDebugVersion5 = (5 << 16), // Constant for version 5.
|
||||
LLVMDebugVersion4 = (4 << 16), // Constant for version 4.
|
||||
LLVMDebugVersionMask = 0xffff0000 // Mask for version number.
|
||||
};
|
||||
|
||||
namespace dwarf {
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Dwarf constants as gleaned from the DWARF Debugging Information Format V.4
|
||||
// reference manual http://dwarf.freestandards.org .
|
||||
//
|
||||
|
||||
// Do not mix the following two enumerations sets. DW_TAG_invalid changes the
|
||||
// enumeration base type.
|
||||
|
||||
enum llvm_dwarf_constants {
|
||||
// llvm mock tags
|
||||
DW_TAG_invalid = ~0U, // Tag for invalid results.
|
||||
|
||||
DW_TAG_auto_variable = 0x100, // Tag for local (auto) variables.
|
||||
DW_TAG_arg_variable = 0x101, // Tag for argument variables.
|
||||
|
||||
DW_TAG_user_base = 0x1000, // Recommended base for user tags.
|
||||
|
||||
DW_CIE_VERSION = 1 // Common frame information version.
|
||||
};
|
||||
|
||||
|
||||
// Special ID values that distinguish a CIE from a FDE in DWARF CFI.
|
||||
// Not inside an enum because a 64-bit value is needed.
|
||||
const uint32_t DW_CIE_ID = UINT32_MAX;
|
||||
const uint64_t DW64_CIE_ID = UINT64_MAX;
|
||||
|
||||
|
||||
enum dwarf_constants {
|
||||
DWARF_VERSION = 2,
|
||||
|
||||
// Tags
|
||||
DW_TAG_array_type = 0x01,
|
||||
DW_TAG_class_type = 0x02,
|
||||
DW_TAG_entry_point = 0x03,
|
||||
DW_TAG_enumeration_type = 0x04,
|
||||
DW_TAG_formal_parameter = 0x05,
|
||||
DW_TAG_imported_declaration = 0x08,
|
||||
DW_TAG_label = 0x0a,
|
||||
DW_TAG_lexical_block = 0x0b,
|
||||
DW_TAG_member = 0x0d,
|
||||
DW_TAG_pointer_type = 0x0f,
|
||||
DW_TAG_reference_type = 0x10,
|
||||
DW_TAG_compile_unit = 0x11,
|
||||
DW_TAG_string_type = 0x12,
|
||||
DW_TAG_structure_type = 0x13,
|
||||
DW_TAG_subroutine_type = 0x15,
|
||||
DW_TAG_typedef = 0x16,
|
||||
DW_TAG_union_type = 0x17,
|
||||
DW_TAG_unspecified_parameters = 0x18,
|
||||
DW_TAG_variant = 0x19,
|
||||
DW_TAG_common_block = 0x1a,
|
||||
DW_TAG_common_inclusion = 0x1b,
|
||||
DW_TAG_inheritance = 0x1c,
|
||||
DW_TAG_inlined_subroutine = 0x1d,
|
||||
DW_TAG_module = 0x1e,
|
||||
DW_TAG_ptr_to_member_type = 0x1f,
|
||||
DW_TAG_set_type = 0x20,
|
||||
DW_TAG_subrange_type = 0x21,
|
||||
DW_TAG_with_stmt = 0x22,
|
||||
DW_TAG_access_declaration = 0x23,
|
||||
DW_TAG_base_type = 0x24,
|
||||
DW_TAG_catch_block = 0x25,
|
||||
DW_TAG_const_type = 0x26,
|
||||
DW_TAG_constant = 0x27,
|
||||
DW_TAG_enumerator = 0x28,
|
||||
DW_TAG_file_type = 0x29,
|
||||
DW_TAG_friend = 0x2a,
|
||||
DW_TAG_namelist = 0x2b,
|
||||
DW_TAG_namelist_item = 0x2c,
|
||||
DW_TAG_packed_type = 0x2d,
|
||||
DW_TAG_subprogram = 0x2e,
|
||||
DW_TAG_template_type_parameter = 0x2f,
|
||||
DW_TAG_template_value_parameter = 0x30,
|
||||
DW_TAG_thrown_type = 0x31,
|
||||
DW_TAG_try_block = 0x32,
|
||||
DW_TAG_variant_part = 0x33,
|
||||
DW_TAG_variable = 0x34,
|
||||
DW_TAG_volatile_type = 0x35,
|
||||
DW_TAG_dwarf_procedure = 0x36,
|
||||
DW_TAG_restrict_type = 0x37,
|
||||
DW_TAG_interface_type = 0x38,
|
||||
DW_TAG_namespace = 0x39,
|
||||
DW_TAG_imported_module = 0x3a,
|
||||
DW_TAG_unspecified_type = 0x3b,
|
||||
DW_TAG_partial_unit = 0x3c,
|
||||
DW_TAG_imported_unit = 0x3d,
|
||||
DW_TAG_condition = 0x3f,
|
||||
DW_TAG_shared_type = 0x40,
|
||||
DW_TAG_type_unit = 0x41,
|
||||
DW_TAG_rvalue_reference_type = 0x42,
|
||||
DW_TAG_template_alias = 0x43,
|
||||
DW_TAG_MIPS_loop = 0x4081,
|
||||
DW_TAG_format_label = 0x4101,
|
||||
DW_TAG_function_template = 0x4102,
|
||||
DW_TAG_class_template = 0x4103,
|
||||
DW_TAG_GNU_template_template_param = 0x4106,
|
||||
DW_TAG_GNU_template_parameter_pack = 0x4107,
|
||||
DW_TAG_GNU_formal_parameter_pack = 0x4108,
|
||||
DW_TAG_lo_user = 0x4080,
|
||||
DW_TAG_APPLE_property = 0x4200,
|
||||
DW_TAG_hi_user = 0xffff,
|
||||
|
||||
// Children flag
|
||||
DW_CHILDREN_no = 0x00,
|
||||
DW_CHILDREN_yes = 0x01,
|
||||
|
||||
// Attributes
|
||||
DW_AT_sibling = 0x01,
|
||||
DW_AT_location = 0x02,
|
||||
DW_AT_name = 0x03,
|
||||
DW_AT_ordering = 0x09,
|
||||
DW_AT_byte_size = 0x0b,
|
||||
DW_AT_bit_offset = 0x0c,
|
||||
DW_AT_bit_size = 0x0d,
|
||||
DW_AT_stmt_list = 0x10,
|
||||
DW_AT_low_pc = 0x11,
|
||||
DW_AT_high_pc = 0x12,
|
||||
DW_AT_language = 0x13,
|
||||
DW_AT_discr = 0x15,
|
||||
DW_AT_discr_value = 0x16,
|
||||
DW_AT_visibility = 0x17,
|
||||
DW_AT_import = 0x18,
|
||||
DW_AT_string_length = 0x19,
|
||||
DW_AT_common_reference = 0x1a,
|
||||
DW_AT_comp_dir = 0x1b,
|
||||
DW_AT_const_value = 0x1c,
|
||||
DW_AT_containing_type = 0x1d,
|
||||
DW_AT_default_value = 0x1e,
|
||||
DW_AT_inline = 0x20,
|
||||
DW_AT_is_optional = 0x21,
|
||||
DW_AT_lower_bound = 0x22,
|
||||
DW_AT_producer = 0x25,
|
||||
DW_AT_prototyped = 0x27,
|
||||
DW_AT_return_addr = 0x2a,
|
||||
DW_AT_start_scope = 0x2c,
|
||||
DW_AT_bit_stride = 0x2e,
|
||||
DW_AT_upper_bound = 0x2f,
|
||||
DW_AT_abstract_origin = 0x31,
|
||||
DW_AT_accessibility = 0x32,
|
||||
DW_AT_address_class = 0x33,
|
||||
DW_AT_artificial = 0x34,
|
||||
DW_AT_base_types = 0x35,
|
||||
DW_AT_calling_convention = 0x36,
|
||||
DW_AT_count = 0x37,
|
||||
DW_AT_data_member_location = 0x38,
|
||||
DW_AT_decl_column = 0x39,
|
||||
DW_AT_decl_file = 0x3a,
|
||||
DW_AT_decl_line = 0x3b,
|
||||
DW_AT_declaration = 0x3c,
|
||||
DW_AT_discr_list = 0x3d,
|
||||
DW_AT_encoding = 0x3e,
|
||||
DW_AT_external = 0x3f,
|
||||
DW_AT_frame_base = 0x40,
|
||||
DW_AT_friend = 0x41,
|
||||
DW_AT_identifier_case = 0x42,
|
||||
DW_AT_macro_info = 0x43,
|
||||
DW_AT_namelist_item = 0x44,
|
||||
DW_AT_priority = 0x45,
|
||||
DW_AT_segment = 0x46,
|
||||
DW_AT_specification = 0x47,
|
||||
DW_AT_static_link = 0x48,
|
||||
DW_AT_type = 0x49,
|
||||
DW_AT_use_location = 0x4a,
|
||||
DW_AT_variable_parameter = 0x4b,
|
||||
DW_AT_virtuality = 0x4c,
|
||||
DW_AT_vtable_elem_location = 0x4d,
|
||||
DW_AT_allocated = 0x4e,
|
||||
DW_AT_associated = 0x4f,
|
||||
DW_AT_data_location = 0x50,
|
||||
DW_AT_byte_stride = 0x51,
|
||||
DW_AT_entry_pc = 0x52,
|
||||
DW_AT_use_UTF8 = 0x53,
|
||||
DW_AT_extension = 0x54,
|
||||
DW_AT_ranges = 0x55,
|
||||
DW_AT_trampoline = 0x56,
|
||||
DW_AT_call_column = 0x57,
|
||||
DW_AT_call_file = 0x58,
|
||||
DW_AT_call_line = 0x59,
|
||||
DW_AT_description = 0x5a,
|
||||
DW_AT_binary_scale = 0x5b,
|
||||
DW_AT_decimal_scale = 0x5c,
|
||||
DW_AT_small = 0x5d,
|
||||
DW_AT_decimal_sign = 0x5e,
|
||||
DW_AT_digit_count = 0x5f,
|
||||
DW_AT_picture_string = 0x60,
|
||||
DW_AT_mutable = 0x61,
|
||||
DW_AT_threads_scaled = 0x62,
|
||||
DW_AT_explicit = 0x63,
|
||||
DW_AT_object_pointer = 0x64,
|
||||
DW_AT_endianity = 0x65,
|
||||
DW_AT_elemental = 0x66,
|
||||
DW_AT_pure = 0x67,
|
||||
DW_AT_recursive = 0x68,
|
||||
DW_AT_signature = 0x69,
|
||||
DW_AT_main_subprogram = 0x6a,
|
||||
DW_AT_data_bit_offset = 0x6b,
|
||||
DW_AT_const_expr = 0x6c,
|
||||
DW_AT_enum_class = 0x6d,
|
||||
DW_AT_linkage_name = 0x6e,
|
||||
|
||||
DW_AT_lo_user = 0x2000,
|
||||
DW_AT_hi_user = 0x3fff,
|
||||
|
||||
DW_AT_MIPS_loop_begin = 0x2002,
|
||||
DW_AT_MIPS_tail_loop_begin = 0x2003,
|
||||
DW_AT_MIPS_epilog_begin = 0x2004,
|
||||
DW_AT_MIPS_loop_unroll_factor = 0x2005,
|
||||
DW_AT_MIPS_software_pipeline_depth = 0x2006,
|
||||
DW_AT_MIPS_linkage_name = 0x2007,
|
||||
DW_AT_MIPS_stride = 0x2008,
|
||||
DW_AT_MIPS_abstract_name = 0x2009,
|
||||
DW_AT_MIPS_clone_origin = 0x200a,
|
||||
DW_AT_MIPS_has_inlines = 0x200b,
|
||||
DW_AT_MIPS_stride_byte = 0x200c,
|
||||
DW_AT_MIPS_stride_elem = 0x200d,
|
||||
DW_AT_MIPS_ptr_dopetype = 0x200e,
|
||||
DW_AT_MIPS_allocatable_dopetype = 0x200f,
|
||||
DW_AT_MIPS_assumed_shape_dopetype = 0x2010,
|
||||
|
||||
// This one appears to have only been implemented by Open64 for
|
||||
// fortran and may conflict with other extensions.
|
||||
DW_AT_MIPS_assumed_size = 0x2011,
|
||||
|
||||
// GNU extensions
|
||||
DW_AT_sf_names = 0x2101,
|
||||
DW_AT_src_info = 0x2102,
|
||||
DW_AT_mac_info = 0x2103,
|
||||
DW_AT_src_coords = 0x2104,
|
||||
DW_AT_body_begin = 0x2105,
|
||||
DW_AT_body_end = 0x2106,
|
||||
DW_AT_GNU_vector = 0x2107,
|
||||
DW_AT_GNU_template_name = 0x2110,
|
||||
|
||||
// Extensions for Fission proposal.
|
||||
DW_AT_GNU_dwo_name = 0x2130,
|
||||
DW_AT_GNU_dwo_id = 0x2131,
|
||||
DW_AT_GNU_ranges_base = 0x2132,
|
||||
DW_AT_GNU_addr_base = 0x2133,
|
||||
DW_AT_GNU_pubnames = 0x2134,
|
||||
DW_AT_GNU_pubtypes = 0x2135,
|
||||
|
||||
// Apple extensions.
|
||||
DW_AT_APPLE_optimized = 0x3fe1,
|
||||
DW_AT_APPLE_flags = 0x3fe2,
|
||||
DW_AT_APPLE_isa = 0x3fe3,
|
||||
DW_AT_APPLE_block = 0x3fe4,
|
||||
DW_AT_APPLE_major_runtime_vers = 0x3fe5,
|
||||
DW_AT_APPLE_runtime_class = 0x3fe6,
|
||||
DW_AT_APPLE_omit_frame_ptr = 0x3fe7,
|
||||
DW_AT_APPLE_property_name = 0x3fe8,
|
||||
DW_AT_APPLE_property_getter = 0x3fe9,
|
||||
DW_AT_APPLE_property_setter = 0x3fea,
|
||||
DW_AT_APPLE_property_attribute = 0x3feb,
|
||||
DW_AT_APPLE_objc_complete_type = 0x3fec,
|
||||
DW_AT_APPLE_property = 0x3fed,
|
||||
|
||||
// Attribute form encodings
|
||||
DW_FORM_addr = 0x01,
|
||||
DW_FORM_block2 = 0x03,
|
||||
DW_FORM_block4 = 0x04,
|
||||
DW_FORM_data2 = 0x05,
|
||||
DW_FORM_data4 = 0x06,
|
||||
DW_FORM_data8 = 0x07,
|
||||
DW_FORM_string = 0x08,
|
||||
DW_FORM_block = 0x09,
|
||||
DW_FORM_block1 = 0x0a,
|
||||
DW_FORM_data1 = 0x0b,
|
||||
DW_FORM_flag = 0x0c,
|
||||
DW_FORM_sdata = 0x0d,
|
||||
DW_FORM_strp = 0x0e,
|
||||
DW_FORM_udata = 0x0f,
|
||||
DW_FORM_ref_addr = 0x10,
|
||||
DW_FORM_ref1 = 0x11,
|
||||
DW_FORM_ref2 = 0x12,
|
||||
DW_FORM_ref4 = 0x13,
|
||||
DW_FORM_ref8 = 0x14,
|
||||
DW_FORM_ref_udata = 0x15,
|
||||
DW_FORM_indirect = 0x16,
|
||||
DW_FORM_sec_offset = 0x17,
|
||||
DW_FORM_exprloc = 0x18,
|
||||
DW_FORM_flag_present = 0x19,
|
||||
DW_FORM_ref_sig8 = 0x20,
|
||||
|
||||
// Extensions for Fission proposal
|
||||
DW_FORM_GNU_addr_index = 0x1f01,
|
||||
DW_FORM_GNU_str_index = 0x1f02,
|
||||
|
||||
// Operation encodings
|
||||
DW_OP_addr = 0x03,
|
||||
DW_OP_deref = 0x06,
|
||||
DW_OP_const1u = 0x08,
|
||||
DW_OP_const1s = 0x09,
|
||||
DW_OP_const2u = 0x0a,
|
||||
DW_OP_const2s = 0x0b,
|
||||
DW_OP_const4u = 0x0c,
|
||||
DW_OP_const4s = 0x0d,
|
||||
DW_OP_const8u = 0x0e,
|
||||
DW_OP_const8s = 0x0f,
|
||||
DW_OP_constu = 0x10,
|
||||
DW_OP_consts = 0x11,
|
||||
DW_OP_dup = 0x12,
|
||||
DW_OP_drop = 0x13,
|
||||
DW_OP_over = 0x14,
|
||||
DW_OP_pick = 0x15,
|
||||
DW_OP_swap = 0x16,
|
||||
DW_OP_rot = 0x17,
|
||||
DW_OP_xderef = 0x18,
|
||||
DW_OP_abs = 0x19,
|
||||
DW_OP_and = 0x1a,
|
||||
DW_OP_div = 0x1b,
|
||||
DW_OP_minus = 0x1c,
|
||||
DW_OP_mod = 0x1d,
|
||||
DW_OP_mul = 0x1e,
|
||||
DW_OP_neg = 0x1f,
|
||||
DW_OP_not = 0x20,
|
||||
DW_OP_or = 0x21,
|
||||
DW_OP_plus = 0x22,
|
||||
DW_OP_plus_uconst = 0x23,
|
||||
DW_OP_shl = 0x24,
|
||||
DW_OP_shr = 0x25,
|
||||
DW_OP_shra = 0x26,
|
||||
DW_OP_xor = 0x27,
|
||||
DW_OP_skip = 0x2f,
|
||||
DW_OP_bra = 0x28,
|
||||
DW_OP_eq = 0x29,
|
||||
DW_OP_ge = 0x2a,
|
||||
DW_OP_gt = 0x2b,
|
||||
DW_OP_le = 0x2c,
|
||||
DW_OP_lt = 0x2d,
|
||||
DW_OP_ne = 0x2e,
|
||||
DW_OP_lit0 = 0x30,
|
||||
DW_OP_lit1 = 0x31,
|
||||
DW_OP_lit2 = 0x32,
|
||||
DW_OP_lit3 = 0x33,
|
||||
DW_OP_lit4 = 0x34,
|
||||
DW_OP_lit5 = 0x35,
|
||||
DW_OP_lit6 = 0x36,
|
||||
DW_OP_lit7 = 0x37,
|
||||
DW_OP_lit8 = 0x38,
|
||||
DW_OP_lit9 = 0x39,
|
||||
DW_OP_lit10 = 0x3a,
|
||||
DW_OP_lit11 = 0x3b,
|
||||
DW_OP_lit12 = 0x3c,
|
||||
DW_OP_lit13 = 0x3d,
|
||||
DW_OP_lit14 = 0x3e,
|
||||
DW_OP_lit15 = 0x3f,
|
||||
DW_OP_lit16 = 0x40,
|
||||
DW_OP_lit17 = 0x41,
|
||||
DW_OP_lit18 = 0x42,
|
||||
DW_OP_lit19 = 0x43,
|
||||
DW_OP_lit20 = 0x44,
|
||||
DW_OP_lit21 = 0x45,
|
||||
DW_OP_lit22 = 0x46,
|
||||
DW_OP_lit23 = 0x47,
|
||||
DW_OP_lit24 = 0x48,
|
||||
DW_OP_lit25 = 0x49,
|
||||
DW_OP_lit26 = 0x4a,
|
||||
DW_OP_lit27 = 0x4b,
|
||||
DW_OP_lit28 = 0x4c,
|
||||
DW_OP_lit29 = 0x4d,
|
||||
DW_OP_lit30 = 0x4e,
|
||||
DW_OP_lit31 = 0x4f,
|
||||
DW_OP_reg0 = 0x50,
|
||||
DW_OP_reg1 = 0x51,
|
||||
DW_OP_reg2 = 0x52,
|
||||
DW_OP_reg3 = 0x53,
|
||||
DW_OP_reg4 = 0x54,
|
||||
DW_OP_reg5 = 0x55,
|
||||
DW_OP_reg6 = 0x56,
|
||||
DW_OP_reg7 = 0x57,
|
||||
DW_OP_reg8 = 0x58,
|
||||
DW_OP_reg9 = 0x59,
|
||||
DW_OP_reg10 = 0x5a,
|
||||
DW_OP_reg11 = 0x5b,
|
||||
DW_OP_reg12 = 0x5c,
|
||||
DW_OP_reg13 = 0x5d,
|
||||
DW_OP_reg14 = 0x5e,
|
||||
DW_OP_reg15 = 0x5f,
|
||||
DW_OP_reg16 = 0x60,
|
||||
DW_OP_reg17 = 0x61,
|
||||
DW_OP_reg18 = 0x62,
|
||||
DW_OP_reg19 = 0x63,
|
||||
DW_OP_reg20 = 0x64,
|
||||
DW_OP_reg21 = 0x65,
|
||||
DW_OP_reg22 = 0x66,
|
||||
DW_OP_reg23 = 0x67,
|
||||
DW_OP_reg24 = 0x68,
|
||||
DW_OP_reg25 = 0x69,
|
||||
DW_OP_reg26 = 0x6a,
|
||||
DW_OP_reg27 = 0x6b,
|
||||
DW_OP_reg28 = 0x6c,
|
||||
DW_OP_reg29 = 0x6d,
|
||||
DW_OP_reg30 = 0x6e,
|
||||
DW_OP_reg31 = 0x6f,
|
||||
DW_OP_breg0 = 0x70,
|
||||
DW_OP_breg1 = 0x71,
|
||||
DW_OP_breg2 = 0x72,
|
||||
DW_OP_breg3 = 0x73,
|
||||
DW_OP_breg4 = 0x74,
|
||||
DW_OP_breg5 = 0x75,
|
||||
DW_OP_breg6 = 0x76,
|
||||
DW_OP_breg7 = 0x77,
|
||||
DW_OP_breg8 = 0x78,
|
||||
DW_OP_breg9 = 0x79,
|
||||
DW_OP_breg10 = 0x7a,
|
||||
DW_OP_breg11 = 0x7b,
|
||||
DW_OP_breg12 = 0x7c,
|
||||
DW_OP_breg13 = 0x7d,
|
||||
DW_OP_breg14 = 0x7e,
|
||||
DW_OP_breg15 = 0x7f,
|
||||
DW_OP_breg16 = 0x80,
|
||||
DW_OP_breg17 = 0x81,
|
||||
DW_OP_breg18 = 0x82,
|
||||
DW_OP_breg19 = 0x83,
|
||||
DW_OP_breg20 = 0x84,
|
||||
DW_OP_breg21 = 0x85,
|
||||
DW_OP_breg22 = 0x86,
|
||||
DW_OP_breg23 = 0x87,
|
||||
DW_OP_breg24 = 0x88,
|
||||
DW_OP_breg25 = 0x89,
|
||||
DW_OP_breg26 = 0x8a,
|
||||
DW_OP_breg27 = 0x8b,
|
||||
DW_OP_breg28 = 0x8c,
|
||||
DW_OP_breg29 = 0x8d,
|
||||
DW_OP_breg30 = 0x8e,
|
||||
DW_OP_breg31 = 0x8f,
|
||||
DW_OP_regx = 0x90,
|
||||
DW_OP_fbreg = 0x91,
|
||||
DW_OP_bregx = 0x92,
|
||||
DW_OP_piece = 0x93,
|
||||
DW_OP_deref_size = 0x94,
|
||||
DW_OP_xderef_size = 0x95,
|
||||
DW_OP_nop = 0x96,
|
||||
DW_OP_push_object_address = 0x97,
|
||||
DW_OP_call2 = 0x98,
|
||||
DW_OP_call4 = 0x99,
|
||||
DW_OP_call_ref = 0x9a,
|
||||
DW_OP_form_tls_address = 0x9b,
|
||||
DW_OP_call_frame_cfa = 0x9c,
|
||||
DW_OP_bit_piece = 0x9d,
|
||||
DW_OP_implicit_value = 0x9e,
|
||||
DW_OP_stack_value = 0x9f,
|
||||
DW_OP_lo_user = 0xe0,
|
||||
DW_OP_hi_user = 0xff,
|
||||
|
||||
// Extensions for Fission proposal.
|
||||
DW_OP_GNU_addr_index = 0xfb,
|
||||
DW_OP_GNU_const_index = 0xfc,
|
||||
|
||||
// Encoding attribute values
|
||||
DW_ATE_address = 0x01,
|
||||
DW_ATE_boolean = 0x02,
|
||||
DW_ATE_complex_float = 0x03,
|
||||
DW_ATE_float = 0x04,
|
||||
DW_ATE_signed = 0x05,
|
||||
DW_ATE_signed_char = 0x06,
|
||||
DW_ATE_unsigned = 0x07,
|
||||
DW_ATE_unsigned_char = 0x08,
|
||||
DW_ATE_imaginary_float = 0x09,
|
||||
DW_ATE_packed_decimal = 0x0a,
|
||||
DW_ATE_numeric_string = 0x0b,
|
||||
DW_ATE_edited = 0x0c,
|
||||
DW_ATE_signed_fixed = 0x0d,
|
||||
DW_ATE_unsigned_fixed = 0x0e,
|
||||
DW_ATE_decimal_float = 0x0f,
|
||||
DW_ATE_UTF = 0x10,
|
||||
DW_ATE_lo_user = 0x80,
|
||||
DW_ATE_hi_user = 0xff,
|
||||
|
||||
// Decimal sign attribute values
|
||||
DW_DS_unsigned = 0x01,
|
||||
DW_DS_leading_overpunch = 0x02,
|
||||
DW_DS_trailing_overpunch = 0x03,
|
||||
DW_DS_leading_separate = 0x04,
|
||||
DW_DS_trailing_separate = 0x05,
|
||||
|
||||
// Endianity attribute values
|
||||
DW_END_default = 0x00,
|
||||
DW_END_big = 0x01,
|
||||
DW_END_little = 0x02,
|
||||
DW_END_lo_user = 0x40,
|
||||
DW_END_hi_user = 0xff,
|
||||
|
||||
// Accessibility codes
|
||||
DW_ACCESS_public = 0x01,
|
||||
DW_ACCESS_protected = 0x02,
|
||||
DW_ACCESS_private = 0x03,
|
||||
|
||||
// Visibility codes
|
||||
DW_VIS_local = 0x01,
|
||||
DW_VIS_exported = 0x02,
|
||||
DW_VIS_qualified = 0x03,
|
||||
|
||||
// Virtuality codes
|
||||
DW_VIRTUALITY_none = 0x00,
|
||||
DW_VIRTUALITY_virtual = 0x01,
|
||||
DW_VIRTUALITY_pure_virtual = 0x02,
|
||||
|
||||
// Language names
|
||||
DW_LANG_C89 = 0x0001,
|
||||
DW_LANG_C = 0x0002,
|
||||
DW_LANG_Ada83 = 0x0003,
|
||||
DW_LANG_C_plus_plus = 0x0004,
|
||||
DW_LANG_Cobol74 = 0x0005,
|
||||
DW_LANG_Cobol85 = 0x0006,
|
||||
DW_LANG_Fortran77 = 0x0007,
|
||||
DW_LANG_Fortran90 = 0x0008,
|
||||
DW_LANG_Pascal83 = 0x0009,
|
||||
DW_LANG_Modula2 = 0x000a,
|
||||
DW_LANG_Java = 0x000b,
|
||||
DW_LANG_C99 = 0x000c,
|
||||
DW_LANG_Ada95 = 0x000d,
|
||||
DW_LANG_Fortran95 = 0x000e,
|
||||
DW_LANG_PLI = 0x000f,
|
||||
DW_LANG_ObjC = 0x0010,
|
||||
DW_LANG_ObjC_plus_plus = 0x0011,
|
||||
DW_LANG_UPC = 0x0012,
|
||||
DW_LANG_D = 0x0013,
|
||||
DW_LANG_Python = 0x0014,
|
||||
DW_LANG_lo_user = 0x8000,
|
||||
DW_LANG_Mips_Assembler = 0x8001,
|
||||
DW_LANG_hi_user = 0xffff,
|
||||
|
||||
// Identifier case codes
|
||||
DW_ID_case_sensitive = 0x00,
|
||||
DW_ID_up_case = 0x01,
|
||||
DW_ID_down_case = 0x02,
|
||||
DW_ID_case_insensitive = 0x03,
|
||||
|
||||
// Calling convention codes
|
||||
DW_CC_normal = 0x01,
|
||||
DW_CC_program = 0x02,
|
||||
DW_CC_nocall = 0x03,
|
||||
DW_CC_lo_user = 0x40,
|
||||
DW_CC_hi_user = 0xff,
|
||||
|
||||
// Inline codes
|
||||
DW_INL_not_inlined = 0x00,
|
||||
DW_INL_inlined = 0x01,
|
||||
DW_INL_declared_not_inlined = 0x02,
|
||||
DW_INL_declared_inlined = 0x03,
|
||||
|
||||
// Array ordering
|
||||
DW_ORD_row_major = 0x00,
|
||||
DW_ORD_col_major = 0x01,
|
||||
|
||||
// Discriminant descriptor values
|
||||
DW_DSC_label = 0x00,
|
||||
DW_DSC_range = 0x01,
|
||||
|
||||
// Line Number Standard Opcode Encodings
|
||||
DW_LNS_extended_op = 0x00,
|
||||
DW_LNS_copy = 0x01,
|
||||
DW_LNS_advance_pc = 0x02,
|
||||
DW_LNS_advance_line = 0x03,
|
||||
DW_LNS_set_file = 0x04,
|
||||
DW_LNS_set_column = 0x05,
|
||||
DW_LNS_negate_stmt = 0x06,
|
||||
DW_LNS_set_basic_block = 0x07,
|
||||
DW_LNS_const_add_pc = 0x08,
|
||||
DW_LNS_fixed_advance_pc = 0x09,
|
||||
DW_LNS_set_prologue_end = 0x0a,
|
||||
DW_LNS_set_epilogue_begin = 0x0b,
|
||||
DW_LNS_set_isa = 0x0c,
|
||||
|
||||
// Line Number Extended Opcode Encodings
|
||||
DW_LNE_end_sequence = 0x01,
|
||||
DW_LNE_set_address = 0x02,
|
||||
DW_LNE_define_file = 0x03,
|
||||
DW_LNE_set_discriminator = 0x04,
|
||||
DW_LNE_lo_user = 0x80,
|
||||
DW_LNE_hi_user = 0xff,
|
||||
|
||||
// Macinfo Type Encodings
|
||||
DW_MACINFO_define = 0x01,
|
||||
DW_MACINFO_undef = 0x02,
|
||||
DW_MACINFO_start_file = 0x03,
|
||||
DW_MACINFO_end_file = 0x04,
|
||||
DW_MACINFO_vendor_ext = 0xff,
|
||||
|
||||
// Call frame instruction encodings
|
||||
DW_CFA_extended = 0x00,
|
||||
DW_CFA_nop = 0x00,
|
||||
DW_CFA_advance_loc = 0x40,
|
||||
DW_CFA_offset = 0x80,
|
||||
DW_CFA_restore = 0xc0,
|
||||
DW_CFA_set_loc = 0x01,
|
||||
DW_CFA_advance_loc1 = 0x02,
|
||||
DW_CFA_advance_loc2 = 0x03,
|
||||
DW_CFA_advance_loc4 = 0x04,
|
||||
DW_CFA_offset_extended = 0x05,
|
||||
DW_CFA_restore_extended = 0x06,
|
||||
DW_CFA_undefined = 0x07,
|
||||
DW_CFA_same_value = 0x08,
|
||||
DW_CFA_register = 0x09,
|
||||
DW_CFA_remember_state = 0x0a,
|
||||
DW_CFA_restore_state = 0x0b,
|
||||
DW_CFA_def_cfa = 0x0c,
|
||||
DW_CFA_def_cfa_register = 0x0d,
|
||||
DW_CFA_def_cfa_offset = 0x0e,
|
||||
DW_CFA_def_cfa_expression = 0x0f,
|
||||
DW_CFA_expression = 0x10,
|
||||
DW_CFA_offset_extended_sf = 0x11,
|
||||
DW_CFA_def_cfa_sf = 0x12,
|
||||
DW_CFA_def_cfa_offset_sf = 0x13,
|
||||
DW_CFA_val_offset = 0x14,
|
||||
DW_CFA_val_offset_sf = 0x15,
|
||||
DW_CFA_val_expression = 0x16,
|
||||
DW_CFA_MIPS_advance_loc8 = 0x1d,
|
||||
DW_CFA_GNU_window_save = 0x2d,
|
||||
DW_CFA_GNU_args_size = 0x2e,
|
||||
DW_CFA_lo_user = 0x1c,
|
||||
DW_CFA_hi_user = 0x3f,
|
||||
|
||||
DW_EH_PE_absptr = 0x00,
|
||||
DW_EH_PE_omit = 0xff,
|
||||
DW_EH_PE_uleb128 = 0x01,
|
||||
DW_EH_PE_udata2 = 0x02,
|
||||
DW_EH_PE_udata4 = 0x03,
|
||||
DW_EH_PE_udata8 = 0x04,
|
||||
DW_EH_PE_sleb128 = 0x09,
|
||||
DW_EH_PE_sdata2 = 0x0A,
|
||||
DW_EH_PE_sdata4 = 0x0B,
|
||||
DW_EH_PE_sdata8 = 0x0C,
|
||||
DW_EH_PE_signed = 0x08,
|
||||
DW_EH_PE_pcrel = 0x10,
|
||||
DW_EH_PE_textrel = 0x20,
|
||||
DW_EH_PE_datarel = 0x30,
|
||||
DW_EH_PE_funcrel = 0x40,
|
||||
DW_EH_PE_aligned = 0x50,
|
||||
DW_EH_PE_indirect = 0x80,
|
||||
|
||||
// Apple Objective-C Property Attributes
|
||||
DW_APPLE_PROPERTY_readonly = 0x01,
|
||||
DW_APPLE_PROPERTY_readwrite = 0x02,
|
||||
DW_APPLE_PROPERTY_assign = 0x04,
|
||||
DW_APPLE_PROPERTY_retain = 0x08,
|
||||
DW_APPLE_PROPERTY_copy = 0x10,
|
||||
DW_APPLE_PROPERTY_nonatomic = 0x20
|
||||
};
|
||||
|
||||
/// TagString - Return the string for the specified tag.
|
||||
///
|
||||
const char *TagString(unsigned Tag);
|
||||
|
||||
/// ChildrenString - Return the string for the specified children flag.
|
||||
///
|
||||
const char *ChildrenString(unsigned Children);
|
||||
|
||||
/// AttributeString - Return the string for the specified attribute.
|
||||
///
|
||||
const char *AttributeString(unsigned Attribute);
|
||||
|
||||
/// FormEncodingString - Return the string for the specified form encoding.
|
||||
///
|
||||
const char *FormEncodingString(unsigned Encoding);
|
||||
|
||||
/// OperationEncodingString - Return the string for the specified operation
|
||||
/// encoding.
|
||||
const char *OperationEncodingString(unsigned Encoding);
|
||||
|
||||
/// AttributeEncodingString - Return the string for the specified attribute
|
||||
/// encoding.
|
||||
const char *AttributeEncodingString(unsigned Encoding);
|
||||
|
||||
/// DecimalSignString - Return the string for the specified decimal sign
|
||||
/// attribute.
|
||||
const char *DecimalSignString(unsigned Sign);
|
||||
|
||||
/// EndianityString - Return the string for the specified endianity.
|
||||
///
|
||||
const char *EndianityString(unsigned Endian);
|
||||
|
||||
/// AccessibilityString - Return the string for the specified accessibility.
|
||||
///
|
||||
const char *AccessibilityString(unsigned Access);
|
||||
|
||||
/// VisibilityString - Return the string for the specified visibility.
|
||||
///
|
||||
const char *VisibilityString(unsigned Visibility);
|
||||
|
||||
/// VirtualityString - Return the string for the specified virtuality.
|
||||
///
|
||||
const char *VirtualityString(unsigned Virtuality);
|
||||
|
||||
/// LanguageString - Return the string for the specified language.
|
||||
///
|
||||
const char *LanguageString(unsigned Language);
|
||||
|
||||
/// CaseString - Return the string for the specified identifier case.
|
||||
///
|
||||
const char *CaseString(unsigned Case);
|
||||
|
||||
/// ConventionString - Return the string for the specified calling convention.
|
||||
///
|
||||
const char *ConventionString(unsigned Convention);
|
||||
|
||||
/// InlineCodeString - Return the string for the specified inline code.
|
||||
///
|
||||
const char *InlineCodeString(unsigned Code);
|
||||
|
||||
/// ArrayOrderString - Return the string for the specified array order.
|
||||
///
|
||||
const char *ArrayOrderString(unsigned Order);
|
||||
|
||||
/// DiscriminantString - Return the string for the specified discriminant
|
||||
/// descriptor.
|
||||
const char *DiscriminantString(unsigned Discriminant);
|
||||
|
||||
/// LNStandardString - Return the string for the specified line number standard.
|
||||
///
|
||||
const char *LNStandardString(unsigned Standard);
|
||||
|
||||
/// LNExtendedString - Return the string for the specified line number extended
|
||||
/// opcode encodings.
|
||||
const char *LNExtendedString(unsigned Encoding);
|
||||
|
||||
/// MacinfoString - Return the string for the specified macinfo type encodings.
|
||||
///
|
||||
const char *MacinfoString(unsigned Encoding);
|
||||
|
||||
/// CallFrameString - Return the string for the specified call frame instruction
|
||||
/// encodings.
|
||||
const char *CallFrameString(unsigned Encoding);
|
||||
} // End of namespace dwarf
|
||||
|
||||
} // End of namespace llvm
|
||||
|
||||
#endif
|
||||
104
thirdparty/clang/include/llvm/Support/DynamicLibrary.h
vendored
Normal file
104
thirdparty/clang/include/llvm/Support/DynamicLibrary.h
vendored
Normal file
@@ -0,0 +1,104 @@
|
||||
//===-- llvm/Support/DynamicLibrary.h - Portable Dynamic Library -*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file declares the sys::DynamicLibrary class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SYSTEM_DYNAMICLIBRARY_H
|
||||
#define LLVM_SYSTEM_DYNAMICLIBRARY_H
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class StringRef;
|
||||
|
||||
namespace sys {
|
||||
|
||||
/// This class provides a portable interface to dynamic libraries which also
|
||||
/// might be known as shared libraries, shared objects, dynamic shared
|
||||
/// objects, or dynamic link libraries. Regardless of the terminology or the
|
||||
/// operating system interface, this class provides a portable interface that
|
||||
/// allows dynamic libraries to be loaded and searched for externally
|
||||
/// defined symbols. This is typically used to provide "plug-in" support.
|
||||
/// It also allows for symbols to be defined which don't live in any library,
|
||||
/// but rather the main program itself, useful on Windows where the main
|
||||
/// executable cannot be searched.
|
||||
///
|
||||
/// Note: there is currently no interface for temporarily loading a library,
|
||||
/// or for unloading libraries when the LLVM library is unloaded.
|
||||
class DynamicLibrary {
|
||||
// Placeholder whose address represents an invalid library.
|
||||
// We use this instead of NULL or a pointer-int pair because the OS library
|
||||
// might define 0 or 1 to be "special" handles, such as "search all".
|
||||
static char Invalid;
|
||||
|
||||
// Opaque data used to interface with OS-specific dynamic library handling.
|
||||
void *Data;
|
||||
|
||||
explicit DynamicLibrary(void *data = &Invalid) : Data(data) {}
|
||||
public:
|
||||
/// Returns true if the object refers to a valid library.
|
||||
bool isValid() { return Data != &Invalid; }
|
||||
|
||||
/// Searches through the library for the symbol \p symbolName. If it is
|
||||
/// found, the address of that symbol is returned. If not, NULL is returned.
|
||||
/// Note that NULL will also be returned if the library failed to load.
|
||||
/// Use isValid() to distinguish these cases if it is important.
|
||||
/// Note that this will \e not search symbols explicitly registered by
|
||||
/// AddSymbol().
|
||||
void *getAddressOfSymbol(const char *symbolName);
|
||||
|
||||
/// This function permanently loads the dynamic library at the given path.
|
||||
/// The library will only be unloaded when the program terminates.
|
||||
/// This returns a valid DynamicLibrary instance on success and an invalid
|
||||
/// instance on failure (see isValid()). \p *errMsg will only be modified
|
||||
/// if the library fails to load.
|
||||
///
|
||||
/// It is safe to call this function multiple times for the same library.
|
||||
/// @brief Open a dynamic library permanently.
|
||||
static DynamicLibrary getPermanentLibrary(const char *filename,
|
||||
std::string *errMsg = 0);
|
||||
|
||||
/// This function permanently loads the dynamic library at the given path.
|
||||
/// Use this instead of getPermanentLibrary() when you won't need to get
|
||||
/// symbols from the library itself.
|
||||
///
|
||||
/// It is safe to call this function multiple times for the same library.
|
||||
static bool LoadLibraryPermanently(const char *Filename,
|
||||
std::string *ErrMsg = 0) {
|
||||
return !getPermanentLibrary(Filename, ErrMsg).isValid();
|
||||
}
|
||||
|
||||
/// This function will search through all previously loaded dynamic
|
||||
/// libraries for the symbol \p symbolName. If it is found, the address of
|
||||
/// that symbol is returned. If not, null is returned. Note that this will
|
||||
/// search permanently loaded libraries (getPermanentLibrary()) as well
|
||||
/// as explicitly registered symbols (AddSymbol()).
|
||||
/// @throws std::string on error.
|
||||
/// @brief Search through libraries for address of a symbol
|
||||
static void *SearchForAddressOfSymbol(const char *symbolName);
|
||||
|
||||
/// @brief Convenience function for C++ophiles.
|
||||
static void *SearchForAddressOfSymbol(const std::string &symbolName) {
|
||||
return SearchForAddressOfSymbol(symbolName.c_str());
|
||||
}
|
||||
|
||||
/// This functions permanently adds the symbol \p symbolName with the
|
||||
/// value \p symbolValue. These symbols are searched before any
|
||||
/// libraries.
|
||||
/// @brief Add searchable symbol/value pair.
|
||||
static void AddSymbol(StringRef symbolName, void *symbolValue);
|
||||
};
|
||||
|
||||
} // End sys namespace
|
||||
} // End llvm namespace
|
||||
|
||||
#endif // LLVM_SYSTEM_DYNAMIC_LIBRARY_H
|
||||
1469
thirdparty/clang/include/llvm/Support/ELF.h
vendored
Normal file
1469
thirdparty/clang/include/llvm/Support/ELF.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
179
thirdparty/clang/include/llvm/Support/Endian.h
vendored
Normal file
179
thirdparty/clang/include/llvm/Support/Endian.h
vendored
Normal file
@@ -0,0 +1,179 @@
|
||||
//===- Endian.h - Utilities for IO with endian specific data ----*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file declares generic functions to read and write endian specific data.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_ENDIAN_H
|
||||
#define LLVM_SUPPORT_ENDIAN_H
|
||||
|
||||
#include "llvm/Support/AlignOf.h"
|
||||
#include "llvm/Support/Host.h"
|
||||
#include "llvm/Support/SwapByteOrder.h"
|
||||
#include "llvm/Support/type_traits.h"
|
||||
|
||||
namespace llvm {
|
||||
namespace support {
|
||||
enum endianness {big, little, native};
|
||||
|
||||
// These are named values for common alignments.
|
||||
enum {aligned = 0, unaligned = 1};
|
||||
|
||||
namespace detail {
|
||||
/// \brief ::value is either alignment, or alignof(T) if alignment is 0.
|
||||
template<class T, int alignment>
|
||||
struct PickAlignment {
|
||||
enum {value = alignment == 0 ? AlignOf<T>::Alignment : alignment};
|
||||
};
|
||||
} // end namespace detail
|
||||
|
||||
namespace endian {
|
||||
template<typename value_type, endianness endian>
|
||||
inline value_type byte_swap(value_type value) {
|
||||
if (endian != native && sys::IsBigEndianHost != (endian == big))
|
||||
return sys::SwapByteOrder(value);
|
||||
return value;
|
||||
}
|
||||
|
||||
template<typename value_type,
|
||||
endianness endian,
|
||||
std::size_t alignment>
|
||||
inline value_type read(const void *memory) {
|
||||
value_type ret;
|
||||
|
||||
memcpy(&ret,
|
||||
LLVM_ASSUME_ALIGNED(memory,
|
||||
(detail::PickAlignment<value_type, alignment>::value)),
|
||||
sizeof(value_type));
|
||||
return byte_swap<value_type, endian>(ret);
|
||||
}
|
||||
|
||||
template<typename value_type,
|
||||
endianness endian,
|
||||
std::size_t alignment>
|
||||
inline void write(void *memory, value_type value) {
|
||||
value = byte_swap<value_type, endian>(value);
|
||||
memcpy(LLVM_ASSUME_ALIGNED(memory,
|
||||
(detail::PickAlignment<value_type, alignment>::value)),
|
||||
&value,
|
||||
sizeof(value_type));
|
||||
}
|
||||
} // end namespace endian
|
||||
|
||||
namespace detail {
|
||||
template<typename value_type,
|
||||
endianness endian,
|
||||
std::size_t alignment>
|
||||
struct packed_endian_specific_integral {
|
||||
operator value_type() const {
|
||||
return endian::read<value_type, endian, alignment>(
|
||||
(const void*)Value.buffer);
|
||||
}
|
||||
|
||||
void operator=(value_type newValue) {
|
||||
endian::write<value_type, endian, alignment>(
|
||||
(void*)Value.buffer, newValue);
|
||||
}
|
||||
|
||||
private:
|
||||
AlignedCharArray<PickAlignment<value_type, alignment>::value,
|
||||
sizeof(value_type)> Value;
|
||||
};
|
||||
} // end namespace detail
|
||||
|
||||
typedef detail::packed_endian_specific_integral
|
||||
<uint8_t, little, unaligned> ulittle8_t;
|
||||
typedef detail::packed_endian_specific_integral
|
||||
<uint16_t, little, unaligned> ulittle16_t;
|
||||
typedef detail::packed_endian_specific_integral
|
||||
<uint32_t, little, unaligned> ulittle32_t;
|
||||
typedef detail::packed_endian_specific_integral
|
||||
<uint64_t, little, unaligned> ulittle64_t;
|
||||
|
||||
typedef detail::packed_endian_specific_integral
|
||||
<int8_t, little, unaligned> little8_t;
|
||||
typedef detail::packed_endian_specific_integral
|
||||
<int16_t, little, unaligned> little16_t;
|
||||
typedef detail::packed_endian_specific_integral
|
||||
<int32_t, little, unaligned> little32_t;
|
||||
typedef detail::packed_endian_specific_integral
|
||||
<int64_t, little, unaligned> little64_t;
|
||||
|
||||
typedef detail::packed_endian_specific_integral
|
||||
<uint8_t, little, aligned> aligned_ulittle8_t;
|
||||
typedef detail::packed_endian_specific_integral
|
||||
<uint16_t, little, aligned> aligned_ulittle16_t;
|
||||
typedef detail::packed_endian_specific_integral
|
||||
<uint32_t, little, aligned> aligned_ulittle32_t;
|
||||
typedef detail::packed_endian_specific_integral
|
||||
<uint64_t, little, aligned> aligned_ulittle64_t;
|
||||
|
||||
typedef detail::packed_endian_specific_integral
|
||||
<int8_t, little, aligned> aligned_little8_t;
|
||||
typedef detail::packed_endian_specific_integral
|
||||
<int16_t, little, aligned> aligned_little16_t;
|
||||
typedef detail::packed_endian_specific_integral
|
||||
<int32_t, little, aligned> aligned_little32_t;
|
||||
typedef detail::packed_endian_specific_integral
|
||||
<int64_t, little, aligned> aligned_little64_t;
|
||||
|
||||
typedef detail::packed_endian_specific_integral
|
||||
<uint8_t, big, unaligned> ubig8_t;
|
||||
typedef detail::packed_endian_specific_integral
|
||||
<uint16_t, big, unaligned> ubig16_t;
|
||||
typedef detail::packed_endian_specific_integral
|
||||
<uint32_t, big, unaligned> ubig32_t;
|
||||
typedef detail::packed_endian_specific_integral
|
||||
<uint64_t, big, unaligned> ubig64_t;
|
||||
|
||||
typedef detail::packed_endian_specific_integral
|
||||
<int8_t, big, unaligned> big8_t;
|
||||
typedef detail::packed_endian_specific_integral
|
||||
<int16_t, big, unaligned> big16_t;
|
||||
typedef detail::packed_endian_specific_integral
|
||||
<int32_t, big, unaligned> big32_t;
|
||||
typedef detail::packed_endian_specific_integral
|
||||
<int64_t, big, unaligned> big64_t;
|
||||
|
||||
typedef detail::packed_endian_specific_integral
|
||||
<uint8_t, big, aligned> aligned_ubig8_t;
|
||||
typedef detail::packed_endian_specific_integral
|
||||
<uint16_t, big, aligned> aligned_ubig16_t;
|
||||
typedef detail::packed_endian_specific_integral
|
||||
<uint32_t, big, aligned> aligned_ubig32_t;
|
||||
typedef detail::packed_endian_specific_integral
|
||||
<uint64_t, big, aligned> aligned_ubig64_t;
|
||||
|
||||
typedef detail::packed_endian_specific_integral
|
||||
<int8_t, big, aligned> aligned_big8_t;
|
||||
typedef detail::packed_endian_specific_integral
|
||||
<int16_t, big, aligned> aligned_big16_t;
|
||||
typedef detail::packed_endian_specific_integral
|
||||
<int32_t, big, aligned> aligned_big32_t;
|
||||
typedef detail::packed_endian_specific_integral
|
||||
<int64_t, big, aligned> aligned_big64_t;
|
||||
|
||||
typedef detail::packed_endian_specific_integral
|
||||
<uint16_t, native, unaligned> unaligned_uint16_t;
|
||||
typedef detail::packed_endian_specific_integral
|
||||
<uint32_t, native, unaligned> unaligned_uint32_t;
|
||||
typedef detail::packed_endian_specific_integral
|
||||
<uint64_t, native, unaligned> unaligned_uint64_t;
|
||||
|
||||
typedef detail::packed_endian_specific_integral
|
||||
<int16_t, native, unaligned> unaligned_int16_t;
|
||||
typedef detail::packed_endian_specific_integral
|
||||
<int32_t, native, unaligned> unaligned_int32_t;
|
||||
typedef detail::packed_endian_specific_integral
|
||||
<int64_t, native, unaligned> unaligned_int64_t;
|
||||
} // end namespace llvm
|
||||
} // end namespace support
|
||||
|
||||
#endif
|
||||
34
thirdparty/clang/include/llvm/Support/Errno.h
vendored
Normal file
34
thirdparty/clang/include/llvm/Support/Errno.h
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
//===- llvm/Support/Errno.h - Portable+convenient errno handling -*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file declares some portable and convenient functions to deal with errno.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_ERRNO_H
|
||||
#define LLVM_SUPPORT_ERRNO_H
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace llvm {
|
||||
namespace sys {
|
||||
|
||||
/// Returns a string representation of the errno value, using whatever
|
||||
/// thread-safe variant of strerror() is available. Be sure to call this
|
||||
/// immediately after the function that set errno, or errno may have been
|
||||
/// overwritten by an intervening call.
|
||||
std::string StrError();
|
||||
|
||||
/// Like the no-argument version above, but uses \p errnum instead of errno.
|
||||
std::string StrError(int errnum);
|
||||
|
||||
} // namespace sys
|
||||
} // namespace llvm
|
||||
|
||||
#endif // LLVM_SYSTEM_ERRNO_H
|
||||
111
thirdparty/clang/include/llvm/Support/ErrorHandling.h
vendored
Normal file
111
thirdparty/clang/include/llvm/Support/ErrorHandling.h
vendored
Normal file
@@ -0,0 +1,111 @@
|
||||
//===- llvm/Support/ErrorHandling.h - Fatal error handling ------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines an API used to indicate fatal error conditions. Non-fatal
|
||||
// errors (most of them) should be handled through LLVMContext.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_ERRORHANDLING_H
|
||||
#define LLVM_SUPPORT_ERRORHANDLING_H
|
||||
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include <string>
|
||||
|
||||
namespace llvm {
|
||||
class Twine;
|
||||
|
||||
/// An error handler callback.
|
||||
typedef void (*fatal_error_handler_t)(void *user_data,
|
||||
const std::string& reason,
|
||||
bool gen_crash_diag);
|
||||
|
||||
/// install_fatal_error_handler - Installs a new error handler to be used
|
||||
/// whenever a serious (non-recoverable) error is encountered by LLVM.
|
||||
///
|
||||
/// If you are using llvm_start_multithreaded, you should register the handler
|
||||
/// before doing that.
|
||||
///
|
||||
/// If no error handler is installed the default is to print the error message
|
||||
/// to stderr, and call exit(1). If an error handler is installed then it is
|
||||
/// the handler's responsibility to log the message, it will no longer be
|
||||
/// printed to stderr. If the error handler returns, then exit(1) will be
|
||||
/// called.
|
||||
///
|
||||
/// It is dangerous to naively use an error handler which throws an exception.
|
||||
/// Even though some applications desire to gracefully recover from arbitrary
|
||||
/// faults, blindly throwing exceptions through unfamiliar code isn't a way to
|
||||
/// achieve this.
|
||||
///
|
||||
/// \param user_data - An argument which will be passed to the install error
|
||||
/// handler.
|
||||
void install_fatal_error_handler(fatal_error_handler_t handler,
|
||||
void *user_data = 0);
|
||||
|
||||
/// Restores default error handling behaviour.
|
||||
/// This must not be called between llvm_start_multithreaded() and
|
||||
/// llvm_stop_multithreaded().
|
||||
void remove_fatal_error_handler();
|
||||
|
||||
/// ScopedFatalErrorHandler - This is a simple helper class which just
|
||||
/// calls install_fatal_error_handler in its constructor and
|
||||
/// remove_fatal_error_handler in its destructor.
|
||||
struct ScopedFatalErrorHandler {
|
||||
explicit ScopedFatalErrorHandler(fatal_error_handler_t handler,
|
||||
void *user_data = 0) {
|
||||
install_fatal_error_handler(handler, user_data);
|
||||
}
|
||||
|
||||
~ScopedFatalErrorHandler() { remove_fatal_error_handler(); }
|
||||
};
|
||||
|
||||
/// Reports a serious error, calling any installed error handler. These
|
||||
/// functions are intended to be used for error conditions which are outside
|
||||
/// the control of the compiler (I/O errors, invalid user input, etc.)
|
||||
///
|
||||
/// If no error handler is installed the default is to print the message to
|
||||
/// standard error, followed by a newline.
|
||||
/// After the error handler is called this function will call exit(1), it
|
||||
/// does not return.
|
||||
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason,
|
||||
bool gen_crash_diag = true);
|
||||
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const std::string &reason,
|
||||
bool gen_crash_diag = true);
|
||||
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(StringRef reason,
|
||||
bool gen_crash_diag = true);
|
||||
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const Twine &reason,
|
||||
bool gen_crash_diag = true);
|
||||
|
||||
/// This function calls abort(), and prints the optional message to stderr.
|
||||
/// Use the llvm_unreachable macro (that adds location info), instead of
|
||||
/// calling this function directly.
|
||||
LLVM_ATTRIBUTE_NORETURN void llvm_unreachable_internal(const char *msg=0,
|
||||
const char *file=0,
|
||||
unsigned line=0);
|
||||
}
|
||||
|
||||
/// Marks that the current location is not supposed to be reachable.
|
||||
/// In !NDEBUG builds, prints the message and location info to stderr.
|
||||
/// In NDEBUG builds, becomes an optimizer hint that the current location
|
||||
/// is not supposed to be reachable. On compilers that don't support
|
||||
/// such hints, prints a reduced message instead.
|
||||
///
|
||||
/// Use this instead of assert(0). It conveys intent more clearly and
|
||||
/// allows compilers to omit some unnecessary code.
|
||||
#ifndef NDEBUG
|
||||
#define llvm_unreachable(msg) \
|
||||
::llvm::llvm_unreachable_internal(msg, __FILE__, __LINE__)
|
||||
#elif defined(LLVM_BUILTIN_UNREACHABLE)
|
||||
#define llvm_unreachable(msg) LLVM_BUILTIN_UNREACHABLE
|
||||
#else
|
||||
#define llvm_unreachable(msg) ::llvm::llvm_unreachable_internal()
|
||||
#endif
|
||||
|
||||
#endif
|
||||
514
thirdparty/clang/include/llvm/Support/ErrorOr.h
vendored
Normal file
514
thirdparty/clang/include/llvm/Support/ErrorOr.h
vendored
Normal file
@@ -0,0 +1,514 @@
|
||||
//===- llvm/Support/ErrorOr.h - Error Smart Pointer -----------------------===//
|
||||
//
|
||||
// The LLVM Linker
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
///
|
||||
/// Provides ErrorOr<T> smart pointer.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_ERROR_OR_H
|
||||
#define LLVM_SUPPORT_ERROR_OR_H
|
||||
|
||||
#include "llvm/ADT/PointerIntPair.h"
|
||||
#include "llvm/Support/AlignOf.h"
|
||||
#include "llvm/Support/system_error.h"
|
||||
#include "llvm/Support/type_traits.h"
|
||||
|
||||
#include <cassert>
|
||||
#if LLVM_HAS_CXX11_TYPETRAITS
|
||||
#include <type_traits>
|
||||
#endif
|
||||
|
||||
namespace llvm {
|
||||
struct ErrorHolderBase {
|
||||
error_code Error;
|
||||
uint16_t RefCount;
|
||||
bool HasUserData;
|
||||
|
||||
ErrorHolderBase() : RefCount(1) {}
|
||||
|
||||
void aquire() {
|
||||
++RefCount;
|
||||
}
|
||||
|
||||
void release() {
|
||||
if (--RefCount == 0)
|
||||
delete this;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ~ErrorHolderBase() {}
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct ErrorHolder : ErrorHolderBase {
|
||||
#if LLVM_HAS_RVALUE_REFERENCES
|
||||
ErrorHolder(T &&UD) : UserData(llvm_move(UD)) {}
|
||||
#else
|
||||
ErrorHolder(T &UD) : UserData(UD) {}
|
||||
#endif
|
||||
T UserData;
|
||||
};
|
||||
|
||||
template<class Tp> struct ErrorOrUserDataTraits : llvm::false_type {};
|
||||
|
||||
#if LLVM_HAS_CXX11_TYPETRAITS && LLVM_HAS_RVALUE_REFERENCES
|
||||
template<class T, class V>
|
||||
typename std::enable_if< std::is_constructible<T, V>::value
|
||||
, typename std::remove_reference<V>::type>::type &&
|
||||
moveIfMoveConstructible(V &Val) {
|
||||
return std::move(Val);
|
||||
}
|
||||
|
||||
template<class T, class V>
|
||||
typename std::enable_if< !std::is_constructible<T, V>::value
|
||||
, typename std::remove_reference<V>::type>::type &
|
||||
moveIfMoveConstructible(V &Val) {
|
||||
return Val;
|
||||
}
|
||||
#else
|
||||
template<class T, class V>
|
||||
V &moveIfMoveConstructible(V &Val) {
|
||||
return Val;
|
||||
}
|
||||
#endif
|
||||
|
||||
/// \brief Stores a reference that can be changed.
|
||||
template <typename T>
|
||||
class ReferenceStorage {
|
||||
T *Storage;
|
||||
|
||||
public:
|
||||
ReferenceStorage(T &Ref) : Storage(&Ref) {}
|
||||
|
||||
operator T &() const { return *Storage; }
|
||||
T &get() const { return *Storage; }
|
||||
};
|
||||
|
||||
/// \brief Represents either an error or a value T.
|
||||
///
|
||||
/// ErrorOr<T> is a pointer-like class that represents the result of an
|
||||
/// operation. The result is either an error, or a value of type T. This is
|
||||
/// designed to emulate the usage of returning a pointer where nullptr indicates
|
||||
/// failure. However instead of just knowing that the operation failed, we also
|
||||
/// have an error_code and optional user data that describes why it failed.
|
||||
///
|
||||
/// It is used like the following.
|
||||
/// \code
|
||||
/// ErrorOr<Buffer> getBuffer();
|
||||
/// void handleError(error_code ec);
|
||||
///
|
||||
/// auto buffer = getBuffer();
|
||||
/// if (!buffer)
|
||||
/// handleError(buffer);
|
||||
/// buffer->write("adena");
|
||||
/// \endcode
|
||||
///
|
||||
/// ErrorOr<T> also supports user defined data for specific error_codes. To use
|
||||
/// this feature you must first add a template specialization of
|
||||
/// ErrorOrUserDataTraits derived from std::true_type for your type in the lld
|
||||
/// namespace. This specialization must have a static error_code error()
|
||||
/// function that returns the error_code this data is used with.
|
||||
///
|
||||
/// getError<UserData>() may be called to get either the stored user data, or
|
||||
/// a default constructed UserData if none was stored.
|
||||
///
|
||||
/// Example:
|
||||
/// \code
|
||||
/// struct InvalidArgError {
|
||||
/// InvalidArgError() {}
|
||||
/// InvalidArgError(std::string S) : ArgName(S) {}
|
||||
/// std::string ArgName;
|
||||
/// };
|
||||
///
|
||||
/// namespace llvm {
|
||||
/// template<>
|
||||
/// struct ErrorOrUserDataTraits<InvalidArgError> : std::true_type {
|
||||
/// static error_code error() {
|
||||
/// return make_error_code(errc::invalid_argument);
|
||||
/// }
|
||||
/// };
|
||||
/// } // end namespace llvm
|
||||
///
|
||||
/// using namespace llvm;
|
||||
///
|
||||
/// ErrorOr<int> foo() {
|
||||
/// return InvalidArgError("adena");
|
||||
/// }
|
||||
///
|
||||
/// int main() {
|
||||
/// auto a = foo();
|
||||
/// if (!a && error_code(a) == errc::invalid_argument)
|
||||
/// llvm::errs() << a.getError<InvalidArgError>().ArgName << "\n";
|
||||
/// }
|
||||
/// \endcode
|
||||
///
|
||||
/// An implicit conversion to bool provides a way to check if there was an
|
||||
/// error. The unary * and -> operators provide pointer like access to the
|
||||
/// value. Accessing the value when there is an error has undefined behavior.
|
||||
///
|
||||
/// When T is a reference type the behaivor is slightly different. The reference
|
||||
/// is held in a std::reference_wrapper<std::remove_reference<T>::type>, and
|
||||
/// there is special handling to make operator -> work as if T was not a
|
||||
/// reference.
|
||||
///
|
||||
/// T cannot be a rvalue reference.
|
||||
template<class T>
|
||||
class ErrorOr {
|
||||
template <class OtherT> friend class ErrorOr;
|
||||
static const bool isRef = is_reference<T>::value;
|
||||
typedef ReferenceStorage<typename remove_reference<T>::type> wrap;
|
||||
|
||||
public:
|
||||
typedef typename
|
||||
conditional< isRef
|
||||
, wrap
|
||||
, T
|
||||
>::type storage_type;
|
||||
|
||||
private:
|
||||
typedef typename remove_reference<T>::type &reference;
|
||||
typedef typename remove_reference<T>::type *pointer;
|
||||
|
||||
public:
|
||||
ErrorOr() : IsValid(false) {}
|
||||
|
||||
template <class E>
|
||||
ErrorOr(E ErrorCode, typename enable_if_c<is_error_code_enum<E>::value ||
|
||||
is_error_condition_enum<E>::value,
|
||||
void *>::type = 0)
|
||||
: HasError(true), IsValid(true) {
|
||||
Error = new ErrorHolderBase;
|
||||
Error->Error = make_error_code(ErrorCode);
|
||||
Error->HasUserData = false;
|
||||
}
|
||||
|
||||
ErrorOr(llvm::error_code EC) : HasError(true), IsValid(true) {
|
||||
Error = new ErrorHolderBase;
|
||||
Error->Error = EC;
|
||||
Error->HasUserData = false;
|
||||
}
|
||||
|
||||
template<class UserDataT>
|
||||
ErrorOr(UserDataT UD, typename
|
||||
enable_if_c<ErrorOrUserDataTraits<UserDataT>::value>::type* = 0)
|
||||
: HasError(true), IsValid(true) {
|
||||
Error = new ErrorHolder<UserDataT>(llvm_move(UD));
|
||||
Error->Error = ErrorOrUserDataTraits<UserDataT>::error();
|
||||
Error->HasUserData = true;
|
||||
}
|
||||
|
||||
ErrorOr(T Val) : HasError(false), IsValid(true) {
|
||||
new (get()) storage_type(moveIfMoveConstructible<storage_type>(Val));
|
||||
}
|
||||
|
||||
ErrorOr(const ErrorOr &Other) : IsValid(false) {
|
||||
copyConstruct(Other);
|
||||
}
|
||||
|
||||
template <class OtherT>
|
||||
ErrorOr(const ErrorOr<OtherT> &Other) : IsValid(false) {
|
||||
copyConstruct(Other);
|
||||
}
|
||||
|
||||
ErrorOr &operator =(const ErrorOr &Other) {
|
||||
copyAssign(Other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class OtherT>
|
||||
ErrorOr &operator =(const ErrorOr<OtherT> &Other) {
|
||||
copyAssign(Other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if LLVM_HAS_RVALUE_REFERENCES
|
||||
ErrorOr(ErrorOr &&Other) : IsValid(false) {
|
||||
moveConstruct(std::move(Other));
|
||||
}
|
||||
|
||||
template <class OtherT>
|
||||
ErrorOr(ErrorOr<OtherT> &&Other) : IsValid(false) {
|
||||
moveConstruct(std::move(Other));
|
||||
}
|
||||
|
||||
ErrorOr &operator =(ErrorOr &&Other) {
|
||||
moveAssign(std::move(Other));
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class OtherT>
|
||||
ErrorOr &operator =(ErrorOr<OtherT> &&Other) {
|
||||
moveAssign(std::move(Other));
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
~ErrorOr() {
|
||||
if (!IsValid)
|
||||
return;
|
||||
if (HasError)
|
||||
Error->release();
|
||||
else
|
||||
get()->~storage_type();
|
||||
}
|
||||
|
||||
template<class ET>
|
||||
ET getError() const {
|
||||
assert(IsValid && "Cannot get the error of a default constructed ErrorOr!");
|
||||
assert(HasError && "Cannot get an error if none exists!");
|
||||
assert(ErrorOrUserDataTraits<ET>::error() == Error->Error &&
|
||||
"Incorrect user error data type for error!");
|
||||
if (!Error->HasUserData)
|
||||
return ET();
|
||||
return reinterpret_cast<const ErrorHolder<ET>*>(Error)->UserData;
|
||||
}
|
||||
|
||||
typedef void (*unspecified_bool_type)();
|
||||
static void unspecified_bool_true() {}
|
||||
|
||||
/// \brief Return false if there is an error.
|
||||
operator unspecified_bool_type() const {
|
||||
assert(IsValid && "Can't do anything on a default constructed ErrorOr!");
|
||||
return HasError ? 0 : unspecified_bool_true;
|
||||
}
|
||||
|
||||
operator llvm::error_code() const {
|
||||
assert(IsValid && "Can't do anything on a default constructed ErrorOr!");
|
||||
return HasError ? Error->Error : llvm::error_code::success();
|
||||
}
|
||||
|
||||
pointer operator ->() {
|
||||
return toPointer(get());
|
||||
}
|
||||
|
||||
reference operator *() {
|
||||
return *get();
|
||||
}
|
||||
|
||||
private:
|
||||
template <class OtherT>
|
||||
void copyConstruct(const ErrorOr<OtherT> &Other) {
|
||||
// Construct an invalid ErrorOr if other is invalid.
|
||||
if (!Other.IsValid)
|
||||
return;
|
||||
IsValid = true;
|
||||
if (!Other.HasError) {
|
||||
// Get the other value.
|
||||
HasError = false;
|
||||
new (get()) storage_type(*Other.get());
|
||||
} else {
|
||||
// Get other's error.
|
||||
Error = Other.Error;
|
||||
HasError = true;
|
||||
Error->aquire();
|
||||
}
|
||||
}
|
||||
|
||||
template <class T1>
|
||||
static bool compareThisIfSameType(const T1 &a, const T1 &b) {
|
||||
return &a == &b;
|
||||
}
|
||||
|
||||
template <class T1, class T2>
|
||||
static bool compareThisIfSameType(const T1 &a, const T2 &b) {
|
||||
return false;
|
||||
}
|
||||
|
||||
template <class OtherT>
|
||||
void copyAssign(const ErrorOr<OtherT> &Other) {
|
||||
if (compareThisIfSameType(*this, Other))
|
||||
return;
|
||||
|
||||
this->~ErrorOr();
|
||||
new (this) ErrorOr(Other);
|
||||
}
|
||||
|
||||
#if LLVM_HAS_RVALUE_REFERENCES
|
||||
template <class OtherT>
|
||||
void moveConstruct(ErrorOr<OtherT> &&Other) {
|
||||
// Construct an invalid ErrorOr if other is invalid.
|
||||
if (!Other.IsValid)
|
||||
return;
|
||||
IsValid = true;
|
||||
if (!Other.HasError) {
|
||||
// Get the other value.
|
||||
HasError = false;
|
||||
new (get()) storage_type(std::move(*Other.get()));
|
||||
// Tell other not to do any destruction.
|
||||
Other.IsValid = false;
|
||||
} else {
|
||||
// Get other's error.
|
||||
Error = Other.Error;
|
||||
HasError = true;
|
||||
// Tell other not to do any destruction.
|
||||
Other.IsValid = false;
|
||||
}
|
||||
}
|
||||
|
||||
template <class OtherT>
|
||||
void moveAssign(ErrorOr<OtherT> &&Other) {
|
||||
if (compareThisIfSameType(*this, Other))
|
||||
return;
|
||||
|
||||
this->~ErrorOr();
|
||||
new (this) ErrorOr(std::move(Other));
|
||||
}
|
||||
#endif
|
||||
|
||||
pointer toPointer(pointer Val) {
|
||||
return Val;
|
||||
}
|
||||
|
||||
pointer toPointer(wrap *Val) {
|
||||
return &Val->get();
|
||||
}
|
||||
|
||||
storage_type *get() {
|
||||
assert(IsValid && "Can't do anything on a default constructed ErrorOr!");
|
||||
assert(!HasError && "Cannot get value when an error exists!");
|
||||
return reinterpret_cast<storage_type*>(TStorage.buffer);
|
||||
}
|
||||
|
||||
const storage_type *get() const {
|
||||
assert(IsValid && "Can't do anything on a default constructed ErrorOr!");
|
||||
assert(!HasError && "Cannot get value when an error exists!");
|
||||
return reinterpret_cast<const storage_type*>(TStorage.buffer);
|
||||
}
|
||||
|
||||
union {
|
||||
AlignedCharArrayUnion<storage_type> TStorage;
|
||||
ErrorHolderBase *Error;
|
||||
};
|
||||
bool HasError : 1;
|
||||
bool IsValid : 1;
|
||||
};
|
||||
|
||||
// ErrorOr specialization for void.
|
||||
template <>
|
||||
class ErrorOr<void> {
|
||||
public:
|
||||
ErrorOr() : Error(0, 0) {}
|
||||
|
||||
template <class E>
|
||||
ErrorOr(E ErrorCode, typename enable_if_c<is_error_code_enum<E>::value ||
|
||||
is_error_condition_enum<E>::value,
|
||||
void *> ::type = 0)
|
||||
: Error(0, 0) {
|
||||
error_code EC = make_error_code(ErrorCode);
|
||||
if (EC == errc::success) {
|
||||
Error.setInt(1);
|
||||
return;
|
||||
}
|
||||
ErrorHolderBase *EHB = new ErrorHolderBase;
|
||||
EHB->Error = EC;
|
||||
EHB->HasUserData = false;
|
||||
Error.setPointer(EHB);
|
||||
}
|
||||
|
||||
ErrorOr(llvm::error_code EC) : Error(0, 0) {
|
||||
if (EC == errc::success) {
|
||||
Error.setInt(1);
|
||||
return;
|
||||
}
|
||||
ErrorHolderBase *E = new ErrorHolderBase;
|
||||
E->Error = EC;
|
||||
E->HasUserData = false;
|
||||
Error.setPointer(E);
|
||||
}
|
||||
|
||||
template<class UserDataT>
|
||||
ErrorOr(UserDataT UD, typename
|
||||
enable_if_c<ErrorOrUserDataTraits<UserDataT>::value>::type* = 0)
|
||||
: Error(0, 0) {
|
||||
ErrorHolderBase *E = new ErrorHolder<UserDataT>(llvm_move(UD));
|
||||
E->Error = ErrorOrUserDataTraits<UserDataT>::error();
|
||||
E->HasUserData = true;
|
||||
Error.setPointer(E);
|
||||
}
|
||||
|
||||
ErrorOr(const ErrorOr &Other) : Error(0, 0) {
|
||||
Error = Other.Error;
|
||||
if (Other.Error.getPointer()->Error) {
|
||||
Error.getPointer()->aquire();
|
||||
}
|
||||
}
|
||||
|
||||
ErrorOr &operator =(const ErrorOr &Other) {
|
||||
if (this == &Other)
|
||||
return *this;
|
||||
|
||||
this->~ErrorOr();
|
||||
new (this) ErrorOr(Other);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if LLVM_HAS_RVALUE_REFERENCES
|
||||
ErrorOr(ErrorOr &&Other) : Error(0) {
|
||||
// Get other's error.
|
||||
Error = Other.Error;
|
||||
// Tell other not to do any destruction.
|
||||
Other.Error.setPointer(0);
|
||||
}
|
||||
|
||||
ErrorOr &operator =(ErrorOr &&Other) {
|
||||
if (this == &Other)
|
||||
return *this;
|
||||
|
||||
this->~ErrorOr();
|
||||
new (this) ErrorOr(std::move(Other));
|
||||
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
~ErrorOr() {
|
||||
if (Error.getPointer())
|
||||
Error.getPointer()->release();
|
||||
}
|
||||
|
||||
template<class ET>
|
||||
ET getError() const {
|
||||
assert(ErrorOrUserDataTraits<ET>::error() == *this &&
|
||||
"Incorrect user error data type for error!");
|
||||
if (!Error.getPointer()->HasUserData)
|
||||
return ET();
|
||||
return reinterpret_cast<const ErrorHolder<ET> *>(
|
||||
Error.getPointer())->UserData;
|
||||
}
|
||||
|
||||
typedef void (*unspecified_bool_type)();
|
||||
static void unspecified_bool_true() {}
|
||||
|
||||
/// \brief Return false if there is an error.
|
||||
operator unspecified_bool_type() const {
|
||||
return Error.getInt() ? unspecified_bool_true : 0;
|
||||
}
|
||||
|
||||
operator llvm::error_code() const {
|
||||
return Error.getInt() ? make_error_code(errc::success)
|
||||
: Error.getPointer()->Error;
|
||||
}
|
||||
|
||||
private:
|
||||
// If the bit is 1, the error is success.
|
||||
llvm::PointerIntPair<ErrorHolderBase *, 1> Error;
|
||||
};
|
||||
|
||||
template<class T, class E>
|
||||
typename enable_if_c<is_error_code_enum<E>::value ||
|
||||
is_error_condition_enum<E>::value, bool>::type
|
||||
operator ==(ErrorOr<T> &Err, E Code) {
|
||||
return error_code(Err) == Code;
|
||||
}
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
56
thirdparty/clang/include/llvm/Support/FEnv.h
vendored
Normal file
56
thirdparty/clang/include/llvm/Support/FEnv.h
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
//===- llvm/Support/FEnv.h - Host floating-point exceptions ------*- 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 an operating system independent interface to
|
||||
// floating-point exception interfaces.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_FENV_H
|
||||
#define LLVM_SUPPORT_FENV_H
|
||||
|
||||
#include "llvm/Config/config.h"
|
||||
#include <cerrno>
|
||||
#ifdef HAVE_FENV_H
|
||||
#include <fenv.h>
|
||||
#endif
|
||||
|
||||
// FIXME: Clang's #include handling apparently doesn't work for libstdc++'s
|
||||
// fenv.h; see PR6907 for details.
|
||||
#if defined(__clang__) && defined(_GLIBCXX_FENV_H)
|
||||
#undef HAVE_FENV_H
|
||||
#endif
|
||||
|
||||
namespace llvm {
|
||||
namespace sys {
|
||||
|
||||
/// llvm_fenv_clearexcept - Clear the floating-point exception state.
|
||||
static inline void llvm_fenv_clearexcept() {
|
||||
#if defined(HAVE_FENV_H) && HAVE_DECL_FE_ALL_EXCEPT
|
||||
feclearexcept(FE_ALL_EXCEPT);
|
||||
#endif
|
||||
errno = 0;
|
||||
}
|
||||
|
||||
/// llvm_fenv_testexcept - Test if a floating-point exception was raised.
|
||||
static inline bool llvm_fenv_testexcept() {
|
||||
int errno_val = errno;
|
||||
if (errno_val == ERANGE || errno_val == EDOM)
|
||||
return true;
|
||||
#if defined(HAVE_FENV_H) && HAVE_DECL_FE_ALL_EXCEPT && HAVE_DECL_FE_INEXACT
|
||||
if (fetestexcept(FE_ALL_EXCEPT & ~FE_INEXACT))
|
||||
return true;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
} // End sys namespace
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
||||
92
thirdparty/clang/include/llvm/Support/FileOutputBuffer.h
vendored
Normal file
92
thirdparty/clang/include/llvm/Support/FileOutputBuffer.h
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
//=== FileOutputBuffer.h - File Output Buffer -------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Utility for creating a in-memory buffer that will be written to a file.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_FILEOUTPUTBUFFER_H
|
||||
#define LLVM_SUPPORT_FILEOUTPUTBUFFER_H
|
||||
|
||||
#include "llvm/ADT/OwningPtr.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/Support/FileSystem.h"
|
||||
|
||||
namespace llvm {
|
||||
class error_code;
|
||||
|
||||
/// FileOutputBuffer - This interface provides simple way to create an in-memory
|
||||
/// buffer which will be written to a file. During the lifetime of these
|
||||
/// objects, the content or existence of the specified file is undefined. That
|
||||
/// is, creating an OutputBuffer for a file may immediately remove the file.
|
||||
/// If the FileOutputBuffer is committed, the target file's content will become
|
||||
/// the buffer content at the time of the commit. If the FileOutputBuffer is
|
||||
/// not committed, the file will be deleted in the FileOutputBuffer destructor.
|
||||
class FileOutputBuffer {
|
||||
public:
|
||||
|
||||
enum {
|
||||
F_executable = 1 /// set the 'x' bit on the resulting file
|
||||
};
|
||||
|
||||
/// Factory method to create an OutputBuffer object which manages a read/write
|
||||
/// buffer of the specified size. When committed, the buffer will be written
|
||||
/// to the file at the specified path.
|
||||
static error_code create(StringRef FilePath, size_t Size,
|
||||
OwningPtr<FileOutputBuffer> &Result,
|
||||
unsigned Flags = 0);
|
||||
|
||||
/// Returns a pointer to the start of the buffer.
|
||||
uint8_t *getBufferStart() {
|
||||
return (uint8_t*)Region->data();
|
||||
}
|
||||
|
||||
/// Returns a pointer to the end of the buffer.
|
||||
uint8_t *getBufferEnd() {
|
||||
return (uint8_t*)Region->data() + Region->size();
|
||||
}
|
||||
|
||||
/// Returns size of the buffer.
|
||||
size_t getBufferSize() const {
|
||||
return Region->size();
|
||||
}
|
||||
|
||||
/// Returns path where file will show up if buffer is committed.
|
||||
StringRef getPath() const {
|
||||
return FinalPath;
|
||||
}
|
||||
|
||||
/// Flushes the content of the buffer to its file and deallocates the
|
||||
/// buffer. If commit() is not called before this object's destructor
|
||||
/// is called, the file is deleted in the destructor. The optional parameter
|
||||
/// is used if it turns out you want the file size to be smaller than
|
||||
/// initially requested.
|
||||
error_code commit(int64_t NewSmallerSize = -1);
|
||||
|
||||
/// If this object was previously committed, the destructor just deletes
|
||||
/// this object. If this object was not committed, the destructor
|
||||
/// deallocates the buffer and the target file is never written.
|
||||
~FileOutputBuffer();
|
||||
|
||||
private:
|
||||
FileOutputBuffer(const FileOutputBuffer &) LLVM_DELETED_FUNCTION;
|
||||
FileOutputBuffer &operator=(const FileOutputBuffer &) LLVM_DELETED_FUNCTION;
|
||||
|
||||
FileOutputBuffer(llvm::sys::fs::mapped_file_region *R,
|
||||
StringRef Path, StringRef TempPath);
|
||||
|
||||
OwningPtr<llvm::sys::fs::mapped_file_region> Region;
|
||||
SmallString<128> FinalPath;
|
||||
SmallString<128> TempPath;
|
||||
};
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
896
thirdparty/clang/include/llvm/Support/FileSystem.h
vendored
Normal file
896
thirdparty/clang/include/llvm/Support/FileSystem.h
vendored
Normal file
@@ -0,0 +1,896 @@
|
||||
//===- llvm/Support/FileSystem.h - File System OS Concept -------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file declares the llvm::sys::fs namespace. It is designed after
|
||||
// TR2/boost filesystem (v3), but modified to remove exception handling and the
|
||||
// path class.
|
||||
//
|
||||
// All functions return an error_code and their actual work via the last out
|
||||
// argument. The out argument is defined if and only if errc::success is
|
||||
// returned. A function may return any error code in the generic or system
|
||||
// category. However, they shall be equivalent to any error conditions listed
|
||||
// in each functions respective documentation if the condition applies. [ note:
|
||||
// this does not guarantee that error_code will be in the set of explicitly
|
||||
// listed codes, but it does guarantee that if any of the explicitly listed
|
||||
// errors occur, the correct error_code will be used ]. All functions may
|
||||
// return errc::not_enough_memory if there is not enough memory to complete the
|
||||
// operation.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_FILESYSTEM_H
|
||||
#define LLVM_SUPPORT_FILESYSTEM_H
|
||||
|
||||
#include "llvm/ADT/IntrusiveRefCntPtr.h"
|
||||
#include "llvm/ADT/OwningPtr.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/ADT/Twine.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/system_error.h"
|
||||
#include <ctime>
|
||||
#include <iterator>
|
||||
#include <stack>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
|
||||
namespace llvm {
|
||||
namespace sys {
|
||||
namespace fs {
|
||||
|
||||
/// file_type - An "enum class" enumeration for the file system's view of the
|
||||
/// type.
|
||||
struct file_type {
|
||||
enum _ {
|
||||
status_error,
|
||||
file_not_found,
|
||||
regular_file,
|
||||
directory_file,
|
||||
symlink_file,
|
||||
block_file,
|
||||
character_file,
|
||||
fifo_file,
|
||||
socket_file,
|
||||
type_unknown
|
||||
};
|
||||
|
||||
file_type(_ v) : v_(v) {}
|
||||
explicit file_type(int v) : v_(_(v)) {}
|
||||
operator int() const {return v_;}
|
||||
|
||||
private:
|
||||
int v_;
|
||||
};
|
||||
|
||||
/// copy_option - An "enum class" enumeration of copy semantics for copy
|
||||
/// operations.
|
||||
struct copy_option {
|
||||
enum _ {
|
||||
fail_if_exists,
|
||||
overwrite_if_exists
|
||||
};
|
||||
|
||||
copy_option(_ v) : v_(v) {}
|
||||
explicit copy_option(int v) : v_(_(v)) {}
|
||||
operator int() const {return v_;}
|
||||
|
||||
private:
|
||||
int v_;
|
||||
};
|
||||
|
||||
/// space_info - Self explanatory.
|
||||
struct space_info {
|
||||
uint64_t capacity;
|
||||
uint64_t free;
|
||||
uint64_t available;
|
||||
};
|
||||
|
||||
|
||||
enum perms {
|
||||
no_perms = 0,
|
||||
owner_read = 0400,
|
||||
owner_write = 0200,
|
||||
owner_exe = 0100,
|
||||
owner_all = owner_read | owner_write | owner_exe,
|
||||
group_read = 040,
|
||||
group_write = 020,
|
||||
group_exe = 010,
|
||||
group_all = group_read | group_write | group_exe,
|
||||
others_read = 04,
|
||||
others_write = 02,
|
||||
others_exe = 01,
|
||||
others_all = others_read | others_write | others_exe,
|
||||
all_all = owner_all | group_all | others_all,
|
||||
set_uid_on_exe = 04000,
|
||||
set_gid_on_exe = 02000,
|
||||
sticky_bit = 01000,
|
||||
perms_mask = all_all | set_uid_on_exe | set_gid_on_exe | sticky_bit,
|
||||
perms_not_known = 0xFFFF,
|
||||
add_perms = 0x1000,
|
||||
remove_perms = 0x2000,
|
||||
symlink_perms = 0x4000
|
||||
};
|
||||
|
||||
// Helper functions so that you can use & and | to manipulate perms bits:
|
||||
inline perms operator|(perms l , perms r) {
|
||||
return static_cast<perms>(
|
||||
static_cast<unsigned short>(l) | static_cast<unsigned short>(r));
|
||||
}
|
||||
inline perms operator&(perms l , perms r) {
|
||||
return static_cast<perms>(
|
||||
static_cast<unsigned short>(l) & static_cast<unsigned short>(r));
|
||||
}
|
||||
inline perms &operator|=(perms &l, perms r) {
|
||||
l = l | r;
|
||||
return l;
|
||||
}
|
||||
inline perms &operator&=(perms &l, perms r) {
|
||||
l = l & r;
|
||||
return l;
|
||||
}
|
||||
inline perms operator~(perms x) {
|
||||
return static_cast<perms>(~static_cast<unsigned short>(x));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// file_status - Represents the result of a call to stat and friends. It has
|
||||
/// a platform specific member to store the result.
|
||||
class file_status
|
||||
{
|
||||
#if defined(LLVM_ON_UNIX)
|
||||
dev_t fs_st_dev;
|
||||
ino_t fs_st_ino;
|
||||
#elif defined (LLVM_ON_WIN32)
|
||||
uint32_t LastWriteTimeHigh;
|
||||
uint32_t LastWriteTimeLow;
|
||||
uint32_t VolumeSerialNumber;
|
||||
uint32_t FileSizeHigh;
|
||||
uint32_t FileSizeLow;
|
||||
uint32_t FileIndexHigh;
|
||||
uint32_t FileIndexLow;
|
||||
#endif
|
||||
friend bool equivalent(file_status A, file_status B);
|
||||
friend error_code status(const Twine &path, file_status &result);
|
||||
file_type Type;
|
||||
perms Perms;
|
||||
public:
|
||||
explicit file_status(file_type v=file_type::status_error,
|
||||
perms prms=perms_not_known)
|
||||
: Type(v), Perms(prms) {}
|
||||
|
||||
// getters
|
||||
file_type type() const { return Type; }
|
||||
perms permissions() const { return Perms; }
|
||||
|
||||
// setters
|
||||
void type(file_type v) { Type = v; }
|
||||
void permissions(perms p) { Perms = p; }
|
||||
};
|
||||
|
||||
/// file_magic - An "enum class" enumeration of file types based on magic (the first
|
||||
/// N bytes of the file).
|
||||
struct file_magic {
|
||||
enum _ {
|
||||
unknown = 0, ///< Unrecognized file
|
||||
bitcode, ///< Bitcode file
|
||||
archive, ///< ar style archive file
|
||||
elf_relocatable, ///< ELF Relocatable object file
|
||||
elf_executable, ///< ELF Executable image
|
||||
elf_shared_object, ///< ELF dynamically linked shared lib
|
||||
elf_core, ///< ELF core image
|
||||
macho_object, ///< Mach-O Object file
|
||||
macho_executable, ///< Mach-O Executable
|
||||
macho_fixed_virtual_memory_shared_lib, ///< Mach-O Shared Lib, FVM
|
||||
macho_core, ///< Mach-O Core File
|
||||
macho_preload_executabl, ///< Mach-O Preloaded Executable
|
||||
macho_dynamically_linked_shared_lib, ///< Mach-O dynlinked shared lib
|
||||
macho_dynamic_linker, ///< The Mach-O dynamic linker
|
||||
macho_bundle, ///< Mach-O Bundle file
|
||||
macho_dynamically_linked_shared_lib_stub, ///< Mach-O Shared lib stub
|
||||
macho_dsym_companion, ///< Mach-O dSYM companion file
|
||||
coff_object, ///< COFF object file
|
||||
pecoff_executable ///< PECOFF executable file
|
||||
};
|
||||
|
||||
bool is_object() const {
|
||||
return v_ == unknown ? false : true;
|
||||
}
|
||||
|
||||
file_magic() : v_(unknown) {}
|
||||
file_magic(_ v) : v_(v) {}
|
||||
explicit file_magic(int v) : v_(_(v)) {}
|
||||
operator int() const {return v_;}
|
||||
|
||||
private:
|
||||
int v_;
|
||||
};
|
||||
|
||||
/// @}
|
||||
/// @name Physical Operators
|
||||
/// @{
|
||||
|
||||
/// @brief Make \a path an absolute path.
|
||||
///
|
||||
/// Makes \a path absolute using the current directory if it is not already. An
|
||||
/// empty \a path will result in the current directory.
|
||||
///
|
||||
/// /absolute/path => /absolute/path
|
||||
/// relative/../path => <current-directory>/relative/../path
|
||||
///
|
||||
/// @param path A path that is modified to be an absolute path.
|
||||
/// @returns errc::success if \a path has been made absolute, otherwise a
|
||||
/// platform specific error_code.
|
||||
error_code make_absolute(SmallVectorImpl<char> &path);
|
||||
|
||||
/// @brief Copy the file at \a from to the path \a to.
|
||||
///
|
||||
/// @param from The path to copy the file from.
|
||||
/// @param to The path to copy the file to.
|
||||
/// @param copt Behavior if \a to already exists.
|
||||
/// @returns errc::success if the file has been successfully copied.
|
||||
/// errc::file_exists if \a to already exists and \a copt ==
|
||||
/// copy_option::fail_if_exists. Otherwise a platform specific
|
||||
/// error_code.
|
||||
error_code copy_file(const Twine &from, const Twine &to,
|
||||
copy_option copt = copy_option::fail_if_exists);
|
||||
|
||||
/// @brief Create all the non-existent directories in path.
|
||||
///
|
||||
/// @param path Directories to create.
|
||||
/// @param existed Set to true if \a path already existed, false otherwise.
|
||||
/// @returns errc::success if is_directory(path) and existed have been set,
|
||||
/// otherwise a platform specific error_code.
|
||||
error_code create_directories(const Twine &path, bool &existed);
|
||||
|
||||
/// @brief Create the directory in path.
|
||||
///
|
||||
/// @param path Directory to create.
|
||||
/// @param existed Set to true if \a path already existed, false otherwise.
|
||||
/// @returns errc::success if is_directory(path) and existed have been set,
|
||||
/// otherwise a platform specific error_code.
|
||||
error_code create_directory(const Twine &path, bool &existed);
|
||||
|
||||
/// @brief Create a hard link from \a from to \a to.
|
||||
///
|
||||
/// @param to The path to hard link to.
|
||||
/// @param from The path to hard link from. This is created.
|
||||
/// @returns errc::success if exists(to) && exists(from) && equivalent(to, from)
|
||||
/// , otherwise a platform specific error_code.
|
||||
error_code create_hard_link(const Twine &to, const Twine &from);
|
||||
|
||||
/// @brief Create a symbolic link from \a from to \a to.
|
||||
///
|
||||
/// @param to The path to symbolically link to.
|
||||
/// @param from The path to symbolically link from. This is created.
|
||||
/// @returns errc::success if exists(to) && exists(from) && is_symlink(from),
|
||||
/// otherwise a platform specific error_code.
|
||||
error_code create_symlink(const Twine &to, const Twine &from);
|
||||
|
||||
/// @brief Get the current path.
|
||||
///
|
||||
/// @param result Holds the current path on return.
|
||||
/// @returns errc::success if the current path has been stored in result,
|
||||
/// otherwise a platform specific error_code.
|
||||
error_code current_path(SmallVectorImpl<char> &result);
|
||||
|
||||
/// @brief Remove path. Equivalent to POSIX remove().
|
||||
///
|
||||
/// @param path Input path.
|
||||
/// @param existed Set to true if \a path existed, false if it did not.
|
||||
/// undefined otherwise.
|
||||
/// @returns errc::success if path has been removed and existed has been
|
||||
/// successfully set, otherwise a platform specific error_code.
|
||||
error_code remove(const Twine &path, bool &existed);
|
||||
|
||||
/// @brief Recursively remove all files below \a path, then \a path. Files are
|
||||
/// removed as if by POSIX remove().
|
||||
///
|
||||
/// @param path Input path.
|
||||
/// @param num_removed Number of files removed.
|
||||
/// @returns errc::success if path has been removed and num_removed has been
|
||||
/// successfully set, otherwise a platform specific error_code.
|
||||
error_code remove_all(const Twine &path, uint32_t &num_removed);
|
||||
|
||||
/// @brief Rename \a from to \a to. Files are renamed as if by POSIX rename().
|
||||
///
|
||||
/// @param from The path to rename from.
|
||||
/// @param to The path to rename to. This is created.
|
||||
error_code rename(const Twine &from, const Twine &to);
|
||||
|
||||
/// @brief Resize path to size. File is resized as if by POSIX truncate().
|
||||
///
|
||||
/// @param path Input path.
|
||||
/// @param size Size to resize to.
|
||||
/// @returns errc::success if \a path has been resized to \a size, otherwise a
|
||||
/// platform specific error_code.
|
||||
error_code resize_file(const Twine &path, uint64_t size);
|
||||
|
||||
/// @}
|
||||
/// @name Physical Observers
|
||||
/// @{
|
||||
|
||||
/// @brief Does file exist?
|
||||
///
|
||||
/// @param status A file_status previously returned from stat.
|
||||
/// @returns True if the file represented by status exists, false if it does
|
||||
/// not.
|
||||
bool exists(file_status status);
|
||||
|
||||
/// @brief Does file exist?
|
||||
///
|
||||
/// @param path Input path.
|
||||
/// @param result Set to true if the file represented by status exists, false if
|
||||
/// it does not. Undefined otherwise.
|
||||
/// @returns errc::success if result has been successfully set, otherwise a
|
||||
/// platform specific error_code.
|
||||
error_code exists(const Twine &path, bool &result);
|
||||
|
||||
/// @brief Simpler version of exists for clients that don't need to
|
||||
/// differentiate between an error and false.
|
||||
inline bool exists(const Twine &path) {
|
||||
bool result;
|
||||
return !exists(path, result) && result;
|
||||
}
|
||||
|
||||
/// @brief Do file_status's represent the same thing?
|
||||
///
|
||||
/// @param A Input file_status.
|
||||
/// @param B Input file_status.
|
||||
///
|
||||
/// assert(status_known(A) || status_known(B));
|
||||
///
|
||||
/// @returns True if A and B both represent the same file system entity, false
|
||||
/// otherwise.
|
||||
bool equivalent(file_status A, file_status B);
|
||||
|
||||
/// @brief Do paths represent the same thing?
|
||||
///
|
||||
/// assert(status_known(A) || status_known(B));
|
||||
///
|
||||
/// @param A Input path A.
|
||||
/// @param B Input path B.
|
||||
/// @param result Set to true if stat(A) and stat(B) have the same device and
|
||||
/// inode (or equivalent).
|
||||
/// @returns errc::success if result has been successfully set, otherwise a
|
||||
/// platform specific error_code.
|
||||
error_code equivalent(const Twine &A, const Twine &B, bool &result);
|
||||
|
||||
/// @brief Simpler version of equivalent for clients that don't need to
|
||||
/// differentiate between an error and false.
|
||||
inline bool equivalent(const Twine &A, const Twine &B) {
|
||||
bool result;
|
||||
return !equivalent(A, B, result) && result;
|
||||
}
|
||||
|
||||
/// @brief Get file size.
|
||||
///
|
||||
/// @param path Input path.
|
||||
/// @param result Set to the size of the file in \a path.
|
||||
/// @returns errc::success if result has been successfully set, otherwise a
|
||||
/// platform specific error_code.
|
||||
error_code file_size(const Twine &path, uint64_t &result);
|
||||
|
||||
/// @brief Does status represent a directory?
|
||||
///
|
||||
/// @param status A file_status previously returned from status.
|
||||
/// @returns status.type() == file_type::directory_file.
|
||||
bool is_directory(file_status status);
|
||||
|
||||
/// @brief Is path a directory?
|
||||
///
|
||||
/// @param path Input path.
|
||||
/// @param result Set to true if \a path is a directory, false if it is not.
|
||||
/// Undefined otherwise.
|
||||
/// @returns errc::success if result has been successfully set, otherwise a
|
||||
/// platform specific error_code.
|
||||
error_code is_directory(const Twine &path, bool &result);
|
||||
|
||||
/// @brief Does status represent a regular file?
|
||||
///
|
||||
/// @param status A file_status previously returned from status.
|
||||
/// @returns status_known(status) && status.type() == file_type::regular_file.
|
||||
bool is_regular_file(file_status status);
|
||||
|
||||
/// @brief Is path a regular file?
|
||||
///
|
||||
/// @param path Input path.
|
||||
/// @param result Set to true if \a path is a regular file, false if it is not.
|
||||
/// Undefined otherwise.
|
||||
/// @returns errc::success if result has been successfully set, otherwise a
|
||||
/// platform specific error_code.
|
||||
error_code is_regular_file(const Twine &path, bool &result);
|
||||
|
||||
/// @brief Does this status represent something that exists but is not a
|
||||
/// directory, regular file, or symlink?
|
||||
///
|
||||
/// @param status A file_status previously returned from status.
|
||||
/// @returns exists(s) && !is_regular_file(s) && !is_directory(s) &&
|
||||
/// !is_symlink(s)
|
||||
bool is_other(file_status status);
|
||||
|
||||
/// @brief Is path something that exists but is not a directory,
|
||||
/// regular file, or symlink?
|
||||
///
|
||||
/// @param path Input path.
|
||||
/// @param result Set to true if \a path exists, but is not a directory, regular
|
||||
/// file, or a symlink, false if it does not. Undefined otherwise.
|
||||
/// @returns errc::success if result has been successfully set, otherwise a
|
||||
/// platform specific error_code.
|
||||
error_code is_other(const Twine &path, bool &result);
|
||||
|
||||
/// @brief Does status represent a symlink?
|
||||
///
|
||||
/// @param status A file_status previously returned from stat.
|
||||
/// @returns status.type() == symlink_file.
|
||||
bool is_symlink(file_status status);
|
||||
|
||||
/// @brief Is path a symlink?
|
||||
///
|
||||
/// @param path Input path.
|
||||
/// @param result Set to true if \a path is a symlink, false if it is not.
|
||||
/// Undefined otherwise.
|
||||
/// @returns errc::success if result has been successfully set, otherwise a
|
||||
/// platform specific error_code.
|
||||
error_code is_symlink(const Twine &path, bool &result);
|
||||
|
||||
/// @brief Get file status as if by POSIX stat().
|
||||
///
|
||||
/// @param path Input path.
|
||||
/// @param result Set to the file status.
|
||||
/// @returns errc::success if result has been successfully set, otherwise a
|
||||
/// platform specific error_code.
|
||||
error_code status(const Twine &path, file_status &result);
|
||||
|
||||
/// @brief Modifies permission bits on a file
|
||||
///
|
||||
/// @param path Input path.
|
||||
/// @returns errc::success if permissions have been changed, otherwise a
|
||||
/// platform specific error_code.
|
||||
error_code permissions(const Twine &path, perms prms);
|
||||
|
||||
/// @brief Is status available?
|
||||
///
|
||||
/// @param s Input file status.
|
||||
/// @returns True if status() != status_error.
|
||||
bool status_known(file_status s);
|
||||
|
||||
/// @brief Is status available?
|
||||
///
|
||||
/// @param path Input path.
|
||||
/// @param result Set to true if status() != status_error.
|
||||
/// @returns errc::success if result has been successfully set, otherwise a
|
||||
/// platform specific error_code.
|
||||
error_code status_known(const Twine &path, bool &result);
|
||||
|
||||
/// @brief Generate a unique path and open it as a file.
|
||||
///
|
||||
/// Generates a unique path suitable for a temporary file and then opens it as a
|
||||
/// file. The name is based on \a model with '%' replaced by a random char in
|
||||
/// [0-9a-f]. If \a model is not an absolute path, a suitable temporary
|
||||
/// directory will be prepended.
|
||||
///
|
||||
/// This is an atomic operation. Either the file is created and opened, or the
|
||||
/// file system is left untouched.
|
||||
///
|
||||
/// clang-%%-%%-%%-%%-%%.s => /tmp/clang-a0-b1-c2-d3-e4.s
|
||||
///
|
||||
/// @param model Name to base unique path off of.
|
||||
/// @param result_fd Set to the opened file's file descriptor.
|
||||
/// @param result_path Set to the opened file's absolute path.
|
||||
/// @param makeAbsolute If true and \a model is not an absolute path, a temp
|
||||
/// directory will be prepended.
|
||||
/// @returns errc::success if result_{fd,path} have been successfully set,
|
||||
/// otherwise a platform specific error_code.
|
||||
error_code unique_file(const Twine &model, int &result_fd,
|
||||
SmallVectorImpl<char> &result_path,
|
||||
bool makeAbsolute = true, unsigned mode = 0600);
|
||||
|
||||
/// @brief Canonicalize path.
|
||||
///
|
||||
/// Sets result to the file system's idea of what path is. The result is always
|
||||
/// absolute and has the same capitalization as the file system.
|
||||
///
|
||||
/// @param path Input path.
|
||||
/// @param result Set to the canonicalized version of \a path.
|
||||
/// @returns errc::success if result has been successfully set, otherwise a
|
||||
/// platform specific error_code.
|
||||
error_code canonicalize(const Twine &path, SmallVectorImpl<char> &result);
|
||||
|
||||
/// @brief Are \a path's first bytes \a magic?
|
||||
///
|
||||
/// @param path Input path.
|
||||
/// @param magic Byte sequence to compare \a path's first len(magic) bytes to.
|
||||
/// @returns errc::success if result has been successfully set, otherwise a
|
||||
/// platform specific error_code.
|
||||
error_code has_magic(const Twine &path, const Twine &magic, bool &result);
|
||||
|
||||
/// @brief Get \a path's first \a len bytes.
|
||||
///
|
||||
/// @param path Input path.
|
||||
/// @param len Number of magic bytes to get.
|
||||
/// @param result Set to the first \a len bytes in the file pointed to by
|
||||
/// \a path. Or the entire file if file_size(path) < len, in which
|
||||
/// case result.size() returns the size of the file.
|
||||
/// @returns errc::success if result has been successfully set,
|
||||
/// errc::value_too_large if len is larger then the file pointed to by
|
||||
/// \a path, otherwise a platform specific error_code.
|
||||
error_code get_magic(const Twine &path, uint32_t len,
|
||||
SmallVectorImpl<char> &result);
|
||||
|
||||
/// @brief Identify the type of a binary file based on how magical it is.
|
||||
file_magic identify_magic(StringRef magic);
|
||||
|
||||
/// @brief Get and identify \a path's type based on its content.
|
||||
///
|
||||
/// @param path Input path.
|
||||
/// @param result Set to the type of file, or LLVMFileType::Unknown_FileType.
|
||||
/// @returns errc::success if result has been successfully set, otherwise a
|
||||
/// platform specific error_code.
|
||||
error_code identify_magic(const Twine &path, file_magic &result);
|
||||
|
||||
/// @brief Get library paths the system linker uses.
|
||||
///
|
||||
/// @param result Set to the list of system library paths.
|
||||
/// @returns errc::success if result has been successfully set, otherwise a
|
||||
/// platform specific error_code.
|
||||
error_code GetSystemLibraryPaths(SmallVectorImpl<std::string> &result);
|
||||
|
||||
/// @brief Get bitcode library paths the system linker uses
|
||||
/// + LLVM_LIB_SEARCH_PATH + LLVM_LIBDIR.
|
||||
///
|
||||
/// @param result Set to the list of bitcode library paths.
|
||||
/// @returns errc::success if result has been successfully set, otherwise a
|
||||
/// platform specific error_code.
|
||||
error_code GetBitcodeLibraryPaths(SmallVectorImpl<std::string> &result);
|
||||
|
||||
/// @brief Find a library.
|
||||
///
|
||||
/// Find the path to a library using its short name. Use the system
|
||||
/// dependent library paths to locate the library.
|
||||
///
|
||||
/// c => /usr/lib/libc.so
|
||||
///
|
||||
/// @param short_name Library name one would give to the system linker.
|
||||
/// @param result Set to the absolute path \a short_name represents.
|
||||
/// @returns errc::success if result has been successfully set, otherwise a
|
||||
/// platform specific error_code.
|
||||
error_code FindLibrary(const Twine &short_name, SmallVectorImpl<char> &result);
|
||||
|
||||
/// @brief Get absolute path of main executable.
|
||||
///
|
||||
/// @param argv0 The program name as it was spelled on the command line.
|
||||
/// @param MainAddr Address of some symbol in the executable (not in a library).
|
||||
/// @param result Set to the absolute path of the current executable.
|
||||
/// @returns errc::success if result has been successfully set, otherwise a
|
||||
/// platform specific error_code.
|
||||
error_code GetMainExecutable(const char *argv0, void *MainAddr,
|
||||
SmallVectorImpl<char> &result);
|
||||
|
||||
/// This class represents a memory mapped file. It is based on
|
||||
/// boost::iostreams::mapped_file.
|
||||
class mapped_file_region {
|
||||
mapped_file_region() LLVM_DELETED_FUNCTION;
|
||||
mapped_file_region(mapped_file_region&) LLVM_DELETED_FUNCTION;
|
||||
mapped_file_region &operator =(mapped_file_region&) LLVM_DELETED_FUNCTION;
|
||||
|
||||
public:
|
||||
enum mapmode {
|
||||
readonly, ///< May only access map via const_data as read only.
|
||||
readwrite, ///< May access map via data and modify it. Written to path.
|
||||
priv ///< May modify via data, but changes are lost on destruction.
|
||||
};
|
||||
|
||||
private:
|
||||
/// Platform specific mapping state.
|
||||
mapmode Mode;
|
||||
uint64_t Size;
|
||||
void *Mapping;
|
||||
#ifdef LLVM_ON_WIN32
|
||||
int FileDescriptor;
|
||||
void *FileHandle;
|
||||
void *FileMappingHandle;
|
||||
#endif
|
||||
|
||||
error_code init(int FD, bool CloseFD, uint64_t Offset);
|
||||
|
||||
public:
|
||||
typedef char char_type;
|
||||
|
||||
#if LLVM_HAS_RVALUE_REFERENCES
|
||||
mapped_file_region(mapped_file_region&&);
|
||||
mapped_file_region &operator =(mapped_file_region&&);
|
||||
#endif
|
||||
|
||||
/// Construct a mapped_file_region at \a path starting at \a offset of length
|
||||
/// \a length and with access \a mode.
|
||||
///
|
||||
/// \param path Path to the file to map. If it does not exist it will be
|
||||
/// created.
|
||||
/// \param mode How to map the memory.
|
||||
/// \param length Number of bytes to map in starting at \a offset. If the file
|
||||
/// is shorter than this, it will be extended. If \a length is
|
||||
/// 0, the entire file will be mapped.
|
||||
/// \param offset Byte offset from the beginning of the file where the map
|
||||
/// should begin. Must be a multiple of
|
||||
/// mapped_file_region::alignment().
|
||||
/// \param ec This is set to errc::success if the map was constructed
|
||||
/// sucessfully. Otherwise it is set to a platform dependent error.
|
||||
mapped_file_region(const Twine &path,
|
||||
mapmode mode,
|
||||
uint64_t length,
|
||||
uint64_t offset,
|
||||
error_code &ec);
|
||||
|
||||
/// \param fd An open file descriptor to map. mapped_file_region takes
|
||||
/// ownership if closefd is true. It must have been opended in the correct
|
||||
/// mode.
|
||||
mapped_file_region(int fd,
|
||||
bool closefd,
|
||||
mapmode mode,
|
||||
uint64_t length,
|
||||
uint64_t offset,
|
||||
error_code &ec);
|
||||
|
||||
~mapped_file_region();
|
||||
|
||||
mapmode flags() const;
|
||||
uint64_t size() const;
|
||||
char *data() const;
|
||||
|
||||
/// Get a const view of the data. Modifying this memory has undefined
|
||||
/// behaivor.
|
||||
const char *const_data() const;
|
||||
|
||||
/// \returns The minimum alignment offset must be.
|
||||
static int alignment();
|
||||
};
|
||||
|
||||
/// @brief Memory maps the contents of a file
|
||||
///
|
||||
/// @param path Path to file to map.
|
||||
/// @param file_offset Byte offset in file where mapping should begin.
|
||||
/// @param size Byte length of range of the file to map.
|
||||
/// @param map_writable If true, the file will be mapped in r/w such
|
||||
/// that changes to the mapped buffer will be flushed back
|
||||
/// to the file. If false, the file will be mapped read-only
|
||||
/// and the buffer will be read-only.
|
||||
/// @param result Set to the start address of the mapped buffer.
|
||||
/// @returns errc::success if result has been successfully set, otherwise a
|
||||
/// platform specific error_code.
|
||||
error_code map_file_pages(const Twine &path, off_t file_offset, size_t size,
|
||||
bool map_writable, void *&result);
|
||||
|
||||
|
||||
/// @brief Memory unmaps the contents of a file
|
||||
///
|
||||
/// @param base Pointer to the start of the buffer.
|
||||
/// @param size Byte length of the range to unmmap.
|
||||
/// @returns errc::success if result has been successfully set, otherwise a
|
||||
/// platform specific error_code.
|
||||
error_code unmap_file_pages(void *base, size_t size);
|
||||
|
||||
|
||||
|
||||
/// @}
|
||||
/// @name Iterators
|
||||
/// @{
|
||||
|
||||
/// directory_entry - A single entry in a directory. Caches the status either
|
||||
/// from the result of the iteration syscall, or the first time status is
|
||||
/// called.
|
||||
class directory_entry {
|
||||
std::string Path;
|
||||
mutable file_status Status;
|
||||
|
||||
public:
|
||||
explicit directory_entry(const Twine &path, file_status st = file_status())
|
||||
: Path(path.str())
|
||||
, Status(st) {}
|
||||
|
||||
directory_entry() {}
|
||||
|
||||
void assign(const Twine &path, file_status st = file_status()) {
|
||||
Path = path.str();
|
||||
Status = st;
|
||||
}
|
||||
|
||||
void replace_filename(const Twine &filename, file_status st = file_status());
|
||||
|
||||
const std::string &path() const { return Path; }
|
||||
error_code status(file_status &result) const;
|
||||
|
||||
bool operator==(const directory_entry& rhs) const { return Path == rhs.Path; }
|
||||
bool operator!=(const directory_entry& rhs) const { return !(*this == rhs); }
|
||||
bool operator< (const directory_entry& rhs) const;
|
||||
bool operator<=(const directory_entry& rhs) const;
|
||||
bool operator> (const directory_entry& rhs) const;
|
||||
bool operator>=(const directory_entry& rhs) const;
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
struct DirIterState;
|
||||
|
||||
error_code directory_iterator_construct(DirIterState&, StringRef);
|
||||
error_code directory_iterator_increment(DirIterState&);
|
||||
error_code directory_iterator_destruct(DirIterState&);
|
||||
|
||||
/// DirIterState - Keeps state for the directory_iterator. It is reference
|
||||
/// counted in order to preserve InputIterator semantics on copy.
|
||||
struct DirIterState : public RefCountedBase<DirIterState> {
|
||||
DirIterState()
|
||||
: IterationHandle(0) {}
|
||||
|
||||
~DirIterState() {
|
||||
directory_iterator_destruct(*this);
|
||||
}
|
||||
|
||||
intptr_t IterationHandle;
|
||||
directory_entry CurrentEntry;
|
||||
};
|
||||
}
|
||||
|
||||
/// directory_iterator - Iterates through the entries in path. There is no
|
||||
/// operator++ because we need an error_code. If it's really needed we can make
|
||||
/// it call report_fatal_error on error.
|
||||
class directory_iterator {
|
||||
IntrusiveRefCntPtr<detail::DirIterState> State;
|
||||
|
||||
public:
|
||||
explicit directory_iterator(const Twine &path, error_code &ec) {
|
||||
State = new detail::DirIterState;
|
||||
SmallString<128> path_storage;
|
||||
ec = detail::directory_iterator_construct(*State,
|
||||
path.toStringRef(path_storage));
|
||||
}
|
||||
|
||||
explicit directory_iterator(const directory_entry &de, error_code &ec) {
|
||||
State = new detail::DirIterState;
|
||||
ec = detail::directory_iterator_construct(*State, de.path());
|
||||
}
|
||||
|
||||
/// Construct end iterator.
|
||||
directory_iterator() : State(new detail::DirIterState) {}
|
||||
|
||||
// No operator++ because we need error_code.
|
||||
directory_iterator &increment(error_code &ec) {
|
||||
ec = directory_iterator_increment(*State);
|
||||
return *this;
|
||||
}
|
||||
|
||||
const directory_entry &operator*() const { return State->CurrentEntry; }
|
||||
const directory_entry *operator->() const { return &State->CurrentEntry; }
|
||||
|
||||
bool operator==(const directory_iterator &RHS) const {
|
||||
return State->CurrentEntry == RHS.State->CurrentEntry;
|
||||
}
|
||||
|
||||
bool operator!=(const directory_iterator &RHS) const {
|
||||
return !(*this == RHS);
|
||||
}
|
||||
// Other members as required by
|
||||
// C++ Std, 24.1.1 Input iterators [input.iterators]
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
/// RecDirIterState - Keeps state for the recursive_directory_iterator. It is
|
||||
/// reference counted in order to preserve InputIterator semantics on copy.
|
||||
struct RecDirIterState : public RefCountedBase<RecDirIterState> {
|
||||
RecDirIterState()
|
||||
: Level(0)
|
||||
, HasNoPushRequest(false) {}
|
||||
|
||||
std::stack<directory_iterator, std::vector<directory_iterator> > Stack;
|
||||
uint16_t Level;
|
||||
bool HasNoPushRequest;
|
||||
};
|
||||
}
|
||||
|
||||
/// recursive_directory_iterator - Same as directory_iterator except for it
|
||||
/// recurses down into child directories.
|
||||
class recursive_directory_iterator {
|
||||
IntrusiveRefCntPtr<detail::RecDirIterState> State;
|
||||
|
||||
public:
|
||||
recursive_directory_iterator() {}
|
||||
explicit recursive_directory_iterator(const Twine &path, error_code &ec)
|
||||
: State(new detail::RecDirIterState) {
|
||||
State->Stack.push(directory_iterator(path, ec));
|
||||
if (State->Stack.top() == directory_iterator())
|
||||
State.reset();
|
||||
}
|
||||
// No operator++ because we need error_code.
|
||||
recursive_directory_iterator &increment(error_code &ec) {
|
||||
static const directory_iterator end_itr;
|
||||
|
||||
if (State->HasNoPushRequest)
|
||||
State->HasNoPushRequest = false;
|
||||
else {
|
||||
file_status st;
|
||||
if ((ec = State->Stack.top()->status(st))) return *this;
|
||||
if (is_directory(st)) {
|
||||
State->Stack.push(directory_iterator(*State->Stack.top(), ec));
|
||||
if (ec) return *this;
|
||||
if (State->Stack.top() != end_itr) {
|
||||
++State->Level;
|
||||
return *this;
|
||||
}
|
||||
State->Stack.pop();
|
||||
}
|
||||
}
|
||||
|
||||
while (!State->Stack.empty()
|
||||
&& State->Stack.top().increment(ec) == end_itr) {
|
||||
State->Stack.pop();
|
||||
--State->Level;
|
||||
}
|
||||
|
||||
// Check if we are done. If so, create an end iterator.
|
||||
if (State->Stack.empty())
|
||||
State.reset();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
const directory_entry &operator*() const { return *State->Stack.top(); }
|
||||
const directory_entry *operator->() const { return &*State->Stack.top(); }
|
||||
|
||||
// observers
|
||||
/// Gets the current level. Starting path is at level 0.
|
||||
int level() const { return State->Level; }
|
||||
|
||||
/// Returns true if no_push has been called for this directory_entry.
|
||||
bool no_push_request() const { return State->HasNoPushRequest; }
|
||||
|
||||
// modifiers
|
||||
/// Goes up one level if Level > 0.
|
||||
void pop() {
|
||||
assert(State && "Cannot pop and end itertor!");
|
||||
assert(State->Level > 0 && "Cannot pop an iterator with level < 1");
|
||||
|
||||
static const directory_iterator end_itr;
|
||||
error_code ec;
|
||||
do {
|
||||
if (ec)
|
||||
report_fatal_error("Error incrementing directory iterator.");
|
||||
State->Stack.pop();
|
||||
--State->Level;
|
||||
} while (!State->Stack.empty()
|
||||
&& State->Stack.top().increment(ec) == end_itr);
|
||||
|
||||
// Check if we are done. If so, create an end iterator.
|
||||
if (State->Stack.empty())
|
||||
State.reset();
|
||||
}
|
||||
|
||||
/// Does not go down into the current directory_entry.
|
||||
void no_push() { State->HasNoPushRequest = true; }
|
||||
|
||||
bool operator==(const recursive_directory_iterator &RHS) const {
|
||||
return State == RHS.State;
|
||||
}
|
||||
|
||||
bool operator!=(const recursive_directory_iterator &RHS) const {
|
||||
return !(*this == RHS);
|
||||
}
|
||||
// Other members as required by
|
||||
// C++ Std, 24.1.1 Input iterators [input.iterators]
|
||||
};
|
||||
|
||||
/// @}
|
||||
|
||||
} // end namespace fs
|
||||
} // end namespace sys
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
80
thirdparty/clang/include/llvm/Support/FileUtilities.h
vendored
Normal file
80
thirdparty/clang/include/llvm/Support/FileUtilities.h
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
//===- llvm/Support/FileUtilities.h - File System Utilities -----*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines a family of utility functions which are useful for doing
|
||||
// various things with files.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_FILEUTILITIES_H
|
||||
#define LLVM_SUPPORT_FILEUTILITIES_H
|
||||
|
||||
#include "llvm/Support/FileSystem.h"
|
||||
#include "llvm/Support/Path.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
/// DiffFilesWithTolerance - Compare the two files specified, returning 0 if
|
||||
/// the files match, 1 if they are different, and 2 if there is a file error.
|
||||
/// This function allows you to specify an absolute and relative FP error that
|
||||
/// is allowed to exist. If you specify a string to fill in for the error
|
||||
/// option, it will set the string to an error message if an error occurs, or
|
||||
/// if the files are different.
|
||||
///
|
||||
int DiffFilesWithTolerance(const sys::PathWithStatus &FileA,
|
||||
const sys::PathWithStatus &FileB,
|
||||
double AbsTol, double RelTol,
|
||||
std::string *Error = 0);
|
||||
|
||||
|
||||
/// FileRemover - This class is a simple object meant to be stack allocated.
|
||||
/// If an exception is thrown from a region, the object removes the filename
|
||||
/// specified (if deleteIt is true).
|
||||
///
|
||||
class FileRemover {
|
||||
SmallString<128> Filename;
|
||||
bool DeleteIt;
|
||||
public:
|
||||
FileRemover() : DeleteIt(false) {}
|
||||
|
||||
explicit FileRemover(const Twine& filename, bool deleteIt = true)
|
||||
: DeleteIt(deleteIt) {
|
||||
filename.toVector(Filename);
|
||||
}
|
||||
|
||||
~FileRemover() {
|
||||
if (DeleteIt) {
|
||||
// Ignore problems deleting the file.
|
||||
bool existed;
|
||||
sys::fs::remove(Filename.str(), existed);
|
||||
}
|
||||
}
|
||||
|
||||
/// setFile - Give ownership of the file to the FileRemover so it will
|
||||
/// be removed when the object is destroyed. If the FileRemover already
|
||||
/// had ownership of a file, remove it first.
|
||||
void setFile(const Twine& filename, bool deleteIt = true) {
|
||||
if (DeleteIt) {
|
||||
// Ignore problems deleting the file.
|
||||
bool existed;
|
||||
sys::fs::remove(Filename.str(), existed);
|
||||
}
|
||||
|
||||
Filename.clear();
|
||||
filename.toVector(Filename);
|
||||
DeleteIt = deleteIt;
|
||||
}
|
||||
|
||||
/// releaseFile - Take ownership of the file away from the FileRemover so it
|
||||
/// will not be removed when the object is destroyed.
|
||||
void releaseFile() { DeleteIt = false; }
|
||||
};
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
||||
236
thirdparty/clang/include/llvm/Support/Format.h
vendored
Normal file
236
thirdparty/clang/include/llvm/Support/Format.h
vendored
Normal file
@@ -0,0 +1,236 @@
|
||||
//===- Format.h - Efficient printf-style formatting for streams -*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements the format() function, which can be used with other
|
||||
// LLVM subsystems to provide printf-style formatting. This gives all the power
|
||||
// and risk of printf. This can be used like this (with raw_ostreams as an
|
||||
// example):
|
||||
//
|
||||
// OS << "mynumber: " << format("%4.5f", 1234.412) << '\n';
|
||||
//
|
||||
// Or if you prefer:
|
||||
//
|
||||
// OS << format("mynumber: %4.5f\n", 1234.412);
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_FORMAT_H
|
||||
#define LLVM_SUPPORT_FORMAT_H
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdio>
|
||||
#ifdef _MSC_VER
|
||||
// FIXME: This define is wrong:
|
||||
// - _snprintf does not guarantee that trailing null is always added - if
|
||||
// there is no space for null, it does not report any error.
|
||||
// - According to C++ standard, snprintf should be visible in the 'std'
|
||||
// namespace - this define makes this impossible.
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
|
||||
namespace llvm {
|
||||
|
||||
/// format_object_base - This is a helper class used for handling formatted
|
||||
/// output. It is the abstract base class of a templated derived class.
|
||||
class format_object_base {
|
||||
protected:
|
||||
const char *Fmt;
|
||||
virtual void home(); // Out of line virtual method.
|
||||
|
||||
/// snprint - Call snprintf() for this object, on the given buffer and size.
|
||||
virtual int snprint(char *Buffer, unsigned BufferSize) const = 0;
|
||||
|
||||
public:
|
||||
format_object_base(const char *fmt) : Fmt(fmt) {}
|
||||
virtual ~format_object_base() {}
|
||||
|
||||
/// print - Format the object into the specified buffer. On success, this
|
||||
/// returns the length of the formatted string. If the buffer is too small,
|
||||
/// this returns a length to retry with, which will be larger than BufferSize.
|
||||
unsigned print(char *Buffer, unsigned BufferSize) const {
|
||||
assert(BufferSize && "Invalid buffer size!");
|
||||
|
||||
// Print the string, leaving room for the terminating null.
|
||||
int N = snprint(Buffer, BufferSize);
|
||||
|
||||
// VC++ and old GlibC return negative on overflow, just double the size.
|
||||
if (N < 0)
|
||||
return BufferSize*2;
|
||||
|
||||
// Other impls yield number of bytes needed, not including the final '\0'.
|
||||
if (unsigned(N) >= BufferSize)
|
||||
return N+1;
|
||||
|
||||
// Otherwise N is the length of output (not including the final '\0').
|
||||
return N;
|
||||
}
|
||||
};
|
||||
|
||||
/// format_object1 - This is a templated helper class used by the format
|
||||
/// function that captures the object to be formated and the format string. When
|
||||
/// actually printed, this synthesizes the string into a temporary buffer
|
||||
/// provided and returns whether or not it is big enough.
|
||||
template <typename T>
|
||||
class format_object1 : public format_object_base {
|
||||
T Val;
|
||||
public:
|
||||
format_object1(const char *fmt, const T &val)
|
||||
: format_object_base(fmt), Val(val) {
|
||||
}
|
||||
|
||||
virtual int snprint(char *Buffer, unsigned BufferSize) const {
|
||||
return snprintf(Buffer, BufferSize, Fmt, Val);
|
||||
}
|
||||
};
|
||||
|
||||
/// format_object2 - This is a templated helper class used by the format
|
||||
/// function that captures the object to be formated and the format string. When
|
||||
/// actually printed, this synthesizes the string into a temporary buffer
|
||||
/// provided and returns whether or not it is big enough.
|
||||
template <typename T1, typename T2>
|
||||
class format_object2 : public format_object_base {
|
||||
T1 Val1;
|
||||
T2 Val2;
|
||||
public:
|
||||
format_object2(const char *fmt, const T1 &val1, const T2 &val2)
|
||||
: format_object_base(fmt), Val1(val1), Val2(val2) {
|
||||
}
|
||||
|
||||
virtual int snprint(char *Buffer, unsigned BufferSize) const {
|
||||
return snprintf(Buffer, BufferSize, Fmt, Val1, Val2);
|
||||
}
|
||||
};
|
||||
|
||||
/// format_object3 - This is a templated helper class used by the format
|
||||
/// function that captures the object to be formated and the format string. When
|
||||
/// actually printed, this synthesizes the string into a temporary buffer
|
||||
/// provided and returns whether or not it is big enough.
|
||||
template <typename T1, typename T2, typename T3>
|
||||
class format_object3 : public format_object_base {
|
||||
T1 Val1;
|
||||
T2 Val2;
|
||||
T3 Val3;
|
||||
public:
|
||||
format_object3(const char *fmt, const T1 &val1, const T2 &val2,const T3 &val3)
|
||||
: format_object_base(fmt), Val1(val1), Val2(val2), Val3(val3) {
|
||||
}
|
||||
|
||||
virtual int snprint(char *Buffer, unsigned BufferSize) const {
|
||||
return snprintf(Buffer, BufferSize, Fmt, Val1, Val2, Val3);
|
||||
}
|
||||
};
|
||||
|
||||
/// format_object4 - This is a templated helper class used by the format
|
||||
/// function that captures the object to be formated and the format string. When
|
||||
/// actually printed, this synthesizes the string into a temporary buffer
|
||||
/// provided and returns whether or not it is big enough.
|
||||
template <typename T1, typename T2, typename T3, typename T4>
|
||||
class format_object4 : public format_object_base {
|
||||
T1 Val1;
|
||||
T2 Val2;
|
||||
T3 Val3;
|
||||
T4 Val4;
|
||||
public:
|
||||
format_object4(const char *fmt, const T1 &val1, const T2 &val2,
|
||||
const T3 &val3, const T4 &val4)
|
||||
: format_object_base(fmt), Val1(val1), Val2(val2), Val3(val3), Val4(val4) {
|
||||
}
|
||||
|
||||
virtual int snprint(char *Buffer, unsigned BufferSize) const {
|
||||
return snprintf(Buffer, BufferSize, Fmt, Val1, Val2, Val3, Val4);
|
||||
}
|
||||
};
|
||||
|
||||
/// format_object5 - This is a templated helper class used by the format
|
||||
/// function that captures the object to be formated and the format string. When
|
||||
/// actually printed, this synthesizes the string into a temporary buffer
|
||||
/// provided and returns whether or not it is big enough.
|
||||
template <typename T1, typename T2, typename T3, typename T4, typename T5>
|
||||
class format_object5 : public format_object_base {
|
||||
T1 Val1;
|
||||
T2 Val2;
|
||||
T3 Val3;
|
||||
T4 Val4;
|
||||
T5 Val5;
|
||||
public:
|
||||
format_object5(const char *fmt, const T1 &val1, const T2 &val2,
|
||||
const T3 &val3, const T4 &val4, const T5 &val5)
|
||||
: format_object_base(fmt), Val1(val1), Val2(val2), Val3(val3), Val4(val4),
|
||||
Val5(val5) {
|
||||
}
|
||||
|
||||
virtual int snprint(char *Buffer, unsigned BufferSize) const {
|
||||
return snprintf(Buffer, BufferSize, Fmt, Val1, Val2, Val3, Val4, Val5);
|
||||
}
|
||||
};
|
||||
|
||||
/// This is a helper function that is used to produce formatted output.
|
||||
///
|
||||
/// This is typically used like:
|
||||
/// \code
|
||||
/// OS << format("%0.4f", myfloat) << '\n';
|
||||
/// \endcode
|
||||
template <typename T>
|
||||
inline format_object1<T> format(const char *Fmt, const T &Val) {
|
||||
return format_object1<T>(Fmt, Val);
|
||||
}
|
||||
|
||||
/// This is a helper function that is used to produce formatted output.
|
||||
///
|
||||
/// This is typically used like:
|
||||
/// \code
|
||||
/// OS << format("%0.4f", myfloat) << '\n';
|
||||
/// \endcode
|
||||
template <typename T1, typename T2>
|
||||
inline format_object2<T1, T2> format(const char *Fmt, const T1 &Val1,
|
||||
const T2 &Val2) {
|
||||
return format_object2<T1, T2>(Fmt, Val1, Val2);
|
||||
}
|
||||
|
||||
/// This is a helper function that is used to produce formatted output.
|
||||
///
|
||||
/// This is typically used like:
|
||||
/// \code
|
||||
/// OS << format("%0.4f", myfloat) << '\n';
|
||||
/// \endcode
|
||||
template <typename T1, typename T2, typename T3>
|
||||
inline format_object3<T1, T2, T3> format(const char *Fmt, const T1 &Val1,
|
||||
const T2 &Val2, const T3 &Val3) {
|
||||
return format_object3<T1, T2, T3>(Fmt, Val1, Val2, Val3);
|
||||
}
|
||||
|
||||
/// This is a helper function that is used to produce formatted output.
|
||||
///
|
||||
/// This is typically used like:
|
||||
/// \code
|
||||
/// OS << format("%0.4f", myfloat) << '\n';
|
||||
/// \endcode
|
||||
template <typename T1, typename T2, typename T3, typename T4>
|
||||
inline format_object4<T1, T2, T3, T4> format(const char *Fmt, const T1 &Val1,
|
||||
const T2 &Val2, const T3 &Val3,
|
||||
const T4 &Val4) {
|
||||
return format_object4<T1, T2, T3, T4>(Fmt, Val1, Val2, Val3, Val4);
|
||||
}
|
||||
|
||||
/// This is a helper function that is used to produce formatted output.
|
||||
///
|
||||
/// This is typically used like:
|
||||
/// \code
|
||||
/// OS << format("%0.4f", myfloat) << '\n';
|
||||
/// \endcode
|
||||
template <typename T1, typename T2, typename T3, typename T4, typename T5>
|
||||
inline format_object5<T1, T2, T3, T4, T5> format(const char *Fmt,const T1 &Val1,
|
||||
const T2 &Val2, const T3 &Val3,
|
||||
const T4 &Val4, const T5 &Val5) {
|
||||
return format_object5<T1, T2, T3, T4, T5>(Fmt, Val1, Val2, Val3, Val4, Val5);
|
||||
}
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
155
thirdparty/clang/include/llvm/Support/FormattedStream.h
vendored
Normal file
155
thirdparty/clang/include/llvm/Support/FormattedStream.h
vendored
Normal file
@@ -0,0 +1,155 @@
|
||||
//===-- llvm/Support/FormattedStream.h - Formatted streams ------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file contains raw_ostream implementations for streams to do
|
||||
// things like pretty-print comments.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_FORMATTEDSTREAM_H
|
||||
#define LLVM_SUPPORT_FORMATTEDSTREAM_H
|
||||
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
/// formatted_raw_ostream - A raw_ostream that wraps another one and keeps track
|
||||
/// of column position, allowing padding out to specific column boundaries.
|
||||
///
|
||||
class formatted_raw_ostream : public raw_ostream {
|
||||
public:
|
||||
/// DELETE_STREAM - Tell the destructor to delete the held stream.
|
||||
///
|
||||
static const bool DELETE_STREAM = true;
|
||||
|
||||
/// PRESERVE_STREAM - Tell the destructor to not delete the held
|
||||
/// stream.
|
||||
///
|
||||
static const bool PRESERVE_STREAM = false;
|
||||
|
||||
private:
|
||||
/// TheStream - The real stream we output to. We set it to be
|
||||
/// unbuffered, since we're already doing our own buffering.
|
||||
///
|
||||
raw_ostream *TheStream;
|
||||
|
||||
/// DeleteStream - Do we need to delete TheStream in the
|
||||
/// destructor?
|
||||
///
|
||||
bool DeleteStream;
|
||||
|
||||
/// ColumnScanned - The current output column of the data that's
|
||||
/// been flushed and the portion of the buffer that's been
|
||||
/// scanned. The column scheme is zero-based.
|
||||
///
|
||||
unsigned ColumnScanned;
|
||||
|
||||
/// Scanned - This points to one past the last character in the
|
||||
/// buffer we've scanned.
|
||||
///
|
||||
const char *Scanned;
|
||||
|
||||
virtual void write_impl(const char *Ptr, size_t Size) LLVM_OVERRIDE;
|
||||
|
||||
/// current_pos - Return the current position within the stream,
|
||||
/// not counting the bytes currently in the buffer.
|
||||
virtual uint64_t current_pos() const LLVM_OVERRIDE {
|
||||
// Our current position in the stream is all the contents which have been
|
||||
// written to the underlying stream (*not* the current position of the
|
||||
// underlying stream).
|
||||
return TheStream->tell();
|
||||
}
|
||||
|
||||
/// ComputeColumn - Examine the given output buffer and figure out which
|
||||
/// column we end up in after output.
|
||||
///
|
||||
void ComputeColumn(const char *Ptr, size_t size);
|
||||
|
||||
public:
|
||||
/// formatted_raw_ostream - Open the specified file for
|
||||
/// writing. If an error occurs, information about the error is
|
||||
/// put into ErrorInfo, and the stream should be immediately
|
||||
/// destroyed; the string will be empty if no error occurred.
|
||||
///
|
||||
/// As a side effect, the given Stream is set to be Unbuffered.
|
||||
/// This is because formatted_raw_ostream does its own buffering,
|
||||
/// so it doesn't want another layer of buffering to be happening
|
||||
/// underneath it.
|
||||
///
|
||||
formatted_raw_ostream(raw_ostream &Stream, bool Delete = false)
|
||||
: raw_ostream(), TheStream(0), DeleteStream(false), ColumnScanned(0) {
|
||||
setStream(Stream, Delete);
|
||||
}
|
||||
explicit formatted_raw_ostream()
|
||||
: raw_ostream(), TheStream(0), DeleteStream(false), ColumnScanned(0) {
|
||||
Scanned = 0;
|
||||
}
|
||||
|
||||
~formatted_raw_ostream() {
|
||||
flush();
|
||||
releaseStream();
|
||||
}
|
||||
|
||||
void setStream(raw_ostream &Stream, bool Delete = false) {
|
||||
releaseStream();
|
||||
|
||||
TheStream = &Stream;
|
||||
DeleteStream = Delete;
|
||||
|
||||
// This formatted_raw_ostream inherits from raw_ostream, so it'll do its
|
||||
// own buffering, and it doesn't need or want TheStream to do another
|
||||
// layer of buffering underneath. Resize the buffer to what TheStream
|
||||
// had been using, and tell TheStream not to do its own buffering.
|
||||
if (size_t BufferSize = TheStream->GetBufferSize())
|
||||
SetBufferSize(BufferSize);
|
||||
else
|
||||
SetUnbuffered();
|
||||
TheStream->SetUnbuffered();
|
||||
|
||||
Scanned = 0;
|
||||
}
|
||||
|
||||
/// PadToColumn - Align the output to some column number. If the current
|
||||
/// column is already equal to or more than NewCol, PadToColumn inserts one
|
||||
/// space.
|
||||
///
|
||||
/// \param NewCol - The column to move to.
|
||||
formatted_raw_ostream &PadToColumn(unsigned NewCol);
|
||||
|
||||
private:
|
||||
void releaseStream() {
|
||||
// Delete the stream if needed. Otherwise, transfer the buffer
|
||||
// settings from this raw_ostream back to the underlying stream.
|
||||
if (!TheStream)
|
||||
return;
|
||||
if (DeleteStream)
|
||||
delete TheStream;
|
||||
else if (size_t BufferSize = GetBufferSize())
|
||||
TheStream->SetBufferSize(BufferSize);
|
||||
else
|
||||
TheStream->SetUnbuffered();
|
||||
}
|
||||
};
|
||||
|
||||
/// fouts() - This returns a reference to a formatted_raw_ostream for
|
||||
/// standard output. Use it like: fouts() << "foo" << "bar";
|
||||
formatted_raw_ostream &fouts();
|
||||
|
||||
/// ferrs() - This returns a reference to a formatted_raw_ostream for
|
||||
/// standard error. Use it like: ferrs() << "foo" << "bar";
|
||||
formatted_raw_ostream &ferrs();
|
||||
|
||||
/// fdbgs() - This returns a reference to a formatted_raw_ostream for
|
||||
/// debug output. Use it like: fdbgs() << "foo" << "bar";
|
||||
formatted_raw_ostream &fdbgs();
|
||||
|
||||
} // end llvm namespace
|
||||
|
||||
|
||||
#endif
|
||||
226
thirdparty/clang/include/llvm/Support/GCOV.h
vendored
Normal file
226
thirdparty/clang/include/llvm/Support/GCOV.h
vendored
Normal file
@@ -0,0 +1,226 @@
|
||||
//===-- llvm/Support/GCOV.h - LLVM coverage tool ----------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This header provides the interface to read and write coverage files that
|
||||
// use 'gcov' format.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_GCOV_H
|
||||
#define LLVM_SUPPORT_GCOV_H
|
||||
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/StringMap.h"
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class GCOVFunction;
|
||||
class GCOVBlock;
|
||||
class GCOVLines;
|
||||
class FileInfo;
|
||||
|
||||
namespace GCOV {
|
||||
enum GCOVFormat {
|
||||
InvalidGCOV,
|
||||
GCNO_402,
|
||||
GCNO_404,
|
||||
GCDA_402,
|
||||
GCDA_404
|
||||
};
|
||||
} // end GCOV namespace
|
||||
|
||||
/// GCOVBuffer - A wrapper around MemoryBuffer to provide GCOV specific
|
||||
/// read operations.
|
||||
class GCOVBuffer {
|
||||
public:
|
||||
GCOVBuffer(MemoryBuffer *B) : Buffer(B), Cursor(0) {}
|
||||
|
||||
/// readGCOVFormat - Read GCOV signature at the beginning of buffer.
|
||||
GCOV::GCOVFormat readGCOVFormat() {
|
||||
StringRef Magic = Buffer->getBuffer().slice(0, 12);
|
||||
Cursor = 12;
|
||||
if (Magic == "oncg*404MVLL")
|
||||
return GCOV::GCNO_404;
|
||||
else if (Magic == "oncg*204MVLL")
|
||||
return GCOV::GCNO_402;
|
||||
else if (Magic == "adcg*404MVLL")
|
||||
return GCOV::GCDA_404;
|
||||
else if (Magic == "adcg*204MVLL")
|
||||
return GCOV::GCDA_402;
|
||||
|
||||
Cursor = 0;
|
||||
return GCOV::InvalidGCOV;
|
||||
}
|
||||
|
||||
/// readFunctionTag - If cursor points to a function tag then increment the
|
||||
/// cursor and return true otherwise return false.
|
||||
bool readFunctionTag() {
|
||||
StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4);
|
||||
if (Tag.empty() ||
|
||||
Tag[0] != '\0' || Tag[1] != '\0' ||
|
||||
Tag[2] != '\0' || Tag[3] != '\1') {
|
||||
return false;
|
||||
}
|
||||
Cursor += 4;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// readBlockTag - If cursor points to a block tag then increment the
|
||||
/// cursor and return true otherwise return false.
|
||||
bool readBlockTag() {
|
||||
StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4);
|
||||
if (Tag.empty() ||
|
||||
Tag[0] != '\0' || Tag[1] != '\0' ||
|
||||
Tag[2] != '\x41' || Tag[3] != '\x01') {
|
||||
return false;
|
||||
}
|
||||
Cursor += 4;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// readEdgeTag - If cursor points to an edge tag then increment the
|
||||
/// cursor and return true otherwise return false.
|
||||
bool readEdgeTag() {
|
||||
StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4);
|
||||
if (Tag.empty() ||
|
||||
Tag[0] != '\0' || Tag[1] != '\0' ||
|
||||
Tag[2] != '\x43' || Tag[3] != '\x01') {
|
||||
return false;
|
||||
}
|
||||
Cursor += 4;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// readLineTag - If cursor points to a line tag then increment the
|
||||
/// cursor and return true otherwise return false.
|
||||
bool readLineTag() {
|
||||
StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4);
|
||||
if (Tag.empty() ||
|
||||
Tag[0] != '\0' || Tag[1] != '\0' ||
|
||||
Tag[2] != '\x45' || Tag[3] != '\x01') {
|
||||
return false;
|
||||
}
|
||||
Cursor += 4;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// readArcTag - If cursor points to an gcda arc tag then increment the
|
||||
/// cursor and return true otherwise return false.
|
||||
bool readArcTag() {
|
||||
StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4);
|
||||
if (Tag.empty() ||
|
||||
Tag[0] != '\0' || Tag[1] != '\0' ||
|
||||
Tag[2] != '\xa1' || Tag[3] != '\1') {
|
||||
return false;
|
||||
}
|
||||
Cursor += 4;
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t readInt() {
|
||||
uint32_t Result;
|
||||
StringRef Str = Buffer->getBuffer().slice(Cursor, Cursor+4);
|
||||
assert (Str.empty() == false && "Unexpected memory buffer end!");
|
||||
Cursor += 4;
|
||||
Result = *(const uint32_t *)(Str.data());
|
||||
return Result;
|
||||
}
|
||||
|
||||
uint64_t readInt64() {
|
||||
uint64_t Lo = readInt();
|
||||
uint64_t Hi = readInt();
|
||||
uint64_t Result = Lo | (Hi << 32);
|
||||
return Result;
|
||||
}
|
||||
|
||||
StringRef readString() {
|
||||
uint32_t Len = readInt() * 4;
|
||||
StringRef Str = Buffer->getBuffer().slice(Cursor, Cursor+Len);
|
||||
Cursor += Len;
|
||||
return Str;
|
||||
}
|
||||
|
||||
uint64_t getCursor() const { return Cursor; }
|
||||
private:
|
||||
MemoryBuffer *Buffer;
|
||||
uint64_t Cursor;
|
||||
};
|
||||
|
||||
/// GCOVFile - Collects coverage information for one pair of coverage file
|
||||
/// (.gcno and .gcda).
|
||||
class GCOVFile {
|
||||
public:
|
||||
GCOVFile() {}
|
||||
~GCOVFile();
|
||||
bool read(GCOVBuffer &Buffer);
|
||||
void dump();
|
||||
void collectLineCounts(FileInfo &FI);
|
||||
private:
|
||||
SmallVector<GCOVFunction *, 16> Functions;
|
||||
};
|
||||
|
||||
/// GCOVFunction - Collects function information.
|
||||
class GCOVFunction {
|
||||
public:
|
||||
GCOVFunction() : Ident(0), LineNumber(0) {}
|
||||
~GCOVFunction();
|
||||
bool read(GCOVBuffer &Buffer, GCOV::GCOVFormat Format);
|
||||
void dump();
|
||||
void collectLineCounts(FileInfo &FI);
|
||||
private:
|
||||
uint32_t Ident;
|
||||
uint32_t LineNumber;
|
||||
StringRef Name;
|
||||
StringRef Filename;
|
||||
SmallVector<GCOVBlock *, 16> Blocks;
|
||||
};
|
||||
|
||||
/// GCOVBlock - Collects block information.
|
||||
class GCOVBlock {
|
||||
public:
|
||||
GCOVBlock(uint32_t N) : Number(N), Counter(0) {}
|
||||
~GCOVBlock();
|
||||
void addEdge(uint32_t N) { Edges.push_back(N); }
|
||||
void addLine(StringRef Filename, uint32_t LineNo);
|
||||
void addCount(uint64_t N) { Counter = N; }
|
||||
void dump();
|
||||
void collectLineCounts(FileInfo &FI);
|
||||
private:
|
||||
uint32_t Number;
|
||||
uint64_t Counter;
|
||||
SmallVector<uint32_t, 16> Edges;
|
||||
StringMap<GCOVLines *> Lines;
|
||||
};
|
||||
|
||||
/// GCOVLines - A wrapper around a vector of int to keep track of line nos.
|
||||
class GCOVLines {
|
||||
public:
|
||||
~GCOVLines() { Lines.clear(); }
|
||||
void add(uint32_t N) { Lines.push_back(N); }
|
||||
void collectLineCounts(FileInfo &FI, StringRef Filename, uint32_t Count);
|
||||
void dump();
|
||||
|
||||
private:
|
||||
SmallVector<uint32_t, 4> Lines;
|
||||
};
|
||||
|
||||
typedef SmallVector<uint32_t, 16> LineCounts;
|
||||
class FileInfo {
|
||||
public:
|
||||
void addLineCount(StringRef Filename, uint32_t Line, uint32_t Count);
|
||||
void print();
|
||||
private:
|
||||
StringMap<LineCounts> LineInfo;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
113
thirdparty/clang/include/llvm/Support/GetElementPtrTypeIterator.h
vendored
Normal file
113
thirdparty/clang/include/llvm/Support/GetElementPtrTypeIterator.h
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
//===- llvm/Support/GetElementPtrTypeIterator.h -----------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements an iterator for walking through the types indexed by
|
||||
// getelementptr instructions.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_GETELEMENTPTRTYPEITERATOR_H
|
||||
#define LLVM_SUPPORT_GETELEMENTPTRTYPEITERATOR_H
|
||||
|
||||
#include "llvm/IR/DerivedTypes.h"
|
||||
#include "llvm/IR/User.h"
|
||||
|
||||
namespace llvm {
|
||||
template<typename ItTy = User::const_op_iterator>
|
||||
class generic_gep_type_iterator
|
||||
: public std::iterator<std::forward_iterator_tag, Type *, ptrdiff_t> {
|
||||
typedef std::iterator<std::forward_iterator_tag,
|
||||
Type *, ptrdiff_t> super;
|
||||
|
||||
ItTy OpIt;
|
||||
Type *CurTy;
|
||||
generic_gep_type_iterator() {}
|
||||
public:
|
||||
|
||||
static generic_gep_type_iterator begin(Type *Ty, ItTy It) {
|
||||
generic_gep_type_iterator I;
|
||||
I.CurTy = Ty;
|
||||
I.OpIt = It;
|
||||
return I;
|
||||
}
|
||||
static generic_gep_type_iterator end(ItTy It) {
|
||||
generic_gep_type_iterator I;
|
||||
I.CurTy = 0;
|
||||
I.OpIt = It;
|
||||
return I;
|
||||
}
|
||||
|
||||
bool operator==(const generic_gep_type_iterator& x) const {
|
||||
return OpIt == x.OpIt;
|
||||
}
|
||||
bool operator!=(const generic_gep_type_iterator& x) const {
|
||||
return !operator==(x);
|
||||
}
|
||||
|
||||
Type *operator*() const {
|
||||
return CurTy;
|
||||
}
|
||||
|
||||
Type *getIndexedType() const {
|
||||
CompositeType *CT = cast<CompositeType>(CurTy);
|
||||
return CT->getTypeAtIndex(getOperand());
|
||||
}
|
||||
|
||||
// This is a non-standard operator->. It allows you to call methods on the
|
||||
// current type directly.
|
||||
Type *operator->() const { return operator*(); }
|
||||
|
||||
Value *getOperand() const { return *OpIt; }
|
||||
|
||||
generic_gep_type_iterator& operator++() { // Preincrement
|
||||
if (CompositeType *CT = dyn_cast<CompositeType>(CurTy)) {
|
||||
CurTy = CT->getTypeAtIndex(getOperand());
|
||||
} else {
|
||||
CurTy = 0;
|
||||
}
|
||||
++OpIt;
|
||||
return *this;
|
||||
}
|
||||
|
||||
generic_gep_type_iterator operator++(int) { // Postincrement
|
||||
generic_gep_type_iterator tmp = *this; ++*this; return tmp;
|
||||
}
|
||||
};
|
||||
|
||||
typedef generic_gep_type_iterator<> gep_type_iterator;
|
||||
|
||||
inline gep_type_iterator gep_type_begin(const User *GEP) {
|
||||
return gep_type_iterator::begin
|
||||
(GEP->getOperand(0)->getType()->getScalarType(), GEP->op_begin()+1);
|
||||
}
|
||||
inline gep_type_iterator gep_type_end(const User *GEP) {
|
||||
return gep_type_iterator::end(GEP->op_end());
|
||||
}
|
||||
inline gep_type_iterator gep_type_begin(const User &GEP) {
|
||||
return gep_type_iterator::begin
|
||||
(GEP.getOperand(0)->getType()->getScalarType(), GEP.op_begin()+1);
|
||||
}
|
||||
inline gep_type_iterator gep_type_end(const User &GEP) {
|
||||
return gep_type_iterator::end(GEP.op_end());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline generic_gep_type_iterator<const T *>
|
||||
gep_type_begin(Type *Op0, ArrayRef<T> A) {
|
||||
return generic_gep_type_iterator<const T *>::begin(Op0, A.begin());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline generic_gep_type_iterator<const T *>
|
||||
gep_type_end(Type *Op0, ArrayRef<T> A) {
|
||||
return generic_gep_type_iterator<const T *>::end(A.end());
|
||||
}
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
369
thirdparty/clang/include/llvm/Support/GraphWriter.h
vendored
Normal file
369
thirdparty/clang/include/llvm/Support/GraphWriter.h
vendored
Normal file
@@ -0,0 +1,369 @@
|
||||
//===-- llvm/Support/GraphWriter.h - Write graph to a .dot file -*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines a simple interface that can be used to print out generic
|
||||
// LLVM graphs to ".dot" files. "dot" is a tool that is part of the AT&T
|
||||
// graphviz package (http://www.research.att.com/sw/tools/graphviz/) which can
|
||||
// be used to turn the files output by this interface into a variety of
|
||||
// different graphics formats.
|
||||
//
|
||||
// Graphs do not need to implement any interface past what is already required
|
||||
// by the GraphTraits template, but they can choose to implement specializations
|
||||
// of the DOTGraphTraits template if they want to customize the graphs output in
|
||||
// any way.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_GRAPHWRITER_H
|
||||
#define LLVM_SUPPORT_GRAPHWRITER_H
|
||||
|
||||
#include "llvm/ADT/GraphTraits.h"
|
||||
#include "llvm/Support/DOTGraphTraits.h"
|
||||
#include "llvm/Support/Path.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <cassert>
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
namespace DOT { // Private functions...
|
||||
std::string EscapeString(const std::string &Label);
|
||||
|
||||
/// \brief Get a color string for this node number. Simply round-robin selects
|
||||
/// from a reasonable number of colors.
|
||||
StringRef getColorString(unsigned NodeNumber);
|
||||
}
|
||||
|
||||
namespace GraphProgram {
|
||||
enum Name {
|
||||
DOT,
|
||||
FDP,
|
||||
NEATO,
|
||||
TWOPI,
|
||||
CIRCO
|
||||
};
|
||||
}
|
||||
|
||||
void DisplayGraph(const sys::Path& Filename, bool wait=true, GraphProgram::Name program = GraphProgram::DOT);
|
||||
|
||||
template<typename GraphType>
|
||||
class GraphWriter {
|
||||
raw_ostream &O;
|
||||
const GraphType &G;
|
||||
|
||||
typedef DOTGraphTraits<GraphType> DOTTraits;
|
||||
typedef GraphTraits<GraphType> GTraits;
|
||||
typedef typename GTraits::NodeType NodeType;
|
||||
typedef typename GTraits::nodes_iterator node_iterator;
|
||||
typedef typename GTraits::ChildIteratorType child_iterator;
|
||||
DOTTraits DTraits;
|
||||
|
||||
// Writes the edge labels of the node to O and returns true if there are any
|
||||
// edge labels not equal to the empty string "".
|
||||
bool getEdgeSourceLabels(raw_ostream &O, NodeType *Node) {
|
||||
child_iterator EI = GTraits::child_begin(Node);
|
||||
child_iterator EE = GTraits::child_end(Node);
|
||||
bool hasEdgeSourceLabels = false;
|
||||
|
||||
for (unsigned i = 0; EI != EE && i != 64; ++EI, ++i) {
|
||||
std::string label = DTraits.getEdgeSourceLabel(Node, EI);
|
||||
|
||||
if (label.empty())
|
||||
continue;
|
||||
|
||||
hasEdgeSourceLabels = true;
|
||||
|
||||
if (i)
|
||||
O << "|";
|
||||
|
||||
O << "<s" << i << ">" << DOT::EscapeString(label);
|
||||
}
|
||||
|
||||
if (EI != EE && hasEdgeSourceLabels)
|
||||
O << "|<s64>truncated...";
|
||||
|
||||
return hasEdgeSourceLabels;
|
||||
}
|
||||
|
||||
public:
|
||||
GraphWriter(raw_ostream &o, const GraphType &g, bool SN) : O(o), G(g) {
|
||||
DTraits = DOTTraits(SN);
|
||||
}
|
||||
|
||||
void writeGraph(const std::string &Title = "") {
|
||||
// Output the header for the graph...
|
||||
writeHeader(Title);
|
||||
|
||||
// Emit all of the nodes in the graph...
|
||||
writeNodes();
|
||||
|
||||
// Output any customizations on the graph
|
||||
DOTGraphTraits<GraphType>::addCustomGraphFeatures(G, *this);
|
||||
|
||||
// Output the end of the graph
|
||||
writeFooter();
|
||||
}
|
||||
|
||||
void writeHeader(const std::string &Title) {
|
||||
std::string GraphName = DTraits.getGraphName(G);
|
||||
|
||||
if (!Title.empty())
|
||||
O << "digraph \"" << DOT::EscapeString(Title) << "\" {\n";
|
||||
else if (!GraphName.empty())
|
||||
O << "digraph \"" << DOT::EscapeString(GraphName) << "\" {\n";
|
||||
else
|
||||
O << "digraph unnamed {\n";
|
||||
|
||||
if (DTraits.renderGraphFromBottomUp())
|
||||
O << "\trankdir=\"BT\";\n";
|
||||
|
||||
if (!Title.empty())
|
||||
O << "\tlabel=\"" << DOT::EscapeString(Title) << "\";\n";
|
||||
else if (!GraphName.empty())
|
||||
O << "\tlabel=\"" << DOT::EscapeString(GraphName) << "\";\n";
|
||||
O << DTraits.getGraphProperties(G);
|
||||
O << "\n";
|
||||
}
|
||||
|
||||
void writeFooter() {
|
||||
// Finish off the graph
|
||||
O << "}\n";
|
||||
}
|
||||
|
||||
void writeNodes() {
|
||||
// Loop over the graph, printing it out...
|
||||
for (node_iterator I = GTraits::nodes_begin(G), E = GTraits::nodes_end(G);
|
||||
I != E; ++I)
|
||||
if (!isNodeHidden(*I))
|
||||
writeNode(*I);
|
||||
}
|
||||
|
||||
bool isNodeHidden(NodeType &Node) {
|
||||
return isNodeHidden(&Node);
|
||||
}
|
||||
|
||||
bool isNodeHidden(NodeType *const *Node) {
|
||||
return isNodeHidden(*Node);
|
||||
}
|
||||
|
||||
bool isNodeHidden(NodeType *Node) {
|
||||
return DTraits.isNodeHidden(Node);
|
||||
}
|
||||
|
||||
void writeNode(NodeType& Node) {
|
||||
writeNode(&Node);
|
||||
}
|
||||
|
||||
void writeNode(NodeType *const *Node) {
|
||||
writeNode(*Node);
|
||||
}
|
||||
|
||||
void writeNode(NodeType *Node) {
|
||||
std::string NodeAttributes = DTraits.getNodeAttributes(Node, G);
|
||||
|
||||
O << "\tNode" << static_cast<const void*>(Node) << " [shape=record,";
|
||||
if (!NodeAttributes.empty()) O << NodeAttributes << ",";
|
||||
O << "label=\"{";
|
||||
|
||||
if (!DTraits.renderGraphFromBottomUp()) {
|
||||
O << DOT::EscapeString(DTraits.getNodeLabel(Node, G));
|
||||
|
||||
// If we should include the address of the node in the label, do so now.
|
||||
if (DTraits.hasNodeAddressLabel(Node, G))
|
||||
O << "|" << static_cast<const void*>(Node);
|
||||
|
||||
std::string NodeDesc = DTraits.getNodeDescription(Node, G);
|
||||
if (!NodeDesc.empty())
|
||||
O << "|" << DOT::EscapeString(NodeDesc);
|
||||
}
|
||||
|
||||
std::string edgeSourceLabels;
|
||||
raw_string_ostream EdgeSourceLabels(edgeSourceLabels);
|
||||
bool hasEdgeSourceLabels = getEdgeSourceLabels(EdgeSourceLabels, Node);
|
||||
|
||||
if (hasEdgeSourceLabels) {
|
||||
if (!DTraits.renderGraphFromBottomUp()) O << "|";
|
||||
|
||||
O << "{" << EdgeSourceLabels.str() << "}";
|
||||
|
||||
if (DTraits.renderGraphFromBottomUp()) O << "|";
|
||||
}
|
||||
|
||||
if (DTraits.renderGraphFromBottomUp()) {
|
||||
O << DOT::EscapeString(DTraits.getNodeLabel(Node, G));
|
||||
|
||||
// If we should include the address of the node in the label, do so now.
|
||||
if (DTraits.hasNodeAddressLabel(Node, G))
|
||||
O << "|" << static_cast<const void*>(Node);
|
||||
|
||||
std::string NodeDesc = DTraits.getNodeDescription(Node, G);
|
||||
if (!NodeDesc.empty())
|
||||
O << "|" << DOT::EscapeString(NodeDesc);
|
||||
}
|
||||
|
||||
if (DTraits.hasEdgeDestLabels()) {
|
||||
O << "|{";
|
||||
|
||||
unsigned i = 0, e = DTraits.numEdgeDestLabels(Node);
|
||||
for (; i != e && i != 64; ++i) {
|
||||
if (i) O << "|";
|
||||
O << "<d" << i << ">"
|
||||
<< DOT::EscapeString(DTraits.getEdgeDestLabel(Node, i));
|
||||
}
|
||||
|
||||
if (i != e)
|
||||
O << "|<d64>truncated...";
|
||||
O << "}";
|
||||
}
|
||||
|
||||
O << "}\"];\n"; // Finish printing the "node" line
|
||||
|
||||
// Output all of the edges now
|
||||
child_iterator EI = GTraits::child_begin(Node);
|
||||
child_iterator EE = GTraits::child_end(Node);
|
||||
for (unsigned i = 0; EI != EE && i != 64; ++EI, ++i)
|
||||
if (!DTraits.isNodeHidden(*EI))
|
||||
writeEdge(Node, i, EI);
|
||||
for (; EI != EE; ++EI)
|
||||
if (!DTraits.isNodeHidden(*EI))
|
||||
writeEdge(Node, 64, EI);
|
||||
}
|
||||
|
||||
void writeEdge(NodeType *Node, unsigned edgeidx, child_iterator EI) {
|
||||
if (NodeType *TargetNode = *EI) {
|
||||
int DestPort = -1;
|
||||
if (DTraits.edgeTargetsEdgeSource(Node, EI)) {
|
||||
child_iterator TargetIt = DTraits.getEdgeTarget(Node, EI);
|
||||
|
||||
// Figure out which edge this targets...
|
||||
unsigned Offset =
|
||||
(unsigned)std::distance(GTraits::child_begin(TargetNode), TargetIt);
|
||||
DestPort = static_cast<int>(Offset);
|
||||
}
|
||||
|
||||
if (DTraits.getEdgeSourceLabel(Node, EI).empty())
|
||||
edgeidx = -1;
|
||||
|
||||
emitEdge(static_cast<const void*>(Node), edgeidx,
|
||||
static_cast<const void*>(TargetNode), DestPort,
|
||||
DTraits.getEdgeAttributes(Node, EI, G));
|
||||
}
|
||||
}
|
||||
|
||||
/// emitSimpleNode - Outputs a simple (non-record) node
|
||||
void emitSimpleNode(const void *ID, const std::string &Attr,
|
||||
const std::string &Label, unsigned NumEdgeSources = 0,
|
||||
const std::vector<std::string> *EdgeSourceLabels = 0) {
|
||||
O << "\tNode" << ID << "[ ";
|
||||
if (!Attr.empty())
|
||||
O << Attr << ",";
|
||||
O << " label =\"";
|
||||
if (NumEdgeSources) O << "{";
|
||||
O << DOT::EscapeString(Label);
|
||||
if (NumEdgeSources) {
|
||||
O << "|{";
|
||||
|
||||
for (unsigned i = 0; i != NumEdgeSources; ++i) {
|
||||
if (i) O << "|";
|
||||
O << "<s" << i << ">";
|
||||
if (EdgeSourceLabels) O << DOT::EscapeString((*EdgeSourceLabels)[i]);
|
||||
}
|
||||
O << "}}";
|
||||
}
|
||||
O << "\"];\n";
|
||||
}
|
||||
|
||||
/// emitEdge - Output an edge from a simple node into the graph...
|
||||
void emitEdge(const void *SrcNodeID, int SrcNodePort,
|
||||
const void *DestNodeID, int DestNodePort,
|
||||
const std::string &Attrs) {
|
||||
if (SrcNodePort > 64) return; // Eminating from truncated part?
|
||||
if (DestNodePort > 64) DestNodePort = 64; // Targeting the truncated part?
|
||||
|
||||
O << "\tNode" << SrcNodeID;
|
||||
if (SrcNodePort >= 0)
|
||||
O << ":s" << SrcNodePort;
|
||||
O << " -> Node" << DestNodeID;
|
||||
if (DestNodePort >= 0 && DTraits.hasEdgeDestLabels())
|
||||
O << ":d" << DestNodePort;
|
||||
|
||||
if (!Attrs.empty())
|
||||
O << "[" << Attrs << "]";
|
||||
O << ";\n";
|
||||
}
|
||||
|
||||
/// getOStream - Get the raw output stream into the graph file. Useful to
|
||||
/// write fancy things using addCustomGraphFeatures().
|
||||
raw_ostream &getOStream() {
|
||||
return O;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename GraphType>
|
||||
raw_ostream &WriteGraph(raw_ostream &O, const GraphType &G,
|
||||
bool ShortNames = false,
|
||||
const Twine &Title = "") {
|
||||
// Start the graph emission process...
|
||||
GraphWriter<GraphType> W(O, G, ShortNames);
|
||||
|
||||
// Emit the graph.
|
||||
W.writeGraph(Title.str());
|
||||
|
||||
return O;
|
||||
}
|
||||
|
||||
template<typename GraphType>
|
||||
sys::Path WriteGraph(const GraphType &G, const Twine &Name,
|
||||
bool ShortNames = false, const Twine &Title = "") {
|
||||
std::string ErrMsg;
|
||||
sys::Path Filename = sys::Path::GetTemporaryDirectory(&ErrMsg);
|
||||
if (Filename.isEmpty()) {
|
||||
errs() << "Error: " << ErrMsg << "\n";
|
||||
return Filename;
|
||||
}
|
||||
Filename.appendComponent((Name + ".dot").str());
|
||||
if (Filename.makeUnique(true,&ErrMsg)) {
|
||||
errs() << "Error: " << ErrMsg << "\n";
|
||||
return sys::Path();
|
||||
}
|
||||
|
||||
errs() << "Writing '" << Filename.str() << "'... ";
|
||||
|
||||
std::string ErrorInfo;
|
||||
raw_fd_ostream O(Filename.c_str(), ErrorInfo);
|
||||
|
||||
if (ErrorInfo.empty()) {
|
||||
llvm::WriteGraph(O, G, ShortNames, Title);
|
||||
errs() << " done. \n";
|
||||
} else {
|
||||
errs() << "error opening file '" << Filename.str() << "' for writing!\n";
|
||||
Filename.clear();
|
||||
}
|
||||
|
||||
return Filename;
|
||||
}
|
||||
|
||||
/// ViewGraph - Emit a dot graph, run 'dot', run gv on the postscript file,
|
||||
/// then cleanup. For use from the debugger.
|
||||
///
|
||||
template<typename GraphType>
|
||||
void ViewGraph(const GraphType &G, const Twine &Name,
|
||||
bool ShortNames = false, const Twine &Title = "",
|
||||
GraphProgram::Name Program = GraphProgram::DOT) {
|
||||
sys::Path Filename = llvm::WriteGraph(G, Name, ShortNames, Title);
|
||||
|
||||
if (Filename.isEmpty())
|
||||
return;
|
||||
|
||||
DisplayGraph(Filename, true, Program);
|
||||
}
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
||||
74
thirdparty/clang/include/llvm/Support/Host.h
vendored
Normal file
74
thirdparty/clang/include/llvm/Support/Host.h
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
//===- llvm/Support/Host.h - Host machine characteristics --------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Methods for querying the nature of the host machine.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_HOST_H
|
||||
#define LLVM_SUPPORT_HOST_H
|
||||
|
||||
#include "llvm/ADT/StringMap.h"
|
||||
|
||||
#if defined(__linux__)
|
||||
#include <endian.h>
|
||||
#else
|
||||
#ifndef LLVM_ON_WIN32
|
||||
#include <machine/endian.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace llvm {
|
||||
namespace sys {
|
||||
|
||||
#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && BYTE_ORDER == BIG_ENDIAN
|
||||
static const bool IsBigEndianHost = true;
|
||||
#else
|
||||
static const bool IsBigEndianHost = false;
|
||||
#endif
|
||||
|
||||
static const bool IsLittleEndianHost = !IsBigEndianHost;
|
||||
|
||||
/// getDefaultTargetTriple() - Return the default target triple the compiler
|
||||
/// has been configured to produce code for.
|
||||
///
|
||||
/// The target triple is a string in the format of:
|
||||
/// CPU_TYPE-VENDOR-OPERATING_SYSTEM
|
||||
/// or
|
||||
/// CPU_TYPE-VENDOR-KERNEL-OPERATING_SYSTEM
|
||||
std::string getDefaultTargetTriple();
|
||||
|
||||
/// getProcessTriple() - Return an appropriate target triple for generating
|
||||
/// code to be loaded into the current process, e.g. when using the JIT.
|
||||
std::string getProcessTriple();
|
||||
|
||||
/// getHostCPUName - Get the LLVM name for the host CPU. The particular format
|
||||
/// of the name is target dependent, and suitable for passing as -mcpu to the
|
||||
/// target which matches the host.
|
||||
///
|
||||
/// \return - The host CPU name, or empty if the CPU could not be determined.
|
||||
std::string getHostCPUName();
|
||||
|
||||
/// getHostCPUFeatures - Get the LLVM names for the host CPU features.
|
||||
/// The particular format of the names are target dependent, and suitable for
|
||||
/// passing as -mattr to the target which matches the host.
|
||||
///
|
||||
/// \param Features - A string mapping feature names to either
|
||||
/// true (if enabled) or false (if disabled). This routine makes no guarantees
|
||||
/// about exactly which features may appear in this map, except that they are
|
||||
/// all valid LLVM feature names.
|
||||
///
|
||||
/// \return - True on success.
|
||||
bool getHostCPUFeatures(StringMap<bool> &Features);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
112
thirdparty/clang/include/llvm/Support/IRReader.h
vendored
Normal file
112
thirdparty/clang/include/llvm/Support/IRReader.h
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
//===---- llvm/Support/IRReader.h - Reader for LLVM IR files ----*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines functions for reading LLVM IR. They support both
|
||||
// Bitcode and Assembly, automatically detecting the input format.
|
||||
//
|
||||
// These functions must be defined in a header file in order to avoid
|
||||
// library dependencies, since they reference both Bitcode and Assembly
|
||||
// functions.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_IRREADER_H
|
||||
#define LLVM_SUPPORT_IRREADER_H
|
||||
|
||||
#include "llvm/ADT/OwningPtr.h"
|
||||
#include "llvm/Assembly/Parser.h"
|
||||
#include "llvm/Bitcode/ReaderWriter.h"
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
#include "llvm/Support/SourceMgr.h"
|
||||
#include "llvm/Support/system_error.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
/// If the given MemoryBuffer holds a bitcode image, return a Module for it
|
||||
/// which does lazy deserialization of function bodies. Otherwise, attempt to
|
||||
/// parse it as LLVM Assembly and return a fully populated Module. This
|
||||
/// function *always* takes ownership of the given MemoryBuffer.
|
||||
inline Module *getLazyIRModule(MemoryBuffer *Buffer,
|
||||
SMDiagnostic &Err,
|
||||
LLVMContext &Context) {
|
||||
if (isBitcode((const unsigned char *)Buffer->getBufferStart(),
|
||||
(const unsigned char *)Buffer->getBufferEnd())) {
|
||||
std::string ErrMsg;
|
||||
Module *M = getLazyBitcodeModule(Buffer, Context, &ErrMsg);
|
||||
if (M == 0) {
|
||||
Err = SMDiagnostic(Buffer->getBufferIdentifier(), SourceMgr::DK_Error,
|
||||
ErrMsg);
|
||||
// ParseBitcodeFile does not take ownership of the Buffer in the
|
||||
// case of an error.
|
||||
delete Buffer;
|
||||
}
|
||||
return M;
|
||||
}
|
||||
|
||||
return ParseAssembly(Buffer, 0, Err, Context);
|
||||
}
|
||||
|
||||
/// If the given file holds a bitcode image, return a Module
|
||||
/// for it which does lazy deserialization of function bodies. Otherwise,
|
||||
/// attempt to parse it as LLVM Assembly and return a fully populated
|
||||
/// Module.
|
||||
inline Module *getLazyIRFileModule(const std::string &Filename,
|
||||
SMDiagnostic &Err,
|
||||
LLVMContext &Context) {
|
||||
OwningPtr<MemoryBuffer> File;
|
||||
if (error_code ec = MemoryBuffer::getFileOrSTDIN(Filename.c_str(), File)) {
|
||||
Err = SMDiagnostic(Filename, SourceMgr::DK_Error,
|
||||
"Could not open input file: " + ec.message());
|
||||
return 0;
|
||||
}
|
||||
|
||||
return getLazyIRModule(File.take(), Err, Context);
|
||||
}
|
||||
|
||||
/// If the given MemoryBuffer holds a bitcode image, return a Module
|
||||
/// for it. Otherwise, attempt to parse it as LLVM Assembly and return
|
||||
/// a Module for it. This function *always* takes ownership of the given
|
||||
/// MemoryBuffer.
|
||||
inline Module *ParseIR(MemoryBuffer *Buffer,
|
||||
SMDiagnostic &Err,
|
||||
LLVMContext &Context) {
|
||||
if (isBitcode((const unsigned char *)Buffer->getBufferStart(),
|
||||
(const unsigned char *)Buffer->getBufferEnd())) {
|
||||
std::string ErrMsg;
|
||||
Module *M = ParseBitcodeFile(Buffer, Context, &ErrMsg);
|
||||
if (M == 0)
|
||||
Err = SMDiagnostic(Buffer->getBufferIdentifier(), SourceMgr::DK_Error,
|
||||
ErrMsg);
|
||||
// ParseBitcodeFile does not take ownership of the Buffer.
|
||||
delete Buffer;
|
||||
return M;
|
||||
}
|
||||
|
||||
return ParseAssembly(Buffer, 0, Err, Context);
|
||||
}
|
||||
|
||||
/// If the given file holds a bitcode image, return a Module for it.
|
||||
/// Otherwise, attempt to parse it as LLVM Assembly and return a Module
|
||||
/// for it.
|
||||
inline Module *ParseIRFile(const std::string &Filename,
|
||||
SMDiagnostic &Err,
|
||||
LLVMContext &Context) {
|
||||
OwningPtr<MemoryBuffer> File;
|
||||
if (error_code ec = MemoryBuffer::getFileOrSTDIN(Filename.c_str(), File)) {
|
||||
Err = SMDiagnostic(Filename, SourceMgr::DK_Error,
|
||||
"Could not open input file: " + ec.message());
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ParseIR(File.take(), Err, Context);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
79
thirdparty/clang/include/llvm/Support/IncludeFile.h
vendored
Normal file
79
thirdparty/clang/include/llvm/Support/IncludeFile.h
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
//===- llvm/Support/IncludeFile.h - Ensure Linking Of Library ---*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the FORCE_DEFINING_FILE_TO_BE_LINKED and DEFINE_FILE_FOR
|
||||
// macros.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_INCLUDEFILE_H
|
||||
#define LLVM_SUPPORT_INCLUDEFILE_H
|
||||
|
||||
/// This macro is the public interface that IncludeFile.h exports. This gives
|
||||
/// us the option to implement the "link the definition" capability in any
|
||||
/// manner that we choose. All header files that depend on a specific .cpp
|
||||
/// file being linked at run time should use this macro instead of the
|
||||
/// IncludeFile class directly.
|
||||
///
|
||||
/// For example, foo.h would use:<br/>
|
||||
/// <tt>FORCE_DEFINING_FILE_TO_BE_LINKED(foo)</tt><br/>
|
||||
///
|
||||
/// And, foo.cp would use:<br/>
|
||||
/// <tt>DEFINING_FILE_FOR(foo)</tt><br/>
|
||||
#ifdef __GNUC__
|
||||
// If the `used' attribute is available, use it to create a variable
|
||||
// with an initializer that will force the linking of the defining file.
|
||||
#define FORCE_DEFINING_FILE_TO_BE_LINKED(name) \
|
||||
namespace llvm { \
|
||||
extern const char name ## LinkVar; \
|
||||
__attribute__((used)) static const char *const name ## LinkObj = \
|
||||
&name ## LinkVar; \
|
||||
}
|
||||
#else
|
||||
// Otherwise use a constructor call.
|
||||
#define FORCE_DEFINING_FILE_TO_BE_LINKED(name) \
|
||||
namespace llvm { \
|
||||
extern const char name ## LinkVar; \
|
||||
static const IncludeFile name ## LinkObj ( &name ## LinkVar ); \
|
||||
}
|
||||
#endif
|
||||
|
||||
/// This macro is the counterpart to FORCE_DEFINING_FILE_TO_BE_LINKED. It should
|
||||
/// be used in a .cpp file to define the name referenced in a header file that
|
||||
/// will cause linkage of the .cpp file. It should only be used at extern level.
|
||||
#define DEFINING_FILE_FOR(name) \
|
||||
namespace llvm { const char name ## LinkVar = 0; }
|
||||
|
||||
namespace llvm {
|
||||
|
||||
/// This class is used in the implementation of FORCE_DEFINING_FILE_TO_BE_LINKED
|
||||
/// macro to make sure that the implementation of a header file is included
|
||||
/// into a tool that uses the header. This is solely
|
||||
/// to overcome problems linking .a files and not getting the implementation
|
||||
/// of compilation units we need. This is commonly an issue with the various
|
||||
/// Passes but also occurs elsewhere in LLVM. We like to use .a files because
|
||||
/// they link faster and provide the smallest executables. However, sometimes
|
||||
/// those executables are too small, if the program doesn't reference something
|
||||
/// that might be needed, especially by a loaded share object. This little class
|
||||
/// helps to resolve that problem. The basic strategy is to use this class in
|
||||
/// a header file and pass the address of a variable to the constructor. If the
|
||||
/// variable is defined in the header file's corresponding .cpp file then all
|
||||
/// tools/libraries that \#include the header file will require the .cpp as
|
||||
/// well.
|
||||
/// For example:<br/>
|
||||
/// <tt>extern int LinkMyCodeStub;</tt><br/>
|
||||
/// <tt>static IncludeFile LinkMyModule(&LinkMyCodeStub);</tt><br/>
|
||||
/// @brief Class to ensure linking of corresponding object file.
|
||||
struct IncludeFile {
|
||||
explicit IncludeFile(const void *);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
147
thirdparty/clang/include/llvm/Support/InstIterator.h
vendored
Normal file
147
thirdparty/clang/include/llvm/Support/InstIterator.h
vendored
Normal file
@@ -0,0 +1,147 @@
|
||||
//===- llvm/Support/InstIterator.h - Classes for inst iteration -*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file contains definitions of two iterators for iterating over the
|
||||
// instructions in a function. This is effectively a wrapper around a two level
|
||||
// iterator that can probably be genericized later.
|
||||
//
|
||||
// Note that this iterator gets invalidated any time that basic blocks or
|
||||
// instructions are moved around.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_INSTITERATOR_H
|
||||
#define LLVM_SUPPORT_INSTITERATOR_H
|
||||
|
||||
#include "llvm/IR/BasicBlock.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
// This class implements inst_begin() & inst_end() for
|
||||
// inst_iterator and const_inst_iterator's.
|
||||
//
|
||||
template <class _BB_t, class _BB_i_t, class _BI_t, class _II_t>
|
||||
class InstIterator {
|
||||
typedef _BB_t BBty;
|
||||
typedef _BB_i_t BBIty;
|
||||
typedef _BI_t BIty;
|
||||
typedef _II_t IIty;
|
||||
_BB_t *BBs; // BasicBlocksType
|
||||
_BB_i_t BB; // BasicBlocksType::iterator
|
||||
_BI_t BI; // BasicBlock::iterator
|
||||
public:
|
||||
typedef std::bidirectional_iterator_tag iterator_category;
|
||||
typedef IIty value_type;
|
||||
typedef signed difference_type;
|
||||
typedef IIty* pointer;
|
||||
typedef IIty& reference;
|
||||
|
||||
// Default constructor
|
||||
InstIterator() {}
|
||||
|
||||
// Copy constructor...
|
||||
template<typename A, typename B, typename C, typename D>
|
||||
InstIterator(const InstIterator<A,B,C,D> &II)
|
||||
: BBs(II.BBs), BB(II.BB), BI(II.BI) {}
|
||||
|
||||
template<typename A, typename B, typename C, typename D>
|
||||
InstIterator(InstIterator<A,B,C,D> &II)
|
||||
: BBs(II.BBs), BB(II.BB), BI(II.BI) {}
|
||||
|
||||
template<class M> InstIterator(M &m)
|
||||
: BBs(&m.getBasicBlockList()), BB(BBs->begin()) { // begin ctor
|
||||
if (BB != BBs->end()) {
|
||||
BI = BB->begin();
|
||||
advanceToNextBB();
|
||||
}
|
||||
}
|
||||
|
||||
template<class M> InstIterator(M &m, bool)
|
||||
: BBs(&m.getBasicBlockList()), BB(BBs->end()) { // end ctor
|
||||
}
|
||||
|
||||
// Accessors to get at the underlying iterators...
|
||||
inline BBIty &getBasicBlockIterator() { return BB; }
|
||||
inline BIty &getInstructionIterator() { return BI; }
|
||||
|
||||
inline reference operator*() const { return *BI; }
|
||||
inline pointer operator->() const { return &operator*(); }
|
||||
|
||||
inline bool operator==(const InstIterator &y) const {
|
||||
return BB == y.BB && (BB == BBs->end() || BI == y.BI);
|
||||
}
|
||||
inline bool operator!=(const InstIterator& y) const {
|
||||
return !operator==(y);
|
||||
}
|
||||
|
||||
InstIterator& operator++() {
|
||||
++BI;
|
||||
advanceToNextBB();
|
||||
return *this;
|
||||
}
|
||||
inline InstIterator operator++(int) {
|
||||
InstIterator tmp = *this; ++*this; return tmp;
|
||||
}
|
||||
|
||||
InstIterator& operator--() {
|
||||
while (BB == BBs->end() || BI == BB->begin()) {
|
||||
--BB;
|
||||
BI = BB->end();
|
||||
}
|
||||
--BI;
|
||||
return *this;
|
||||
}
|
||||
inline InstIterator operator--(int) {
|
||||
InstIterator tmp = *this; --*this; return tmp;
|
||||
}
|
||||
|
||||
inline bool atEnd() const { return BB == BBs->end(); }
|
||||
|
||||
private:
|
||||
inline void advanceToNextBB() {
|
||||
// The only way that the II could be broken is if it is now pointing to
|
||||
// the end() of the current BasicBlock and there are successor BBs.
|
||||
while (BI == BB->end()) {
|
||||
++BB;
|
||||
if (BB == BBs->end()) break;
|
||||
BI = BB->begin();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
typedef InstIterator<iplist<BasicBlock>,
|
||||
Function::iterator, BasicBlock::iterator,
|
||||
Instruction> inst_iterator;
|
||||
typedef InstIterator<const iplist<BasicBlock>,
|
||||
Function::const_iterator,
|
||||
BasicBlock::const_iterator,
|
||||
const Instruction> const_inst_iterator;
|
||||
|
||||
inline inst_iterator inst_begin(Function *F) { return inst_iterator(*F); }
|
||||
inline inst_iterator inst_end(Function *F) { return inst_iterator(*F, true); }
|
||||
inline const_inst_iterator inst_begin(const Function *F) {
|
||||
return const_inst_iterator(*F);
|
||||
}
|
||||
inline const_inst_iterator inst_end(const Function *F) {
|
||||
return const_inst_iterator(*F, true);
|
||||
}
|
||||
inline inst_iterator inst_begin(Function &F) { return inst_iterator(F); }
|
||||
inline inst_iterator inst_end(Function &F) { return inst_iterator(F, true); }
|
||||
inline const_inst_iterator inst_begin(const Function &F) {
|
||||
return const_inst_iterator(F);
|
||||
}
|
||||
inline const_inst_iterator inst_end(const Function &F) {
|
||||
return const_inst_iterator(F, true);
|
||||
}
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
||||
282
thirdparty/clang/include/llvm/Support/InstVisitor.h
vendored
Normal file
282
thirdparty/clang/include/llvm/Support/InstVisitor.h
vendored
Normal file
@@ -0,0 +1,282 @@
|
||||
//===- llvm/Support/InstVisitor.h - Define instruction visitors -*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
||||
#ifndef LLVM_SUPPORT_INSTVISITOR_H
|
||||
#define LLVM_SUPPORT_INSTVISITOR_H
|
||||
|
||||
#include "llvm/Function.h"
|
||||
#include "llvm/Instructions.h"
|
||||
#include "llvm/Intrinsics.h"
|
||||
#include "llvm/IntrinsicInst.h"
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/Support/CallSite.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
// We operate on opaque instruction classes, so forward declare all instruction
|
||||
// types now...
|
||||
//
|
||||
#define HANDLE_INST(NUM, OPCODE, CLASS) class CLASS;
|
||||
#include "llvm/Instruction.def"
|
||||
|
||||
#define DELEGATE(CLASS_TO_VISIT) \
|
||||
return static_cast<SubClass*>(this)-> \
|
||||
visit##CLASS_TO_VISIT(static_cast<CLASS_TO_VISIT&>(I))
|
||||
|
||||
|
||||
/// @brief Base class for instruction visitors
|
||||
///
|
||||
/// Instruction visitors are used when you want to perform different actions
|
||||
/// for different kinds of instructions without having to use lots of casts
|
||||
/// and a big switch statement (in your code, that is).
|
||||
///
|
||||
/// To define your own visitor, inherit from this class, specifying your
|
||||
/// new type for the 'SubClass' template parameter, and "override" visitXXX
|
||||
/// functions in your class. I say "override" because this class is defined
|
||||
/// in terms of statically resolved overloading, not virtual functions.
|
||||
///
|
||||
/// For example, here is a visitor that counts the number of malloc
|
||||
/// instructions processed:
|
||||
///
|
||||
/// /// Declare the class. Note that we derive from InstVisitor instantiated
|
||||
/// /// with _our new subclasses_ type.
|
||||
/// ///
|
||||
/// struct CountAllocaVisitor : public InstVisitor<CountAllocaVisitor> {
|
||||
/// unsigned Count;
|
||||
/// CountAllocaVisitor() : Count(0) {}
|
||||
///
|
||||
/// void visitAllocaInst(AllocaInst &AI) { ++Count; }
|
||||
/// };
|
||||
///
|
||||
/// And this class would be used like this:
|
||||
/// CountAllocaVisitor CAV;
|
||||
/// CAV.visit(function);
|
||||
/// NumAllocas = CAV.Count;
|
||||
///
|
||||
/// The defined has 'visit' methods for Instruction, and also for BasicBlock,
|
||||
/// Function, and Module, which recursively process all contained instructions.
|
||||
///
|
||||
/// Note that if you don't implement visitXXX for some instruction type,
|
||||
/// the visitXXX method for instruction superclass will be invoked. So
|
||||
/// if instructions are added in the future, they will be automatically
|
||||
/// supported, if you handle one of their superclasses.
|
||||
///
|
||||
/// The optional second template argument specifies the type that instruction
|
||||
/// visitation functions should return. If you specify this, you *MUST* provide
|
||||
/// an implementation of visitInstruction though!.
|
||||
///
|
||||
/// Note that this class is specifically designed as a template to avoid
|
||||
/// virtual function call overhead. Defining and using an InstVisitor is just
|
||||
/// as efficient as having your own switch statement over the instruction
|
||||
/// opcode.
|
||||
template<typename SubClass, typename RetTy=void>
|
||||
class InstVisitor {
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Interface code - This is the public interface of the InstVisitor that you
|
||||
// use to visit instructions...
|
||||
//
|
||||
|
||||
public:
|
||||
// Generic visit method - Allow visitation to all instructions in a range
|
||||
template<class Iterator>
|
||||
void visit(Iterator Start, Iterator End) {
|
||||
while (Start != End)
|
||||
static_cast<SubClass*>(this)->visit(*Start++);
|
||||
}
|
||||
|
||||
// Define visitors for functions and basic blocks...
|
||||
//
|
||||
void visit(Module &M) {
|
||||
static_cast<SubClass*>(this)->visitModule(M);
|
||||
visit(M.begin(), M.end());
|
||||
}
|
||||
void visit(Function &F) {
|
||||
static_cast<SubClass*>(this)->visitFunction(F);
|
||||
visit(F.begin(), F.end());
|
||||
}
|
||||
void visit(BasicBlock &BB) {
|
||||
static_cast<SubClass*>(this)->visitBasicBlock(BB);
|
||||
visit(BB.begin(), BB.end());
|
||||
}
|
||||
|
||||
// Forwarding functions so that the user can visit with pointers AND refs.
|
||||
void visit(Module *M) { visit(*M); }
|
||||
void visit(Function *F) { visit(*F); }
|
||||
void visit(BasicBlock *BB) { visit(*BB); }
|
||||
RetTy visit(Instruction *I) { return visit(*I); }
|
||||
|
||||
// visit - Finally, code to visit an instruction...
|
||||
//
|
||||
RetTy visit(Instruction &I) {
|
||||
switch (I.getOpcode()) {
|
||||
default: llvm_unreachable("Unknown instruction type encountered!");
|
||||
// Build the switch statement using the Instruction.def file...
|
||||
#define HANDLE_INST(NUM, OPCODE, CLASS) \
|
||||
case Instruction::OPCODE: return \
|
||||
static_cast<SubClass*>(this)-> \
|
||||
visit##OPCODE(static_cast<CLASS&>(I));
|
||||
#include "llvm/Instruction.def"
|
||||
}
|
||||
}
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Visitation functions... these functions provide default fallbacks in case
|
||||
// the user does not specify what to do for a particular instruction type.
|
||||
// The default behavior is to generalize the instruction type to its subtype
|
||||
// and try visiting the subtype. All of this should be inlined perfectly,
|
||||
// because there are no virtual functions to get in the way.
|
||||
//
|
||||
|
||||
// When visiting a module, function or basic block directly, these methods get
|
||||
// called to indicate when transitioning into a new unit.
|
||||
//
|
||||
void visitModule (Module &M) {}
|
||||
void visitFunction (Function &F) {}
|
||||
void visitBasicBlock(BasicBlock &BB) {}
|
||||
|
||||
// Define instruction specific visitor functions that can be overridden to
|
||||
// handle SPECIFIC instructions. These functions automatically define
|
||||
// visitMul to proxy to visitBinaryOperator for instance in case the user does
|
||||
// not need this generality.
|
||||
//
|
||||
// These functions can also implement fan-out, when a single opcode and
|
||||
// instruction have multiple more specific Instruction subclasses. The Call
|
||||
// instruction currently supports this. We implement that by redirecting that
|
||||
// instruction to a special delegation helper.
|
||||
#define HANDLE_INST(NUM, OPCODE, CLASS) \
|
||||
RetTy visit##OPCODE(CLASS &I) { \
|
||||
if (NUM == Instruction::Call) \
|
||||
return delegateCallInst(I); \
|
||||
else \
|
||||
DELEGATE(CLASS); \
|
||||
}
|
||||
#include "llvm/Instruction.def"
|
||||
|
||||
// Specific Instruction type classes... note that all of the casts are
|
||||
// necessary because we use the instruction classes as opaque types...
|
||||
//
|
||||
RetTy visitReturnInst(ReturnInst &I) { DELEGATE(TerminatorInst);}
|
||||
RetTy visitBranchInst(BranchInst &I) { DELEGATE(TerminatorInst);}
|
||||
RetTy visitSwitchInst(SwitchInst &I) { DELEGATE(TerminatorInst);}
|
||||
RetTy visitIndirectBrInst(IndirectBrInst &I) { DELEGATE(TerminatorInst);}
|
||||
RetTy visitResumeInst(ResumeInst &I) { DELEGATE(TerminatorInst);}
|
||||
RetTy visitUnreachableInst(UnreachableInst &I) { DELEGATE(TerminatorInst);}
|
||||
RetTy visitICmpInst(ICmpInst &I) { DELEGATE(CmpInst);}
|
||||
RetTy visitFCmpInst(FCmpInst &I) { DELEGATE(CmpInst);}
|
||||
RetTy visitAllocaInst(AllocaInst &I) { DELEGATE(UnaryInstruction);}
|
||||
RetTy visitLoadInst(LoadInst &I) { DELEGATE(UnaryInstruction);}
|
||||
RetTy visitStoreInst(StoreInst &I) { DELEGATE(Instruction);}
|
||||
RetTy visitAtomicCmpXchgInst(AtomicCmpXchgInst &I) { DELEGATE(Instruction);}
|
||||
RetTy visitAtomicRMWInst(AtomicRMWInst &I) { DELEGATE(Instruction);}
|
||||
RetTy visitFenceInst(FenceInst &I) { DELEGATE(Instruction);}
|
||||
RetTy visitGetElementPtrInst(GetElementPtrInst &I){ DELEGATE(Instruction);}
|
||||
RetTy visitPHINode(PHINode &I) { DELEGATE(Instruction);}
|
||||
RetTy visitTruncInst(TruncInst &I) { DELEGATE(CastInst);}
|
||||
RetTy visitZExtInst(ZExtInst &I) { DELEGATE(CastInst);}
|
||||
RetTy visitSExtInst(SExtInst &I) { DELEGATE(CastInst);}
|
||||
RetTy visitFPTruncInst(FPTruncInst &I) { DELEGATE(CastInst);}
|
||||
RetTy visitFPExtInst(FPExtInst &I) { DELEGATE(CastInst);}
|
||||
RetTy visitFPToUIInst(FPToUIInst &I) { DELEGATE(CastInst);}
|
||||
RetTy visitFPToSIInst(FPToSIInst &I) { DELEGATE(CastInst);}
|
||||
RetTy visitUIToFPInst(UIToFPInst &I) { DELEGATE(CastInst);}
|
||||
RetTy visitSIToFPInst(SIToFPInst &I) { DELEGATE(CastInst);}
|
||||
RetTy visitPtrToIntInst(PtrToIntInst &I) { DELEGATE(CastInst);}
|
||||
RetTy visitIntToPtrInst(IntToPtrInst &I) { DELEGATE(CastInst);}
|
||||
RetTy visitBitCastInst(BitCastInst &I) { DELEGATE(CastInst);}
|
||||
RetTy visitSelectInst(SelectInst &I) { DELEGATE(Instruction);}
|
||||
RetTy visitVAArgInst(VAArgInst &I) { DELEGATE(UnaryInstruction);}
|
||||
RetTy visitExtractElementInst(ExtractElementInst &I) { DELEGATE(Instruction);}
|
||||
RetTy visitInsertElementInst(InsertElementInst &I) { DELEGATE(Instruction);}
|
||||
RetTy visitShuffleVectorInst(ShuffleVectorInst &I) { DELEGATE(Instruction);}
|
||||
RetTy visitExtractValueInst(ExtractValueInst &I){ DELEGATE(UnaryInstruction);}
|
||||
RetTy visitInsertValueInst(InsertValueInst &I) { DELEGATE(Instruction); }
|
||||
RetTy visitLandingPadInst(LandingPadInst &I) { DELEGATE(Instruction); }
|
||||
|
||||
// Handle the special instrinsic instruction classes.
|
||||
RetTy visitDbgDeclareInst(DbgDeclareInst &I) { DELEGATE(DbgInfoIntrinsic);}
|
||||
RetTy visitDbgValueInst(DbgValueInst &I) { DELEGATE(DbgInfoIntrinsic);}
|
||||
RetTy visitDbgInfoIntrinsic(DbgInfoIntrinsic &I) { DELEGATE(IntrinsicInst); }
|
||||
RetTy visitMemSetInst(MemSetInst &I) { DELEGATE(MemIntrinsic); }
|
||||
RetTy visitMemCpyInst(MemCpyInst &I) { DELEGATE(MemTransferInst); }
|
||||
RetTy visitMemMoveInst(MemMoveInst &I) { DELEGATE(MemTransferInst); }
|
||||
RetTy visitMemTransferInst(MemTransferInst &I) { DELEGATE(MemIntrinsic); }
|
||||
RetTy visitMemIntrinsic(MemIntrinsic &I) { DELEGATE(IntrinsicInst); }
|
||||
RetTy visitIntrinsicInst(IntrinsicInst &I) { DELEGATE(CallInst); }
|
||||
|
||||
// Call and Invoke are slightly different as they delegate first through
|
||||
// a generic CallSite visitor.
|
||||
RetTy visitCallInst(CallInst &I) {
|
||||
return static_cast<SubClass*>(this)->visitCallSite(&I);
|
||||
}
|
||||
RetTy visitInvokeInst(InvokeInst &I) {
|
||||
return static_cast<SubClass*>(this)->visitCallSite(&I);
|
||||
}
|
||||
|
||||
// Next level propagators: If the user does not overload a specific
|
||||
// instruction type, they can overload one of these to get the whole class
|
||||
// of instructions...
|
||||
//
|
||||
RetTy visitCastInst(CastInst &I) { DELEGATE(UnaryInstruction);}
|
||||
RetTy visitBinaryOperator(BinaryOperator &I) { DELEGATE(Instruction);}
|
||||
RetTy visitCmpInst(CmpInst &I) { DELEGATE(Instruction);}
|
||||
RetTy visitTerminatorInst(TerminatorInst &I) { DELEGATE(Instruction);}
|
||||
RetTy visitUnaryInstruction(UnaryInstruction &I){ DELEGATE(Instruction);}
|
||||
|
||||
// Provide a special visitor for a 'callsite' that visits both calls and
|
||||
// invokes. When unimplemented, properly delegates to either the terminator or
|
||||
// regular instruction visitor.
|
||||
RetTy visitCallSite(CallSite CS) {
|
||||
assert(CS);
|
||||
Instruction &I = *CS.getInstruction();
|
||||
if (CS.isCall())
|
||||
DELEGATE(Instruction);
|
||||
|
||||
assert(CS.isInvoke());
|
||||
DELEGATE(TerminatorInst);
|
||||
}
|
||||
|
||||
// If the user wants a 'default' case, they can choose to override this
|
||||
// function. If this function is not overloaded in the user's subclass, then
|
||||
// this instruction just gets ignored.
|
||||
//
|
||||
// Note that you MUST override this function if your return type is not void.
|
||||
//
|
||||
void visitInstruction(Instruction &I) {} // Ignore unhandled instructions
|
||||
|
||||
private:
|
||||
// Special helper function to delegate to CallInst subclass visitors.
|
||||
RetTy delegateCallInst(CallInst &I) {
|
||||
if (const Function *F = I.getCalledFunction()) {
|
||||
switch ((Intrinsic::ID)F->getIntrinsicID()) {
|
||||
default: DELEGATE(IntrinsicInst);
|
||||
case Intrinsic::dbg_declare: DELEGATE(DbgDeclareInst);
|
||||
case Intrinsic::dbg_value: DELEGATE(DbgValueInst);
|
||||
case Intrinsic::memcpy: DELEGATE(MemCpyInst);
|
||||
case Intrinsic::memmove: DELEGATE(MemMoveInst);
|
||||
case Intrinsic::memset: DELEGATE(MemSetInst);
|
||||
case Intrinsic::not_intrinsic: break;
|
||||
}
|
||||
}
|
||||
DELEGATE(CallInst);
|
||||
}
|
||||
|
||||
// An overload that will never actually be called, it is used only from dead
|
||||
// code in the dispatching from opcodes to instruction subclasses.
|
||||
RetTy delegateCallInst(Instruction &I) {
|
||||
llvm_unreachable("delegateCallInst called for non-CallInst");
|
||||
}
|
||||
};
|
||||
|
||||
#undef DELEGATE
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
||||
540
thirdparty/clang/include/llvm/Support/IntegersSubset.h
vendored
Normal file
540
thirdparty/clang/include/llvm/Support/IntegersSubset.h
vendored
Normal file
@@ -0,0 +1,540 @@
|
||||
//===-- llvm/IntegersSubset.h - The subset of integers ----------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
/// @file
|
||||
/// This file contains class that implements constant set of ranges:
|
||||
/// [<Low0,High0>,...,<LowN,HighN>]. Initially, this class was created for
|
||||
/// SwitchInst and was used for case value representation that may contain
|
||||
/// multiple ranges for a single successor.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_INTEGERSSUBSET_H
|
||||
#define LLVM_SUPPORT_INTEGERSSUBSET_H
|
||||
|
||||
#include "llvm/IR/Constants.h"
|
||||
#include "llvm/IR/DerivedTypes.h"
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
#include <list>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
// The IntItem is a wrapper for APInt.
|
||||
// 1. It determines sign of integer, it allows to use
|
||||
// comparison operators >,<,>=,<=, and as result we got shorter and cleaner
|
||||
// constructions.
|
||||
// 2. It helps to implement PR1255 (case ranges) as a series of small patches.
|
||||
// 3. Currently we can interpret IntItem both as ConstantInt and as APInt.
|
||||
// It allows to provide SwitchInst methods that works with ConstantInt for
|
||||
// non-updated passes. And it allows to use APInt interface for new methods.
|
||||
// 4. IntItem can be easily replaced with APInt.
|
||||
|
||||
// The set of macros that allows to propagate APInt operators to the IntItem.
|
||||
|
||||
#define INT_ITEM_DEFINE_COMPARISON(op,func) \
|
||||
bool operator op (const APInt& RHS) const { \
|
||||
return getAPIntValue().func(RHS); \
|
||||
}
|
||||
|
||||
#define INT_ITEM_DEFINE_UNARY_OP(op) \
|
||||
IntItem operator op () const { \
|
||||
APInt res = op(getAPIntValue()); \
|
||||
Constant *NewVal = ConstantInt::get(ConstantIntVal->getContext(), res); \
|
||||
return IntItem(cast<ConstantInt>(NewVal)); \
|
||||
}
|
||||
|
||||
#define INT_ITEM_DEFINE_BINARY_OP(op) \
|
||||
IntItem operator op (const APInt& RHS) const { \
|
||||
APInt res = getAPIntValue() op RHS; \
|
||||
Constant *NewVal = ConstantInt::get(ConstantIntVal->getContext(), res); \
|
||||
return IntItem(cast<ConstantInt>(NewVal)); \
|
||||
}
|
||||
|
||||
#define INT_ITEM_DEFINE_ASSIGNMENT_BY_OP(op) \
|
||||
IntItem& operator op (const APInt& RHS) {\
|
||||
APInt res = getAPIntValue();\
|
||||
res op RHS; \
|
||||
Constant *NewVal = ConstantInt::get(ConstantIntVal->getContext(), res); \
|
||||
ConstantIntVal = cast<ConstantInt>(NewVal); \
|
||||
return *this; \
|
||||
}
|
||||
|
||||
#define INT_ITEM_DEFINE_PREINCDEC(op) \
|
||||
IntItem& operator op () { \
|
||||
APInt res = getAPIntValue(); \
|
||||
op(res); \
|
||||
Constant *NewVal = ConstantInt::get(ConstantIntVal->getContext(), res); \
|
||||
ConstantIntVal = cast<ConstantInt>(NewVal); \
|
||||
return *this; \
|
||||
}
|
||||
|
||||
#define INT_ITEM_DEFINE_POSTINCDEC(op) \
|
||||
IntItem& operator op (int) { \
|
||||
APInt res = getAPIntValue();\
|
||||
op(res); \
|
||||
Constant *NewVal = ConstantInt::get(ConstantIntVal->getContext(), res); \
|
||||
OldConstantIntVal = ConstantIntVal; \
|
||||
ConstantIntVal = cast<ConstantInt>(NewVal); \
|
||||
return IntItem(OldConstantIntVal); \
|
||||
}
|
||||
|
||||
#define INT_ITEM_DEFINE_OP_STANDARD_INT(RetTy, op, IntTy) \
|
||||
RetTy operator op (IntTy RHS) const { \
|
||||
return (*this) op APInt(getAPIntValue().getBitWidth(), RHS); \
|
||||
}
|
||||
|
||||
class IntItem {
|
||||
ConstantInt *ConstantIntVal;
|
||||
const APInt* APIntVal;
|
||||
IntItem(const ConstantInt *V) :
|
||||
ConstantIntVal(const_cast<ConstantInt*>(V)),
|
||||
APIntVal(&ConstantIntVal->getValue()){}
|
||||
const APInt& getAPIntValue() const {
|
||||
return *APIntVal;
|
||||
}
|
||||
public:
|
||||
|
||||
IntItem() {}
|
||||
|
||||
operator const APInt&() const {
|
||||
return getAPIntValue();
|
||||
}
|
||||
|
||||
// Propagate APInt operators.
|
||||
// Note, that
|
||||
// /,/=,>>,>>= are not implemented in APInt.
|
||||
// <<= is implemented for unsigned RHS, but not implemented for APInt RHS.
|
||||
|
||||
INT_ITEM_DEFINE_COMPARISON(<, ult)
|
||||
INT_ITEM_DEFINE_COMPARISON(>, ugt)
|
||||
INT_ITEM_DEFINE_COMPARISON(<=, ule)
|
||||
INT_ITEM_DEFINE_COMPARISON(>=, uge)
|
||||
|
||||
INT_ITEM_DEFINE_COMPARISON(==, eq)
|
||||
INT_ITEM_DEFINE_OP_STANDARD_INT(bool,==,uint64_t)
|
||||
|
||||
INT_ITEM_DEFINE_COMPARISON(!=, ne)
|
||||
INT_ITEM_DEFINE_OP_STANDARD_INT(bool,!=,uint64_t)
|
||||
|
||||
INT_ITEM_DEFINE_BINARY_OP(*)
|
||||
INT_ITEM_DEFINE_BINARY_OP(+)
|
||||
INT_ITEM_DEFINE_OP_STANDARD_INT(IntItem,+,uint64_t)
|
||||
INT_ITEM_DEFINE_BINARY_OP(-)
|
||||
INT_ITEM_DEFINE_OP_STANDARD_INT(IntItem,-,uint64_t)
|
||||
INT_ITEM_DEFINE_BINARY_OP(<<)
|
||||
INT_ITEM_DEFINE_OP_STANDARD_INT(IntItem,<<,unsigned)
|
||||
INT_ITEM_DEFINE_BINARY_OP(&)
|
||||
INT_ITEM_DEFINE_BINARY_OP(^)
|
||||
INT_ITEM_DEFINE_BINARY_OP(|)
|
||||
|
||||
INT_ITEM_DEFINE_ASSIGNMENT_BY_OP(*=)
|
||||
INT_ITEM_DEFINE_ASSIGNMENT_BY_OP(+=)
|
||||
INT_ITEM_DEFINE_ASSIGNMENT_BY_OP(-=)
|
||||
INT_ITEM_DEFINE_ASSIGNMENT_BY_OP(&=)
|
||||
INT_ITEM_DEFINE_ASSIGNMENT_BY_OP(^=)
|
||||
INT_ITEM_DEFINE_ASSIGNMENT_BY_OP(|=)
|
||||
|
||||
// Special case for <<=
|
||||
IntItem& operator <<= (unsigned RHS) {
|
||||
APInt res = getAPIntValue();
|
||||
res <<= RHS;
|
||||
Constant *NewVal = ConstantInt::get(ConstantIntVal->getContext(), res);
|
||||
ConstantIntVal = cast<ConstantInt>(NewVal);
|
||||
return *this;
|
||||
}
|
||||
|
||||
INT_ITEM_DEFINE_UNARY_OP(-)
|
||||
INT_ITEM_DEFINE_UNARY_OP(~)
|
||||
|
||||
INT_ITEM_DEFINE_PREINCDEC(++)
|
||||
INT_ITEM_DEFINE_PREINCDEC(--)
|
||||
|
||||
// The set of workarounds, since currently we use ConstantInt implemented
|
||||
// integer.
|
||||
|
||||
static IntItem fromConstantInt(const ConstantInt *V) {
|
||||
return IntItem(V);
|
||||
}
|
||||
static IntItem fromType(Type* Ty, const APInt& V) {
|
||||
ConstantInt *C = cast<ConstantInt>(ConstantInt::get(Ty, V));
|
||||
return fromConstantInt(C);
|
||||
}
|
||||
static IntItem withImplLikeThis(const IntItem& LikeThis, const APInt& V) {
|
||||
ConstantInt *C = cast<ConstantInt>(ConstantInt::get(
|
||||
LikeThis.ConstantIntVal->getContext(), V));
|
||||
return fromConstantInt(C);
|
||||
}
|
||||
ConstantInt *toConstantInt() const {
|
||||
return ConstantIntVal;
|
||||
}
|
||||
};
|
||||
|
||||
template<class IntType>
|
||||
class IntRange {
|
||||
protected:
|
||||
IntType Low;
|
||||
IntType High;
|
||||
bool IsEmpty : 1;
|
||||
bool IsSingleNumber : 1;
|
||||
|
||||
public:
|
||||
typedef IntRange<IntType> self;
|
||||
typedef std::pair<self, self> SubRes;
|
||||
|
||||
IntRange() : IsEmpty(true) {}
|
||||
IntRange(const self &RHS) :
|
||||
Low(RHS.Low), High(RHS.High),
|
||||
IsEmpty(RHS.IsEmpty), IsSingleNumber(RHS.IsSingleNumber) {}
|
||||
IntRange(const IntType &C) :
|
||||
Low(C), High(C), IsEmpty(false), IsSingleNumber(true) {}
|
||||
|
||||
IntRange(const IntType &L, const IntType &H) : Low(L), High(H),
|
||||
IsEmpty(false), IsSingleNumber(Low == High) {}
|
||||
|
||||
bool isEmpty() const { return IsEmpty; }
|
||||
bool isSingleNumber() const { return IsSingleNumber; }
|
||||
|
||||
const IntType& getLow() const {
|
||||
assert(!IsEmpty && "Range is empty.");
|
||||
return Low;
|
||||
}
|
||||
const IntType& getHigh() const {
|
||||
assert(!IsEmpty && "Range is empty.");
|
||||
return High;
|
||||
}
|
||||
|
||||
bool operator<(const self &RHS) const {
|
||||
assert(!IsEmpty && "Left range is empty.");
|
||||
assert(!RHS.IsEmpty && "Right range is empty.");
|
||||
if (Low == RHS.Low) {
|
||||
if (High > RHS.High)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
if (Low < RHS.Low)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator==(const self &RHS) const {
|
||||
assert(!IsEmpty && "Left range is empty.");
|
||||
assert(!RHS.IsEmpty && "Right range is empty.");
|
||||
return Low == RHS.Low && High == RHS.High;
|
||||
}
|
||||
|
||||
bool operator!=(const self &RHS) const {
|
||||
return !operator ==(RHS);
|
||||
}
|
||||
|
||||
static bool LessBySize(const self &LHS, const self &RHS) {
|
||||
return (LHS.High - LHS.Low) < (RHS.High - RHS.Low);
|
||||
}
|
||||
|
||||
bool isInRange(const IntType &IntVal) const {
|
||||
assert(!IsEmpty && "Range is empty.");
|
||||
return IntVal >= Low && IntVal <= High;
|
||||
}
|
||||
|
||||
SubRes sub(const self &RHS) const {
|
||||
SubRes Res;
|
||||
|
||||
// RHS is either more global and includes this range or
|
||||
// if it doesn't intersected with this range.
|
||||
if (!isInRange(RHS.Low) && !isInRange(RHS.High)) {
|
||||
|
||||
// If RHS more global (it is enough to check
|
||||
// only one border in this case.
|
||||
if (RHS.isInRange(Low))
|
||||
return std::make_pair(self(Low, High), self());
|
||||
|
||||
return Res;
|
||||
}
|
||||
|
||||
if (Low < RHS.Low) {
|
||||
Res.first.Low = Low;
|
||||
IntType NewHigh = RHS.Low;
|
||||
--NewHigh;
|
||||
Res.first.High = NewHigh;
|
||||
}
|
||||
if (High > RHS.High) {
|
||||
IntType NewLow = RHS.High;
|
||||
++NewLow;
|
||||
Res.second.Low = NewLow;
|
||||
Res.second.High = High;
|
||||
}
|
||||
return Res;
|
||||
}
|
||||
};
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
/// IntegersSubsetGeneric - class that implements the subset of integers. It
|
||||
/// consists from ranges and single numbers.
|
||||
template <class IntTy>
|
||||
class IntegersSubsetGeneric {
|
||||
public:
|
||||
// Use Chris Lattner idea, that was initially described here:
|
||||
// http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20120213/136954.html
|
||||
// In short, for more compact memory consumption we can store flat
|
||||
// numbers collection, and define range as pair of indices.
|
||||
// In that case we can safe some memory on 32 bit machines.
|
||||
typedef std::vector<IntTy> FlatCollectionTy;
|
||||
typedef std::pair<IntTy*, IntTy*> RangeLinkTy;
|
||||
typedef std::vector<RangeLinkTy> RangeLinksTy;
|
||||
typedef typename RangeLinksTy::const_iterator RangeLinksConstIt;
|
||||
|
||||
typedef IntegersSubsetGeneric<IntTy> self;
|
||||
|
||||
protected:
|
||||
|
||||
FlatCollectionTy FlatCollection;
|
||||
RangeLinksTy RangeLinks;
|
||||
|
||||
bool IsSingleNumber;
|
||||
bool IsSingleNumbersOnly;
|
||||
|
||||
public:
|
||||
|
||||
template<class RangesCollectionTy>
|
||||
explicit IntegersSubsetGeneric(const RangesCollectionTy& Links) {
|
||||
assert(Links.size() && "Empty ranges are not allowed.");
|
||||
|
||||
// In case of big set of single numbers consumes additional RAM space,
|
||||
// but allows to avoid additional reallocation.
|
||||
FlatCollection.reserve(Links.size() * 2);
|
||||
RangeLinks.reserve(Links.size());
|
||||
IsSingleNumbersOnly = true;
|
||||
for (typename RangesCollectionTy::const_iterator i = Links.begin(),
|
||||
e = Links.end(); i != e; ++i) {
|
||||
RangeLinkTy RangeLink;
|
||||
FlatCollection.push_back(i->getLow());
|
||||
RangeLink.first = &FlatCollection.back();
|
||||
if (i->getLow() != i->getHigh()) {
|
||||
FlatCollection.push_back(i->getHigh());
|
||||
IsSingleNumbersOnly = false;
|
||||
}
|
||||
RangeLink.second = &FlatCollection.back();
|
||||
RangeLinks.push_back(RangeLink);
|
||||
}
|
||||
IsSingleNumber = IsSingleNumbersOnly && RangeLinks.size() == 1;
|
||||
}
|
||||
|
||||
IntegersSubsetGeneric(const self& RHS) {
|
||||
*this = RHS;
|
||||
}
|
||||
|
||||
self& operator=(const self& RHS) {
|
||||
FlatCollection.clear();
|
||||
RangeLinks.clear();
|
||||
FlatCollection.reserve(RHS.RangeLinks.size() * 2);
|
||||
RangeLinks.reserve(RHS.RangeLinks.size());
|
||||
for (RangeLinksConstIt i = RHS.RangeLinks.begin(), e = RHS.RangeLinks.end();
|
||||
i != e; ++i) {
|
||||
RangeLinkTy RangeLink;
|
||||
FlatCollection.push_back(*(i->first));
|
||||
RangeLink.first = &FlatCollection.back();
|
||||
if (i->first != i->second)
|
||||
FlatCollection.push_back(*(i->second));
|
||||
RangeLink.second = &FlatCollection.back();
|
||||
RangeLinks.push_back(RangeLink);
|
||||
}
|
||||
IsSingleNumber = RHS.IsSingleNumber;
|
||||
IsSingleNumbersOnly = RHS.IsSingleNumbersOnly;
|
||||
return *this;
|
||||
}
|
||||
|
||||
typedef IntRange<IntTy> Range;
|
||||
|
||||
/// Checks is the given constant satisfies this case. Returns
|
||||
/// true if it equals to one of contained values or belongs to the one of
|
||||
/// contained ranges.
|
||||
bool isSatisfies(const IntTy &CheckingVal) const {
|
||||
if (IsSingleNumber)
|
||||
return FlatCollection.front() == CheckingVal;
|
||||
if (IsSingleNumbersOnly)
|
||||
return std::find(FlatCollection.begin(),
|
||||
FlatCollection.end(),
|
||||
CheckingVal) != FlatCollection.end();
|
||||
|
||||
for (unsigned i = 0, e = getNumItems(); i < e; ++i) {
|
||||
if (RangeLinks[i].first == RangeLinks[i].second) {
|
||||
if (*RangeLinks[i].first == CheckingVal)
|
||||
return true;
|
||||
} else if (*RangeLinks[i].first <= CheckingVal &&
|
||||
*RangeLinks[i].second >= CheckingVal)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Returns set's item with given index.
|
||||
Range getItem(unsigned idx) const {
|
||||
const RangeLinkTy &Link = RangeLinks[idx];
|
||||
if (Link.first != Link.second)
|
||||
return Range(*Link.first, *Link.second);
|
||||
else
|
||||
return Range(*Link.first);
|
||||
}
|
||||
|
||||
/// Return number of items (ranges) stored in set.
|
||||
unsigned getNumItems() const {
|
||||
return RangeLinks.size();
|
||||
}
|
||||
|
||||
/// Returns true if whole subset contains single element.
|
||||
bool isSingleNumber() const {
|
||||
return IsSingleNumber;
|
||||
}
|
||||
|
||||
/// Returns true if whole subset contains only single numbers, no ranges.
|
||||
bool isSingleNumbersOnly() const {
|
||||
return IsSingleNumbersOnly;
|
||||
}
|
||||
|
||||
/// Does the same like getItem(idx).isSingleNumber(), but
|
||||
/// works faster, since we avoid creation of temporary range object.
|
||||
bool isSingleNumber(unsigned idx) const {
|
||||
return RangeLinks[idx].first == RangeLinks[idx].second;
|
||||
}
|
||||
|
||||
/// Returns set the size, that equals number of all values + sizes of all
|
||||
/// ranges.
|
||||
/// Ranges set is considered as flat numbers collection.
|
||||
/// E.g.: for range [<0>, <1>, <4,8>] the size will 7;
|
||||
/// for range [<0>, <1>, <5>] the size will 3
|
||||
unsigned getSize() const {
|
||||
APInt sz(((const APInt&)getItem(0).getLow()).getBitWidth(), 0);
|
||||
for (unsigned i = 0, e = getNumItems(); i != e; ++i) {
|
||||
const APInt Low = getItem(i).getLow();
|
||||
const APInt High = getItem(i).getHigh();
|
||||
APInt S = High - Low + 1;
|
||||
sz += S;
|
||||
}
|
||||
return sz.getZExtValue();
|
||||
}
|
||||
|
||||
/// Allows to access single value even if it belongs to some range.
|
||||
/// Ranges set is considered as flat numbers collection.
|
||||
/// [<1>, <4,8>] is considered as [1,4,5,6,7,8]
|
||||
/// For range [<1>, <4,8>] getSingleValue(3) returns 6.
|
||||
APInt getSingleValue(unsigned idx) const {
|
||||
APInt sz(((const APInt&)getItem(0).getLow()).getBitWidth(), 0);
|
||||
for (unsigned i = 0, e = getNumItems(); i != e; ++i) {
|
||||
const APInt Low = getItem(i).getLow();
|
||||
const APInt High = getItem(i).getHigh();
|
||||
APInt S = High - Low + 1;
|
||||
APInt oldSz = sz;
|
||||
sz += S;
|
||||
if (sz.ugt(idx)) {
|
||||
APInt Res = Low;
|
||||
APInt Offset(oldSz.getBitWidth(), idx);
|
||||
Offset -= oldSz;
|
||||
Res += Offset;
|
||||
return Res;
|
||||
}
|
||||
}
|
||||
assert(0 && "Index exceeds high border.");
|
||||
return sz;
|
||||
}
|
||||
|
||||
/// Does the same as getSingleValue, but works only if subset contains
|
||||
/// single numbers only.
|
||||
const IntTy& getSingleNumber(unsigned idx) const {
|
||||
assert(IsSingleNumbersOnly && "This method works properly if subset "
|
||||
"contains single numbers only.");
|
||||
return FlatCollection[idx];
|
||||
}
|
||||
};
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
/// IntegersSubset - currently is extension of IntegersSubsetGeneric
|
||||
/// that also supports conversion to/from Constant* object.
|
||||
class IntegersSubset : public IntegersSubsetGeneric<IntItem> {
|
||||
|
||||
typedef IntegersSubsetGeneric<IntItem> ParentTy;
|
||||
|
||||
Constant *Holder;
|
||||
|
||||
static unsigned getNumItemsFromConstant(Constant *C) {
|
||||
return cast<ArrayType>(C->getType())->getNumElements();
|
||||
}
|
||||
|
||||
static Range getItemFromConstant(Constant *C, unsigned idx) {
|
||||
const Constant *CV = C->getAggregateElement(idx);
|
||||
|
||||
unsigned NumEls = cast<VectorType>(CV->getType())->getNumElements();
|
||||
switch (NumEls) {
|
||||
case 1:
|
||||
return Range(IntItem::fromConstantInt(
|
||||
cast<ConstantInt>(CV->getAggregateElement(0U))),
|
||||
IntItem::fromConstantInt(cast<ConstantInt>(
|
||||
cast<ConstantInt>(CV->getAggregateElement(0U)))));
|
||||
case 2:
|
||||
return Range(IntItem::fromConstantInt(
|
||||
cast<ConstantInt>(CV->getAggregateElement(0U))),
|
||||
IntItem::fromConstantInt(
|
||||
cast<ConstantInt>(CV->getAggregateElement(1))));
|
||||
default:
|
||||
assert(0 && "Only pairs and single numbers are allowed here.");
|
||||
return Range();
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<Range> rangesFromConstant(Constant *C) {
|
||||
unsigned NumItems = getNumItemsFromConstant(C);
|
||||
std::vector<Range> r;
|
||||
r.reserve(NumItems);
|
||||
for (unsigned i = 0, e = NumItems; i != e; ++i)
|
||||
r.push_back(getItemFromConstant(C, i));
|
||||
return r;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
explicit IntegersSubset(Constant *C) : ParentTy(rangesFromConstant(C)),
|
||||
Holder(C) {}
|
||||
|
||||
IntegersSubset(const IntegersSubset& RHS) :
|
||||
ParentTy(*(const ParentTy *)&RHS), // FIXME: tweak for msvc.
|
||||
Holder(RHS.Holder) {}
|
||||
|
||||
template<class RangesCollectionTy>
|
||||
explicit IntegersSubset(const RangesCollectionTy& Src) : ParentTy(Src) {
|
||||
std::vector<Constant*> Elts;
|
||||
Elts.reserve(Src.size());
|
||||
for (typename RangesCollectionTy::const_iterator i = Src.begin(),
|
||||
e = Src.end(); i != e; ++i) {
|
||||
const Range &R = *i;
|
||||
std::vector<Constant*> r;
|
||||
if (R.isSingleNumber()) {
|
||||
r.reserve(2);
|
||||
// FIXME: Since currently we have ConstantInt based numbers
|
||||
// use hack-conversion of IntItem to ConstantInt
|
||||
r.push_back(R.getLow().toConstantInt());
|
||||
r.push_back(R.getHigh().toConstantInt());
|
||||
} else {
|
||||
r.reserve(1);
|
||||
r.push_back(R.getLow().toConstantInt());
|
||||
}
|
||||
Constant *CV = ConstantVector::get(r);
|
||||
Elts.push_back(CV);
|
||||
}
|
||||
ArrayType *ArrTy =
|
||||
ArrayType::get(Elts.front()->getType(), (uint64_t)Elts.size());
|
||||
Holder = ConstantArray::get(ArrTy, Elts);
|
||||
}
|
||||
|
||||
operator Constant*() { return Holder; }
|
||||
operator const Constant*() const { return Holder; }
|
||||
Constant *operator->() { return Holder; }
|
||||
const Constant *operator->() const { return Holder; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* CLLVM_SUPPORT_INTEGERSSUBSET_H */
|
||||
588
thirdparty/clang/include/llvm/Support/IntegersSubsetMapping.h
vendored
Normal file
588
thirdparty/clang/include/llvm/Support/IntegersSubsetMapping.h
vendored
Normal file
@@ -0,0 +1,588 @@
|
||||
//===- IntegersSubsetMapping.h - Mapping subset ==> Successor ---*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
/// @file
|
||||
/// IntegersSubsetMapping is mapping from A to B, where
|
||||
/// Items in A is subsets of integers,
|
||||
/// Items in B some pointers (Successors).
|
||||
/// If user which to add another subset for successor that is already
|
||||
/// exists in mapping, IntegersSubsetMapping merges existing subset with
|
||||
/// added one.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_INTEGERSSUBSETMAPPING_H
|
||||
#define LLVM_SUPPORT_INTEGERSSUBSETMAPPING_H
|
||||
|
||||
#include "llvm/Support/IntegersSubset.h"
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
template <class SuccessorClass,
|
||||
class IntegersSubsetTy = IntegersSubset,
|
||||
class IntTy = IntItem>
|
||||
class IntegersSubsetMapping {
|
||||
// FIXME: To much similar iterators typedefs, similar names.
|
||||
// - Rename RangeIterator to the cluster iterator.
|
||||
// - Remove unused "add" methods.
|
||||
// - Class contents needs cleaning.
|
||||
public:
|
||||
|
||||
typedef IntRange<IntTy> RangeTy;
|
||||
|
||||
struct RangeEx : public RangeTy {
|
||||
RangeEx() : Weight(1) {}
|
||||
RangeEx(const RangeTy &R) : RangeTy(R), Weight(1) {}
|
||||
RangeEx(const RangeTy &R, unsigned W) : RangeTy(R), Weight(W) {}
|
||||
RangeEx(const IntTy &C) : RangeTy(C), Weight(1) {}
|
||||
RangeEx(const IntTy &L, const IntTy &H) : RangeTy(L, H), Weight(1) {}
|
||||
RangeEx(const IntTy &L, const IntTy &H, unsigned W) :
|
||||
RangeTy(L, H), Weight(W) {}
|
||||
unsigned Weight;
|
||||
};
|
||||
|
||||
typedef std::pair<RangeEx, SuccessorClass*> Cluster;
|
||||
|
||||
typedef std::list<RangeTy> RangesCollection;
|
||||
typedef typename RangesCollection::iterator RangesCollectionIt;
|
||||
typedef typename RangesCollection::const_iterator RangesCollectionConstIt;
|
||||
typedef IntegersSubsetMapping<SuccessorClass, IntegersSubsetTy, IntTy> self;
|
||||
|
||||
protected:
|
||||
|
||||
typedef std::list<Cluster> CaseItems;
|
||||
typedef typename CaseItems::iterator CaseItemIt;
|
||||
typedef typename CaseItems::const_iterator CaseItemConstIt;
|
||||
|
||||
// TODO: Change unclean CRS prefixes to SubsetMap for example.
|
||||
typedef std::map<SuccessorClass*, RangesCollection > CRSMap;
|
||||
typedef typename CRSMap::iterator CRSMapIt;
|
||||
|
||||
struct ClustersCmp {
|
||||
bool operator()(const Cluster &C1, const Cluster &C2) {
|
||||
return C1.first < C2.first;
|
||||
}
|
||||
};
|
||||
|
||||
CaseItems Items;
|
||||
bool Sorted;
|
||||
|
||||
bool isIntersected(CaseItemIt& LItem, CaseItemIt& RItem) {
|
||||
return LItem->first.getHigh() >= RItem->first.getLow();
|
||||
}
|
||||
|
||||
bool isJoinable(CaseItemIt& LItem, CaseItemIt& RItem) {
|
||||
if (LItem->second != RItem->second) {
|
||||
assert(!isIntersected(LItem, RItem) &&
|
||||
"Intersected items with different successors!");
|
||||
return false;
|
||||
}
|
||||
APInt RLow = RItem->first.getLow();
|
||||
if (RLow != APInt::getNullValue(RLow.getBitWidth()))
|
||||
--RLow;
|
||||
return LItem->first.getHigh() >= RLow;
|
||||
}
|
||||
|
||||
void sort() {
|
||||
if (!Sorted) {
|
||||
std::vector<Cluster> clustersVector;
|
||||
clustersVector.reserve(Items.size());
|
||||
clustersVector.insert(clustersVector.begin(), Items.begin(), Items.end());
|
||||
std::sort(clustersVector.begin(), clustersVector.end(), ClustersCmp());
|
||||
Items.clear();
|
||||
Items.insert(Items.begin(), clustersVector.begin(), clustersVector.end());
|
||||
Sorted = true;
|
||||
}
|
||||
}
|
||||
|
||||
enum DiffProcessState {
|
||||
L_OPENED,
|
||||
INTERSECT_OPENED,
|
||||
R_OPENED,
|
||||
ALL_IS_CLOSED
|
||||
};
|
||||
|
||||
class DiffStateMachine {
|
||||
|
||||
DiffProcessState State;
|
||||
IntTy OpenPt;
|
||||
SuccessorClass *CurrentLSuccessor;
|
||||
SuccessorClass *CurrentRSuccessor;
|
||||
|
||||
self *LeftMapping;
|
||||
self *IntersectionMapping;
|
||||
self *RightMapping;
|
||||
|
||||
public:
|
||||
|
||||
typedef
|
||||
IntegersSubsetMapping<SuccessorClass, IntegersSubsetTy, IntTy> MappingTy;
|
||||
|
||||
DiffStateMachine(MappingTy *L,
|
||||
MappingTy *Intersection,
|
||||
MappingTy *R) :
|
||||
State(ALL_IS_CLOSED),
|
||||
LeftMapping(L),
|
||||
IntersectionMapping(Intersection),
|
||||
RightMapping(R)
|
||||
{}
|
||||
|
||||
void onLOpen(const IntTy &Pt, SuccessorClass *S) {
|
||||
switch (State) {
|
||||
case R_OPENED:
|
||||
if (Pt > OpenPt/*Don't add empty ranges.*/ && RightMapping)
|
||||
RightMapping->add(OpenPt, Pt-1, CurrentRSuccessor);
|
||||
State = INTERSECT_OPENED;
|
||||
break;
|
||||
case ALL_IS_CLOSED:
|
||||
State = L_OPENED;
|
||||
break;
|
||||
default:
|
||||
assert(0 && "Got unexpected point.");
|
||||
break;
|
||||
}
|
||||
CurrentLSuccessor = S;
|
||||
OpenPt = Pt;
|
||||
}
|
||||
|
||||
void onLClose(const IntTy &Pt) {
|
||||
switch (State) {
|
||||
case L_OPENED:
|
||||
assert(Pt >= OpenPt &&
|
||||
"Subset is not sorted or contains overlapped ranges");
|
||||
if (LeftMapping)
|
||||
LeftMapping->add(OpenPt, Pt, CurrentLSuccessor);
|
||||
State = ALL_IS_CLOSED;
|
||||
break;
|
||||
case INTERSECT_OPENED:
|
||||
if (IntersectionMapping)
|
||||
IntersectionMapping->add(OpenPt, Pt, CurrentLSuccessor);
|
||||
OpenPt = Pt + 1;
|
||||
State = R_OPENED;
|
||||
break;
|
||||
default:
|
||||
assert(0 && "Got unexpected point.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void onROpen(const IntTy &Pt, SuccessorClass *S) {
|
||||
switch (State) {
|
||||
case L_OPENED:
|
||||
if (Pt > OpenPt && LeftMapping)
|
||||
LeftMapping->add(OpenPt, Pt-1, CurrentLSuccessor);
|
||||
State = INTERSECT_OPENED;
|
||||
break;
|
||||
case ALL_IS_CLOSED:
|
||||
State = R_OPENED;
|
||||
break;
|
||||
default:
|
||||
assert(0 && "Got unexpected point.");
|
||||
break;
|
||||
}
|
||||
CurrentRSuccessor = S;
|
||||
OpenPt = Pt;
|
||||
}
|
||||
|
||||
void onRClose(const IntTy &Pt) {
|
||||
switch (State) {
|
||||
case R_OPENED:
|
||||
assert(Pt >= OpenPt &&
|
||||
"Subset is not sorted or contains overlapped ranges");
|
||||
if (RightMapping)
|
||||
RightMapping->add(OpenPt, Pt, CurrentRSuccessor);
|
||||
State = ALL_IS_CLOSED;
|
||||
break;
|
||||
case INTERSECT_OPENED:
|
||||
if (IntersectionMapping)
|
||||
IntersectionMapping->add(OpenPt, Pt, CurrentLSuccessor);
|
||||
OpenPt = Pt + 1;
|
||||
State = L_OPENED;
|
||||
break;
|
||||
default:
|
||||
assert(0 && "Got unexpected point.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void onLROpen(const IntTy &Pt,
|
||||
SuccessorClass *LS,
|
||||
SuccessorClass *RS) {
|
||||
switch (State) {
|
||||
case ALL_IS_CLOSED:
|
||||
State = INTERSECT_OPENED;
|
||||
break;
|
||||
default:
|
||||
assert(0 && "Got unexpected point.");
|
||||
break;
|
||||
}
|
||||
CurrentLSuccessor = LS;
|
||||
CurrentRSuccessor = RS;
|
||||
OpenPt = Pt;
|
||||
}
|
||||
|
||||
void onLRClose(const IntTy &Pt) {
|
||||
switch (State) {
|
||||
case INTERSECT_OPENED:
|
||||
if (IntersectionMapping)
|
||||
IntersectionMapping->add(OpenPt, Pt, CurrentLSuccessor);
|
||||
State = ALL_IS_CLOSED;
|
||||
break;
|
||||
default:
|
||||
assert(0 && "Got unexpected point.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool isLOpened() { return State == L_OPENED; }
|
||||
bool isROpened() { return State == R_OPENED; }
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
// Don't public CaseItems itself. Don't allow edit the Items directly.
|
||||
// Just present the user way to iterate over the internal collection
|
||||
// sharing iterator, begin() and end(). Editing should be controlled by
|
||||
// factory.
|
||||
typedef CaseItemIt RangeIterator;
|
||||
|
||||
typedef std::pair<SuccessorClass*, IntegersSubsetTy> Case;
|
||||
typedef std::list<Case> Cases;
|
||||
typedef typename Cases::iterator CasesIt;
|
||||
|
||||
IntegersSubsetMapping() {
|
||||
Sorted = false;
|
||||
}
|
||||
|
||||
bool verify() {
|
||||
RangeIterator DummyErrItem;
|
||||
return verify(DummyErrItem);
|
||||
}
|
||||
|
||||
bool verify(RangeIterator& errItem) {
|
||||
if (Items.empty())
|
||||
return true;
|
||||
sort();
|
||||
for (CaseItemIt j = Items.begin(), i = j++, e = Items.end();
|
||||
j != e; i = j++) {
|
||||
if (isIntersected(i, j) && i->second != j->second) {
|
||||
errItem = j;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isOverlapped(self &RHS) {
|
||||
if (Items.empty() || RHS.empty())
|
||||
return true;
|
||||
|
||||
for (CaseItemIt L = Items.begin(), R = RHS.Items.begin(),
|
||||
el = Items.end(), er = RHS.Items.end(); L != el && R != er;) {
|
||||
|
||||
const RangeTy &LRange = L->first;
|
||||
const RangeTy &RRange = R->first;
|
||||
|
||||
if (LRange.getLow() > RRange.getLow()) {
|
||||
if (RRange.isSingleNumber() || LRange.getLow() > RRange.getHigh())
|
||||
++R;
|
||||
else
|
||||
return true;
|
||||
} else if (LRange.getLow() < RRange.getLow()) {
|
||||
if (LRange.isSingleNumber() || LRange.getHigh() < RRange.getLow())
|
||||
++L;
|
||||
else
|
||||
return true;
|
||||
} else // iRange.getLow() == jRange.getLow()
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void optimize() {
|
||||
if (Items.size() < 2)
|
||||
return;
|
||||
sort();
|
||||
CaseItems OldItems = Items;
|
||||
Items.clear();
|
||||
const IntTy *Low = &OldItems.begin()->first.getLow();
|
||||
const IntTy *High = &OldItems.begin()->first.getHigh();
|
||||
unsigned Weight = OldItems.begin()->first.Weight;
|
||||
SuccessorClass *Successor = OldItems.begin()->second;
|
||||
for (CaseItemIt j = OldItems.begin(), i = j++, e = OldItems.end();
|
||||
j != e; i = j++) {
|
||||
if (isJoinable(i, j)) {
|
||||
const IntTy *CurHigh = &j->first.getHigh();
|
||||
Weight += j->first.Weight;
|
||||
if (*CurHigh > *High)
|
||||
High = CurHigh;
|
||||
} else {
|
||||
RangeEx R(*Low, *High, Weight);
|
||||
add(R, Successor);
|
||||
Low = &j->first.getLow();
|
||||
High = &j->first.getHigh();
|
||||
Weight = j->first.Weight;
|
||||
Successor = j->second;
|
||||
}
|
||||
}
|
||||
RangeEx R(*Low, *High, Weight);
|
||||
add(R, Successor);
|
||||
// We recollected the Items, but we kept it sorted.
|
||||
Sorted = true;
|
||||
}
|
||||
|
||||
/// Adds a constant value.
|
||||
void add(const IntTy &C, SuccessorClass *S = 0) {
|
||||
RangeTy R(C);
|
||||
add(R, S);
|
||||
}
|
||||
|
||||
/// Adds a range.
|
||||
void add(const IntTy &Low, const IntTy &High, SuccessorClass *S = 0) {
|
||||
RangeTy R(Low, High);
|
||||
add(R, S);
|
||||
}
|
||||
void add(const RangeTy &R, SuccessorClass *S = 0) {
|
||||
RangeEx REx = R;
|
||||
add(REx, S);
|
||||
}
|
||||
void add(const RangeEx &R, SuccessorClass *S = 0) {
|
||||
Items.push_back(std::make_pair(R, S));
|
||||
Sorted = false;
|
||||
}
|
||||
|
||||
/// Adds all ranges and values from given ranges set to the current
|
||||
/// mapping.
|
||||
void add(const IntegersSubsetTy &CRS, SuccessorClass *S = 0,
|
||||
unsigned Weight = 0) {
|
||||
unsigned ItemWeight = 1;
|
||||
if (Weight)
|
||||
// Weight is associated with CRS, for now we perform a division to
|
||||
// get the weight for each item.
|
||||
ItemWeight = Weight / CRS.getNumItems();
|
||||
for (unsigned i = 0, e = CRS.getNumItems(); i < e; ++i) {
|
||||
RangeTy R = CRS.getItem(i);
|
||||
RangeEx REx(R, ItemWeight);
|
||||
add(REx, S);
|
||||
}
|
||||
}
|
||||
|
||||
void add(self& RHS) {
|
||||
Items.insert(Items.end(), RHS.Items.begin(), RHS.Items.end());
|
||||
}
|
||||
|
||||
void add(self& RHS, SuccessorClass *S) {
|
||||
for (CaseItemIt i = RHS.Items.begin(), e = RHS.Items.end(); i != e; ++i)
|
||||
add(i->first, S);
|
||||
}
|
||||
|
||||
void add(const RangesCollection& RHS, SuccessorClass *S = 0) {
|
||||
for (RangesCollectionConstIt i = RHS.begin(), e = RHS.end(); i != e; ++i)
|
||||
add(*i, S);
|
||||
}
|
||||
|
||||
/// Removes items from set.
|
||||
void removeItem(RangeIterator i) { Items.erase(i); }
|
||||
|
||||
/// Moves whole case from current mapping to the NewMapping object.
|
||||
void detachCase(self& NewMapping, SuccessorClass *Succ) {
|
||||
for (CaseItemIt i = Items.begin(); i != Items.end();)
|
||||
if (i->second == Succ) {
|
||||
NewMapping.add(i->first, i->second);
|
||||
Items.erase(i++);
|
||||
} else
|
||||
++i;
|
||||
}
|
||||
|
||||
/// Removes all clusters for given successor.
|
||||
void removeCase(SuccessorClass *Succ) {
|
||||
for (CaseItemIt i = Items.begin(); i != Items.end();)
|
||||
if (i->second == Succ) {
|
||||
Items.erase(i++);
|
||||
} else
|
||||
++i;
|
||||
}
|
||||
|
||||
/// Find successor that satisfies given value.
|
||||
SuccessorClass *findSuccessor(const IntTy& Val) {
|
||||
for (CaseItemIt i = Items.begin(); i != Items.end(); ++i) {
|
||||
if (i->first.isInRange(Val))
|
||||
return i->second;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// Calculates the difference between this mapping and RHS.
|
||||
/// THIS without RHS is placed into LExclude,
|
||||
/// RHS without THIS is placed into RExclude,
|
||||
/// THIS intersect RHS is placed into Intersection.
|
||||
void diff(self *LExclude, self *Intersection, self *RExclude,
|
||||
const self& RHS) {
|
||||
|
||||
DiffStateMachine Machine(LExclude, Intersection, RExclude);
|
||||
|
||||
CaseItemConstIt L = Items.begin(), R = RHS.Items.begin();
|
||||
while (L != Items.end() && R != RHS.Items.end()) {
|
||||
const Cluster &LCluster = *L;
|
||||
const RangeEx &LRange = LCluster.first;
|
||||
const Cluster &RCluster = *R;
|
||||
const RangeEx &RRange = RCluster.first;
|
||||
|
||||
if (LRange.getHigh() < RRange.getLow()) {
|
||||
Machine.onLOpen(LRange.getLow(), LCluster.second);
|
||||
Machine.onLClose(LRange.getHigh());
|
||||
++L;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (LRange.getLow() > RRange.getHigh()) {
|
||||
Machine.onROpen(RRange.getLow(), RCluster.second);
|
||||
Machine.onRClose(RRange.getHigh());
|
||||
++R;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (LRange.getLow() < RRange.getLow()) {
|
||||
// May be opened in previous iteration.
|
||||
if (!Machine.isLOpened())
|
||||
Machine.onLOpen(LRange.getLow(), LCluster.second);
|
||||
Machine.onROpen(RRange.getLow(), RCluster.second);
|
||||
}
|
||||
else if (RRange.getLow() < LRange.getLow()) {
|
||||
if (!Machine.isROpened())
|
||||
Machine.onROpen(RRange.getLow(), RCluster.second);
|
||||
Machine.onLOpen(LRange.getLow(), LCluster.second);
|
||||
}
|
||||
else
|
||||
Machine.onLROpen(LRange.getLow(), LCluster.second, RCluster.second);
|
||||
|
||||
if (LRange.getHigh() < RRange.getHigh()) {
|
||||
Machine.onLClose(LRange.getHigh());
|
||||
++L;
|
||||
while(L != Items.end() && L->first.getHigh() < RRange.getHigh()) {
|
||||
Machine.onLOpen(L->first.getLow(), L->second);
|
||||
Machine.onLClose(L->first.getHigh());
|
||||
++L;
|
||||
}
|
||||
}
|
||||
else if (RRange.getHigh() < LRange.getHigh()) {
|
||||
Machine.onRClose(RRange.getHigh());
|
||||
++R;
|
||||
while(R != RHS.Items.end() && R->first.getHigh() < LRange.getHigh()) {
|
||||
Machine.onROpen(R->first.getLow(), R->second);
|
||||
Machine.onRClose(R->first.getHigh());
|
||||
++R;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Machine.onLRClose(LRange.getHigh());
|
||||
++L;
|
||||
++R;
|
||||
}
|
||||
}
|
||||
|
||||
if (L != Items.end()) {
|
||||
if (Machine.isLOpened()) {
|
||||
Machine.onLClose(L->first.getHigh());
|
||||
++L;
|
||||
}
|
||||
if (LExclude)
|
||||
while (L != Items.end()) {
|
||||
LExclude->add(L->first, L->second);
|
||||
++L;
|
||||
}
|
||||
} else if (R != RHS.Items.end()) {
|
||||
if (Machine.isROpened()) {
|
||||
Machine.onRClose(R->first.getHigh());
|
||||
++R;
|
||||
}
|
||||
if (RExclude)
|
||||
while (R != RHS.Items.end()) {
|
||||
RExclude->add(R->first, R->second);
|
||||
++R;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Builds the finalized case objects.
|
||||
void getCases(Cases& TheCases, bool PreventMerging = false) {
|
||||
//FIXME: PreventMerging is a temporary parameter.
|
||||
//Currently a set of passes is still knows nothing about
|
||||
//switches with case ranges, and if these passes meet switch
|
||||
//with complex case that crashs the application.
|
||||
if (PreventMerging) {
|
||||
for (RangeIterator i = this->begin(); i != this->end(); ++i) {
|
||||
RangesCollection SingleRange;
|
||||
SingleRange.push_back(i->first);
|
||||
TheCases.push_back(std::make_pair(i->second,
|
||||
IntegersSubsetTy(SingleRange)));
|
||||
}
|
||||
return;
|
||||
}
|
||||
CRSMap TheCRSMap;
|
||||
for (RangeIterator i = this->begin(); i != this->end(); ++i)
|
||||
TheCRSMap[i->second].push_back(i->first);
|
||||
for (CRSMapIt i = TheCRSMap.begin(), e = TheCRSMap.end(); i != e; ++i)
|
||||
TheCases.push_back(std::make_pair(i->first, IntegersSubsetTy(i->second)));
|
||||
}
|
||||
|
||||
/// Builds the finalized case objects ignoring successor values, as though
|
||||
/// all ranges belongs to the same successor.
|
||||
IntegersSubsetTy getCase() {
|
||||
RangesCollection Ranges;
|
||||
for (RangeIterator i = this->begin(); i != this->end(); ++i)
|
||||
Ranges.push_back(i->first);
|
||||
return IntegersSubsetTy(Ranges);
|
||||
}
|
||||
|
||||
/// Returns pointer to value of case if it is single-numbered or 0
|
||||
/// in another case.
|
||||
const IntTy* getCaseSingleNumber(SuccessorClass *Succ) {
|
||||
const IntTy* Res = 0;
|
||||
for (CaseItemIt i = Items.begin(); i != Items.end(); ++i)
|
||||
if (i->second == Succ) {
|
||||
if (!i->first.isSingleNumber())
|
||||
return 0;
|
||||
if (Res)
|
||||
return 0;
|
||||
else
|
||||
Res = &(i->first.getLow());
|
||||
}
|
||||
return Res;
|
||||
}
|
||||
|
||||
/// Returns true if there is no ranges and values inside.
|
||||
bool empty() const { return Items.empty(); }
|
||||
|
||||
void clear() {
|
||||
Items.clear();
|
||||
// Don't reset Sorted flag:
|
||||
// 1. For empty mapping it matters nothing.
|
||||
// 2. After first item will added Sorted flag will cleared.
|
||||
}
|
||||
|
||||
// Returns number of clusters
|
||||
unsigned size() const {
|
||||
return Items.size();
|
||||
}
|
||||
|
||||
RangeIterator begin() { return Items.begin(); }
|
||||
RangeIterator end() { return Items.end(); }
|
||||
};
|
||||
|
||||
class BasicBlock;
|
||||
typedef IntegersSubsetMapping<BasicBlock> IntegersSubsetToBB;
|
||||
|
||||
}
|
||||
|
||||
#endif /* LLVM_SUPPORT_INTEGERSSUBSETMAPPING_CRSBUILDER_H */
|
||||
95
thirdparty/clang/include/llvm/Support/LEB128.h
vendored
Normal file
95
thirdparty/clang/include/llvm/Support/LEB128.h
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
//===- llvm/Support/LEB128.h - [SU]LEB128 utility functions -----*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file declares some utility functions for encoding SLEB128 and
|
||||
// ULEB128 values.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_LEB128_H
|
||||
#define LLVM_SUPPORT_LEB128_H
|
||||
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
/// Utility function to encode a SLEB128 value to an output stream.
|
||||
static inline void encodeSLEB128(int64_t Value, raw_ostream &OS) {
|
||||
bool More;
|
||||
do {
|
||||
uint8_t Byte = Value & 0x7f;
|
||||
// NOTE: this assumes that this signed shift is an arithmetic right shift.
|
||||
Value >>= 7;
|
||||
More = !((((Value == 0 ) && ((Byte & 0x40) == 0)) ||
|
||||
((Value == -1) && ((Byte & 0x40) != 0))));
|
||||
if (More)
|
||||
Byte |= 0x80; // Mark this byte that that more bytes will follow.
|
||||
OS << char(Byte);
|
||||
} while (More);
|
||||
}
|
||||
|
||||
/// Utility function to encode a ULEB128 value to an output stream.
|
||||
static inline void encodeULEB128(uint64_t Value, raw_ostream &OS,
|
||||
unsigned Padding = 0) {
|
||||
do {
|
||||
uint8_t Byte = Value & 0x7f;
|
||||
Value >>= 7;
|
||||
if (Value != 0 || Padding != 0)
|
||||
Byte |= 0x80; // Mark this byte that that more bytes will follow.
|
||||
OS << char(Byte);
|
||||
} while (Value != 0);
|
||||
|
||||
// Pad with 0x80 and emit a null byte at the end.
|
||||
if (Padding != 0) {
|
||||
for (; Padding != 1; --Padding)
|
||||
OS << '\x80';
|
||||
OS << '\x00';
|
||||
}
|
||||
}
|
||||
|
||||
/// Utility function to encode a ULEB128 value to a buffer. Returns
|
||||
/// the length in bytes of the encoded value.
|
||||
static inline unsigned encodeULEB128(uint64_t Value, uint8_t *p,
|
||||
unsigned Padding = 0) {
|
||||
uint8_t *orig_p = p;
|
||||
do {
|
||||
uint8_t Byte = Value & 0x7f;
|
||||
Value >>= 7;
|
||||
if (Value != 0 || Padding != 0)
|
||||
Byte |= 0x80; // Mark this byte that that more bytes will follow.
|
||||
*p++ = Byte;
|
||||
} while (Value != 0);
|
||||
|
||||
// Pad with 0x80 and emit a null byte at the end.
|
||||
if (Padding != 0) {
|
||||
for (; Padding != 1; --Padding)
|
||||
*p++ = '\x80';
|
||||
*p++ = '\x00';
|
||||
}
|
||||
return (unsigned)(p - orig_p);
|
||||
}
|
||||
|
||||
|
||||
/// Utility function to decode a ULEB128 value.
|
||||
static inline uint64_t decodeULEB128(const uint8_t *p, unsigned *n = 0) {
|
||||
const uint8_t *orig_p = p;
|
||||
uint64_t Value = 0;
|
||||
unsigned Shift = 0;
|
||||
do {
|
||||
Value += (*p & 0x7f) << Shift;
|
||||
Shift += 7;
|
||||
} while (*p++ >= 128);
|
||||
if (n)
|
||||
*n = (unsigned)(p - orig_p);
|
||||
return Value;
|
||||
}
|
||||
|
||||
} // namespace llvm
|
||||
|
||||
#endif // LLVM_SYSTEM_LEB128_H
|
||||
92
thirdparty/clang/include/llvm/Support/LeakDetector.h
vendored
Normal file
92
thirdparty/clang/include/llvm/Support/LeakDetector.h
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
//===-- llvm/Support/LeakDetector.h - Provide leak detection ----*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines a class that can be used to provide very simple memory leak
|
||||
// checks for an API. Basically LLVM uses this to make sure that Instructions,
|
||||
// for example, are deleted when they are supposed to be, and not leaked away.
|
||||
//
|
||||
// When compiling with NDEBUG (Release build), this class does nothing, thus
|
||||
// adding no checking overhead to release builds. Note that this class is
|
||||
// implemented in a very simple way, requiring completely manual manipulation
|
||||
// and checking for garbage, but this is intentional: users should not be using
|
||||
// this API, only other APIs should.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_LEAKDETECTOR_H
|
||||
#define LLVM_SUPPORT_LEAKDETECTOR_H
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class LLVMContext;
|
||||
class Value;
|
||||
|
||||
struct LeakDetector {
|
||||
/// addGarbageObject - Add a pointer to the internal set of "garbage" object
|
||||
/// pointers. This should be called when objects are created, or if they are
|
||||
/// taken out of an owning collection.
|
||||
///
|
||||
static void addGarbageObject(void *Object) {
|
||||
#ifndef NDEBUG
|
||||
addGarbageObjectImpl(Object);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// removeGarbageObject - Remove a pointer from our internal representation of
|
||||
/// our "garbage" objects. This should be called when an object is added to
|
||||
/// an "owning" collection.
|
||||
///
|
||||
static void removeGarbageObject(void *Object) {
|
||||
#ifndef NDEBUG
|
||||
removeGarbageObjectImpl(Object);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// checkForGarbage - Traverse the internal representation of garbage
|
||||
/// pointers. If there are any pointers that have been add'ed, but not
|
||||
/// remove'd, big obnoxious warnings about memory leaks are issued.
|
||||
///
|
||||
/// The specified message will be printed indicating when the check was
|
||||
/// performed.
|
||||
///
|
||||
static void checkForGarbage(LLVMContext &C, const std::string &Message) {
|
||||
#ifndef NDEBUG
|
||||
checkForGarbageImpl(C, Message);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Overload the normal methods to work better with Value*'s because they are
|
||||
/// by far the most common in LLVM. This does not affect the actual
|
||||
/// functioning of this class, it just makes the warning messages nicer.
|
||||
///
|
||||
static void addGarbageObject(const Value *Object) {
|
||||
#ifndef NDEBUG
|
||||
addGarbageObjectImpl(Object);
|
||||
#endif
|
||||
}
|
||||
static void removeGarbageObject(const Value *Object) {
|
||||
#ifndef NDEBUG
|
||||
removeGarbageObjectImpl(Object);
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
// If we are debugging, the actual implementations will be called...
|
||||
static void addGarbageObjectImpl(const Value *Object);
|
||||
static void removeGarbageObjectImpl(const Value *Object);
|
||||
static void addGarbageObjectImpl(void *Object);
|
||||
static void removeGarbageObjectImpl(void *Object);
|
||||
static void checkForGarbageImpl(LLVMContext &C, const std::string &Message);
|
||||
};
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
||||
17
thirdparty/clang/include/llvm/Support/Locale.h
vendored
Normal file
17
thirdparty/clang/include/llvm/Support/Locale.h
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
#ifndef LLVM_SUPPORT_LOCALE_H
|
||||
#define LLVM_SUPPORT_LOCALE_H
|
||||
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
|
||||
namespace llvm {
|
||||
namespace sys {
|
||||
namespace locale {
|
||||
|
||||
int columnWidth(StringRef s);
|
||||
bool isPrint(int c);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // LLVM_SUPPORT_LOCALE_H
|
||||
75
thirdparty/clang/include/llvm/Support/LockFileManager.h
vendored
Normal file
75
thirdparty/clang/include/llvm/Support/LockFileManager.h
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
//===--- LockFileManager.h - File-level locking utility ---------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
#ifndef LLVM_SUPPORT_LOCKFILEMANAGER_H
|
||||
#define LLVM_SUPPORT_LOCKFILEMANAGER_H
|
||||
|
||||
#include "llvm/ADT/Optional.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Support/system_error.h"
|
||||
#include <utility> // for std::pair
|
||||
|
||||
namespace llvm {
|
||||
|
||||
/// \brief Class that manages the creation of a lock file to aid
|
||||
/// implicit coordination between different processes.
|
||||
///
|
||||
/// The implicit coordination works by creating a ".lock" file alongside
|
||||
/// the file that we're coordinating for, using the atomicity of the file
|
||||
/// system to ensure that only a single process can create that ".lock" file.
|
||||
/// When the lock file is removed, the owning process has finished the
|
||||
/// operation.
|
||||
class LockFileManager {
|
||||
public:
|
||||
/// \brief Describes the state of a lock file.
|
||||
enum LockFileState {
|
||||
/// \brief The lock file has been created and is owned by this instance
|
||||
/// of the object.
|
||||
LFS_Owned,
|
||||
/// \brief The lock file already exists and is owned by some other
|
||||
/// instance.
|
||||
LFS_Shared,
|
||||
/// \brief An error occurred while trying to create or find the lock
|
||||
/// file.
|
||||
LFS_Error
|
||||
};
|
||||
|
||||
private:
|
||||
SmallString<128> FileName;
|
||||
SmallString<128> LockFileName;
|
||||
SmallString<128> UniqueLockFileName;
|
||||
|
||||
Optional<std::pair<std::string, int> > Owner;
|
||||
Optional<error_code> Error;
|
||||
|
||||
LockFileManager(const LockFileManager &) LLVM_DELETED_FUNCTION;
|
||||
LockFileManager &operator=(const LockFileManager &) LLVM_DELETED_FUNCTION;
|
||||
|
||||
static Optional<std::pair<std::string, int> >
|
||||
readLockFile(StringRef LockFileName);
|
||||
|
||||
static bool processStillExecuting(StringRef Hostname, int PID);
|
||||
|
||||
public:
|
||||
|
||||
LockFileManager(StringRef FileName);
|
||||
~LockFileManager();
|
||||
|
||||
/// \brief Determine the state of the lock file.
|
||||
LockFileState getState() const;
|
||||
|
||||
operator LockFileState() const { return getState(); }
|
||||
|
||||
/// \brief For a shared lock, wait until the owner releases the lock.
|
||||
void waitForUnlock();
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif // LLVM_SUPPORT_LOCKFILEMANAGER_H
|
||||
714
thirdparty/clang/include/llvm/Support/MachO.h
vendored
Normal file
714
thirdparty/clang/include/llvm/Support/MachO.h
vendored
Normal file
@@ -0,0 +1,714 @@
|
||||
//===-- llvm/Support/MachO.h - The MachO file format ------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines manifest constants for the MachO object file format.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_MACHO_H
|
||||
#define LLVM_SUPPORT_MACHO_H
|
||||
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
|
||||
// NOTE: The enums in this file are intentially named to be different than those
|
||||
// in the headers in /usr/include/mach (on darwin systems) to avoid conflicts
|
||||
// with those macros.
|
||||
namespace llvm {
|
||||
namespace MachO {
|
||||
// Enums from <mach-o/loader.h>
|
||||
enum {
|
||||
// Constants for the "magic" field in llvm::MachO::mach_header and
|
||||
// llvm::MachO::mach_header_64
|
||||
HeaderMagic32 = 0xFEEDFACEu, // MH_MAGIC
|
||||
HeaderMagic32Swapped = 0xCEFAEDFEu, // MH_CIGAM
|
||||
HeaderMagic64 = 0xFEEDFACFu, // MH_MAGIC_64
|
||||
HeaderMagic64Swapped = 0xCFFAEDFEu, // MH_CIGAM_64
|
||||
UniversalMagic = 0xCAFEBABEu, // FAT_MAGIC
|
||||
UniversalMagicSwapped = 0xBEBAFECAu, // FAT_CIGAM
|
||||
|
||||
// Constants for the "filetype" field in llvm::MachO::mach_header and
|
||||
// llvm::MachO::mach_header_64
|
||||
HeaderFileTypeObject = 0x1u, // MH_OBJECT
|
||||
HeaderFileTypeExecutable = 0x2u, // MH_EXECUTE
|
||||
HeaderFileTypeFixedVMShlib = 0x3u, // MH_FVMLIB
|
||||
HeaderFileTypeCore = 0x4u, // MH_CORE
|
||||
HeaderFileTypePreloadedExecutable = 0x5u, // MH_PRELOAD
|
||||
HeaderFileTypeDynamicShlib = 0x6u, // MH_DYLIB
|
||||
HeaderFileTypeDynamicLinkEditor = 0x7u, // MH_DYLINKER
|
||||
HeaderFileTypeBundle = 0x8u, // MH_BUNDLE
|
||||
HeaderFileTypeDynamicShlibStub = 0x9u, // MH_DYLIB_STUB
|
||||
HeaderFileTypeDSYM = 0xAu, // MH_DSYM
|
||||
HeaderFileTypeKextBundle = 0xBu, // MH_KEXT_BUNDLE
|
||||
|
||||
// Constant bits for the "flags" field in llvm::MachO::mach_header and
|
||||
// llvm::MachO::mach_header_64
|
||||
HeaderFlagBitNoUndefinedSymbols = 0x00000001u, // MH_NOUNDEFS
|
||||
HeaderFlagBitIsIncrementalLinkObject= 0x00000002u, // MH_INCRLINK
|
||||
HeaderFlagBitIsDynamicLinkObject = 0x00000004u, // MH_DYLDLINK
|
||||
HeaderFlagBitBindAtLoad = 0x00000008u, // MH_BINDATLOAD
|
||||
HeaderFlagBitPrebound = 0x00000010u, // MH_PREBOUND
|
||||
HeaderFlagBitSplitSegments = 0x00000020u, // MH_SPLIT_SEGS
|
||||
HeaderFlagBitLazyInit = 0x00000040u, // MH_LAZY_INIT
|
||||
HeaderFlagBitTwoLevelNamespace = 0x00000080u, // MH_TWOLEVEL
|
||||
HeaderFlagBitForceFlatNamespace = 0x00000100u, // MH_FORCE_FLAT
|
||||
HeaderFlagBitNoMultipleDefintions = 0x00000200u, // MH_NOMULTIDEFS
|
||||
HeaderFlagBitNoFixPrebinding = 0x00000400u, // MH_NOFIXPREBINDING
|
||||
HeaderFlagBitPrebindable = 0x00000800u, // MH_PREBINDABLE
|
||||
HeaderFlagBitAllModulesBound = 0x00001000u, // MH_ALLMODSBOUND
|
||||
HeaderFlagBitSubsectionsViaSymbols = 0x00002000u, // MH_SUBSECTIONS_VIA_SYMBOLS
|
||||
HeaderFlagBitCanonical = 0x00004000u, // MH_CANONICAL
|
||||
HeaderFlagBitWeakDefines = 0x00008000u, // MH_WEAK_DEFINES
|
||||
HeaderFlagBitBindsToWeak = 0x00010000u, // MH_BINDS_TO_WEAK
|
||||
HeaderFlagBitAllowStackExecution = 0x00020000u, // MH_ALLOW_STACK_EXECUTION
|
||||
HeaderFlagBitRootSafe = 0x00040000u, // MH_ROOT_SAFE
|
||||
HeaderFlagBitSetUIDSafe = 0x00080000u, // MH_SETUID_SAFE
|
||||
HeaderFlagBitNoReexportedDylibs = 0x00100000u, // MH_NO_REEXPORTED_DYLIBS
|
||||
HeaderFlagBitPIE = 0x00200000u, // MH_PIE
|
||||
HeaderFlagBitDeadStrippableDylib = 0x00400000u, // MH_DEAD_STRIPPABLE_DYLIB
|
||||
|
||||
// Constants for the "cmd" field in llvm::MachO::load_command
|
||||
LoadCommandDynamicLinkerRequired = 0x80000000u, // LC_REQ_DYLD
|
||||
LoadCommandSegment32 = 0x00000001u, // LC_SEGMENT
|
||||
LoadCommandSymtab = 0x00000002u, // LC_SYMTAB
|
||||
LoadCommandSymSeg = 0x00000003u, // LC_SYMSEG
|
||||
LoadCommandThread = 0x00000004u, // LC_THREAD
|
||||
LoadCommandUnixThread = 0x00000005u, // LC_UNIXTHREAD
|
||||
LoadCommandFixedVMShlibLoad = 0x00000006u, // LC_LOADFVMLIB
|
||||
LoadCommandFixedVMShlibIdent = 0x00000007u, // LC_IDFVMLIB
|
||||
LoadCommandIdent = 0x00000008u, // LC_IDENT
|
||||
LoadCommandFixedVMFileInclusion = 0x00000009u, // LC_FVMFILE
|
||||
LoadCommandPrePage = 0x0000000Au, // LC_PREPAGE
|
||||
LoadCommandDynamicSymtabInfo = 0x0000000Bu, // LC_DYSYMTAB
|
||||
LoadCommandDylibLoad = 0x0000000Cu, // LC_LOAD_DYLIB
|
||||
LoadCommandDylibIdent = 0x0000000Du, // LC_ID_DYLIB
|
||||
LoadCommandDynamicLinkerLoad = 0x0000000Eu, // LC_LOAD_DYLINKER
|
||||
LoadCommandDynamicLinkerIdent = 0x0000000Fu, // LC_ID_DYLINKER
|
||||
LoadCommandDylibPrebound = 0x00000010u, // LC_PREBOUND_DYLIB
|
||||
LoadCommandRoutines32 = 0x00000011u, // LC_ROUTINES
|
||||
LoadCommandSubFramework = 0x00000012u, // LC_SUB_FRAMEWORK
|
||||
LoadCommandSubUmbrella = 0x00000013u, // LC_SUB_UMBRELLA
|
||||
LoadCommandSubClient = 0x00000014u, // LC_SUB_CLIENT
|
||||
LoadCommandSubLibrary = 0x00000015u, // LC_SUB_LIBRARY
|
||||
LoadCommandTwoLevelHints = 0x00000016u, // LC_TWOLEVEL_HINTS
|
||||
LoadCommandPreBindChecksum = 0x00000017u, // LC_PREBIND_CKSUM
|
||||
LoadCommandDylibLoadWeak = 0x80000018u, // LC_LOAD_WEAK_DYLIB
|
||||
LoadCommandSegment64 = 0x00000019u, // LC_SEGMENT_64
|
||||
LoadCommandRoutines64 = 0x0000001Au, // LC_ROUTINES_64
|
||||
LoadCommandUUID = 0x0000001Bu, // LC_UUID
|
||||
LoadCommandRunpath = 0x8000001Cu, // LC_RPATH
|
||||
LoadCommandCodeSignature = 0x0000001Du, // LC_CODE_SIGNATURE
|
||||
LoadCommandSegmentSplitInfo = 0x0000001Eu, // LC_SEGMENT_SPLIT_INFO
|
||||
LoadCommandDylibReexport = 0x8000001Fu, // LC_REEXPORT_DYLIB
|
||||
LoadCommandDylibLazyLoad = 0x00000020u, // LC_LAZY_LOAD_DYLIB
|
||||
LoadCommandEncryptionInfo = 0x00000021u, // LC_ENCRYPTION_INFO
|
||||
LoadCommandDynamicLinkerInfo = 0x00000022u, // LC_DYLD_INFO
|
||||
LoadCommandDynamicLinkerInfoOnly = 0x80000022u, // LC_DYLD_INFO_ONLY
|
||||
LoadCommandDylibLoadUpward = 0x80000023u, // LC_LOAD_UPWARD_DYLIB
|
||||
LoadCommandVersionMinMacOSX = 0x00000024u, // LC_VERSION_MIN_MACOSX
|
||||
LoadCommandVersionMinIPhoneOS = 0x00000025u, // LC_VERSION_MIN_IPHONEOS
|
||||
LoadCommandFunctionStarts = 0x00000026u, // LC_FUNCTION_STARTS
|
||||
LoadCommandDyldEnvironment = 0x00000027u, // LC_DYLD_ENVIRONMENT
|
||||
LoadCommandMain = 0x80000028u, // LC_MAIN
|
||||
LoadCommandDataInCode = 0x00000029u, // LC_DATA_IN_CODE
|
||||
LoadCommandSourceVersion = 0x0000002Au, // LC_SOURCE_VERSION
|
||||
LoadCommandCodeSignDRs = 0x0000002Bu, // LC_DYLIB_CODE_SIGN_DRS
|
||||
|
||||
// Constant bits for the "flags" field in llvm::MachO::segment_command
|
||||
SegmentCommandFlagBitHighVM = 0x1u, // SG_HIGHVM
|
||||
SegmentCommandFlagBitFixedVMLibrary = 0x2u, // SG_FVMLIB
|
||||
SegmentCommandFlagBitNoRelocations = 0x4u, // SG_NORELOC
|
||||
SegmentCommandFlagBitProtectedVersion1 = 0x8u, // SG_PROTECTED_VERSION_1
|
||||
|
||||
|
||||
// Constant masks for the "flags" field in llvm::MachO::section and
|
||||
// llvm::MachO::section_64
|
||||
SectionFlagMaskSectionType = 0x000000ffu, // SECTION_TYPE
|
||||
SectionFlagMaskAllAttributes = 0xffffff00u, // SECTION_ATTRIBUTES
|
||||
SectionFlagMaskUserAttributes = 0xff000000u, // SECTION_ATTRIBUTES_USR
|
||||
SectionFlagMaskSystemAttributes = 0x00ffff00u, // SECTION_ATTRIBUTES_SYS
|
||||
|
||||
// Constant masks for the "flags[7:0]" field in llvm::MachO::section and
|
||||
// llvm::MachO::section_64 (mask "flags" with SECTION_TYPE)
|
||||
SectionTypeRegular = 0x00u, // S_REGULAR
|
||||
SectionTypeZeroFill = 0x01u, // S_ZEROFILL
|
||||
SectionTypeCStringLiterals = 0x02u, // S_CSTRING_LITERALS
|
||||
SectionType4ByteLiterals = 0x03u, // S_4BYTE_LITERALS
|
||||
SectionType8ByteLiterals = 0x04u, // S_8BYTE_LITERALS
|
||||
SectionTypeLiteralPointers = 0x05u, // S_LITERAL_POINTERS
|
||||
SectionTypeNonLazySymbolPointers = 0x06u, // S_NON_LAZY_SYMBOL_POINTERS
|
||||
SectionTypeLazySymbolPointers = 0x07u, // S_LAZY_SYMBOL_POINTERS
|
||||
SectionTypeSymbolStubs = 0x08u, // S_SYMBOL_STUBS
|
||||
SectionTypeModuleInitFunctionPointers = 0x09u, // S_MOD_INIT_FUNC_POINTERS
|
||||
SectionTypeModuleTermFunctionPointers = 0x0au, // S_MOD_TERM_FUNC_POINTERS
|
||||
SectionTypeCoalesced = 0x0bu, // S_COALESCED
|
||||
SectionTypeZeroFillLarge = 0x0cu, // S_GB_ZEROFILL
|
||||
SectionTypeInterposing = 0x0du, // S_INTERPOSING
|
||||
SectionType16ByteLiterals = 0x0eu, // S_16BYTE_LITERALS
|
||||
SectionTypeDTraceObjectFormat = 0x0fu, // S_DTRACE_DOF
|
||||
SectionTypeLazyDylibSymbolPointers = 0x10u, // S_LAZY_DYLIB_SYMBOL_POINTERS
|
||||
|
||||
// Constant masks for the "flags[31:24]" field in llvm::MachO::section and
|
||||
// llvm::MachO::section_64 (mask "flags" with SECTION_ATTRIBUTES_USR)
|
||||
SectionAttrUserPureInstructions = 0x80000000u, // S_ATTR_PURE_INSTRUCTIONS
|
||||
SectionAttrUserNoTableOfContents = 0x40000000u, // S_ATTR_NO_TOC
|
||||
SectionAttrUserCanStripStaticSymbols = 0x20000000u, // S_ATTR_STRIP_STATIC_SYMS
|
||||
SectionAttrUserNoDeadStrip = 0x10000000u, // S_ATTR_NO_DEAD_STRIP
|
||||
SectionAttrUserLiveSupport = 0x08000000u, // S_ATTR_LIVE_SUPPORT
|
||||
SectionAttrUserSelfModifyingCode = 0x04000000u, // S_ATTR_SELF_MODIFYING_CODE
|
||||
SectionAttrUserDebug = 0x02000000u, // S_ATTR_DEBUG
|
||||
|
||||
// Constant masks for the "flags[23:8]" field in llvm::MachO::section and
|
||||
// llvm::MachO::section_64 (mask "flags" with SECTION_ATTRIBUTES_SYS)
|
||||
SectionAttrSytemSomeInstructions = 0x00000400u, // S_ATTR_SOME_INSTRUCTIONS
|
||||
SectionAttrSytemHasExternalRelocations= 0x00000200u, // S_ATTR_EXT_RELOC
|
||||
SectionAttrSytemHasLocalRelocations = 0x00000100u, // S_ATTR_LOC_RELOC
|
||||
|
||||
IndirectSymbolLocal = 0x80000000u, // INDIRECT_SYMBOL_LOCAL
|
||||
IndirectSymbolAbsolute = 0x40000000u, // INDIRECT_SYMBOL_ABS
|
||||
|
||||
RebaseTypePointer = 1u, // REBASE_TYPE_POINTER
|
||||
RebaseTypeTextAbsolute32 = 2u, // REBASE_TYPE_TEXT_ABSOLUTE32
|
||||
RebaseTypeTextPCRelative32 = 3u, // REBASE_TYPE_TEXT_PCREL32
|
||||
|
||||
RebaseOpcodeMask = 0xF0u, // REBASE_OPCODE_MASK
|
||||
RebaseImmediateMask = 0x0Fu, // REBASE_IMMEDIATE_MASK
|
||||
RebaseOpcodeDone = 0x00u, // REBASE_OPCODE_DONE
|
||||
RebaseOpcodeSetTypeImmediate = 0x10u, // REBASE_OPCODE_SET_TYPE_IMM
|
||||
RebaseOpcodeSetSegmentAndOffsetULEB = 0x20u, // REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB
|
||||
RebaseOpcodeAddAddressULEB = 0x30u, // REBASE_OPCODE_ADD_ADDR_ULEB
|
||||
RebaseOpcodeAddAddressImmediateScaled = 0x40u, // REBASE_OPCODE_ADD_ADDR_IMM_SCALED
|
||||
RebaseOpcodeDoRebaseImmediateTimes = 0x50u, // REBASE_OPCODE_DO_REBASE_IMM_TIMES
|
||||
RebaseOpcodeDoRebaseULEBTimes = 0x60u, // REBASE_OPCODE_DO_REBASE_ULEB_TIMES
|
||||
RebaseOpcodeDoRebaseAddAddressULEB = 0x70u, // REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB
|
||||
RebaseOpcodeDoRebaseULEBTimesSkippingULEB = 0x80u, // REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB
|
||||
|
||||
|
||||
BindTypePointer = 1u, // BIND_TYPE_POINTER
|
||||
BindTypeTextAbsolute32 = 2u, // BIND_TYPE_TEXT_ABSOLUTE32
|
||||
BindTypeTextPCRelative32 = 3u, // BIND_TYPE_TEXT_PCREL32
|
||||
|
||||
BindSpecialDylibSelf = 0u, // BIND_SPECIAL_DYLIB_SELF
|
||||
BindSpecialDylibMainExecutable = -1u, // BIND_SPECIAL_DYLIB_MAIN_EXECUTABLE
|
||||
BindSpecialDylibFlatLookup = -2u, // BIND_SPECIAL_DYLIB_FLAT_LOOKUP
|
||||
|
||||
BindSymbolFlagsWeakImport = 0x1u, // BIND_SYMBOL_FLAGS_WEAK_IMPORT
|
||||
BindSymbolFlagsNonWeakDefinition = 0x8u, // BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION
|
||||
|
||||
BindOpcodeMask = 0xF0u, // BIND_OPCODE_MASK
|
||||
BindImmediateMask = 0x0Fu, // BIND_IMMEDIATE_MASK
|
||||
BindOpcodeDone = 0x00u, // BIND_OPCODE_DONE
|
||||
BindOpcodeSetDylibOrdinalImmediate = 0x10u, // BIND_OPCODE_SET_DYLIB_ORDINAL_IMM
|
||||
BindOpcodeSetDylibOrdinalULEB = 0x20u, // BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB
|
||||
BindOpcodeSetDylibSpecialImmediate = 0x30u, // BIND_OPCODE_SET_DYLIB_SPECIAL_IMM
|
||||
BindOpcodeSetSymbolTrailingFlagsImmediate = 0x40u, // BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM
|
||||
BindOpcodeSetTypeImmediate = 0x50u, // BIND_OPCODE_SET_TYPE_IMM
|
||||
BindOpcodeSetAppendSLEB = 0x60u, // BIND_OPCODE_SET_ADDEND_SLEB
|
||||
BindOpcodeSetSegmentAndOffsetULEB = 0x70u, // BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB
|
||||
BindOpcodeAddAddressULEB = 0x80u, // BIND_OPCODE_ADD_ADDR_ULEB
|
||||
BindOpcodeDoBind = 0x90u, // BIND_OPCODE_DO_BIND
|
||||
BindOpcodeDoBindAddAddressULEB = 0xA0u, // BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB
|
||||
BindOpcodeDoBindAddAddressImmediateScaled = 0xB0u, // BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED
|
||||
BindOpcodeDoBindULEBTimesSkippingULEB = 0xC0u, // BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB
|
||||
|
||||
ExportSymbolFlagsKindMask = 0x03u, // EXPORT_SYMBOL_FLAGS_KIND_MASK
|
||||
ExportSymbolFlagsKindRegular = 0x00u, // EXPORT_SYMBOL_FLAGS_KIND_REGULAR
|
||||
ExportSymbolFlagsKindThreadLocal = 0x01u, // EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL
|
||||
ExportSymbolFlagsWeakDefinition = 0x04u, // EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION
|
||||
ExportSymbolFlagsIndirectDefinition = 0x08u, // EXPORT_SYMBOL_FLAGS_INDIRECT_DEFINITION
|
||||
ExportSymbolFlagsHasSpecializations = 0x10u, // EXPORT_SYMBOL_FLAGS_HAS_SPECIALIZATIONS
|
||||
|
||||
|
||||
// Constant masks for the "n_type" field in llvm::MachO::nlist and
|
||||
// llvm::MachO::nlist_64
|
||||
NlistMaskStab = 0xe0, // N_STAB
|
||||
NlistMaskPrivateExternal = 0x10, // N_PEXT
|
||||
NlistMaskType = 0x0e, // N_TYPE
|
||||
NlistMaskExternal = 0x01, // N_EXT
|
||||
|
||||
// Constants for the "n_type & N_TYPE" llvm::MachO::nlist and
|
||||
// llvm::MachO::nlist_64
|
||||
NListTypeUndefined = 0x0u, // N_UNDF
|
||||
NListTypeAbsolute = 0x2u, // N_ABS
|
||||
NListTypeSection = 0xeu, // N_SECT
|
||||
NListTypePreboundUndefined = 0xcu, // N_PBUD
|
||||
NListTypeIndirect = 0xau, // N_INDR
|
||||
|
||||
// Constant masks for the "n_sect" field in llvm::MachO::nlist and
|
||||
// llvm::MachO::nlist_64
|
||||
NListSectionNoSection = 0u, // NO_SECT
|
||||
NListSectionMaxSection = 0xffu, // MAX_SECT
|
||||
|
||||
NListDescWeakRef = 0x40u,
|
||||
NListDescWeakDef = 0x80u,
|
||||
|
||||
// Constant values for the "n_type" field in llvm::MachO::nlist and
|
||||
// llvm::MachO::nlist_64 when "(n_type & NlistMaskStab) != 0"
|
||||
StabGlobalSymbol = 0x20u, // N_GSYM
|
||||
StabFunctionName = 0x22u, // N_FNAME
|
||||
StabFunction = 0x24u, // N_FUN
|
||||
StabStaticSymbol = 0x26u, // N_STSYM
|
||||
StabLocalCommon = 0x28u, // N_LCSYM
|
||||
StabBeginSymbol = 0x2Eu, // N_BNSYM
|
||||
StabSourceFileOptions = 0x3Cu, // N_OPT
|
||||
StabRegisterSymbol = 0x40u, // N_RSYM
|
||||
StabSourceLine = 0x44u, // N_SLINE
|
||||
StabEndSymbol = 0x4Eu, // N_ENSYM
|
||||
StabStructureType = 0x60u, // N_SSYM
|
||||
StabSourceFileName = 0x64u, // N_SO
|
||||
StabObjectFileName = 0x66u, // N_OSO
|
||||
StabLocalSymbol = 0x80u, // N_LSYM
|
||||
StabBeginIncludeFileName = 0x82u, // N_BINCL
|
||||
StabIncludeFileName = 0x84u, // N_SOL
|
||||
StabCompilerParameters = 0x86u, // N_PARAMS
|
||||
StabCompilerVersion = 0x88u, // N_VERSION
|
||||
StabCompilerOptLevel = 0x8Au, // N_OLEVEL
|
||||
StabParameter = 0xA0u, // N_PSYM
|
||||
StabEndIncludeFile = 0xA2u, // N_EINCL
|
||||
StabAlternateEntry = 0xA4u, // N_ENTRY
|
||||
StabLeftBracket = 0xC0u, // N_LBRAC
|
||||
StabDeletedIncludeFile = 0xC2u, // N_EXCL
|
||||
StabRightBracket = 0xE0u, // N_RBRAC
|
||||
StabBeginCommon = 0xE2u, // N_BCOMM
|
||||
StabEndCommon = 0xE4u, // N_ECOMM
|
||||
StabEndCommonLocal = 0xE8u, // N_ECOML
|
||||
StabLength = 0xFEu // N_LENG
|
||||
|
||||
};
|
||||
|
||||
// Structs from <mach-o/loader.h>
|
||||
|
||||
struct mach_header {
|
||||
uint32_t magic;
|
||||
uint32_t cputype;
|
||||
uint32_t cpusubtype;
|
||||
uint32_t filetype;
|
||||
uint32_t ncmds;
|
||||
uint32_t sizeofcmds;
|
||||
uint32_t flags;
|
||||
};
|
||||
|
||||
struct mach_header_64 {
|
||||
uint32_t magic;
|
||||
uint32_t cputype;
|
||||
uint32_t cpusubtype;
|
||||
uint32_t filetype;
|
||||
uint32_t ncmds;
|
||||
uint32_t sizeofcmds;
|
||||
uint32_t flags;
|
||||
uint32_t reserved;
|
||||
};
|
||||
|
||||
struct load_command {
|
||||
uint32_t cmd;
|
||||
uint32_t cmdsize;
|
||||
};
|
||||
|
||||
struct segment_command {
|
||||
uint32_t cmd;
|
||||
uint32_t cmdsize;
|
||||
char segname[16];
|
||||
uint32_t vmaddr;
|
||||
uint32_t vmsize;
|
||||
uint32_t fileoff;
|
||||
uint32_t filesize;
|
||||
uint32_t maxprot;
|
||||
uint32_t initprot;
|
||||
uint32_t nsects;
|
||||
uint32_t flags;
|
||||
};
|
||||
|
||||
struct segment_command_64 {
|
||||
uint32_t cmd;
|
||||
uint32_t cmdsize;
|
||||
char segname[16];
|
||||
uint64_t vmaddr;
|
||||
uint64_t vmsize;
|
||||
uint64_t fileoff;
|
||||
uint64_t filesize;
|
||||
uint32_t maxprot;
|
||||
uint32_t initprot;
|
||||
uint32_t nsects;
|
||||
uint32_t flags;
|
||||
};
|
||||
|
||||
struct section {
|
||||
char sectname[16];
|
||||
char segname[16];
|
||||
uint32_t addr;
|
||||
uint32_t size;
|
||||
uint32_t offset;
|
||||
uint32_t align;
|
||||
uint32_t reloff;
|
||||
uint32_t nreloc;
|
||||
uint32_t flags;
|
||||
uint32_t reserved1;
|
||||
uint32_t reserved2;
|
||||
};
|
||||
|
||||
struct section_64 {
|
||||
char sectname[16];
|
||||
char segname[16];
|
||||
uint64_t addr;
|
||||
uint64_t size;
|
||||
uint32_t offset;
|
||||
uint32_t align;
|
||||
uint32_t reloff;
|
||||
uint32_t nreloc;
|
||||
uint32_t flags;
|
||||
uint32_t reserved1;
|
||||
uint32_t reserved2;
|
||||
uint32_t reserved3;
|
||||
};
|
||||
|
||||
struct fvmlib {
|
||||
uint32_t name;
|
||||
uint32_t minor_version;
|
||||
uint32_t header_addr;
|
||||
};
|
||||
|
||||
struct fvmlib_command {
|
||||
uint32_t cmd;
|
||||
uint32_t cmdsize;
|
||||
struct fvmlib fvmlib;
|
||||
};
|
||||
|
||||
struct dylib {
|
||||
uint32_t name;
|
||||
uint32_t timestamp;
|
||||
uint32_t current_version;
|
||||
uint32_t compatibility_version;
|
||||
};
|
||||
|
||||
struct dylib_command {
|
||||
uint32_t cmd;
|
||||
uint32_t cmdsize;
|
||||
struct dylib dylib;
|
||||
};
|
||||
|
||||
struct sub_framework_command {
|
||||
uint32_t cmd;
|
||||
uint32_t cmdsize;
|
||||
uint32_t umbrella;
|
||||
};
|
||||
|
||||
struct sub_client_command {
|
||||
uint32_t cmd;
|
||||
uint32_t cmdsize;
|
||||
uint32_t client;
|
||||
};
|
||||
|
||||
struct sub_umbrella_command {
|
||||
uint32_t cmd;
|
||||
uint32_t cmdsize;
|
||||
uint32_t sub_umbrella;
|
||||
};
|
||||
|
||||
struct sub_library_command {
|
||||
uint32_t cmd;
|
||||
uint32_t cmdsize;
|
||||
uint32_t sub_library;
|
||||
};
|
||||
|
||||
struct prebound_dylib_command {
|
||||
uint32_t cmd;
|
||||
uint32_t cmdsize;
|
||||
uint32_t name;
|
||||
uint32_t nmodules;
|
||||
uint32_t linked_modules;
|
||||
};
|
||||
|
||||
struct dylinker_command {
|
||||
uint32_t cmd;
|
||||
uint32_t cmdsize;
|
||||
uint32_t name;
|
||||
};
|
||||
|
||||
struct thread_command {
|
||||
uint32_t cmd;
|
||||
uint32_t cmdsize;
|
||||
};
|
||||
|
||||
struct routines_command {
|
||||
uint32_t cmd;
|
||||
uint32_t cmdsize;
|
||||
uint32_t init_address;
|
||||
uint32_t init_module;
|
||||
uint32_t reserved1;
|
||||
uint32_t reserved2;
|
||||
uint32_t reserved3;
|
||||
uint32_t reserved4;
|
||||
uint32_t reserved5;
|
||||
uint32_t reserved6;
|
||||
};
|
||||
|
||||
struct routines_command_64 {
|
||||
uint32_t cmd;
|
||||
uint32_t cmdsize;
|
||||
uint64_t init_address;
|
||||
uint64_t init_module;
|
||||
uint64_t reserved1;
|
||||
uint64_t reserved2;
|
||||
uint64_t reserved3;
|
||||
uint64_t reserved4;
|
||||
uint64_t reserved5;
|
||||
uint64_t reserved6;
|
||||
};
|
||||
|
||||
struct symtab_command {
|
||||
uint32_t cmd;
|
||||
uint32_t cmdsize;
|
||||
uint32_t symoff;
|
||||
uint32_t nsyms;
|
||||
uint32_t stroff;
|
||||
uint32_t strsize;
|
||||
};
|
||||
|
||||
struct dysymtab_command {
|
||||
uint32_t cmd;
|
||||
uint32_t cmdsize;
|
||||
uint32_t ilocalsym;
|
||||
uint32_t nlocalsym;
|
||||
uint32_t iextdefsym;
|
||||
uint32_t nextdefsym;
|
||||
uint32_t iundefsym;
|
||||
uint32_t nundefsym;
|
||||
uint32_t tocoff;
|
||||
uint32_t ntoc;
|
||||
uint32_t modtaboff;
|
||||
uint32_t nmodtab;
|
||||
uint32_t extrefsymoff;
|
||||
uint32_t nextrefsyms;
|
||||
uint32_t indirectsymoff;
|
||||
uint32_t nindirectsyms;
|
||||
uint32_t extreloff;
|
||||
uint32_t nextrel;
|
||||
uint32_t locreloff;
|
||||
uint32_t nlocrel;
|
||||
};
|
||||
|
||||
struct dylib_table_of_contents {
|
||||
uint32_t symbol_index;
|
||||
uint32_t module_index;
|
||||
};
|
||||
|
||||
struct dylib_module {
|
||||
uint32_t module_name;
|
||||
uint32_t iextdefsym;
|
||||
uint32_t nextdefsym;
|
||||
uint32_t irefsym;
|
||||
uint32_t nrefsym;
|
||||
uint32_t ilocalsym;
|
||||
uint32_t nlocalsym;
|
||||
uint32_t iextrel;
|
||||
uint32_t nextrel;
|
||||
uint32_t iinit_iterm;
|
||||
uint32_t ninit_nterm;
|
||||
uint32_t objc_module_info_addr;
|
||||
uint32_t objc_module_info_size;
|
||||
};
|
||||
|
||||
struct dylib_module_64 {
|
||||
uint32_t module_name;
|
||||
uint32_t iextdefsym;
|
||||
uint32_t nextdefsym;
|
||||
uint32_t irefsym;
|
||||
uint32_t nrefsym;
|
||||
uint32_t ilocalsym;
|
||||
uint32_t nlocalsym;
|
||||
uint32_t iextrel;
|
||||
uint32_t nextrel;
|
||||
uint32_t iinit_iterm;
|
||||
uint32_t ninit_nterm;
|
||||
uint32_t objc_module_info_size;
|
||||
uint64_t objc_module_info_addr;
|
||||
};
|
||||
|
||||
struct dylib_reference {
|
||||
uint32_t isym:24,
|
||||
flags:8;
|
||||
};
|
||||
|
||||
|
||||
struct twolevel_hints_command {
|
||||
uint32_t cmd;
|
||||
uint32_t cmdsize;
|
||||
uint32_t offset;
|
||||
uint32_t nhints;
|
||||
};
|
||||
|
||||
struct twolevel_hint {
|
||||
uint32_t isub_image:8,
|
||||
itoc:24;
|
||||
};
|
||||
|
||||
struct prebind_cksum_command {
|
||||
uint32_t cmd;
|
||||
uint32_t cmdsize;
|
||||
uint32_t cksum;
|
||||
};
|
||||
|
||||
struct uuid_command {
|
||||
uint32_t cmd;
|
||||
uint32_t cmdsize;
|
||||
uint8_t uuid[16];
|
||||
};
|
||||
|
||||
struct rpath_command {
|
||||
uint32_t cmd;
|
||||
uint32_t cmdsize;
|
||||
uint32_t path;
|
||||
};
|
||||
|
||||
struct linkedit_data_command {
|
||||
uint32_t cmd;
|
||||
uint32_t cmdsize;
|
||||
uint32_t dataoff;
|
||||
uint32_t datasize;
|
||||
};
|
||||
|
||||
struct encryption_info_command {
|
||||
uint32_t cmd;
|
||||
uint32_t cmdsize;
|
||||
uint32_t cryptoff;
|
||||
uint32_t cryptsize;
|
||||
uint32_t cryptid;
|
||||
};
|
||||
|
||||
struct version_min_command {
|
||||
uint32_t cmd;
|
||||
uint32_t cmdsize;
|
||||
uint32_t version;
|
||||
uint32_t reserved;
|
||||
};
|
||||
|
||||
struct dyld_info_command {
|
||||
uint32_t cmd;
|
||||
uint32_t cmdsize;
|
||||
uint32_t rebase_off;
|
||||
uint32_t rebase_size;
|
||||
uint32_t bind_off;
|
||||
uint32_t bind_size;
|
||||
uint32_t weak_bind_off;
|
||||
uint32_t weak_bind_size;
|
||||
uint32_t lazy_bind_off;
|
||||
uint32_t lazy_bind_size;
|
||||
uint32_t export_off;
|
||||
uint32_t export_size;
|
||||
};
|
||||
|
||||
struct symseg_command {
|
||||
uint32_t cmd;
|
||||
uint32_t cmdsize;
|
||||
uint32_t offset;
|
||||
uint32_t size;
|
||||
};
|
||||
|
||||
struct ident_command {
|
||||
uint32_t cmd;
|
||||
uint32_t cmdsize;
|
||||
};
|
||||
|
||||
struct fvmfile_command {
|
||||
uint32_t cmd;
|
||||
uint32_t cmdsize;
|
||||
uint32_t name;
|
||||
uint32_t header_addr;
|
||||
};
|
||||
|
||||
|
||||
// Structs from <mach-o/fat.h>
|
||||
struct fat_header {
|
||||
uint32_t magic;
|
||||
uint32_t nfat_arch;
|
||||
};
|
||||
|
||||
struct fat_arch {
|
||||
uint32_t cputype;
|
||||
uint32_t cpusubtype;
|
||||
uint32_t offset;
|
||||
uint32_t size;
|
||||
uint32_t align;
|
||||
};
|
||||
|
||||
// Structs from <mach-o/fat.h>
|
||||
struct nlist {
|
||||
uint32_t n_strx;
|
||||
uint8_t n_type;
|
||||
uint8_t n_sect;
|
||||
int16_t n_desc;
|
||||
uint32_t n_value;
|
||||
};
|
||||
|
||||
struct nlist_64 {
|
||||
uint32_t n_strx;
|
||||
uint8_t n_type;
|
||||
uint8_t n_sect;
|
||||
uint16_t n_desc;
|
||||
uint64_t n_value;
|
||||
};
|
||||
|
||||
// Get/Set functions from <mach-o/nlist.h>
|
||||
|
||||
static inline uint16_t GET_LIBRARY_ORDINAL(uint16_t n_desc)
|
||||
{
|
||||
return (((n_desc) >> 8u) & 0xffu);
|
||||
}
|
||||
|
||||
static inline void SET_LIBRARY_ORDINAL(uint16_t &n_desc, uint8_t ordinal)
|
||||
{
|
||||
n_desc = (((n_desc) & 0x00ff) | (((ordinal) & 0xff) << 8));
|
||||
}
|
||||
|
||||
static inline uint8_t GET_COMM_ALIGN (uint16_t n_desc)
|
||||
{
|
||||
return (n_desc >> 8u) & 0x0fu;
|
||||
}
|
||||
|
||||
static inline void SET_COMM_ALIGN (uint16_t &n_desc, uint8_t align)
|
||||
{
|
||||
n_desc = ((n_desc & 0xf0ffu) | ((align & 0x0fu) << 8u));
|
||||
}
|
||||
|
||||
// Enums from <mach/machine.h>
|
||||
enum {
|
||||
// Capability bits used in the definition of cpu_type.
|
||||
CPUArchMask = 0xff000000, // Mask for architecture bits
|
||||
CPUArchABI64 = 0x01000000, // 64 bit ABI
|
||||
|
||||
// Constants for the cputype field.
|
||||
CPUTypeI386 = 7,
|
||||
CPUTypeX86_64 = CPUTypeI386 | CPUArchABI64,
|
||||
CPUTypeARM = 12,
|
||||
CPUTypeSPARC = 14,
|
||||
CPUTypePowerPC = 18,
|
||||
CPUTypePowerPC64 = CPUTypePowerPC | CPUArchABI64,
|
||||
|
||||
|
||||
// Constants for the cpusubtype field.
|
||||
|
||||
// X86
|
||||
CPUSubType_I386_ALL = 3,
|
||||
CPUSubType_X86_64_ALL = 3,
|
||||
|
||||
// ARM
|
||||
CPUSubType_ARM_ALL = 0,
|
||||
CPUSubType_ARM_V4T = 5,
|
||||
CPUSubType_ARM_V5 = 7,
|
||||
CPUSubType_ARM_V6 = 6,
|
||||
CPUSubType_ARM_V7 = 9,
|
||||
|
||||
// PowerPC
|
||||
CPUSubType_POWERPC_ALL = 0,
|
||||
|
||||
CPUSubType_SPARC_ALL = 0
|
||||
};
|
||||
} // end namespace MachO
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
115
thirdparty/clang/include/llvm/Support/ManagedStatic.h
vendored
Normal file
115
thirdparty/clang/include/llvm/Support/ManagedStatic.h
vendored
Normal file
@@ -0,0 +1,115 @@
|
||||
//===-- llvm/Support/ManagedStatic.h - Static Global wrapper ----*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the ManagedStatic class and the llvm_shutdown() function.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_MANAGED_STATIC_H
|
||||
#define LLVM_SUPPORT_MANAGED_STATIC_H
|
||||
|
||||
#include "llvm/Support/Atomic.h"
|
||||
#include "llvm/Support/Threading.h"
|
||||
#include "llvm/Support/Valgrind.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
/// object_creator - Helper method for ManagedStatic.
|
||||
template<class C>
|
||||
void* object_creator() {
|
||||
return new C();
|
||||
}
|
||||
|
||||
/// object_deleter - Helper method for ManagedStatic.
|
||||
///
|
||||
template<typename T> struct object_deleter {
|
||||
static void call(void * Ptr) { delete (T*)Ptr; }
|
||||
};
|
||||
template<typename T, size_t N> struct object_deleter<T[N]> {
|
||||
static void call(void * Ptr) { delete[] (T*)Ptr; }
|
||||
};
|
||||
|
||||
/// ManagedStaticBase - Common base class for ManagedStatic instances.
|
||||
class ManagedStaticBase {
|
||||
protected:
|
||||
// This should only be used as a static variable, which guarantees that this
|
||||
// will be zero initialized.
|
||||
mutable void *Ptr;
|
||||
mutable void (*DeleterFn)(void*);
|
||||
mutable const ManagedStaticBase *Next;
|
||||
|
||||
void RegisterManagedStatic(void *(*creator)(), void (*deleter)(void*)) const;
|
||||
public:
|
||||
/// isConstructed - Return true if this object has not been created yet.
|
||||
bool isConstructed() const { return Ptr != 0; }
|
||||
|
||||
void destroy() const;
|
||||
};
|
||||
|
||||
/// ManagedStatic - This transparently changes the behavior of global statics to
|
||||
/// be lazily constructed on demand (good for reducing startup times of dynamic
|
||||
/// libraries that link in LLVM components) and for making destruction be
|
||||
/// explicit through the llvm_shutdown() function call.
|
||||
///
|
||||
template<class C>
|
||||
class ManagedStatic : public ManagedStaticBase {
|
||||
public:
|
||||
|
||||
// Accessors.
|
||||
C &operator*() {
|
||||
void* tmp = Ptr;
|
||||
if (llvm_is_multithreaded()) sys::MemoryFence();
|
||||
if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
|
||||
TsanHappensAfter(this);
|
||||
|
||||
return *static_cast<C*>(Ptr);
|
||||
}
|
||||
C *operator->() {
|
||||
void* tmp = Ptr;
|
||||
if (llvm_is_multithreaded()) sys::MemoryFence();
|
||||
if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
|
||||
TsanHappensAfter(this);
|
||||
|
||||
return static_cast<C*>(Ptr);
|
||||
}
|
||||
const C &operator*() const {
|
||||
void* tmp = Ptr;
|
||||
if (llvm_is_multithreaded()) sys::MemoryFence();
|
||||
if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
|
||||
TsanHappensAfter(this);
|
||||
|
||||
return *static_cast<C*>(Ptr);
|
||||
}
|
||||
const C *operator->() const {
|
||||
void* tmp = Ptr;
|
||||
if (llvm_is_multithreaded()) sys::MemoryFence();
|
||||
if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
|
||||
TsanHappensAfter(this);
|
||||
|
||||
return static_cast<C*>(Ptr);
|
||||
}
|
||||
};
|
||||
|
||||
/// llvm_shutdown - Deallocate and destroy all ManagedStatic variables.
|
||||
void llvm_shutdown();
|
||||
|
||||
|
||||
/// llvm_shutdown_obj - This is a simple helper class that calls
|
||||
/// llvm_shutdown() when it is destroyed.
|
||||
struct llvm_shutdown_obj {
|
||||
llvm_shutdown_obj() { }
|
||||
explicit llvm_shutdown_obj(bool multithreaded) {
|
||||
if (multithreaded) llvm_start_multithreaded();
|
||||
}
|
||||
~llvm_shutdown_obj() { llvm_shutdown(); }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
501
thirdparty/clang/include/llvm/Support/MathExtras.h
vendored
Normal file
501
thirdparty/clang/include/llvm/Support/MathExtras.h
vendored
Normal file
@@ -0,0 +1,501 @@
|
||||
//===-- llvm/Support/MathExtras.h - Useful math functions -------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file contains some functions that are useful for math stuff.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_MATHEXTRAS_H
|
||||
#define LLVM_SUPPORT_MATHEXTRAS_H
|
||||
|
||||
#include "llvm/Support/SwapByteOrder.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# include <intrin.h>
|
||||
#endif
|
||||
|
||||
namespace llvm {
|
||||
|
||||
// NOTE: The following support functions use the _32/_64 extensions instead of
|
||||
// type overloading so that signed and unsigned integers can be used without
|
||||
// ambiguity.
|
||||
|
||||
/// Hi_32 - This function returns the high 32 bits of a 64 bit value.
|
||||
inline uint32_t Hi_32(uint64_t Value) {
|
||||
return static_cast<uint32_t>(Value >> 32);
|
||||
}
|
||||
|
||||
/// Lo_32 - This function returns the low 32 bits of a 64 bit value.
|
||||
inline uint32_t Lo_32(uint64_t Value) {
|
||||
return static_cast<uint32_t>(Value);
|
||||
}
|
||||
|
||||
/// isInt - Checks if an integer fits into the given bit width.
|
||||
template<unsigned N>
|
||||
inline bool isInt(int64_t x) {
|
||||
return N >= 64 || (-(INT64_C(1)<<(N-1)) <= x && x < (INT64_C(1)<<(N-1)));
|
||||
}
|
||||
// Template specializations to get better code for common cases.
|
||||
template<>
|
||||
inline bool isInt<8>(int64_t x) {
|
||||
return static_cast<int8_t>(x) == x;
|
||||
}
|
||||
template<>
|
||||
inline bool isInt<16>(int64_t x) {
|
||||
return static_cast<int16_t>(x) == x;
|
||||
}
|
||||
template<>
|
||||
inline bool isInt<32>(int64_t x) {
|
||||
return static_cast<int32_t>(x) == x;
|
||||
}
|
||||
|
||||
/// isShiftedInt<N,S> - Checks if a signed integer is an N bit number shifted
|
||||
/// left by S.
|
||||
template<unsigned N, unsigned S>
|
||||
inline bool isShiftedInt(int64_t x) {
|
||||
return isInt<N+S>(x) && (x % (1<<S) == 0);
|
||||
}
|
||||
|
||||
/// isUInt - Checks if an unsigned integer fits into the given bit width.
|
||||
template<unsigned N>
|
||||
inline bool isUInt(uint64_t x) {
|
||||
return N >= 64 || x < (UINT64_C(1)<<(N));
|
||||
}
|
||||
// Template specializations to get better code for common cases.
|
||||
template<>
|
||||
inline bool isUInt<8>(uint64_t x) {
|
||||
return static_cast<uint8_t>(x) == x;
|
||||
}
|
||||
template<>
|
||||
inline bool isUInt<16>(uint64_t x) {
|
||||
return static_cast<uint16_t>(x) == x;
|
||||
}
|
||||
template<>
|
||||
inline bool isUInt<32>(uint64_t x) {
|
||||
return static_cast<uint32_t>(x) == x;
|
||||
}
|
||||
|
||||
/// isShiftedUInt<N,S> - Checks if a unsigned integer is an N bit number shifted
|
||||
/// left by S.
|
||||
template<unsigned N, unsigned S>
|
||||
inline bool isShiftedUInt(uint64_t x) {
|
||||
return isUInt<N+S>(x) && (x % (1<<S) == 0);
|
||||
}
|
||||
|
||||
/// isUIntN - Checks if an unsigned integer fits into the given (dynamic)
|
||||
/// bit width.
|
||||
inline bool isUIntN(unsigned N, uint64_t x) {
|
||||
return x == (x & (~0ULL >> (64 - N)));
|
||||
}
|
||||
|
||||
/// isIntN - Checks if an signed integer fits into the given (dynamic)
|
||||
/// bit width.
|
||||
inline bool isIntN(unsigned N, int64_t x) {
|
||||
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
|
||||
/// starting at the least significant bit with the remainder zero (32 bit
|
||||
/// version). Ex. isMask_32(0x0000FFFFU) == true.
|
||||
inline bool isMask_32(uint32_t Value) {
|
||||
return Value && ((Value + 1) & Value) == 0;
|
||||
}
|
||||
|
||||
/// isMask_64 - This function returns true if the argument is a sequence of ones
|
||||
/// starting at the least significant bit with the remainder zero (64 bit
|
||||
/// version).
|
||||
inline bool isMask_64(uint64_t Value) {
|
||||
return Value && ((Value + 1) & Value) == 0;
|
||||
}
|
||||
|
||||
/// isShiftedMask_32 - This function returns true if the argument contains a
|
||||
/// sequence of ones with the remainder zero (32 bit version.)
|
||||
/// Ex. isShiftedMask_32(0x0000FF00U) == true.
|
||||
inline bool isShiftedMask_32(uint32_t Value) {
|
||||
return isMask_32((Value - 1) | Value);
|
||||
}
|
||||
|
||||
/// isShiftedMask_64 - This function returns true if the argument contains a
|
||||
/// sequence of ones with the remainder zero (64 bit version.)
|
||||
inline bool isShiftedMask_64(uint64_t Value) {
|
||||
return isMask_64((Value - 1) | Value);
|
||||
}
|
||||
|
||||
/// isPowerOf2_32 - This function returns true if the argument is a power of
|
||||
/// two > 0. Ex. isPowerOf2_32(0x00100000U) == true (32 bit edition.)
|
||||
inline bool isPowerOf2_32(uint32_t Value) {
|
||||
return Value && !(Value & (Value - 1));
|
||||
}
|
||||
|
||||
/// isPowerOf2_64 - This function returns true if the argument is a power of two
|
||||
/// > 0 (64 bit edition.)
|
||||
inline bool isPowerOf2_64(uint64_t Value) {
|
||||
return Value && !(Value & (Value - int64_t(1L)));
|
||||
}
|
||||
|
||||
/// ByteSwap_16 - This function returns a byte-swapped representation of the
|
||||
/// 16-bit argument, Value.
|
||||
inline uint16_t ByteSwap_16(uint16_t Value) {
|
||||
return sys::SwapByteOrder_16(Value);
|
||||
}
|
||||
|
||||
/// ByteSwap_32 - This function returns a byte-swapped representation of the
|
||||
/// 32-bit argument, Value.
|
||||
inline uint32_t ByteSwap_32(uint32_t Value) {
|
||||
return sys::SwapByteOrder_32(Value);
|
||||
}
|
||||
|
||||
/// ByteSwap_64 - This function returns a byte-swapped representation of the
|
||||
/// 64-bit argument, Value.
|
||||
inline uint64_t ByteSwap_64(uint64_t Value) {
|
||||
return sys::SwapByteOrder_64(Value);
|
||||
}
|
||||
|
||||
/// CountLeadingZeros_32 - this function performs the platform optimal form of
|
||||
/// counting the number of zeros from the most significant bit to the first one
|
||||
/// bit. Ex. CountLeadingZeros_32(0x00F000FF) == 8.
|
||||
/// Returns 32 if the word is zero.
|
||||
inline unsigned CountLeadingZeros_32(uint32_t Value) {
|
||||
unsigned Count; // result
|
||||
#if __GNUC__ >= 4
|
||||
// PowerPC is defined for __builtin_clz(0)
|
||||
#if !defined(__ppc__) && !defined(__ppc64__)
|
||||
if (!Value) return 32;
|
||||
#endif
|
||||
Count = __builtin_clz(Value);
|
||||
#else
|
||||
if (!Value) return 32;
|
||||
Count = 0;
|
||||
// bisection method for count leading zeros
|
||||
for (unsigned Shift = 32 >> 1; Shift; Shift >>= 1) {
|
||||
uint32_t Tmp = Value >> Shift;
|
||||
if (Tmp) {
|
||||
Value = Tmp;
|
||||
} else {
|
||||
Count |= Shift;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return Count;
|
||||
}
|
||||
|
||||
/// CountLeadingOnes_32 - this function performs the operation of
|
||||
/// counting the number of ones from the most significant bit to the first zero
|
||||
/// bit. Ex. CountLeadingOnes_32(0xFF0FFF00) == 8.
|
||||
/// Returns 32 if the word is all ones.
|
||||
inline unsigned CountLeadingOnes_32(uint32_t Value) {
|
||||
return CountLeadingZeros_32(~Value);
|
||||
}
|
||||
|
||||
/// CountLeadingZeros_64 - This function performs the platform optimal form
|
||||
/// of counting the number of zeros from the most significant bit to the first
|
||||
/// one bit (64 bit edition.)
|
||||
/// Returns 64 if the word is zero.
|
||||
inline unsigned CountLeadingZeros_64(uint64_t Value) {
|
||||
unsigned Count; // result
|
||||
#if __GNUC__ >= 4
|
||||
// PowerPC is defined for __builtin_clzll(0)
|
||||
#if !defined(__ppc__) && !defined(__ppc64__)
|
||||
if (!Value) return 64;
|
||||
#endif
|
||||
Count = __builtin_clzll(Value);
|
||||
#else
|
||||
if (sizeof(long) == sizeof(int64_t)) {
|
||||
if (!Value) return 64;
|
||||
Count = 0;
|
||||
// bisection method for count leading zeros
|
||||
for (unsigned Shift = 64 >> 1; Shift; Shift >>= 1) {
|
||||
uint64_t Tmp = Value >> Shift;
|
||||
if (Tmp) {
|
||||
Value = Tmp;
|
||||
} else {
|
||||
Count |= Shift;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// get hi portion
|
||||
uint32_t Hi = Hi_32(Value);
|
||||
|
||||
// if some bits in hi portion
|
||||
if (Hi) {
|
||||
// leading zeros in hi portion plus all bits in lo portion
|
||||
Count = CountLeadingZeros_32(Hi);
|
||||
} else {
|
||||
// get lo portion
|
||||
uint32_t Lo = Lo_32(Value);
|
||||
// same as 32 bit value
|
||||
Count = CountLeadingZeros_32(Lo)+32;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return Count;
|
||||
}
|
||||
|
||||
/// CountLeadingOnes_64 - This function performs the operation
|
||||
/// of counting the number of ones from the most significant bit to the first
|
||||
/// zero bit (64 bit edition.)
|
||||
/// Returns 64 if the word is all ones.
|
||||
inline unsigned CountLeadingOnes_64(uint64_t Value) {
|
||||
return CountLeadingZeros_64(~Value);
|
||||
}
|
||||
|
||||
/// CountTrailingZeros_32 - this function performs the platform optimal form of
|
||||
/// counting the number of zeros from the least significant bit to the first one
|
||||
/// bit. Ex. CountTrailingZeros_32(0xFF00FF00) == 8.
|
||||
/// Returns 32 if the word is zero.
|
||||
inline unsigned CountTrailingZeros_32(uint32_t Value) {
|
||||
#if __GNUC__ >= 4
|
||||
return Value ? __builtin_ctz(Value) : 32;
|
||||
#else
|
||||
static const unsigned Mod37BitPosition[] = {
|
||||
32, 0, 1, 26, 2, 23, 27, 0, 3, 16, 24, 30, 28, 11, 0, 13,
|
||||
4, 7, 17, 0, 25, 22, 31, 15, 29, 10, 12, 6, 0, 21, 14, 9,
|
||||
5, 20, 8, 19, 18
|
||||
};
|
||||
// Replace "-Value" by "1+~Value" in the following commented code to avoid
|
||||
// MSVC warning C4146
|
||||
// return Mod37BitPosition[(-Value & Value) % 37];
|
||||
return Mod37BitPosition[((1 + ~Value) & Value) % 37];
|
||||
#endif
|
||||
}
|
||||
|
||||
/// CountTrailingOnes_32 - this function performs the operation of
|
||||
/// counting the number of ones from the least significant bit to the first zero
|
||||
/// bit. Ex. CountTrailingOnes_32(0x00FF00FF) == 8.
|
||||
/// Returns 32 if the word is all ones.
|
||||
inline unsigned CountTrailingOnes_32(uint32_t Value) {
|
||||
return CountTrailingZeros_32(~Value);
|
||||
}
|
||||
|
||||
/// CountTrailingZeros_64 - This function performs the platform optimal form
|
||||
/// of counting the number of zeros from the least significant bit to the first
|
||||
/// one bit (64 bit edition.)
|
||||
/// Returns 64 if the word is zero.
|
||||
inline unsigned CountTrailingZeros_64(uint64_t Value) {
|
||||
#if __GNUC__ >= 4
|
||||
return Value ? __builtin_ctzll(Value) : 64;
|
||||
#else
|
||||
static const unsigned Mod67Position[] = {
|
||||
64, 0, 1, 39, 2, 15, 40, 23, 3, 12, 16, 59, 41, 19, 24, 54,
|
||||
4, 64, 13, 10, 17, 62, 60, 28, 42, 30, 20, 51, 25, 44, 55,
|
||||
47, 5, 32, 65, 38, 14, 22, 11, 58, 18, 53, 63, 9, 61, 27,
|
||||
29, 50, 43, 46, 31, 37, 21, 57, 52, 8, 26, 49, 45, 36, 56,
|
||||
7, 48, 35, 6, 34, 33, 0
|
||||
};
|
||||
// Replace "-Value" by "1+~Value" in the following commented code to avoid
|
||||
// MSVC warning C4146
|
||||
// return Mod67Position[(-Value & Value) % 67];
|
||||
return Mod67Position[((1 + ~Value) & Value) % 67];
|
||||
#endif
|
||||
}
|
||||
|
||||
/// 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_64(~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
|
||||
return __builtin_popcount(Value);
|
||||
#else
|
||||
uint32_t v = Value - ((Value >> 1) & 0x55555555);
|
||||
v = (v & 0x33333333) + ((v >> 2) & 0x33333333);
|
||||
return ((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// CountPopulation_64 - this function counts the number of set bits in a value,
|
||||
/// (64 bit edition.)
|
||||
inline unsigned CountPopulation_64(uint64_t Value) {
|
||||
#if __GNUC__ >= 4
|
||||
return __builtin_popcountll(Value);
|
||||
#else
|
||||
uint64_t v = Value - ((Value >> 1) & 0x5555555555555555ULL);
|
||||
v = (v & 0x3333333333333333ULL) + ((v >> 2) & 0x3333333333333333ULL);
|
||||
v = (v + (v >> 4)) & 0x0F0F0F0F0F0F0F0FULL;
|
||||
return unsigned((uint64_t)(v * 0x0101010101010101ULL) >> 56);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Log2_32 - This function returns the floor log base 2 of the specified value,
|
||||
/// -1 if the value is zero. (32 bit edition.)
|
||||
/// Ex. Log2_32(32) == 5, Log2_32(1) == 0, Log2_32(0) == -1, Log2_32(6) == 2
|
||||
inline unsigned Log2_32(uint32_t Value) {
|
||||
return 31 - CountLeadingZeros_32(Value);
|
||||
}
|
||||
|
||||
/// Log2_64 - This function returns the floor log base 2 of the specified value,
|
||||
/// -1 if the value is zero. (64 bit edition.)
|
||||
inline unsigned Log2_64(uint64_t Value) {
|
||||
return 63 - CountLeadingZeros_64(Value);
|
||||
}
|
||||
|
||||
/// Log2_32_Ceil - This function returns the ceil log base 2 of the specified
|
||||
/// value, 32 if the value is zero. (32 bit edition).
|
||||
/// Ex. Log2_32_Ceil(32) == 5, Log2_32_Ceil(1) == 0, Log2_32_Ceil(6) == 3
|
||||
inline unsigned Log2_32_Ceil(uint32_t Value) {
|
||||
return 32-CountLeadingZeros_32(Value-1);
|
||||
}
|
||||
|
||||
/// Log2_64_Ceil - This function returns the ceil log base 2 of the specified
|
||||
/// value, 64 if the value is zero. (64 bit edition.)
|
||||
inline unsigned Log2_64_Ceil(uint64_t Value) {
|
||||
return 64-CountLeadingZeros_64(Value-1);
|
||||
}
|
||||
|
||||
/// GreatestCommonDivisor64 - Return the greatest common divisor of the two
|
||||
/// values using Euclid's algorithm.
|
||||
inline uint64_t GreatestCommonDivisor64(uint64_t A, uint64_t B) {
|
||||
while (B) {
|
||||
uint64_t T = B;
|
||||
B = A % B;
|
||||
A = T;
|
||||
}
|
||||
return A;
|
||||
}
|
||||
|
||||
/// BitsToDouble - This function takes a 64-bit integer and returns the bit
|
||||
/// equivalent double.
|
||||
inline double BitsToDouble(uint64_t Bits) {
|
||||
union {
|
||||
uint64_t L;
|
||||
double D;
|
||||
} T;
|
||||
T.L = Bits;
|
||||
return T.D;
|
||||
}
|
||||
|
||||
/// BitsToFloat - This function takes a 32-bit integer and returns the bit
|
||||
/// equivalent float.
|
||||
inline float BitsToFloat(uint32_t Bits) {
|
||||
union {
|
||||
uint32_t I;
|
||||
float F;
|
||||
} T;
|
||||
T.I = Bits;
|
||||
return T.F;
|
||||
}
|
||||
|
||||
/// DoubleToBits - This function takes a double and returns the bit
|
||||
/// equivalent 64-bit integer. Note that copying doubles around
|
||||
/// changes the bits of NaNs on some hosts, notably x86, so this
|
||||
/// routine cannot be used if these bits are needed.
|
||||
inline uint64_t DoubleToBits(double Double) {
|
||||
union {
|
||||
uint64_t L;
|
||||
double D;
|
||||
} T;
|
||||
T.D = Double;
|
||||
return T.L;
|
||||
}
|
||||
|
||||
/// FloatToBits - This function takes a float and returns the bit
|
||||
/// equivalent 32-bit integer. Note that copying floats around
|
||||
/// changes the bits of NaNs on some hosts, notably x86, so this
|
||||
/// routine cannot be used if these bits are needed.
|
||||
inline uint32_t FloatToBits(float Float) {
|
||||
union {
|
||||
uint32_t I;
|
||||
float F;
|
||||
} T;
|
||||
T.F = Float;
|
||||
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
|
||||
/// alignment that may be assumed after adding the two together.
|
||||
inline uint64_t MinAlign(uint64_t A, uint64_t B) {
|
||||
// The largest power of 2 that divides both A and B.
|
||||
//
|
||||
// Replace "-Value" by "1+~Value" in the following commented code to avoid
|
||||
// MSVC warning C4146
|
||||
// return (A | B) & -(A | B);
|
||||
return (A | B) & (1 + ~(A | B));
|
||||
}
|
||||
|
||||
/// NextPowerOf2 - Returns the next power of two (in 64-bits)
|
||||
/// that is strictly greater than A. Returns zero on overflow.
|
||||
inline uint64_t NextPowerOf2(uint64_t A) {
|
||||
A |= (A >> 1);
|
||||
A |= (A >> 2);
|
||||
A |= (A >> 4);
|
||||
A |= (A >> 8);
|
||||
A |= (A >> 16);
|
||||
A |= (A >> 32);
|
||||
return A + 1;
|
||||
}
|
||||
|
||||
/// 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.
|
||||
///
|
||||
/// Examples:
|
||||
/// \code
|
||||
/// RoundUpToAlignment(5, 8) = 8
|
||||
/// RoundUpToAlignment(17, 8) = 24
|
||||
/// RoundUpToAlignment(~0LL, 8) = 0
|
||||
/// \endcode
|
||||
inline uint64_t RoundUpToAlignment(uint64_t Value, uint64_t Align) {
|
||||
return ((Value + Align - 1) / Align) * Align;
|
||||
}
|
||||
|
||||
/// Returns the offset to 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.
|
||||
inline uint64_t OffsetToAlignment(uint64_t Value, uint64_t Align) {
|
||||
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.
|
||||
/// Usage int32_t r = SignExtend32<5>(x);
|
||||
template <unsigned B> inline int32_t SignExtend32(uint32_t x) {
|
||||
return int32_t(x << (32 - B)) >> (32 - B);
|
||||
}
|
||||
|
||||
/// \brief Sign extend number in the bottom B bits of X to a 32-bit int.
|
||||
/// Requires 0 < B <= 32.
|
||||
inline int32_t SignExtend32(uint32_t X, unsigned B) {
|
||||
return int32_t(X << (32 - B)) >> (32 - B);
|
||||
}
|
||||
|
||||
/// SignExtend64 - Sign extend B-bit number x to 64-bit int.
|
||||
/// Usage int64_t r = SignExtend64<5>(x);
|
||||
template <unsigned B> inline int64_t SignExtend64(uint64_t x) {
|
||||
return int64_t(x << (64 - B)) >> (64 - B);
|
||||
}
|
||||
|
||||
/// \brief Sign extend number in the bottom B bits of X to a 64-bit int.
|
||||
/// Requires 0 < B <= 64.
|
||||
inline int64_t SignExtend64(uint64_t X, unsigned B) {
|
||||
return int64_t(X << (64 - B)) >> (64 - B);
|
||||
}
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
||||
161
thirdparty/clang/include/llvm/Support/Memory.h
vendored
Normal file
161
thirdparty/clang/include/llvm/Support/Memory.h
vendored
Normal file
@@ -0,0 +1,161 @@
|
||||
//===- llvm/Support/Memory.h - Memory Support --------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file declares the llvm::sys::Memory class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_MEMORY_H
|
||||
#define LLVM_SUPPORT_MEMORY_H
|
||||
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/Support/system_error.h"
|
||||
#include <string>
|
||||
|
||||
namespace llvm {
|
||||
namespace sys {
|
||||
|
||||
/// This class encapsulates the notion of a memory block which has an address
|
||||
/// and a size. It is used by the Memory class (a friend) as the result of
|
||||
/// various memory allocation operations.
|
||||
/// @see Memory
|
||||
/// @brief Memory block abstraction.
|
||||
class MemoryBlock {
|
||||
public:
|
||||
MemoryBlock() : Address(0), Size(0) { }
|
||||
MemoryBlock(void *addr, size_t size) : Address(addr), Size(size) { }
|
||||
void *base() const { return Address; }
|
||||
size_t size() const { return Size; }
|
||||
private:
|
||||
void *Address; ///< Address of first byte of memory area
|
||||
size_t Size; ///< Size, in bytes of the memory area
|
||||
friend class Memory;
|
||||
};
|
||||
|
||||
/// This class provides various memory handling functions that manipulate
|
||||
/// MemoryBlock instances.
|
||||
/// @since 1.4
|
||||
/// @brief An abstraction for memory operations.
|
||||
class Memory {
|
||||
public:
|
||||
enum ProtectionFlags {
|
||||
MF_READ = 0x1000000,
|
||||
MF_WRITE = 0x2000000,
|
||||
MF_EXEC = 0x4000000
|
||||
};
|
||||
|
||||
/// This method allocates a block of memory that is suitable for loading
|
||||
/// dynamically generated code (e.g. JIT). An attempt to allocate
|
||||
/// \p NumBytes bytes of virtual memory is made.
|
||||
/// \p NearBlock may point to an existing allocation in which case
|
||||
/// an attempt is made to allocate more memory near the existing block.
|
||||
/// The actual allocated address is not guaranteed to be near the requested
|
||||
/// address.
|
||||
/// \p Flags is used to set the initial protection flags for the block
|
||||
/// of the memory.
|
||||
/// \p EC [out] returns an object describing any error that occurs.
|
||||
///
|
||||
/// This method may allocate more than the number of bytes requested. The
|
||||
/// actual number of bytes allocated is indicated in the returned
|
||||
/// MemoryBlock.
|
||||
///
|
||||
/// The start of the allocated block must be aligned with the
|
||||
/// system allocation granularity (64K on Windows, page size on Linux).
|
||||
/// If the address following \p NearBlock is not so aligned, it will be
|
||||
/// rounded up to the next allocation granularity boundary.
|
||||
///
|
||||
/// \r a non-null MemoryBlock if the function was successful,
|
||||
/// otherwise a null MemoryBlock is with \p EC describing the error.
|
||||
///
|
||||
/// @brief Allocate mapped memory.
|
||||
static MemoryBlock allocateMappedMemory(size_t NumBytes,
|
||||
const MemoryBlock *const NearBlock,
|
||||
unsigned Flags,
|
||||
error_code &EC);
|
||||
|
||||
/// This method releases a block of memory that was allocated with the
|
||||
/// allocateMappedMemory method. It should not be used to release any
|
||||
/// memory block allocated any other way.
|
||||
/// \p Block describes the memory to be released.
|
||||
///
|
||||
/// \r error_success if the function was successful, or an error_code
|
||||
/// describing the failure if an error occurred.
|
||||
///
|
||||
/// @brief Release mapped memory.
|
||||
static error_code releaseMappedMemory(MemoryBlock &Block);
|
||||
|
||||
/// This method sets the protection flags for a block of memory to the
|
||||
/// state specified by /p Flags. The behavior is not specified if the
|
||||
/// memory was not allocated using the allocateMappedMemory method.
|
||||
/// \p Block describes the memory block to be protected.
|
||||
/// \p Flags specifies the new protection state to be assigned to the block.
|
||||
/// \p ErrMsg [out] returns a string describing any error that occured.
|
||||
///
|
||||
/// If \p Flags is MF_WRITE, the actual behavior varies
|
||||
/// with the operating system (i.e. MF_READ | MF_WRITE on Windows) and the
|
||||
/// target architecture (i.e. MF_WRITE -> MF_READ | MF_WRITE on i386).
|
||||
///
|
||||
/// \r error_success if the function was successful, or an error_code
|
||||
/// describing the failure if an error occurred.
|
||||
///
|
||||
/// @brief Set memory protection state.
|
||||
static error_code protectMappedMemory(const MemoryBlock &Block,
|
||||
unsigned Flags);
|
||||
|
||||
/// This method allocates a block of Read/Write/Execute memory that is
|
||||
/// suitable for executing dynamically generated code (e.g. JIT). An
|
||||
/// attempt to allocate \p NumBytes bytes of virtual memory is made.
|
||||
/// \p NearBlock may point to an existing allocation in which case
|
||||
/// an attempt is made to allocate more memory near the existing block.
|
||||
///
|
||||
/// On success, this returns a non-null memory block, otherwise it returns
|
||||
/// a null memory block and fills in *ErrMsg.
|
||||
///
|
||||
/// @brief Allocate Read/Write/Execute memory.
|
||||
static MemoryBlock AllocateRWX(size_t NumBytes,
|
||||
const MemoryBlock *NearBlock,
|
||||
std::string *ErrMsg = 0);
|
||||
|
||||
/// This method releases a block of Read/Write/Execute memory that was
|
||||
/// allocated with the AllocateRWX method. It should not be used to
|
||||
/// release any memory block allocated any other way.
|
||||
///
|
||||
/// On success, this returns false, otherwise it returns true and fills
|
||||
/// in *ErrMsg.
|
||||
/// @brief Release Read/Write/Execute memory.
|
||||
static bool ReleaseRWX(MemoryBlock &block, std::string *ErrMsg = 0);
|
||||
|
||||
|
||||
/// InvalidateInstructionCache - Before the JIT can run a block of code
|
||||
/// that has been emitted it must invalidate the instruction cache on some
|
||||
/// platforms.
|
||||
static void InvalidateInstructionCache(const void *Addr, size_t Len);
|
||||
|
||||
/// setExecutable - Before the JIT can run a block of code, it has to be
|
||||
/// given read and executable privilege. Return true if it is already r-x
|
||||
/// or the system is able to change its previlege.
|
||||
static bool setExecutable(MemoryBlock &M, std::string *ErrMsg = 0);
|
||||
|
||||
/// setWritable - When adding to a block of code, the JIT may need
|
||||
/// to mark a block of code as RW since the protections are on page
|
||||
/// boundaries, and the JIT internal allocations are not page aligned.
|
||||
static bool setWritable(MemoryBlock &M, std::string *ErrMsg = 0);
|
||||
|
||||
/// setRangeExecutable - Mark the page containing a range of addresses
|
||||
/// as executable.
|
||||
static bool setRangeExecutable(const void *Addr, size_t Size);
|
||||
|
||||
/// setRangeWritable - Mark the page containing a range of addresses
|
||||
/// as writable.
|
||||
static bool setRangeWritable(const void *Addr, size_t Size);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
142
thirdparty/clang/include/llvm/Support/MemoryBuffer.h
vendored
Normal file
142
thirdparty/clang/include/llvm/Support/MemoryBuffer.h
vendored
Normal file
@@ -0,0 +1,142 @@
|
||||
//===--- MemoryBuffer.h - Memory Buffer Interface ---------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the MemoryBuffer interface.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_MEMORYBUFFER_H
|
||||
#define LLVM_SUPPORT_MEMORYBUFFER_H
|
||||
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class error_code;
|
||||
template<class T> class OwningPtr;
|
||||
|
||||
/// MemoryBuffer - This interface provides simple read-only access to a block
|
||||
/// of memory, and provides simple methods for reading files and standard input
|
||||
/// into a memory buffer. In addition to basic access to the characters in the
|
||||
/// file, this interface guarantees you can read one character past the end of
|
||||
/// the file, and that this character will read as '\0'.
|
||||
///
|
||||
/// The '\0' guarantee is needed to support an optimization -- it's intended to
|
||||
/// be more efficient for clients which are reading all the data to stop
|
||||
/// reading when they encounter a '\0' than to continually check the file
|
||||
/// position to see if it has reached the end of the file.
|
||||
class MemoryBuffer {
|
||||
const char *BufferStart; // Start of the buffer.
|
||||
const char *BufferEnd; // End of the buffer.
|
||||
|
||||
MemoryBuffer(const MemoryBuffer &) LLVM_DELETED_FUNCTION;
|
||||
MemoryBuffer &operator=(const MemoryBuffer &) LLVM_DELETED_FUNCTION;
|
||||
protected:
|
||||
MemoryBuffer() {}
|
||||
void init(const char *BufStart, const char *BufEnd,
|
||||
bool RequiresNullTerminator);
|
||||
public:
|
||||
virtual ~MemoryBuffer();
|
||||
|
||||
const char *getBufferStart() const { return BufferStart; }
|
||||
const char *getBufferEnd() const { return BufferEnd; }
|
||||
size_t getBufferSize() const { return BufferEnd-BufferStart; }
|
||||
|
||||
StringRef getBuffer() const {
|
||||
return StringRef(BufferStart, getBufferSize());
|
||||
}
|
||||
|
||||
/// getBufferIdentifier - Return an identifier for this buffer, typically the
|
||||
/// filename it was read from.
|
||||
virtual const char *getBufferIdentifier() const {
|
||||
return "Unknown buffer";
|
||||
}
|
||||
|
||||
/// getFile - Open the specified file as a MemoryBuffer, returning a new
|
||||
/// MemoryBuffer if successful, otherwise returning null. If FileSize is
|
||||
/// specified, this means that the client knows that the file exists and that
|
||||
/// it has the specified size.
|
||||
static error_code getFile(StringRef Filename, OwningPtr<MemoryBuffer> &result,
|
||||
int64_t FileSize = -1,
|
||||
bool RequiresNullTerminator = true);
|
||||
static error_code getFile(const char *Filename,
|
||||
OwningPtr<MemoryBuffer> &result,
|
||||
int64_t FileSize = -1,
|
||||
bool RequiresNullTerminator = true);
|
||||
|
||||
/// getOpenFile - Given an already-open file descriptor, read the file and
|
||||
/// return a MemoryBuffer.
|
||||
static error_code getOpenFile(int FD, const char *Filename,
|
||||
OwningPtr<MemoryBuffer> &result,
|
||||
uint64_t FileSize = -1,
|
||||
uint64_t MapSize = -1,
|
||||
int64_t Offset = 0,
|
||||
bool RequiresNullTerminator = true);
|
||||
|
||||
/// getMemBuffer - Open the specified memory range as a MemoryBuffer. Note
|
||||
/// that InputData must be null terminated if RequiresNullTerminator is true.
|
||||
static MemoryBuffer *getMemBuffer(StringRef InputData,
|
||||
StringRef BufferName = "",
|
||||
bool RequiresNullTerminator = true);
|
||||
|
||||
/// getMemBufferCopy - Open the specified memory range as a MemoryBuffer,
|
||||
/// copying the contents and taking ownership of it. InputData does not
|
||||
/// have to be null terminated.
|
||||
static MemoryBuffer *getMemBufferCopy(StringRef InputData,
|
||||
StringRef BufferName = "");
|
||||
|
||||
/// getNewMemBuffer - Allocate a new MemoryBuffer of the specified size that
|
||||
/// is completely initialized to zeros. Note that the caller should
|
||||
/// initialize the memory allocated by this method. The memory is owned by
|
||||
/// the MemoryBuffer object.
|
||||
static MemoryBuffer *getNewMemBuffer(size_t Size, StringRef BufferName = "");
|
||||
|
||||
/// getNewUninitMemBuffer - Allocate a new MemoryBuffer of the specified size
|
||||
/// that is not initialized. Note that the caller should initialize the
|
||||
/// memory allocated by this method. The memory is owned by the MemoryBuffer
|
||||
/// object.
|
||||
static MemoryBuffer *getNewUninitMemBuffer(size_t Size,
|
||||
StringRef BufferName = "");
|
||||
|
||||
/// getSTDIN - Read all of stdin into a file buffer, and return it.
|
||||
/// If an error occurs, this returns null and sets ec.
|
||||
static error_code getSTDIN(OwningPtr<MemoryBuffer> &result);
|
||||
|
||||
|
||||
/// getFileOrSTDIN - Open the specified file as a MemoryBuffer, or open stdin
|
||||
/// if the Filename is "-". If an error occurs, this returns null and sets
|
||||
/// ec.
|
||||
static error_code getFileOrSTDIN(StringRef Filename,
|
||||
OwningPtr<MemoryBuffer> &result,
|
||||
int64_t FileSize = -1);
|
||||
static error_code getFileOrSTDIN(const char *Filename,
|
||||
OwningPtr<MemoryBuffer> &result,
|
||||
int64_t FileSize = -1);
|
||||
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Provided for performance analysis.
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
||||
/// The kind of memory backing used to support the MemoryBuffer.
|
||||
enum BufferKind {
|
||||
MemoryBuffer_Malloc,
|
||||
MemoryBuffer_MMap
|
||||
};
|
||||
|
||||
/// Return information on the memory mechanism used to support the
|
||||
/// MemoryBuffer.
|
||||
virtual BufferKind getBufferKind() const = 0;
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
69
thirdparty/clang/include/llvm/Support/MemoryObject.h
vendored
Normal file
69
thirdparty/clang/include/llvm/Support/MemoryObject.h
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
//===- MemoryObject.h - Abstract memory interface ---------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_MEMORYOBJECT_H
|
||||
#define LLVM_SUPPORT_MEMORYOBJECT_H
|
||||
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
/// MemoryObject - Abstract base class for contiguous addressable memory.
|
||||
/// Necessary for cases in which the memory is in another process, in a
|
||||
/// file, or on a remote machine.
|
||||
/// All size and offset parameters are uint64_ts, to allow 32-bit processes
|
||||
/// access to 64-bit address spaces.
|
||||
class MemoryObject {
|
||||
public:
|
||||
/// Destructor - Override as necessary.
|
||||
virtual ~MemoryObject();
|
||||
|
||||
/// getBase - Returns the lowest valid address in the region.
|
||||
///
|
||||
/// @result - The lowest valid address.
|
||||
virtual uint64_t getBase() const = 0;
|
||||
|
||||
/// getExtent - Returns the size of the region in bytes. (The region is
|
||||
/// contiguous, so the highest valid address of the region
|
||||
/// is getBase() + getExtent() - 1).
|
||||
///
|
||||
/// @result - The size of the region.
|
||||
virtual uint64_t getExtent() const = 0;
|
||||
|
||||
/// readByte - Tries to read a single byte from the region.
|
||||
///
|
||||
/// @param address - The address of the byte, in the same space as getBase().
|
||||
/// @param ptr - A pointer to a byte to be filled in. Must be non-NULL.
|
||||
/// @result - 0 if successful; -1 if not. Failure may be due to a
|
||||
/// bounds violation or an implementation-specific error.
|
||||
virtual int readByte(uint64_t address, uint8_t* ptr) const = 0;
|
||||
|
||||
/// readBytes - Tries to read a contiguous range of bytes from the
|
||||
/// region, up to the end of the region.
|
||||
/// You should override this function if there is a quicker
|
||||
/// way than going back and forth with individual bytes.
|
||||
///
|
||||
/// @param address - The address of the first byte, in the same space as
|
||||
/// getBase().
|
||||
/// @param size - The maximum number of bytes to copy.
|
||||
/// @param buf - A pointer to a buffer to be filled in. Must be non-NULL
|
||||
/// and large enough to hold size bytes.
|
||||
/// @param copied - A pointer to a nunber that is filled in with the number
|
||||
/// of bytes actually read. May be NULL.
|
||||
/// @result - 0 if successful; -1 if not. Failure may be due to a
|
||||
/// bounds violation or an implementation-specific error.
|
||||
virtual int readBytes(uint64_t address,
|
||||
uint64_t size,
|
||||
uint8_t* buf,
|
||||
uint64_t* copied) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
155
thirdparty/clang/include/llvm/Support/Mutex.h
vendored
Normal file
155
thirdparty/clang/include/llvm/Support/Mutex.h
vendored
Normal file
@@ -0,0 +1,155 @@
|
||||
//===- llvm/Support/Mutex.h - Mutex Operating System Concept -----*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file declares the llvm::sys::Mutex class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_MUTEX_H
|
||||
#define LLVM_SUPPORT_MUTEX_H
|
||||
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Support/Threading.h"
|
||||
#include <cassert>
|
||||
|
||||
namespace llvm
|
||||
{
|
||||
namespace sys
|
||||
{
|
||||
/// @brief Platform agnostic Mutex class.
|
||||
class MutexImpl
|
||||
{
|
||||
/// @name Constructors
|
||||
/// @{
|
||||
public:
|
||||
|
||||
/// Initializes the lock but doesn't acquire it. if \p recursive is set
|
||||
/// to false, the lock will not be recursive which makes it cheaper but
|
||||
/// also more likely to deadlock (same thread can't acquire more than
|
||||
/// once).
|
||||
/// @brief Default Constructor.
|
||||
explicit MutexImpl(bool recursive = true);
|
||||
|
||||
/// Releases and removes the lock
|
||||
/// @brief Destructor
|
||||
~MutexImpl();
|
||||
|
||||
/// @}
|
||||
/// @name Methods
|
||||
/// @{
|
||||
public:
|
||||
|
||||
/// Attempts to unconditionally acquire the lock. If the lock is held by
|
||||
/// another thread, this method will wait until it can acquire the lock.
|
||||
/// @returns false if any kind of error occurs, true otherwise.
|
||||
/// @brief Unconditionally acquire the lock.
|
||||
bool acquire();
|
||||
|
||||
/// Attempts to release the lock. If the lock is held by the current
|
||||
/// thread, the lock is released allowing other threads to acquire the
|
||||
/// lock.
|
||||
/// @returns false if any kind of error occurs, true otherwise.
|
||||
/// @brief Unconditionally release the lock.
|
||||
bool release();
|
||||
|
||||
/// Attempts to acquire the lock without blocking. If the lock is not
|
||||
/// available, this function returns false quickly (without blocking). If
|
||||
/// the lock is available, it is acquired.
|
||||
/// @returns false if any kind of error occurs or the lock is not
|
||||
/// available, true otherwise.
|
||||
/// @brief Try to acquire the lock.
|
||||
bool tryacquire();
|
||||
|
||||
//@}
|
||||
/// @name Platform Dependent Data
|
||||
/// @{
|
||||
private:
|
||||
void* data_; ///< We don't know what the data will be
|
||||
|
||||
/// @}
|
||||
/// @name Do Not Implement
|
||||
/// @{
|
||||
private:
|
||||
MutexImpl(const MutexImpl &) LLVM_DELETED_FUNCTION;
|
||||
void operator=(const MutexImpl &) LLVM_DELETED_FUNCTION;
|
||||
/// @}
|
||||
};
|
||||
|
||||
|
||||
/// SmartMutex - A mutex with a compile time constant parameter that
|
||||
/// indicates whether this mutex should become a no-op when we're not
|
||||
/// running in multithreaded mode.
|
||||
template<bool mt_only>
|
||||
class SmartMutex : public MutexImpl {
|
||||
unsigned acquired;
|
||||
bool recursive;
|
||||
public:
|
||||
explicit SmartMutex(bool rec = true) :
|
||||
MutexImpl(rec), acquired(0), recursive(rec) { }
|
||||
|
||||
bool acquire() {
|
||||
if (!mt_only || llvm_is_multithreaded()) {
|
||||
return MutexImpl::acquire();
|
||||
} else {
|
||||
// Single-threaded debugging code. This would be racy in
|
||||
// multithreaded mode, but provides not sanity checks in single
|
||||
// threaded mode.
|
||||
assert((recursive || acquired == 0) && "Lock already acquired!!");
|
||||
++acquired;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool release() {
|
||||
if (!mt_only || llvm_is_multithreaded()) {
|
||||
return MutexImpl::release();
|
||||
} else {
|
||||
// Single-threaded debugging code. This would be racy in
|
||||
// multithreaded mode, but provides not sanity checks in single
|
||||
// threaded mode.
|
||||
assert(((recursive && acquired) || (acquired == 1)) &&
|
||||
"Lock not acquired before release!");
|
||||
--acquired;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool tryacquire() {
|
||||
if (!mt_only || llvm_is_multithreaded())
|
||||
return MutexImpl::tryacquire();
|
||||
else return true;
|
||||
}
|
||||
|
||||
private:
|
||||
SmartMutex(const SmartMutex<mt_only> & original);
|
||||
void operator=(const SmartMutex<mt_only> &);
|
||||
};
|
||||
|
||||
/// Mutex - A standard, always enforced mutex.
|
||||
typedef SmartMutex<false> Mutex;
|
||||
|
||||
template<bool mt_only>
|
||||
class SmartScopedLock {
|
||||
SmartMutex<mt_only>& mtx;
|
||||
|
||||
public:
|
||||
SmartScopedLock(SmartMutex<mt_only>& m) : mtx(m) {
|
||||
mtx.acquire();
|
||||
}
|
||||
|
||||
~SmartScopedLock() {
|
||||
mtx.release();
|
||||
}
|
||||
};
|
||||
|
||||
typedef SmartScopedLock<false> ScopedLock;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
41
thirdparty/clang/include/llvm/Support/MutexGuard.h
vendored
Normal file
41
thirdparty/clang/include/llvm/Support/MutexGuard.h
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
//===-- Support/MutexGuard.h - Acquire/Release Mutex In Scope ---*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines a guard for a block of code that ensures a Mutex is locked
|
||||
// upon construction and released upon destruction.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_MUTEXGUARD_H
|
||||
#define LLVM_SUPPORT_MUTEXGUARD_H
|
||||
|
||||
#include "llvm/Support/Mutex.h"
|
||||
|
||||
namespace llvm {
|
||||
/// Instances of this class acquire a given Mutex Lock when constructed and
|
||||
/// hold that lock until destruction. The intention is to instantiate one of
|
||||
/// these on the stack at the top of some scope to be assured that C++
|
||||
/// destruction of the object will always release the Mutex and thus avoid
|
||||
/// a host of nasty multi-threading problems in the face of exceptions, etc.
|
||||
/// @brief Guard a section of code with a Mutex.
|
||||
class MutexGuard {
|
||||
sys::Mutex &M;
|
||||
MutexGuard(const MutexGuard &) LLVM_DELETED_FUNCTION;
|
||||
void operator=(const MutexGuard &) LLVM_DELETED_FUNCTION;
|
||||
public:
|
||||
MutexGuard(sys::Mutex &m) : M(m) { M.acquire(); }
|
||||
~MutexGuard() { M.release(); }
|
||||
/// holds - Returns true if this locker instance holds the specified lock.
|
||||
/// This is mostly used in assertions to validate that the correct mutex
|
||||
/// is held.
|
||||
bool holds(const sys::Mutex& lock) const { return &M == &lock; }
|
||||
};
|
||||
}
|
||||
|
||||
#endif // LLVM_SUPPORT_MUTEXGUARD_H
|
||||
298
thirdparty/clang/include/llvm/Support/NoFolder.h
vendored
Normal file
298
thirdparty/clang/include/llvm/Support/NoFolder.h
vendored
Normal file
@@ -0,0 +1,298 @@
|
||||
//======-- llvm/Support/NoFolder.h - Constant folding helper -*- C++ -*-======//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the NoFolder class, a helper for IRBuilder. It provides
|
||||
// IRBuilder with a set of methods for creating unfolded constants. This is
|
||||
// useful for learners trying to understand how LLVM IR works, and who don't
|
||||
// want details to be hidden by the constant folder. For general constant
|
||||
// creation and folding, use ConstantExpr and the routines in
|
||||
// llvm/Analysis/ConstantFolding.h.
|
||||
//
|
||||
// Note: since it is not actually possible to create unfolded constants, this
|
||||
// class returns instructions rather than constants.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_NOFOLDER_H
|
||||
#define LLVM_SUPPORT_NOFOLDER_H
|
||||
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/IR/Constants.h"
|
||||
#include "llvm/IR/Instructions.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
/// NoFolder - Create "constants" (actually, instructions) with no folding.
|
||||
class NoFolder {
|
||||
public:
|
||||
explicit NoFolder() {}
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Binary Operators
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
||||
Instruction *CreateAdd(Constant *LHS, Constant *RHS,
|
||||
bool HasNUW = false, bool HasNSW = false) const {
|
||||
BinaryOperator *BO = BinaryOperator::CreateAdd(LHS, RHS);
|
||||
if (HasNUW) BO->setHasNoUnsignedWrap();
|
||||
if (HasNSW) BO->setHasNoSignedWrap();
|
||||
return BO;
|
||||
}
|
||||
Instruction *CreateNSWAdd(Constant *LHS, Constant *RHS) const {
|
||||
return BinaryOperator::CreateNSWAdd(LHS, RHS);
|
||||
}
|
||||
Instruction *CreateNUWAdd(Constant *LHS, Constant *RHS) const {
|
||||
return BinaryOperator::CreateNUWAdd(LHS, RHS);
|
||||
}
|
||||
Instruction *CreateFAdd(Constant *LHS, Constant *RHS) const {
|
||||
return BinaryOperator::CreateFAdd(LHS, RHS);
|
||||
}
|
||||
Instruction *CreateSub(Constant *LHS, Constant *RHS,
|
||||
bool HasNUW = false, bool HasNSW = false) const {
|
||||
BinaryOperator *BO = BinaryOperator::CreateSub(LHS, RHS);
|
||||
if (HasNUW) BO->setHasNoUnsignedWrap();
|
||||
if (HasNSW) BO->setHasNoSignedWrap();
|
||||
return BO;
|
||||
}
|
||||
Instruction *CreateNSWSub(Constant *LHS, Constant *RHS) const {
|
||||
return BinaryOperator::CreateNSWSub(LHS, RHS);
|
||||
}
|
||||
Instruction *CreateNUWSub(Constant *LHS, Constant *RHS) const {
|
||||
return BinaryOperator::CreateNUWSub(LHS, RHS);
|
||||
}
|
||||
Instruction *CreateFSub(Constant *LHS, Constant *RHS) const {
|
||||
return BinaryOperator::CreateFSub(LHS, RHS);
|
||||
}
|
||||
Instruction *CreateMul(Constant *LHS, Constant *RHS,
|
||||
bool HasNUW = false, bool HasNSW = false) const {
|
||||
BinaryOperator *BO = BinaryOperator::CreateMul(LHS, RHS);
|
||||
if (HasNUW) BO->setHasNoUnsignedWrap();
|
||||
if (HasNSW) BO->setHasNoSignedWrap();
|
||||
return BO;
|
||||
}
|
||||
Instruction *CreateNSWMul(Constant *LHS, Constant *RHS) const {
|
||||
return BinaryOperator::CreateNSWMul(LHS, RHS);
|
||||
}
|
||||
Instruction *CreateNUWMul(Constant *LHS, Constant *RHS) const {
|
||||
return BinaryOperator::CreateNUWMul(LHS, RHS);
|
||||
}
|
||||
Instruction *CreateFMul(Constant *LHS, Constant *RHS) const {
|
||||
return BinaryOperator::CreateFMul(LHS, RHS);
|
||||
}
|
||||
Instruction *CreateUDiv(Constant *LHS, Constant *RHS,
|
||||
bool isExact = false) const {
|
||||
if (!isExact)
|
||||
return BinaryOperator::CreateUDiv(LHS, RHS);
|
||||
return BinaryOperator::CreateExactUDiv(LHS, RHS);
|
||||
}
|
||||
Instruction *CreateExactUDiv(Constant *LHS, Constant *RHS) const {
|
||||
return BinaryOperator::CreateExactUDiv(LHS, RHS);
|
||||
}
|
||||
Instruction *CreateSDiv(Constant *LHS, Constant *RHS,
|
||||
bool isExact = false) const {
|
||||
if (!isExact)
|
||||
return BinaryOperator::CreateSDiv(LHS, RHS);
|
||||
return BinaryOperator::CreateExactSDiv(LHS, RHS);
|
||||
}
|
||||
Instruction *CreateExactSDiv(Constant *LHS, Constant *RHS) const {
|
||||
return BinaryOperator::CreateExactSDiv(LHS, RHS);
|
||||
}
|
||||
Instruction *CreateFDiv(Constant *LHS, Constant *RHS) const {
|
||||
return BinaryOperator::CreateFDiv(LHS, RHS);
|
||||
}
|
||||
Instruction *CreateURem(Constant *LHS, Constant *RHS) const {
|
||||
return BinaryOperator::CreateURem(LHS, RHS);
|
||||
}
|
||||
Instruction *CreateSRem(Constant *LHS, Constant *RHS) const {
|
||||
return BinaryOperator::CreateSRem(LHS, RHS);
|
||||
}
|
||||
Instruction *CreateFRem(Constant *LHS, Constant *RHS) const {
|
||||
return BinaryOperator::CreateFRem(LHS, RHS);
|
||||
}
|
||||
Instruction *CreateShl(Constant *LHS, Constant *RHS, bool HasNUW = false,
|
||||
bool HasNSW = false) const {
|
||||
BinaryOperator *BO = BinaryOperator::CreateShl(LHS, RHS);
|
||||
if (HasNUW) BO->setHasNoUnsignedWrap();
|
||||
if (HasNSW) BO->setHasNoSignedWrap();
|
||||
return BO;
|
||||
}
|
||||
Instruction *CreateLShr(Constant *LHS, Constant *RHS,
|
||||
bool isExact = false) const {
|
||||
if (!isExact)
|
||||
return BinaryOperator::CreateLShr(LHS, RHS);
|
||||
return BinaryOperator::CreateExactLShr(LHS, RHS);
|
||||
}
|
||||
Instruction *CreateAShr(Constant *LHS, Constant *RHS,
|
||||
bool isExact = false) const {
|
||||
if (!isExact)
|
||||
return BinaryOperator::CreateAShr(LHS, RHS);
|
||||
return BinaryOperator::CreateExactAShr(LHS, RHS);
|
||||
}
|
||||
Instruction *CreateAnd(Constant *LHS, Constant *RHS) const {
|
||||
return BinaryOperator::CreateAnd(LHS, RHS);
|
||||
}
|
||||
Instruction *CreateOr(Constant *LHS, Constant *RHS) const {
|
||||
return BinaryOperator::CreateOr(LHS, RHS);
|
||||
}
|
||||
Instruction *CreateXor(Constant *LHS, Constant *RHS) const {
|
||||
return BinaryOperator::CreateXor(LHS, RHS);
|
||||
}
|
||||
|
||||
Instruction *CreateBinOp(Instruction::BinaryOps Opc,
|
||||
Constant *LHS, Constant *RHS) const {
|
||||
return BinaryOperator::Create(Opc, LHS, RHS);
|
||||
}
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Unary Operators
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
||||
Instruction *CreateNeg(Constant *C,
|
||||
bool HasNUW = false, bool HasNSW = false) const {
|
||||
BinaryOperator *BO = BinaryOperator::CreateNeg(C);
|
||||
if (HasNUW) BO->setHasNoUnsignedWrap();
|
||||
if (HasNSW) BO->setHasNoSignedWrap();
|
||||
return BO;
|
||||
}
|
||||
Instruction *CreateNSWNeg(Constant *C) const {
|
||||
return BinaryOperator::CreateNSWNeg(C);
|
||||
}
|
||||
Instruction *CreateNUWNeg(Constant *C) const {
|
||||
return BinaryOperator::CreateNUWNeg(C);
|
||||
}
|
||||
Instruction *CreateFNeg(Constant *C) const {
|
||||
return BinaryOperator::CreateFNeg(C);
|
||||
}
|
||||
Instruction *CreateNot(Constant *C) const {
|
||||
return BinaryOperator::CreateNot(C);
|
||||
}
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Memory Instructions
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
||||
Constant *CreateGetElementPtr(Constant *C,
|
||||
ArrayRef<Constant *> IdxList) const {
|
||||
return ConstantExpr::getGetElementPtr(C, IdxList);
|
||||
}
|
||||
Constant *CreateGetElementPtr(Constant *C, Constant *Idx) const {
|
||||
// This form of the function only exists to avoid ambiguous overload
|
||||
// warnings about whether to convert Idx to ArrayRef<Constant *> or
|
||||
// ArrayRef<Value *>.
|
||||
return ConstantExpr::getGetElementPtr(C, Idx);
|
||||
}
|
||||
Instruction *CreateGetElementPtr(Constant *C,
|
||||
ArrayRef<Value *> IdxList) const {
|
||||
return GetElementPtrInst::Create(C, IdxList);
|
||||
}
|
||||
|
||||
Constant *CreateInBoundsGetElementPtr(Constant *C,
|
||||
ArrayRef<Constant *> IdxList) const {
|
||||
return ConstantExpr::getInBoundsGetElementPtr(C, IdxList);
|
||||
}
|
||||
Constant *CreateInBoundsGetElementPtr(Constant *C, Constant *Idx) const {
|
||||
// This form of the function only exists to avoid ambiguous overload
|
||||
// warnings about whether to convert Idx to ArrayRef<Constant *> or
|
||||
// ArrayRef<Value *>.
|
||||
return ConstantExpr::getInBoundsGetElementPtr(C, Idx);
|
||||
}
|
||||
Instruction *CreateInBoundsGetElementPtr(Constant *C,
|
||||
ArrayRef<Value *> IdxList) const {
|
||||
return GetElementPtrInst::CreateInBounds(C, IdxList);
|
||||
}
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Cast/Conversion Operators
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
||||
Instruction *CreateCast(Instruction::CastOps Op, Constant *C,
|
||||
Type *DestTy) const {
|
||||
return CastInst::Create(Op, C, DestTy);
|
||||
}
|
||||
Instruction *CreatePointerCast(Constant *C, Type *DestTy) const {
|
||||
return CastInst::CreatePointerCast(C, DestTy);
|
||||
}
|
||||
Instruction *CreateIntCast(Constant *C, Type *DestTy,
|
||||
bool isSigned) const {
|
||||
return CastInst::CreateIntegerCast(C, DestTy, isSigned);
|
||||
}
|
||||
Instruction *CreateFPCast(Constant *C, Type *DestTy) const {
|
||||
return CastInst::CreateFPCast(C, DestTy);
|
||||
}
|
||||
|
||||
Instruction *CreateBitCast(Constant *C, Type *DestTy) const {
|
||||
return CreateCast(Instruction::BitCast, C, DestTy);
|
||||
}
|
||||
Instruction *CreateIntToPtr(Constant *C, Type *DestTy) const {
|
||||
return CreateCast(Instruction::IntToPtr, C, DestTy);
|
||||
}
|
||||
Instruction *CreatePtrToInt(Constant *C, Type *DestTy) const {
|
||||
return CreateCast(Instruction::PtrToInt, C, DestTy);
|
||||
}
|
||||
Instruction *CreateZExtOrBitCast(Constant *C, Type *DestTy) const {
|
||||
return CastInst::CreateZExtOrBitCast(C, DestTy);
|
||||
}
|
||||
Instruction *CreateSExtOrBitCast(Constant *C, Type *DestTy) const {
|
||||
return CastInst::CreateSExtOrBitCast(C, DestTy);
|
||||
}
|
||||
|
||||
Instruction *CreateTruncOrBitCast(Constant *C, Type *DestTy) const {
|
||||
return CastInst::CreateTruncOrBitCast(C, DestTy);
|
||||
}
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Compare Instructions
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
||||
Instruction *CreateICmp(CmpInst::Predicate P,
|
||||
Constant *LHS, Constant *RHS) const {
|
||||
return new ICmpInst(P, LHS, RHS);
|
||||
}
|
||||
Instruction *CreateFCmp(CmpInst::Predicate P,
|
||||
Constant *LHS, Constant *RHS) const {
|
||||
return new FCmpInst(P, LHS, RHS);
|
||||
}
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Other Instructions
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
||||
Instruction *CreateSelect(Constant *C,
|
||||
Constant *True, Constant *False) const {
|
||||
return SelectInst::Create(C, True, False);
|
||||
}
|
||||
|
||||
Instruction *CreateExtractElement(Constant *Vec, Constant *Idx) const {
|
||||
return ExtractElementInst::Create(Vec, Idx);
|
||||
}
|
||||
|
||||
Instruction *CreateInsertElement(Constant *Vec, Constant *NewElt,
|
||||
Constant *Idx) const {
|
||||
return InsertElementInst::Create(Vec, NewElt, Idx);
|
||||
}
|
||||
|
||||
Instruction *CreateShuffleVector(Constant *V1, Constant *V2,
|
||||
Constant *Mask) const {
|
||||
return new ShuffleVectorInst(V1, V2, Mask);
|
||||
}
|
||||
|
||||
Instruction *CreateExtractValue(Constant *Agg,
|
||||
ArrayRef<unsigned> IdxList) const {
|
||||
return ExtractValueInst::Create(Agg, IdxList);
|
||||
}
|
||||
|
||||
Instruction *CreateInsertValue(Constant *Agg, Constant *Val,
|
||||
ArrayRef<unsigned> IdxList) const {
|
||||
return InsertValueInst::Create(Agg, Val, IdxList);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
166
thirdparty/clang/include/llvm/Support/OutputBuffer.h
vendored
Normal file
166
thirdparty/clang/include/llvm/Support/OutputBuffer.h
vendored
Normal file
@@ -0,0 +1,166 @@
|
||||
//=== OutputBuffer.h - Output Buffer ----------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Methods to output values to a data buffer.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_OUTPUTBUFFER_H
|
||||
#define LLVM_SUPPORT_OUTPUTBUFFER_H
|
||||
|
||||
#include <cassert>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class OutputBuffer {
|
||||
/// Output buffer.
|
||||
std::vector<unsigned char> &Output;
|
||||
|
||||
/// is64Bit/isLittleEndian - This information is inferred from the target
|
||||
/// machine directly, indicating what header values and flags to set.
|
||||
bool is64Bit, isLittleEndian;
|
||||
public:
|
||||
OutputBuffer(std::vector<unsigned char> &Out,
|
||||
bool is64bit, bool le)
|
||||
: Output(Out), is64Bit(is64bit), isLittleEndian(le) {}
|
||||
|
||||
// align - Emit padding into the file until the current output position is
|
||||
// aligned to the specified power of two boundary.
|
||||
void align(unsigned Boundary) {
|
||||
assert(Boundary && (Boundary & (Boundary - 1)) == 0 &&
|
||||
"Must align to 2^k boundary");
|
||||
size_t Size = Output.size();
|
||||
|
||||
if (Size & (Boundary - 1)) {
|
||||
// Add padding to get alignment to the correct place.
|
||||
size_t Pad = Boundary - (Size & (Boundary - 1));
|
||||
Output.resize(Size + Pad);
|
||||
}
|
||||
}
|
||||
|
||||
//===------------------------------------------------------------------===//
|
||||
// Out Functions - Output the specified value to the data buffer.
|
||||
|
||||
void outbyte(unsigned char X) {
|
||||
Output.push_back(X);
|
||||
}
|
||||
void outhalf(unsigned short X) {
|
||||
if (isLittleEndian) {
|
||||
Output.push_back(X & 255);
|
||||
Output.push_back(X >> 8);
|
||||
} else {
|
||||
Output.push_back(X >> 8);
|
||||
Output.push_back(X & 255);
|
||||
}
|
||||
}
|
||||
void outword(unsigned X) {
|
||||
if (isLittleEndian) {
|
||||
Output.push_back((X >> 0) & 255);
|
||||
Output.push_back((X >> 8) & 255);
|
||||
Output.push_back((X >> 16) & 255);
|
||||
Output.push_back((X >> 24) & 255);
|
||||
} else {
|
||||
Output.push_back((X >> 24) & 255);
|
||||
Output.push_back((X >> 16) & 255);
|
||||
Output.push_back((X >> 8) & 255);
|
||||
Output.push_back((X >> 0) & 255);
|
||||
}
|
||||
}
|
||||
void outxword(uint64_t X) {
|
||||
if (isLittleEndian) {
|
||||
Output.push_back(unsigned(X >> 0) & 255);
|
||||
Output.push_back(unsigned(X >> 8) & 255);
|
||||
Output.push_back(unsigned(X >> 16) & 255);
|
||||
Output.push_back(unsigned(X >> 24) & 255);
|
||||
Output.push_back(unsigned(X >> 32) & 255);
|
||||
Output.push_back(unsigned(X >> 40) & 255);
|
||||
Output.push_back(unsigned(X >> 48) & 255);
|
||||
Output.push_back(unsigned(X >> 56) & 255);
|
||||
} else {
|
||||
Output.push_back(unsigned(X >> 56) & 255);
|
||||
Output.push_back(unsigned(X >> 48) & 255);
|
||||
Output.push_back(unsigned(X >> 40) & 255);
|
||||
Output.push_back(unsigned(X >> 32) & 255);
|
||||
Output.push_back(unsigned(X >> 24) & 255);
|
||||
Output.push_back(unsigned(X >> 16) & 255);
|
||||
Output.push_back(unsigned(X >> 8) & 255);
|
||||
Output.push_back(unsigned(X >> 0) & 255);
|
||||
}
|
||||
}
|
||||
void outaddr32(unsigned X) {
|
||||
outword(X);
|
||||
}
|
||||
void outaddr64(uint64_t X) {
|
||||
outxword(X);
|
||||
}
|
||||
void outaddr(uint64_t X) {
|
||||
if (!is64Bit)
|
||||
outword((unsigned)X);
|
||||
else
|
||||
outxword(X);
|
||||
}
|
||||
void outstring(const std::string &S, unsigned Length) {
|
||||
unsigned len_to_copy = static_cast<unsigned>(S.length()) < Length
|
||||
? static_cast<unsigned>(S.length()) : Length;
|
||||
unsigned len_to_fill = static_cast<unsigned>(S.length()) < Length
|
||||
? Length - static_cast<unsigned>(S.length()) : 0;
|
||||
|
||||
for (unsigned i = 0; i < len_to_copy; ++i)
|
||||
outbyte(S[i]);
|
||||
|
||||
for (unsigned i = 0; i < len_to_fill; ++i)
|
||||
outbyte(0);
|
||||
}
|
||||
|
||||
//===------------------------------------------------------------------===//
|
||||
// Fix Functions - Replace an existing entry at an offset.
|
||||
|
||||
void fixhalf(unsigned short X, unsigned Offset) {
|
||||
unsigned char *P = &Output[Offset];
|
||||
P[0] = (X >> (isLittleEndian ? 0 : 8)) & 255;
|
||||
P[1] = (X >> (isLittleEndian ? 8 : 0)) & 255;
|
||||
}
|
||||
void fixword(unsigned X, unsigned Offset) {
|
||||
unsigned char *P = &Output[Offset];
|
||||
P[0] = (X >> (isLittleEndian ? 0 : 24)) & 255;
|
||||
P[1] = (X >> (isLittleEndian ? 8 : 16)) & 255;
|
||||
P[2] = (X >> (isLittleEndian ? 16 : 8)) & 255;
|
||||
P[3] = (X >> (isLittleEndian ? 24 : 0)) & 255;
|
||||
}
|
||||
void fixxword(uint64_t X, unsigned Offset) {
|
||||
unsigned char *P = &Output[Offset];
|
||||
P[0] = (X >> (isLittleEndian ? 0 : 56)) & 255;
|
||||
P[1] = (X >> (isLittleEndian ? 8 : 48)) & 255;
|
||||
P[2] = (X >> (isLittleEndian ? 16 : 40)) & 255;
|
||||
P[3] = (X >> (isLittleEndian ? 24 : 32)) & 255;
|
||||
P[4] = (X >> (isLittleEndian ? 32 : 24)) & 255;
|
||||
P[5] = (X >> (isLittleEndian ? 40 : 16)) & 255;
|
||||
P[6] = (X >> (isLittleEndian ? 48 : 8)) & 255;
|
||||
P[7] = (X >> (isLittleEndian ? 56 : 0)) & 255;
|
||||
}
|
||||
void fixaddr(uint64_t X, unsigned Offset) {
|
||||
if (!is64Bit)
|
||||
fixword((unsigned)X, Offset);
|
||||
else
|
||||
fixxword(X, Offset);
|
||||
}
|
||||
|
||||
unsigned char &operator[](unsigned Index) {
|
||||
return Output[Index];
|
||||
}
|
||||
const unsigned char &operator[](unsigned Index) const {
|
||||
return Output[Index];
|
||||
}
|
||||
};
|
||||
|
||||
} // end llvm namespace
|
||||
|
||||
#endif // LLVM_SUPPORT_OUTPUTBUFFER_H
|
||||
137
thirdparty/clang/include/llvm/Support/PassNameParser.h
vendored
Normal file
137
thirdparty/clang/include/llvm/Support/PassNameParser.h
vendored
Normal file
@@ -0,0 +1,137 @@
|
||||
//===- llvm/Support/PassNameParser.h ----------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file the PassNameParser and FilteredPassNameParser<> classes, which are
|
||||
// used to add command line arguments to a utility for all of the passes that
|
||||
// have been registered into the system.
|
||||
//
|
||||
// The PassNameParser class adds ALL passes linked into the system (that are
|
||||
// creatable) as command line arguments to the tool (when instantiated with the
|
||||
// appropriate command line option template). The FilteredPassNameParser<>
|
||||
// template is used for the same purposes as PassNameParser, except that it only
|
||||
// includes passes that have a PassType that are compatible with the filter
|
||||
// (which is the template argument).
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_PASSNAMEPARSER_H
|
||||
#define LLVM_SUPPORT_PASSNAMEPARSER_H
|
||||
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <cstring>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// PassNameParser class - Make use of the pass registration mechanism to
|
||||
// automatically add a command line argument to opt for each pass.
|
||||
//
|
||||
class PassNameParser : public PassRegistrationListener,
|
||||
public cl::parser<const PassInfo*> {
|
||||
cl::Option *Opt;
|
||||
public:
|
||||
PassNameParser() : Opt(0) {}
|
||||
virtual ~PassNameParser();
|
||||
|
||||
void initialize(cl::Option &O) {
|
||||
Opt = &O;
|
||||
cl::parser<const PassInfo*>::initialize(O);
|
||||
|
||||
// Add all of the passes to the map that got initialized before 'this' did.
|
||||
enumeratePasses();
|
||||
}
|
||||
|
||||
// ignorablePassImpl - Can be overriden in subclasses to refine the list of
|
||||
// which passes we want to include.
|
||||
//
|
||||
virtual bool ignorablePassImpl(const PassInfo *P) const { return false; }
|
||||
|
||||
inline bool ignorablePass(const PassInfo *P) const {
|
||||
// Ignore non-selectable and non-constructible passes! Ignore
|
||||
// non-optimizations.
|
||||
return P->getPassArgument() == 0 || *P->getPassArgument() == 0 ||
|
||||
P->getNormalCtor() == 0 || ignorablePassImpl(P);
|
||||
}
|
||||
|
||||
// Implement the PassRegistrationListener callbacks used to populate our map
|
||||
//
|
||||
virtual void passRegistered(const PassInfo *P) {
|
||||
if (ignorablePass(P) || !Opt) return;
|
||||
if (findOption(P->getPassArgument()) != getNumOptions()) {
|
||||
errs() << "Two passes with the same argument (-"
|
||||
<< P->getPassArgument() << ") attempted to be registered!\n";
|
||||
llvm_unreachable(0);
|
||||
}
|
||||
addLiteralOption(P->getPassArgument(), P, P->getPassName());
|
||||
}
|
||||
virtual void passEnumerate(const PassInfo *P) { passRegistered(P); }
|
||||
|
||||
// printOptionInfo - Print out information about this option. Override the
|
||||
// default implementation to sort the table before we print...
|
||||
virtual void printOptionInfo(const cl::Option &O, size_t GlobalWidth) const {
|
||||
PassNameParser *PNP = const_cast<PassNameParser*>(this);
|
||||
array_pod_sort(PNP->Values.begin(), PNP->Values.end(), ValLessThan);
|
||||
cl::parser<const PassInfo*>::printOptionInfo(O, GlobalWidth);
|
||||
}
|
||||
|
||||
private:
|
||||
// ValLessThan - Provide a sorting comparator for Values elements...
|
||||
static int ValLessThan(const void *VT1, const void *VT2) {
|
||||
typedef PassNameParser::OptionInfo ValType;
|
||||
return std::strcmp(static_cast<const ValType *>(VT1)->Name,
|
||||
static_cast<const ValType *>(VT2)->Name);
|
||||
}
|
||||
};
|
||||
|
||||
///===----------------------------------------------------------------------===//
|
||||
/// FilteredPassNameParser class - Make use of the pass registration
|
||||
/// mechanism to automatically add a command line argument to opt for
|
||||
/// each pass that satisfies a filter criteria. Filter should return
|
||||
/// true for passes to be registered as command-line options.
|
||||
///
|
||||
template<typename Filter>
|
||||
class FilteredPassNameParser : public PassNameParser {
|
||||
private:
|
||||
Filter filter;
|
||||
|
||||
public:
|
||||
bool ignorablePassImpl(const PassInfo *P) const { return !filter(*P); }
|
||||
};
|
||||
|
||||
///===----------------------------------------------------------------------===//
|
||||
/// PassArgFilter - A filter for use with PassNameFilterParser that only
|
||||
/// accepts a Pass whose Arg matches certain strings.
|
||||
///
|
||||
/// Use like this:
|
||||
///
|
||||
/// extern const char AllowedPassArgs[] = "-anders_aa -dse";
|
||||
///
|
||||
/// static cl::list<
|
||||
/// const PassInfo*,
|
||||
/// bool,
|
||||
/// FilteredPassNameParser<PassArgFilter<AllowedPassArgs> > >
|
||||
/// PassList(cl::desc("Passes available:"));
|
||||
///
|
||||
/// Only the -anders_aa and -dse options will be available to the user.
|
||||
///
|
||||
template<const char *Args>
|
||||
class PassArgFilter {
|
||||
public:
|
||||
bool operator()(const PassInfo &P) const {
|
||||
return(std::strstr(Args, P.getPassArgument()));
|
||||
}
|
||||
};
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
||||
16
thirdparty/clang/include/llvm/Support/Path.h
vendored
Normal file
16
thirdparty/clang/include/llvm/Support/Path.h
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
//===- llvm/Support/Path.h - Path Operating System Concept ------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file currently includes both PathV1 and PathV2 to facilitate moving
|
||||
// clients over to the new interface.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Support/PathV1.h"
|
||||
#include "llvm/Support/PathV2.h"
|
||||
743
thirdparty/clang/include/llvm/Support/PathV1.h
vendored
Normal file
743
thirdparty/clang/include/llvm/Support/PathV1.h
vendored
Normal file
@@ -0,0 +1,743 @@
|
||||
//===- llvm/Support/PathV1.h - Path Operating System Concept ----*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file declares the llvm::sys::Path class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_PATHV1_H
|
||||
#define LLVM_SUPPORT_PATHV1_H
|
||||
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Support/TimeValue.h"
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#define LLVM_PATH_DEPRECATED_MSG(replacement) \
|
||||
"PathV1 has been deprecated and will be removed as soon as all LLVM and" \
|
||||
" Clang clients have been moved over to PathV2. Please use `" #replacement \
|
||||
"` from PathV2 instead."
|
||||
|
||||
namespace llvm {
|
||||
namespace sys {
|
||||
|
||||
/// This structure provides basic file system information about a file. It
|
||||
/// is patterned after the stat(2) Unix operating system call but made
|
||||
/// platform independent and eliminates many of the unix-specific fields.
|
||||
/// However, to support llvm-ar, the mode, user, and group fields are
|
||||
/// retained. These pertain to unix security and may not have a meaningful
|
||||
/// value on non-Unix platforms. However, the other fields should
|
||||
/// always be applicable on all platforms. The structure is filled in by
|
||||
/// the PathWithStatus class.
|
||||
/// @brief File status structure
|
||||
class FileStatus {
|
||||
public:
|
||||
uint64_t fileSize; ///< Size of the file in bytes
|
||||
TimeValue modTime; ///< Time of file's modification
|
||||
uint32_t mode; ///< Mode of the file, if applicable
|
||||
uint32_t user; ///< User ID of owner, if applicable
|
||||
uint32_t group; ///< Group ID of owner, if applicable
|
||||
uint64_t uniqueID; ///< A number to uniquely ID this file
|
||||
bool isDir : 1; ///< True if this is a directory.
|
||||
bool isFile : 1; ///< True if this is a file.
|
||||
|
||||
FileStatus() : fileSize(0), modTime(0,0), mode(0777), user(999),
|
||||
group(999), uniqueID(0), isDir(false), isFile(false) { }
|
||||
|
||||
TimeValue getTimestamp() const { return modTime; }
|
||||
uint64_t getSize() const { return fileSize; }
|
||||
uint32_t getMode() const { return mode; }
|
||||
uint32_t getUser() const { return user; }
|
||||
uint32_t getGroup() const { return group; }
|
||||
uint64_t getUniqueID() const { return uniqueID; }
|
||||
};
|
||||
|
||||
/// This class provides an abstraction for the path to a file or directory
|
||||
/// in the operating system's filesystem and provides various basic operations
|
||||
/// on it. Note that this class only represents the name of a path to a file
|
||||
/// or directory which may or may not be valid for a given machine's file
|
||||
/// system. The class is patterned after the java.io.File class with various
|
||||
/// extensions and several omissions (not relevant to LLVM). A Path object
|
||||
/// ensures that the path it encapsulates is syntactically valid for the
|
||||
/// operating system it is running on but does not ensure correctness for
|
||||
/// any particular file system. That is, a syntactically valid path might
|
||||
/// specify path components that do not exist in the file system and using
|
||||
/// such a Path to act on the file system could produce errors. There is one
|
||||
/// invalid Path value which is permitted: the empty path. The class should
|
||||
/// never allow a syntactically invalid non-empty path name to be assigned.
|
||||
/// Empty paths are required in order to indicate an error result in some
|
||||
/// situations. If the path is empty, the isValid operation will return
|
||||
/// false. All operations will fail if isValid is false. Operations that
|
||||
/// change the path will either return false if it would cause a syntactically
|
||||
/// invalid path name (in which case the Path object is left unchanged) or
|
||||
/// throw an std::string exception indicating the error. The methods are
|
||||
/// grouped into four basic categories: Path Accessors (provide information
|
||||
/// about the path without accessing disk), Disk Accessors (provide
|
||||
/// information about the underlying file or directory), Path Mutators
|
||||
/// (change the path information, not the disk), and Disk Mutators (change
|
||||
/// the disk file/directory referenced by the path). The Disk Mutator methods
|
||||
/// all have the word "disk" embedded in their method name to reinforce the
|
||||
/// notion that the operation modifies the file system.
|
||||
/// @since 1.4
|
||||
/// @brief An abstraction for operating system paths.
|
||||
class Path {
|
||||
/// @name Constructors
|
||||
/// @{
|
||||
public:
|
||||
/// Construct a path to the root directory of the file system. The root
|
||||
/// directory is a top level directory above which there are no more
|
||||
/// directories. For example, on UNIX, the root directory is /. On Windows
|
||||
/// it is file:///. Other operating systems may have different notions of
|
||||
/// what the root directory is or none at all. In that case, a consistent
|
||||
/// default root directory will be used.
|
||||
LLVM_ATTRIBUTE_DEPRECATED(static Path GetRootDirectory(),
|
||||
LLVM_PATH_DEPRECATED_MSG(NOTHING));
|
||||
|
||||
/// Construct a path to a unique temporary directory that is created in
|
||||
/// a "standard" place for the operating system. The directory is
|
||||
/// guaranteed to be created on exit from this function. If the directory
|
||||
/// cannot be created, the function will throw an exception.
|
||||
/// @returns an invalid path (empty) on error
|
||||
/// @param ErrMsg Optional place for an error message if an error occurs
|
||||
/// @brief Construct a path to an new, unique, existing temporary
|
||||
/// directory.
|
||||
static Path GetTemporaryDirectory(std::string* ErrMsg = 0);
|
||||
|
||||
/// Construct a vector of sys::Path that contains the "standard" system
|
||||
/// library paths suitable for linking into programs.
|
||||
/// @brief Construct a path to the system library directory
|
||||
static void GetSystemLibraryPaths(std::vector<sys::Path>& Paths);
|
||||
|
||||
/// Construct a vector of sys::Path that contains the "standard" bitcode
|
||||
/// library paths suitable for linking into an llvm program. This function
|
||||
/// *must* return the value of LLVM_LIB_SEARCH_PATH as well as the value
|
||||
/// of LLVM_LIBDIR. It also must provide the System library paths as
|
||||
/// returned by GetSystemLibraryPaths.
|
||||
/// @see GetSystemLibraryPaths
|
||||
/// @brief Construct a list of directories in which bitcode could be
|
||||
/// found.
|
||||
static void GetBitcodeLibraryPaths(std::vector<sys::Path>& Paths);
|
||||
|
||||
/// Find the path to a library using its short name. Use the system
|
||||
/// dependent library paths to locate the library.
|
||||
/// @brief Find a library.
|
||||
static Path FindLibrary(std::string& short_name);
|
||||
|
||||
/// Construct a path to the current user's home directory. The
|
||||
/// implementation must use an operating system specific mechanism for
|
||||
/// determining the user's home directory. For example, the environment
|
||||
/// variable "HOME" could be used on Unix. If a given operating system
|
||||
/// does not have the concept of a user's home directory, this static
|
||||
/// constructor must provide the same result as GetRootDirectory.
|
||||
/// @brief Construct a path to the current user's "home" directory
|
||||
static Path GetUserHomeDirectory();
|
||||
|
||||
/// Construct a path to the current directory for the current process.
|
||||
/// @returns The current working directory.
|
||||
/// @brief Returns the current working directory.
|
||||
static Path GetCurrentDirectory();
|
||||
|
||||
/// Return the suffix commonly used on file names that contain an
|
||||
/// executable.
|
||||
/// @returns The executable file suffix for the current platform.
|
||||
/// @brief Return the executable file suffix.
|
||||
static StringRef GetEXESuffix();
|
||||
|
||||
/// Return the suffix commonly used on file names that contain a shared
|
||||
/// object, shared archive, or dynamic link library. Such files are
|
||||
/// linked at runtime into a process and their code images are shared
|
||||
/// between processes.
|
||||
/// @returns The dynamic link library suffix for the current platform.
|
||||
/// @brief Return the dynamic link library suffix.
|
||||
static StringRef GetDLLSuffix();
|
||||
|
||||
/// GetMainExecutable - Return the path to the main executable, given the
|
||||
/// value of argv[0] from program startup and the address of main itself.
|
||||
/// In extremis, this function may fail and return an empty path.
|
||||
static Path GetMainExecutable(const char *argv0, void *MainAddr);
|
||||
|
||||
/// This is one of the very few ways in which a path can be constructed
|
||||
/// with a syntactically invalid name. The only *legal* invalid name is an
|
||||
/// empty one. Other invalid names are not permitted. Empty paths are
|
||||
/// provided so that they can be used to indicate null or error results in
|
||||
/// other lib/System functionality.
|
||||
/// @brief Construct an empty (and invalid) path.
|
||||
Path() : path() {}
|
||||
Path(const Path &that) : path(that.path) {}
|
||||
|
||||
/// This constructor will accept a char* or std::string as a path. No
|
||||
/// checking is done on this path to determine if it is valid. To
|
||||
/// determine validity of the path, use the isValid method.
|
||||
/// @param p The path to assign.
|
||||
/// @brief Construct a Path from a string.
|
||||
explicit Path(StringRef p);
|
||||
|
||||
/// This constructor will accept a character range as a path. No checking
|
||||
/// is done on this path to determine if it is valid. To determine
|
||||
/// validity of the path, use the isValid method.
|
||||
/// @param StrStart A pointer to the first character of the path name
|
||||
/// @param StrLen The length of the path name at StrStart
|
||||
/// @brief Construct a Path from a string.
|
||||
Path(const char *StrStart, unsigned StrLen);
|
||||
|
||||
/// @}
|
||||
/// @name Operators
|
||||
/// @{
|
||||
public:
|
||||
/// Makes a copy of \p that to \p this.
|
||||
/// @returns \p this
|
||||
/// @brief Assignment Operator
|
||||
Path &operator=(const Path &that) {
|
||||
path = that.path;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Makes a copy of \p that to \p this.
|
||||
/// @param that A StringRef denoting the path
|
||||
/// @returns \p this
|
||||
/// @brief Assignment Operator
|
||||
Path &operator=(StringRef that);
|
||||
|
||||
/// Compares \p this Path with \p that Path for equality.
|
||||
/// @returns true if \p this and \p that refer to the same thing.
|
||||
/// @brief Equality Operator
|
||||
bool operator==(const Path &that) const;
|
||||
|
||||
/// Compares \p this Path with \p that Path for inequality.
|
||||
/// @returns true if \p this and \p that refer to different things.
|
||||
/// @brief Inequality Operator
|
||||
bool operator!=(const Path &that) const { return !(*this == that); }
|
||||
|
||||
/// Determines if \p this Path is less than \p that Path. This is required
|
||||
/// so that Path objects can be placed into ordered collections (e.g.
|
||||
/// std::map). The comparison is done lexicographically as defined by
|
||||
/// the std::string::compare method.
|
||||
/// @returns true if \p this path is lexicographically less than \p that.
|
||||
/// @brief Less Than Operator
|
||||
bool operator<(const Path& that) const;
|
||||
|
||||
/// @}
|
||||
/// @name Path Accessors
|
||||
/// @{
|
||||
public:
|
||||
/// This function will use an operating system specific algorithm to
|
||||
/// determine if the current value of \p this is a syntactically valid
|
||||
/// path name for the operating system. The path name does not need to
|
||||
/// exist, validity is simply syntactical. Empty paths are always invalid.
|
||||
/// @returns true iff the path name is syntactically legal for the
|
||||
/// host operating system.
|
||||
/// @brief Determine if a path is syntactically valid or not.
|
||||
bool isValid() const;
|
||||
|
||||
/// This function determines if the contents of the path name are empty.
|
||||
/// That is, the path name has a zero length. This does NOT determine if
|
||||
/// if the file is empty. To get the length of the file itself, Use the
|
||||
/// PathWithStatus::getFileStatus() method and then the getSize() method
|
||||
/// on the returned FileStatus object.
|
||||
/// @returns true iff the path is empty.
|
||||
/// @brief Determines if the path name is empty (invalid).
|
||||
bool isEmpty() const { return path.empty(); }
|
||||
|
||||
/// This function returns the last component of the path name. The last
|
||||
/// component is the file or directory name occurring after the last
|
||||
/// directory separator. If no directory separator is present, the entire
|
||||
/// path name is returned (i.e. same as toString).
|
||||
/// @returns StringRef containing the last component of the path name.
|
||||
/// @brief Returns the last component of the path name.
|
||||
LLVM_ATTRIBUTE_DEPRECATED(
|
||||
StringRef getLast() const,
|
||||
LLVM_PATH_DEPRECATED_MSG(path::filename));
|
||||
|
||||
/// This function strips off the path and suffix of the file or directory
|
||||
/// name and returns just the basename. For example /a/foo.bar would cause
|
||||
/// this function to return "foo".
|
||||
/// @returns StringRef containing the basename of the path
|
||||
/// @brief Get the base name of the path
|
||||
LLVM_ATTRIBUTE_DEPRECATED(StringRef getBasename() const,
|
||||
LLVM_PATH_DEPRECATED_MSG(path::stem));
|
||||
|
||||
/// This function strips off the suffix of the path beginning with the
|
||||
/// path separator ('/' on Unix, '\' on Windows) and returns the result.
|
||||
LLVM_ATTRIBUTE_DEPRECATED(StringRef getDirname() const,
|
||||
LLVM_PATH_DEPRECATED_MSG(path::parent_path));
|
||||
|
||||
/// This function strips off the path and basename(up to and
|
||||
/// including the last dot) of the file or directory name and
|
||||
/// returns just the suffix. For example /a/foo.bar would cause
|
||||
/// this function to return "bar".
|
||||
/// @returns StringRef containing the suffix of the path
|
||||
/// @brief Get the suffix of the path
|
||||
LLVM_ATTRIBUTE_DEPRECATED(StringRef getSuffix() const,
|
||||
LLVM_PATH_DEPRECATED_MSG(path::extension));
|
||||
|
||||
/// Obtain a 'C' string for the path name.
|
||||
/// @returns a 'C' string containing the path name.
|
||||
/// @brief Returns the path as a C string.
|
||||
const char *c_str() const { return path.c_str(); }
|
||||
const std::string &str() const { return path; }
|
||||
|
||||
|
||||
/// size - Return the length in bytes of this path name.
|
||||
size_t size() const { return path.size(); }
|
||||
|
||||
/// empty - Returns true if the path is empty.
|
||||
unsigned empty() const { return path.empty(); }
|
||||
|
||||
/// @}
|
||||
/// @name Disk Accessors
|
||||
/// @{
|
||||
public:
|
||||
/// This function determines if the path name is absolute, as opposed to
|
||||
/// relative.
|
||||
/// @brief Determine if the path is absolute.
|
||||
LLVM_ATTRIBUTE_DEPRECATED(
|
||||
bool isAbsolute() const,
|
||||
LLVM_PATH_DEPRECATED_MSG(path::is_absolute));
|
||||
|
||||
/// This function determines if the path name is absolute, as opposed to
|
||||
/// relative.
|
||||
/// @brief Determine if the path is absolute.
|
||||
LLVM_ATTRIBUTE_DEPRECATED(
|
||||
static bool isAbsolute(const char *NameStart, unsigned NameLen),
|
||||
LLVM_PATH_DEPRECATED_MSG(path::is_absolute));
|
||||
|
||||
/// This function opens the file associated with the path name provided by
|
||||
/// the Path object and reads its magic number. If the magic number at the
|
||||
/// start of the file matches \p magic, true is returned. In all other
|
||||
/// cases (file not found, file not accessible, etc.) it returns false.
|
||||
/// @returns true if the magic number of the file matches \p magic.
|
||||
/// @brief Determine if file has a specific magic number
|
||||
LLVM_ATTRIBUTE_DEPRECATED(bool hasMagicNumber(StringRef magic) const,
|
||||
LLVM_PATH_DEPRECATED_MSG(fs::has_magic));
|
||||
|
||||
/// This function retrieves the first \p len bytes of the file associated
|
||||
/// with \p this. These bytes are returned as the "magic number" in the
|
||||
/// \p Magic parameter.
|
||||
/// @returns true if the Path is a file and the magic number is retrieved,
|
||||
/// false otherwise.
|
||||
/// @brief Get the file's magic number.
|
||||
bool getMagicNumber(std::string& Magic, unsigned len) const;
|
||||
|
||||
/// This function determines if the path name in the object references an
|
||||
/// archive file by looking at its magic number.
|
||||
/// @returns true if the file starts with the magic number for an archive
|
||||
/// file.
|
||||
/// @brief Determine if the path references an archive file.
|
||||
bool isArchive() const;
|
||||
|
||||
/// This function determines if the path name in the object references an
|
||||
/// LLVM Bitcode file by looking at its magic number.
|
||||
/// @returns true if the file starts with the magic number for LLVM
|
||||
/// bitcode files.
|
||||
/// @brief Determine if the path references a bitcode file.
|
||||
bool isBitcodeFile() const;
|
||||
|
||||
/// This function determines if the path name in the object references a
|
||||
/// native Dynamic Library (shared library, shared object) by looking at
|
||||
/// the file's magic number. The Path object must reference a file, not a
|
||||
/// directory.
|
||||
/// @returns true if the file starts with the magic number for a native
|
||||
/// shared library.
|
||||
/// @brief Determine if the path references a dynamic library.
|
||||
bool isDynamicLibrary() const;
|
||||
|
||||
/// This function determines if the path name in the object references a
|
||||
/// native object file by looking at it's magic number. The term object
|
||||
/// file is defined as "an organized collection of separate, named
|
||||
/// sequences of binary data." This covers the obvious file formats such
|
||||
/// as COFF and ELF, but it also includes llvm ir bitcode, archives,
|
||||
/// libraries, etc...
|
||||
/// @returns true if the file starts with the magic number for an object
|
||||
/// file.
|
||||
/// @brief Determine if the path references an object file.
|
||||
bool isObjectFile() const;
|
||||
|
||||
/// This function determines if the path name references an existing file
|
||||
/// or directory in the file system.
|
||||
/// @returns true if the pathname references an existing file or
|
||||
/// directory.
|
||||
/// @brief Determines if the path is a file or directory in
|
||||
/// the file system.
|
||||
LLVM_ATTRIBUTE_DEPRECATED(bool exists() const,
|
||||
LLVM_PATH_DEPRECATED_MSG(fs::exists));
|
||||
|
||||
/// This function determines if the path name references an
|
||||
/// existing directory.
|
||||
/// @returns true if the pathname references an existing directory.
|
||||
/// @brief Determines if the path is a directory in the file system.
|
||||
LLVM_ATTRIBUTE_DEPRECATED(bool isDirectory() const,
|
||||
LLVM_PATH_DEPRECATED_MSG(fs::is_directory));
|
||||
|
||||
/// This function determines if the path name references an
|
||||
/// existing symbolic link.
|
||||
/// @returns true if the pathname references an existing symlink.
|
||||
/// @brief Determines if the path is a symlink in the file system.
|
||||
LLVM_ATTRIBUTE_DEPRECATED(bool isSymLink() const,
|
||||
LLVM_PATH_DEPRECATED_MSG(fs::is_symlink));
|
||||
|
||||
/// This function determines if the path name references a readable file
|
||||
/// or directory in the file system. This function checks for
|
||||
/// the existence and readability (by the current program) of the file
|
||||
/// or directory.
|
||||
/// @returns true if the pathname references a readable file.
|
||||
/// @brief Determines if the path is a readable file or directory
|
||||
/// in the file system.
|
||||
bool canRead() const;
|
||||
|
||||
/// This function determines if the path name references a writable file
|
||||
/// or directory in the file system. This function checks for the
|
||||
/// existence and writability (by the current program) of the file or
|
||||
/// directory.
|
||||
/// @returns true if the pathname references a writable file.
|
||||
/// @brief Determines if the path is a writable file or directory
|
||||
/// in the file system.
|
||||
bool canWrite() const;
|
||||
|
||||
/// This function checks that what we're trying to work only on a regular
|
||||
/// file. Check for things like /dev/null, any block special file, or
|
||||
/// other things that aren't "regular" regular files.
|
||||
/// @returns true if the file is S_ISREG.
|
||||
/// @brief Determines if the file is a regular file
|
||||
bool isRegularFile() const;
|
||||
|
||||
/// This function determines if the path name references an executable
|
||||
/// file in the file system. This function checks for the existence and
|
||||
/// executability (by the current program) of the file.
|
||||
/// @returns true if the pathname references an executable file.
|
||||
/// @brief Determines if the path is an executable file in the file
|
||||
/// system.
|
||||
bool canExecute() const;
|
||||
|
||||
/// This function builds a list of paths that are the names of the
|
||||
/// files and directories in a directory.
|
||||
/// @returns true if an error occurs, true otherwise
|
||||
/// @brief Build a list of directory's contents.
|
||||
bool getDirectoryContents(
|
||||
std::set<Path> &paths, ///< The resulting list of file & directory names
|
||||
std::string* ErrMsg ///< Optional place to return an error message.
|
||||
) const;
|
||||
|
||||
/// @}
|
||||
/// @name Path Mutators
|
||||
/// @{
|
||||
public:
|
||||
/// The path name is cleared and becomes empty. This is an invalid
|
||||
/// path name but is the *only* invalid path name. This is provided
|
||||
/// so that path objects can be used to indicate the lack of a
|
||||
/// valid path being found.
|
||||
/// @brief Make the path empty.
|
||||
void clear() { path.clear(); }
|
||||
|
||||
/// This method sets the Path object to \p unverified_path. This can fail
|
||||
/// if the \p unverified_path does not pass the syntactic checks of the
|
||||
/// isValid() method. If verification fails, the Path object remains
|
||||
/// unchanged and false is returned. Otherwise true is returned and the
|
||||
/// Path object takes on the path value of \p unverified_path
|
||||
/// @returns true if the path was set, false otherwise.
|
||||
/// @param unverified_path The path to be set in Path object.
|
||||
/// @brief Set a full path from a StringRef
|
||||
bool set(StringRef unverified_path);
|
||||
|
||||
/// One path component is removed from the Path. If only one component is
|
||||
/// present in the path, the Path object becomes empty. If the Path object
|
||||
/// is empty, no change is made.
|
||||
/// @returns false if the path component could not be removed.
|
||||
/// @brief Removes the last directory component of the Path.
|
||||
bool eraseComponent();
|
||||
|
||||
/// The \p component is added to the end of the Path if it is a legal
|
||||
/// name for the operating system. A directory separator will be added if
|
||||
/// needed.
|
||||
/// @returns false if the path component could not be added.
|
||||
/// @brief Appends one path component to the Path.
|
||||
bool appendComponent(StringRef component);
|
||||
|
||||
/// A period and the \p suffix are appended to the end of the pathname.
|
||||
/// When the \p suffix is empty, no action is performed.
|
||||
/// @brief Adds a period and the \p suffix to the end of the pathname.
|
||||
void appendSuffix(StringRef suffix);
|
||||
|
||||
/// The suffix of the filename is erased. The suffix begins with and
|
||||
/// includes the last . character in the filename after the last directory
|
||||
/// separator and extends until the end of the name. If no . character is
|
||||
/// after the last directory separator, then the file name is left
|
||||
/// unchanged (i.e. it was already without a suffix) but the function
|
||||
/// returns false.
|
||||
/// @returns false if there was no suffix to remove, true otherwise.
|
||||
/// @brief Remove the suffix from a path name.
|
||||
bool eraseSuffix();
|
||||
|
||||
/// The current Path name is made unique in the file system. Upon return,
|
||||
/// the Path will have been changed to make a unique file in the file
|
||||
/// system or it will not have been changed if the current path name is
|
||||
/// already unique.
|
||||
/// @throws std::string if an unrecoverable error occurs.
|
||||
/// @brief Make the current path name unique in the file system.
|
||||
bool makeUnique( bool reuse_current /*= true*/, std::string* ErrMsg );
|
||||
|
||||
/// The current Path name is made absolute by prepending the
|
||||
/// current working directory if necessary.
|
||||
LLVM_ATTRIBUTE_DEPRECATED(
|
||||
void makeAbsolute(),
|
||||
LLVM_PATH_DEPRECATED_MSG(fs::make_absolute));
|
||||
|
||||
/// @}
|
||||
/// @name Disk Mutators
|
||||
/// @{
|
||||
public:
|
||||
/// This method attempts to make the file referenced by the Path object
|
||||
/// available for reading so that the canRead() method will return true.
|
||||
/// @brief Make the file readable;
|
||||
bool makeReadableOnDisk(std::string* ErrMsg = 0);
|
||||
|
||||
/// This method attempts to make the file referenced by the Path object
|
||||
/// available for writing so that the canWrite() method will return true.
|
||||
/// @brief Make the file writable;
|
||||
bool makeWriteableOnDisk(std::string* ErrMsg = 0);
|
||||
|
||||
/// This method attempts to make the file referenced by the Path object
|
||||
/// available for execution so that the canExecute() method will return
|
||||
/// true.
|
||||
/// @brief Make the file readable;
|
||||
bool makeExecutableOnDisk(std::string* ErrMsg = 0);
|
||||
|
||||
/// This method allows the last modified time stamp and permission bits
|
||||
/// to be set on the disk object referenced by the Path.
|
||||
/// @throws std::string if an error occurs.
|
||||
/// @returns true on error.
|
||||
/// @brief Set the status information.
|
||||
bool setStatusInfoOnDisk(const FileStatus &SI,
|
||||
std::string *ErrStr = 0) const;
|
||||
|
||||
/// This method attempts to create a directory in the file system with the
|
||||
/// same name as the Path object. The \p create_parents parameter controls
|
||||
/// whether intermediate directories are created or not. if \p
|
||||
/// create_parents is true, then an attempt will be made to create all
|
||||
/// intermediate directories, as needed. If \p create_parents is false,
|
||||
/// then only the final directory component of the Path name will be
|
||||
/// created. The created directory will have no entries.
|
||||
/// @returns true if the directory could not be created, false otherwise
|
||||
/// @brief Create the directory this Path refers to.
|
||||
bool createDirectoryOnDisk(
|
||||
bool create_parents = false, ///< Determines whether non-existent
|
||||
///< directory components other than the last one (the "parents")
|
||||
///< are created or not.
|
||||
std::string* ErrMsg = 0 ///< Optional place to put error messages.
|
||||
);
|
||||
|
||||
/// This method attempts to create a file in the file system with the same
|
||||
/// name as the Path object. The intermediate directories must all exist
|
||||
/// at the time this method is called. Use createDirectoriesOnDisk to
|
||||
/// accomplish that. The created file will be empty upon return from this
|
||||
/// function.
|
||||
/// @returns true if the file could not be created, false otherwise.
|
||||
/// @brief Create the file this Path refers to.
|
||||
bool createFileOnDisk(
|
||||
std::string* ErrMsg = 0 ///< Optional place to put error messages.
|
||||
);
|
||||
|
||||
/// This is like createFile except that it creates a temporary file. A
|
||||
/// unique temporary file name is generated based on the contents of
|
||||
/// \p this before the call. The new name is assigned to \p this and the
|
||||
/// file is created. Note that this will both change the Path object
|
||||
/// *and* create the corresponding file. This function will ensure that
|
||||
/// the newly generated temporary file name is unique in the file system.
|
||||
/// @returns true if the file couldn't be created, false otherwise.
|
||||
/// @brief Create a unique temporary file
|
||||
bool createTemporaryFileOnDisk(
|
||||
bool reuse_current = false, ///< When set to true, this parameter
|
||||
///< indicates that if the current file name does not exist then
|
||||
///< it will be used without modification.
|
||||
std::string* ErrMsg = 0 ///< Optional place to put error messages
|
||||
);
|
||||
|
||||
/// This method renames the file referenced by \p this as \p newName. The
|
||||
/// file referenced by \p this must exist. The file referenced by
|
||||
/// \p newName does not need to exist.
|
||||
/// @returns true on error, false otherwise
|
||||
/// @brief Rename one file as another.
|
||||
bool renamePathOnDisk(const Path& newName, std::string* ErrMsg);
|
||||
|
||||
/// This method attempts to destroy the file or directory named by the
|
||||
/// last component of the Path. If the Path refers to a directory and the
|
||||
/// \p destroy_contents is false, an attempt will be made to remove just
|
||||
/// the directory (the final Path component). If \p destroy_contents is
|
||||
/// true, an attempt will be made to remove the entire contents of the
|
||||
/// directory, recursively. If the Path refers to a file, the
|
||||
/// \p destroy_contents parameter is ignored.
|
||||
/// @param destroy_contents Indicates whether the contents of a destroyed
|
||||
/// @param Err An optional string to receive an error message.
|
||||
/// directory should also be destroyed (recursively).
|
||||
/// @returns false if the file/directory was destroyed, true on error.
|
||||
/// @brief Removes the file or directory from the filesystem.
|
||||
bool eraseFromDisk(bool destroy_contents = false,
|
||||
std::string *Err = 0) const;
|
||||
|
||||
|
||||
/// MapInFilePages - This is a low level system API to map in the file
|
||||
/// that is currently opened as FD into the current processes' address
|
||||
/// space for read only access. This function may return null on failure
|
||||
/// or if the system cannot provide the following constraints:
|
||||
/// 1) The pages must be valid after the FD is closed, until
|
||||
/// UnMapFilePages is called.
|
||||
/// 2) Any padding after the end of the file must be zero filled, if
|
||||
/// present.
|
||||
/// 3) The pages must be contiguous.
|
||||
///
|
||||
/// This API is not intended for general use, clients should use
|
||||
/// MemoryBuffer::getFile instead.
|
||||
static const char *MapInFilePages(int FD, size_t FileSize,
|
||||
off_t Offset);
|
||||
|
||||
/// UnMapFilePages - Free pages mapped into the current process by
|
||||
/// MapInFilePages.
|
||||
///
|
||||
/// This API is not intended for general use, clients should use
|
||||
/// MemoryBuffer::getFile instead.
|
||||
static void UnMapFilePages(const char *Base, size_t FileSize);
|
||||
|
||||
/// @}
|
||||
/// @name Data
|
||||
/// @{
|
||||
protected:
|
||||
// Our win32 implementation relies on this string being mutable.
|
||||
mutable std::string path; ///< Storage for the path name.
|
||||
|
||||
|
||||
/// @}
|
||||
};
|
||||
|
||||
/// This class is identical to Path class except it allows you to obtain the
|
||||
/// file status of the Path as well. The reason for the distinction is one of
|
||||
/// efficiency. First, the file status requires additional space and the space
|
||||
/// is incorporated directly into PathWithStatus without an additional malloc.
|
||||
/// Second, obtaining status information is an expensive operation on most
|
||||
/// operating systems so we want to be careful and explicit about where we
|
||||
/// allow this operation in LLVM.
|
||||
/// @brief Path with file status class.
|
||||
class PathWithStatus : public Path {
|
||||
/// @name Constructors
|
||||
/// @{
|
||||
public:
|
||||
/// @brief Default constructor
|
||||
PathWithStatus() : Path(), status(), fsIsValid(false) {}
|
||||
|
||||
/// @brief Copy constructor
|
||||
PathWithStatus(const PathWithStatus &that)
|
||||
: Path(static_cast<const Path&>(that)), status(that.status),
|
||||
fsIsValid(that.fsIsValid) {}
|
||||
|
||||
/// This constructor allows construction from a Path object
|
||||
/// @brief Path constructor
|
||||
PathWithStatus(const Path &other)
|
||||
: Path(other), status(), fsIsValid(false) {}
|
||||
|
||||
/// This constructor will accept a char* or std::string as a path. No
|
||||
/// checking is done on this path to determine if it is valid. To
|
||||
/// determine validity of the path, use the isValid method.
|
||||
/// @brief Construct a Path from a string.
|
||||
explicit PathWithStatus(
|
||||
StringRef p ///< The path to assign.
|
||||
) : Path(p), status(), fsIsValid(false) {}
|
||||
|
||||
/// This constructor will accept a character range as a path. No checking
|
||||
/// is done on this path to determine if it is valid. To determine
|
||||
/// validity of the path, use the isValid method.
|
||||
/// @brief Construct a Path from a string.
|
||||
explicit PathWithStatus(
|
||||
const char *StrStart, ///< Pointer to the first character of the path
|
||||
unsigned StrLen ///< Length of the path.
|
||||
) : Path(StrStart, StrLen), status(), fsIsValid(false) {}
|
||||
|
||||
/// Makes a copy of \p that to \p this.
|
||||
/// @returns \p this
|
||||
/// @brief Assignment Operator
|
||||
PathWithStatus &operator=(const PathWithStatus &that) {
|
||||
static_cast<Path&>(*this) = static_cast<const Path&>(that);
|
||||
status = that.status;
|
||||
fsIsValid = that.fsIsValid;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Makes a copy of \p that to \p this.
|
||||
/// @returns \p this
|
||||
/// @brief Assignment Operator
|
||||
PathWithStatus &operator=(const Path &that) {
|
||||
static_cast<Path&>(*this) = static_cast<const Path&>(that);
|
||||
fsIsValid = false;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// @}
|
||||
/// @name Methods
|
||||
/// @{
|
||||
public:
|
||||
/// This function returns status information about the file. The type of
|
||||
/// path (file or directory) is updated to reflect the actual contents
|
||||
/// of the file system.
|
||||
/// @returns 0 on failure, with Error explaining why (if non-zero),
|
||||
/// otherwise returns a pointer to a FileStatus structure on success.
|
||||
/// @brief Get file status.
|
||||
const FileStatus *getFileStatus(
|
||||
bool forceUpdate = false, ///< Force an update from the file system
|
||||
std::string *Error = 0 ///< Optional place to return an error msg.
|
||||
) const;
|
||||
|
||||
/// @}
|
||||
/// @name Data
|
||||
/// @{
|
||||
private:
|
||||
mutable FileStatus status; ///< Status information.
|
||||
mutable bool fsIsValid; ///< Whether we've obtained it or not
|
||||
|
||||
/// @}
|
||||
};
|
||||
|
||||
/// This enumeration delineates the kinds of files that LLVM knows about.
|
||||
enum LLVMFileType {
|
||||
Unknown_FileType = 0, ///< Unrecognized file
|
||||
Bitcode_FileType, ///< Bitcode file
|
||||
Archive_FileType, ///< ar style archive file
|
||||
ELF_Relocatable_FileType, ///< ELF Relocatable object file
|
||||
ELF_Executable_FileType, ///< ELF Executable image
|
||||
ELF_SharedObject_FileType, ///< ELF dynamically linked shared lib
|
||||
ELF_Core_FileType, ///< ELF core image
|
||||
Mach_O_Object_FileType, ///< Mach-O Object file
|
||||
Mach_O_Executable_FileType, ///< Mach-O Executable
|
||||
Mach_O_FixedVirtualMemorySharedLib_FileType, ///< Mach-O Shared Lib, FVM
|
||||
Mach_O_Core_FileType, ///< Mach-O Core File
|
||||
Mach_O_PreloadExecutable_FileType, ///< Mach-O Preloaded Executable
|
||||
Mach_O_DynamicallyLinkedSharedLib_FileType, ///< Mach-O dynlinked shared lib
|
||||
Mach_O_DynamicLinker_FileType, ///< The Mach-O dynamic linker
|
||||
Mach_O_Bundle_FileType, ///< Mach-O Bundle file
|
||||
Mach_O_DynamicallyLinkedSharedLibStub_FileType, ///< Mach-O Shared lib stub
|
||||
Mach_O_DSYMCompanion_FileType, ///< Mach-O dSYM companion file
|
||||
COFF_FileType ///< COFF object file or lib
|
||||
};
|
||||
|
||||
/// This utility function allows any memory block to be examined in order
|
||||
/// to determine its file type.
|
||||
LLVMFileType IdentifyFileType(const char*magic, unsigned length);
|
||||
|
||||
/// This function can be used to copy the file specified by Src to the
|
||||
/// file specified by Dest. If an error occurs, Dest is removed.
|
||||
/// @returns true if an error occurs, false otherwise
|
||||
/// @brief Copy one file to another.
|
||||
bool CopyFile(const Path& Dest, const Path& Src, std::string* ErrMsg);
|
||||
|
||||
/// This is the OS-specific path separator: a colon on Unix or a semicolon
|
||||
/// on Windows.
|
||||
extern const char PathSeparator;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
381
thirdparty/clang/include/llvm/Support/PathV2.h
vendored
Normal file
381
thirdparty/clang/include/llvm/Support/PathV2.h
vendored
Normal file
@@ -0,0 +1,381 @@
|
||||
//===- llvm/Support/PathV2.h - Path Operating System Concept ----*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file declares the llvm::sys::path namespace. It is designed after
|
||||
// TR2/boost filesystem (v3), but modified to remove exception handling and the
|
||||
// path class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_PATHV2_H
|
||||
#define LLVM_SUPPORT_PATHV2_H
|
||||
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/ADT/Twine.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include <iterator>
|
||||
|
||||
namespace llvm {
|
||||
namespace sys {
|
||||
namespace path {
|
||||
|
||||
/// @name Lexical Component Iterator
|
||||
/// @{
|
||||
|
||||
/// @brief Path iterator.
|
||||
///
|
||||
/// This is a bidirectional iterator that iterates over the individual
|
||||
/// components in \a path. The forward traversal order is as follows:
|
||||
/// * The root-name element, if present.
|
||||
/// * The root-directory element, if present.
|
||||
/// * Each successive filename element, if present.
|
||||
/// * Dot, if one or more trailing non-root slash characters are present.
|
||||
/// The backwards traversal order is the reverse of forward traversal.
|
||||
///
|
||||
/// Iteration examples. Each component is separated by ',':
|
||||
/// @code
|
||||
/// / => /
|
||||
/// /foo => /,foo
|
||||
/// foo/ => foo,.
|
||||
/// /foo/bar => /,foo,bar
|
||||
/// ../ => ..,.
|
||||
/// C:\foo\bar => C:,/,foo,bar
|
||||
/// @endcode
|
||||
class const_iterator {
|
||||
StringRef Path; ///< The entire path.
|
||||
StringRef Component; ///< The current component. Not necessarily in Path.
|
||||
size_t Position; ///< The iterators current position within Path.
|
||||
|
||||
// An end iterator has Position = Path.size() + 1.
|
||||
friend const_iterator begin(StringRef path);
|
||||
friend const_iterator end(StringRef path);
|
||||
|
||||
public:
|
||||
typedef const StringRef value_type;
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef value_type &reference;
|
||||
typedef value_type *pointer;
|
||||
typedef std::bidirectional_iterator_tag iterator_category;
|
||||
|
||||
reference operator*() const { return Component; }
|
||||
pointer operator->() const { return &Component; }
|
||||
const_iterator &operator++(); // preincrement
|
||||
const_iterator &operator++(int); // postincrement
|
||||
const_iterator &operator--(); // predecrement
|
||||
const_iterator &operator--(int); // postdecrement
|
||||
bool operator==(const const_iterator &RHS) const;
|
||||
bool operator!=(const const_iterator &RHS) const;
|
||||
|
||||
/// @brief Difference in bytes between this and RHS.
|
||||
ptrdiff_t operator-(const const_iterator &RHS) const;
|
||||
};
|
||||
|
||||
typedef std::reverse_iterator<const_iterator> reverse_iterator;
|
||||
|
||||
/// @brief Get begin iterator over \a path.
|
||||
/// @param path Input path.
|
||||
/// @returns Iterator initialized with the first component of \a path.
|
||||
const_iterator begin(StringRef path);
|
||||
|
||||
/// @brief Get end iterator over \a path.
|
||||
/// @param path Input path.
|
||||
/// @returns Iterator initialized to the end of \a path.
|
||||
const_iterator end(StringRef path);
|
||||
|
||||
/// @brief Get reverse begin iterator over \a path.
|
||||
/// @param path Input path.
|
||||
/// @returns Iterator initialized with the first reverse component of \a path.
|
||||
inline reverse_iterator rbegin(StringRef path) {
|
||||
return reverse_iterator(end(path));
|
||||
}
|
||||
|
||||
/// @brief Get reverse end iterator over \a path.
|
||||
/// @param path Input path.
|
||||
/// @returns Iterator initialized to the reverse end of \a path.
|
||||
inline reverse_iterator rend(StringRef path) {
|
||||
return reverse_iterator(begin(path));
|
||||
}
|
||||
|
||||
/// @}
|
||||
/// @name Lexical Modifiers
|
||||
/// @{
|
||||
|
||||
/// @brief Remove the last component from \a path unless it is the root dir.
|
||||
///
|
||||
/// @code
|
||||
/// directory/filename.cpp => directory/
|
||||
/// directory/ => directory
|
||||
/// / => /
|
||||
/// @endcode
|
||||
///
|
||||
/// @param path A path that is modified to not have a file component.
|
||||
void remove_filename(SmallVectorImpl<char> &path);
|
||||
|
||||
/// @brief Replace the file extension of \a path with \a extension.
|
||||
///
|
||||
/// @code
|
||||
/// ./filename.cpp => ./filename.extension
|
||||
/// ./filename => ./filename.extension
|
||||
/// ./ => ./.extension
|
||||
/// @endcode
|
||||
///
|
||||
/// @param path A path that has its extension replaced with \a extension.
|
||||
/// @param extension The extension to be added. It may be empty. It may also
|
||||
/// optionally start with a '.', if it does not, one will be
|
||||
/// prepended.
|
||||
void replace_extension(SmallVectorImpl<char> &path, const Twine &extension);
|
||||
|
||||
/// @brief Append to path.
|
||||
///
|
||||
/// @code
|
||||
/// /foo + bar/f => /foo/bar/f
|
||||
/// /foo/ + bar/f => /foo/bar/f
|
||||
/// foo + bar/f => foo/bar/f
|
||||
/// @endcode
|
||||
///
|
||||
/// @param path Set to \a path + \a component.
|
||||
/// @param a The component to be appended to \a path.
|
||||
void append(SmallVectorImpl<char> &path, const Twine &a,
|
||||
const Twine &b = "",
|
||||
const Twine &c = "",
|
||||
const Twine &d = "");
|
||||
|
||||
/// @brief Append to path.
|
||||
///
|
||||
/// @code
|
||||
/// /foo + [bar,f] => /foo/bar/f
|
||||
/// /foo/ + [bar,f] => /foo/bar/f
|
||||
/// foo + [bar,f] => foo/bar/f
|
||||
/// @endcode
|
||||
///
|
||||
/// @param path Set to \a path + [\a begin, \a end).
|
||||
/// @param begin Start of components to append.
|
||||
/// @param end One past the end of components to append.
|
||||
void append(SmallVectorImpl<char> &path,
|
||||
const_iterator begin, const_iterator end);
|
||||
|
||||
/// @}
|
||||
/// @name Transforms (or some other better name)
|
||||
/// @{
|
||||
|
||||
/// Convert path to the native form. This is used to give paths to users and
|
||||
/// operating system calls in the platform's normal way. For example, on Windows
|
||||
/// all '/' are converted to '\'.
|
||||
///
|
||||
/// @param path A path that is transformed to native format.
|
||||
/// @param result Holds the result of the transformation.
|
||||
void native(const Twine &path, SmallVectorImpl<char> &result);
|
||||
|
||||
/// @}
|
||||
/// @name Lexical Observers
|
||||
/// @{
|
||||
|
||||
/// @brief Get root name.
|
||||
///
|
||||
/// @code
|
||||
/// //net/hello => //net
|
||||
/// c:/hello => c: (on Windows, on other platforms nothing)
|
||||
/// /hello => <empty>
|
||||
/// @endcode
|
||||
///
|
||||
/// @param path Input path.
|
||||
/// @result The root name of \a path if it has one, otherwise "".
|
||||
const StringRef root_name(StringRef path);
|
||||
|
||||
/// @brief Get root directory.
|
||||
///
|
||||
/// @code
|
||||
/// /goo/hello => /
|
||||
/// c:/hello => /
|
||||
/// d/file.txt => <empty>
|
||||
/// @endcode
|
||||
///
|
||||
/// @param path Input path.
|
||||
/// @result The root directory of \a path if it has one, otherwise
|
||||
/// "".
|
||||
const StringRef root_directory(StringRef path);
|
||||
|
||||
/// @brief Get root path.
|
||||
///
|
||||
/// Equivalent to root_name + root_directory.
|
||||
///
|
||||
/// @param path Input path.
|
||||
/// @result The root path of \a path if it has one, otherwise "".
|
||||
const StringRef root_path(StringRef path);
|
||||
|
||||
/// @brief Get relative path.
|
||||
///
|
||||
/// @code
|
||||
/// C:\hello\world => hello\world
|
||||
/// foo/bar => foo/bar
|
||||
/// /foo/bar => foo/bar
|
||||
/// @endcode
|
||||
///
|
||||
/// @param path Input path.
|
||||
/// @result The path starting after root_path if one exists, otherwise "".
|
||||
const StringRef relative_path(StringRef path);
|
||||
|
||||
/// @brief Get parent path.
|
||||
///
|
||||
/// @code
|
||||
/// / => <empty>
|
||||
/// /foo => /
|
||||
/// foo/../bar => foo/..
|
||||
/// @endcode
|
||||
///
|
||||
/// @param path Input path.
|
||||
/// @result The parent path of \a path if one exists, otherwise "".
|
||||
const StringRef parent_path(StringRef path);
|
||||
|
||||
/// @brief Get filename.
|
||||
///
|
||||
/// @code
|
||||
/// /foo.txt => foo.txt
|
||||
/// . => .
|
||||
/// .. => ..
|
||||
/// / => /
|
||||
/// @endcode
|
||||
///
|
||||
/// @param path Input path.
|
||||
/// @result The filename part of \a path. This is defined as the last component
|
||||
/// of \a path.
|
||||
const StringRef filename(StringRef path);
|
||||
|
||||
/// @brief Get stem.
|
||||
///
|
||||
/// If filename contains a dot but not solely one or two dots, result is the
|
||||
/// substring of filename ending at (but not including) the last dot. Otherwise
|
||||
/// it is filename.
|
||||
///
|
||||
/// @code
|
||||
/// /foo/bar.txt => bar
|
||||
/// /foo/bar => bar
|
||||
/// /foo/.txt => <empty>
|
||||
/// /foo/. => .
|
||||
/// /foo/.. => ..
|
||||
/// @endcode
|
||||
///
|
||||
/// @param path Input path.
|
||||
/// @result The stem of \a path.
|
||||
const StringRef stem(StringRef path);
|
||||
|
||||
/// @brief Get extension.
|
||||
///
|
||||
/// If filename contains a dot but not solely one or two dots, result is the
|
||||
/// substring of filename starting at (and including) the last dot, and ending
|
||||
/// at the end of \a path. Otherwise "".
|
||||
///
|
||||
/// @code
|
||||
/// /foo/bar.txt => .txt
|
||||
/// /foo/bar => <empty>
|
||||
/// /foo/.txt => .txt
|
||||
/// @endcode
|
||||
///
|
||||
/// @param path Input path.
|
||||
/// @result The extension of \a path.
|
||||
const StringRef extension(StringRef path);
|
||||
|
||||
/// @brief Check whether the given char is a path separator on the host OS.
|
||||
///
|
||||
/// @param value a character
|
||||
/// @result true if \a value is a path separator character on the host OS
|
||||
bool is_separator(char value);
|
||||
|
||||
/// @brief Get the typical temporary directory for the system, e.g.,
|
||||
/// "/var/tmp" or "C:/TEMP"
|
||||
///
|
||||
/// @param erasedOnReboot Whether to favor a path that is erased on reboot
|
||||
/// rather than one that potentially persists longer. This parameter will be
|
||||
/// ignored if the user or system has set the typical environment variable
|
||||
/// (e.g., TEMP on Windows, TMPDIR on *nix) to specify a temporary directory.
|
||||
///
|
||||
/// @param result Holds the resulting path name.
|
||||
void system_temp_directory(bool erasedOnReboot, SmallVectorImpl<char> &result);
|
||||
|
||||
/// @brief Has root name?
|
||||
///
|
||||
/// root_name != ""
|
||||
///
|
||||
/// @param path Input path.
|
||||
/// @result True if the path has a root name, false otherwise.
|
||||
bool has_root_name(const Twine &path);
|
||||
|
||||
/// @brief Has root directory?
|
||||
///
|
||||
/// root_directory != ""
|
||||
///
|
||||
/// @param path Input path.
|
||||
/// @result True if the path has a root directory, false otherwise.
|
||||
bool has_root_directory(const Twine &path);
|
||||
|
||||
/// @brief Has root path?
|
||||
///
|
||||
/// root_path != ""
|
||||
///
|
||||
/// @param path Input path.
|
||||
/// @result True if the path has a root path, false otherwise.
|
||||
bool has_root_path(const Twine &path);
|
||||
|
||||
/// @brief Has relative path?
|
||||
///
|
||||
/// relative_path != ""
|
||||
///
|
||||
/// @param path Input path.
|
||||
/// @result True if the path has a relative path, false otherwise.
|
||||
bool has_relative_path(const Twine &path);
|
||||
|
||||
/// @brief Has parent path?
|
||||
///
|
||||
/// parent_path != ""
|
||||
///
|
||||
/// @param path Input path.
|
||||
/// @result True if the path has a parent path, false otherwise.
|
||||
bool has_parent_path(const Twine &path);
|
||||
|
||||
/// @brief Has filename?
|
||||
///
|
||||
/// filename != ""
|
||||
///
|
||||
/// @param path Input path.
|
||||
/// @result True if the path has a filename, false otherwise.
|
||||
bool has_filename(const Twine &path);
|
||||
|
||||
/// @brief Has stem?
|
||||
///
|
||||
/// stem != ""
|
||||
///
|
||||
/// @param path Input path.
|
||||
/// @result True if the path has a stem, false otherwise.
|
||||
bool has_stem(const Twine &path);
|
||||
|
||||
/// @brief Has extension?
|
||||
///
|
||||
/// extension != ""
|
||||
///
|
||||
/// @param path Input path.
|
||||
/// @result True if the path has a extension, false otherwise.
|
||||
bool has_extension(const Twine &path);
|
||||
|
||||
/// @brief Is path absolute?
|
||||
///
|
||||
/// @param path Input path.
|
||||
/// @result True if the path is absolute, false if it is not.
|
||||
bool is_absolute(const Twine &path);
|
||||
|
||||
/// @brief Is path relative?
|
||||
///
|
||||
/// @param path Input path.
|
||||
/// @result True if the path is relative, false if it is not.
|
||||
bool is_relative(const Twine &path);
|
||||
|
||||
} // end namespace path
|
||||
} // end namespace sys
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
1020
thirdparty/clang/include/llvm/Support/PatternMatch.h
vendored
Normal file
1020
thirdparty/clang/include/llvm/Support/PatternMatch.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
37
thirdparty/clang/include/llvm/Support/PluginLoader.h
vendored
Normal file
37
thirdparty/clang/include/llvm/Support/PluginLoader.h
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
//===-- llvm/Support/PluginLoader.h - Plugin Loader for Tools ---*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// A tool can #include this file to get a -load option that allows the user to
|
||||
// load arbitrary shared objects into the tool's address space. Note that this
|
||||
// header can only be included by a program ONCE, so it should never to used by
|
||||
// library authors.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_PLUGINLOADER_H
|
||||
#define LLVM_SUPPORT_PLUGINLOADER_H
|
||||
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
|
||||
namespace llvm {
|
||||
struct PluginLoader {
|
||||
void operator=(const std::string &Filename);
|
||||
static unsigned getNumPlugins();
|
||||
static std::string& getPlugin(unsigned num);
|
||||
};
|
||||
|
||||
#ifndef DONT_GET_PLUGIN_LOADER_OPTION
|
||||
// This causes operator= above to be invoked for every -load option.
|
||||
static cl::opt<PluginLoader, false, cl::parser<std::string> >
|
||||
LoadOpt("load", cl::ZeroOrMore, cl::value_desc("pluginfilename"),
|
||||
cl::desc("Load the specified plugin"));
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
81
thirdparty/clang/include/llvm/Support/PointerLikeTypeTraits.h
vendored
Normal file
81
thirdparty/clang/include/llvm/Support/PointerLikeTypeTraits.h
vendored
Normal file
@@ -0,0 +1,81 @@
|
||||
//===- llvm/Support/PointerLikeTypeTraits.h - Pointer 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 defines the PointerLikeTypeTraits class. This allows data
|
||||
// structures to reason about pointers and other things that are pointer sized.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_POINTERLIKETYPETRAITS_H
|
||||
#define LLVM_SUPPORT_POINTERLIKETYPETRAITS_H
|
||||
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
/// PointerLikeTypeTraits - This is a traits object that is used to handle
|
||||
/// pointer types and things that are just wrappers for pointers as a uniform
|
||||
/// entity.
|
||||
template <typename T>
|
||||
class PointerLikeTypeTraits {
|
||||
// getAsVoidPointer
|
||||
// getFromVoidPointer
|
||||
// getNumLowBitsAvailable
|
||||
};
|
||||
|
||||
// Provide PointerLikeTypeTraits for non-cvr pointers.
|
||||
template<typename T>
|
||||
class PointerLikeTypeTraits<T*> {
|
||||
public:
|
||||
static inline void *getAsVoidPointer(T* P) { return P; }
|
||||
static inline T *getFromVoidPointer(void *P) {
|
||||
return static_cast<T*>(P);
|
||||
}
|
||||
|
||||
/// Note, we assume here that malloc returns objects at least 4-byte aligned.
|
||||
/// However, this may be wrong, or pointers may be from something other than
|
||||
/// malloc. In this case, you should specialize this template to reduce this.
|
||||
///
|
||||
/// All clients should use assertions to do a run-time check to ensure that
|
||||
/// this is actually true.
|
||||
enum { NumLowBitsAvailable = 2 };
|
||||
};
|
||||
|
||||
// Provide PointerLikeTypeTraits for const pointers.
|
||||
template<typename T>
|
||||
class PointerLikeTypeTraits<const T*> {
|
||||
typedef PointerLikeTypeTraits<T*> NonConst;
|
||||
|
||||
public:
|
||||
static inline const void *getAsVoidPointer(const T* P) {
|
||||
return NonConst::getAsVoidPointer(const_cast<T*>(P));
|
||||
}
|
||||
static inline const T *getFromVoidPointer(const void *P) {
|
||||
return NonConst::getFromVoidPointer(const_cast<void*>(P));
|
||||
}
|
||||
enum { NumLowBitsAvailable = NonConst::NumLowBitsAvailable };
|
||||
};
|
||||
|
||||
// Provide PointerLikeTypeTraits for uintptr_t.
|
||||
template<>
|
||||
class PointerLikeTypeTraits<uintptr_t> {
|
||||
public:
|
||||
static inline void *getAsVoidPointer(uintptr_t P) {
|
||||
return reinterpret_cast<void*>(P);
|
||||
}
|
||||
static inline uintptr_t getFromVoidPointer(void *P) {
|
||||
return reinterpret_cast<uintptr_t>(P);
|
||||
}
|
||||
// No bits are available!
|
||||
enum { NumLowBitsAvailable = 0 };
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
70
thirdparty/clang/include/llvm/Support/PredIteratorCache.h
vendored
Normal file
70
thirdparty/clang/include/llvm/Support/PredIteratorCache.h
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
//===- llvm/Support/PredIteratorCache.h - pred_iterator Cache ---*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the PredIteratorCache class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/Support/Allocator.h"
|
||||
#include "llvm/Support/CFG.h"
|
||||
|
||||
#ifndef LLVM_SUPPORT_PREDITERATORCACHE_H
|
||||
#define LLVM_SUPPORT_PREDITERATORCACHE_H
|
||||
|
||||
namespace llvm {
|
||||
|
||||
/// PredIteratorCache - This class is an extremely trivial cache for
|
||||
/// predecessor iterator queries. This is useful for code that repeatedly
|
||||
/// wants the predecessor list for the same blocks.
|
||||
class PredIteratorCache {
|
||||
/// BlockToPredsMap - Pointer to null-terminated list.
|
||||
DenseMap<BasicBlock*, BasicBlock**> BlockToPredsMap;
|
||||
DenseMap<BasicBlock*, unsigned> BlockToPredCountMap;
|
||||
|
||||
/// Memory - This is the space that holds cached preds.
|
||||
BumpPtrAllocator Memory;
|
||||
public:
|
||||
|
||||
/// GetPreds - Get a cached list for the null-terminated predecessor list of
|
||||
/// the specified block. This can be used in a loop like this:
|
||||
/// for (BasicBlock **PI = PredCache->GetPreds(BB); *PI; ++PI)
|
||||
/// use(*PI);
|
||||
/// instead of:
|
||||
/// for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI)
|
||||
BasicBlock **GetPreds(BasicBlock *BB) {
|
||||
BasicBlock **&Entry = BlockToPredsMap[BB];
|
||||
if (Entry) return Entry;
|
||||
|
||||
SmallVector<BasicBlock*, 32> PredCache(pred_begin(BB), pred_end(BB));
|
||||
PredCache.push_back(0); // null terminator.
|
||||
|
||||
BlockToPredCountMap[BB] = PredCache.size()-1;
|
||||
|
||||
Entry = Memory.Allocate<BasicBlock*>(PredCache.size());
|
||||
std::copy(PredCache.begin(), PredCache.end(), Entry);
|
||||
return Entry;
|
||||
}
|
||||
|
||||
unsigned GetNumPreds(BasicBlock *BB) {
|
||||
GetPreds(BB);
|
||||
return BlockToPredCountMap[BB];
|
||||
}
|
||||
|
||||
/// clear - Remove all information.
|
||||
void clear() {
|
||||
BlockToPredsMap.clear();
|
||||
BlockToPredCountMap.clear();
|
||||
Memory.Reset();
|
||||
}
|
||||
};
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
73
thirdparty/clang/include/llvm/Support/PrettyStackTrace.h
vendored
Normal file
73
thirdparty/clang/include/llvm/Support/PrettyStackTrace.h
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
//===- llvm/Support/PrettyStackTrace.h - Pretty Crash Handling --*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the PrettyStackTraceEntry class, which is used to make
|
||||
// crashes give more contextual information about what the program was doing
|
||||
// when it crashed.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_PRETTYSTACKTRACE_H
|
||||
#define LLVM_SUPPORT_PRETTYSTACKTRACE_H
|
||||
|
||||
#include "llvm/Support/Compiler.h"
|
||||
|
||||
namespace llvm {
|
||||
class raw_ostream;
|
||||
|
||||
/// DisablePrettyStackTrace - Set this to true to disable this module. This
|
||||
/// might be necessary if the host application installs its own signal
|
||||
/// handlers which conflict with the ones installed by this module.
|
||||
/// Defaults to false.
|
||||
extern bool DisablePrettyStackTrace;
|
||||
|
||||
/// PrettyStackTraceEntry - This class is used to represent a frame of the
|
||||
/// "pretty" stack trace that is dumped when a program crashes. You can define
|
||||
/// subclasses of this and declare them on the program stack: when they are
|
||||
/// constructed and destructed, they will add their symbolic frames to a
|
||||
/// virtual stack trace. This gets dumped out if the program crashes.
|
||||
class PrettyStackTraceEntry {
|
||||
const PrettyStackTraceEntry *NextEntry;
|
||||
PrettyStackTraceEntry(const PrettyStackTraceEntry &) LLVM_DELETED_FUNCTION;
|
||||
void operator=(const PrettyStackTraceEntry&) LLVM_DELETED_FUNCTION;
|
||||
public:
|
||||
PrettyStackTraceEntry();
|
||||
virtual ~PrettyStackTraceEntry();
|
||||
|
||||
/// print - Emit information about this stack frame to OS.
|
||||
virtual void print(raw_ostream &OS) const = 0;
|
||||
|
||||
/// getNextEntry - Return the next entry in the list of frames.
|
||||
const PrettyStackTraceEntry *getNextEntry() const { return NextEntry; }
|
||||
};
|
||||
|
||||
/// PrettyStackTraceString - This object prints a specified string (which
|
||||
/// should not contain newlines) to the stream as the stack trace when a crash
|
||||
/// occurs.
|
||||
class PrettyStackTraceString : public PrettyStackTraceEntry {
|
||||
const char *Str;
|
||||
public:
|
||||
PrettyStackTraceString(const char *str) : Str(str) {}
|
||||
virtual void print(raw_ostream &OS) const LLVM_OVERRIDE;
|
||||
};
|
||||
|
||||
/// PrettyStackTraceProgram - This object prints a specified program arguments
|
||||
/// to the stream as the stack trace when a crash occurs.
|
||||
class PrettyStackTraceProgram : public PrettyStackTraceEntry {
|
||||
int ArgC;
|
||||
const char *const *ArgV;
|
||||
public:
|
||||
PrettyStackTraceProgram(int argc, const char * const*argv)
|
||||
: ArgC(argc), ArgV(argv) {}
|
||||
virtual void print(raw_ostream &OS) const LLVM_OVERRIDE;
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
252
thirdparty/clang/include/llvm/Support/Process.h
vendored
Normal file
252
thirdparty/clang/include/llvm/Support/Process.h
vendored
Normal file
@@ -0,0 +1,252 @@
|
||||
//===- llvm/Support/Process.h -----------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
/// \file
|
||||
///
|
||||
/// Provides a library for accessing information about this process and other
|
||||
/// processes on the operating system. Also provides means of spawning
|
||||
/// subprocess for commands. The design of this library is modeled after the
|
||||
/// proposed design of the Boost.Process library, and is design specifically to
|
||||
/// follow the style of standard libraries and potentially become a proposal
|
||||
/// for a standard library.
|
||||
///
|
||||
/// This file declares the llvm::sys::Process class which contains a collection
|
||||
/// of legacy static interfaces for extracting various information about the
|
||||
/// current process. The goal is to migrate users of this API over to the new
|
||||
/// interfaces.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_PROCESS_H
|
||||
#define LLVM_SUPPORT_PROCESS_H
|
||||
|
||||
#include "llvm/Config/llvm-config.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/Support/TimeValue.h"
|
||||
|
||||
namespace llvm {
|
||||
namespace sys {
|
||||
|
||||
class self_process;
|
||||
|
||||
/// \brief Generic base class which exposes information about an operating
|
||||
/// system process.
|
||||
///
|
||||
/// This base class is the core interface behind any OS process. It exposes
|
||||
/// methods to query for generic information about a particular process.
|
||||
///
|
||||
/// Subclasses implement this interface based on the mechanisms available, and
|
||||
/// can optionally expose more interfaces unique to certain process kinds.
|
||||
class process {
|
||||
protected:
|
||||
/// \brief Only specific subclasses of process objects can be destroyed.
|
||||
virtual ~process();
|
||||
|
||||
public:
|
||||
/// \brief Operating system specific type to identify a process.
|
||||
///
|
||||
/// Note that the windows one is defined to 'void *' as this is the
|
||||
/// documented type for HANDLE on windows, and we don't want to pull in the
|
||||
/// Windows headers here.
|
||||
#if defined(LLVM_ON_UNIX)
|
||||
typedef pid_t id_type;
|
||||
#elif defined(LLVM_ON_WIN32)
|
||||
typedef void *id_type; // Must match the type of HANDLE.
|
||||
#else
|
||||
#error Unsupported operating system.
|
||||
#endif
|
||||
|
||||
/// \brief Get the operating system specific identifier for this process.
|
||||
virtual id_type get_id() = 0;
|
||||
|
||||
/// \brief Get the user time consumed by this process.
|
||||
///
|
||||
/// Note that this is often an approximation and may be zero on platforms
|
||||
/// where we don't have good support for the functionality.
|
||||
virtual TimeValue get_user_time() const = 0;
|
||||
|
||||
/// \brief Get the system time consumed by this process.
|
||||
///
|
||||
/// Note that this is often an approximation and may be zero on platforms
|
||||
/// where we don't have good support for the functionality.
|
||||
virtual TimeValue get_system_time() const = 0;
|
||||
|
||||
/// \brief Get the wall time consumed by this process.
|
||||
///
|
||||
/// Note that this is often an approximation and may be zero on platforms
|
||||
/// where we don't have good support for the functionality.
|
||||
virtual TimeValue get_wall_time() const = 0;
|
||||
|
||||
/// \name Static factory routines for processes.
|
||||
/// @{
|
||||
|
||||
/// \brief Get the process object for the current process.
|
||||
static self_process *get_self();
|
||||
|
||||
/// @}
|
||||
|
||||
};
|
||||
|
||||
/// \brief The specific class representing the current process.
|
||||
///
|
||||
/// The current process can both specialize the implementation of the routines
|
||||
/// and can expose certain information not available for other OS processes.
|
||||
class self_process : public process {
|
||||
friend class process;
|
||||
|
||||
/// \brief Private destructor, as users shouldn't create objects of this
|
||||
/// type.
|
||||
virtual ~self_process();
|
||||
|
||||
public:
|
||||
virtual id_type get_id();
|
||||
virtual TimeValue get_user_time() const;
|
||||
virtual TimeValue get_system_time() const;
|
||||
virtual TimeValue get_wall_time() const;
|
||||
|
||||
/// \name Process configuration (sysconf on POSIX)
|
||||
/// @{
|
||||
|
||||
/// \brief Get the virtual memory page size.
|
||||
///
|
||||
/// Query the operating system for this process's page size.
|
||||
size_t page_size() const { return PageSize; };
|
||||
|
||||
/// @}
|
||||
|
||||
private:
|
||||
/// \name Cached process state.
|
||||
/// @{
|
||||
|
||||
/// \brief Cached page size, this cannot vary during the life of the process.
|
||||
size_t PageSize;
|
||||
|
||||
/// @}
|
||||
|
||||
/// \brief Constructor, used by \c process::get_self() only.
|
||||
self_process();
|
||||
};
|
||||
|
||||
|
||||
/// \brief A collection of legacy interfaces for querying information about the
|
||||
/// current executing process.
|
||||
class Process {
|
||||
public:
|
||||
/// \brief Return process memory usage.
|
||||
/// This static function will return the total amount of memory allocated
|
||||
/// by the process. This only counts the memory allocated via the malloc,
|
||||
/// calloc and realloc functions and includes any "free" holes in the
|
||||
/// allocated space.
|
||||
static size_t GetMallocUsage();
|
||||
|
||||
/// This static function will set \p user_time to the amount of CPU time
|
||||
/// spent in user (non-kernel) mode and \p sys_time to the amount of CPU
|
||||
/// time spent in system (kernel) mode. If the operating system does not
|
||||
/// support collection of these metrics, a zero TimeValue will be for both
|
||||
/// values.
|
||||
/// \param elapsed Returns the TimeValue::now() giving current time
|
||||
/// \param user_time Returns the current amount of user time for the process
|
||||
/// \param sys_time Returns the current amount of system time for the process
|
||||
static void GetTimeUsage(TimeValue &elapsed, TimeValue &user_time,
|
||||
TimeValue &sys_time);
|
||||
|
||||
/// This static function will return the process' current user id number.
|
||||
/// Not all operating systems support this feature. Where it is not
|
||||
/// supported, the function should return 65536 as the value.
|
||||
static int GetCurrentUserId();
|
||||
|
||||
/// This static function will return the process' current group id number.
|
||||
/// Not all operating systems support this feature. Where it is not
|
||||
/// supported, the function should return 65536 as the value.
|
||||
static int GetCurrentGroupId();
|
||||
|
||||
/// This function makes the necessary calls to the operating system to
|
||||
/// prevent core files or any other kind of large memory dumps that can
|
||||
/// occur when a program fails.
|
||||
/// @brief Prevent core file generation.
|
||||
static void PreventCoreFiles();
|
||||
|
||||
/// This function determines if the standard input is connected directly
|
||||
/// to a user's input (keyboard probably), rather than coming from a file
|
||||
/// or pipe.
|
||||
static bool StandardInIsUserInput();
|
||||
|
||||
/// This function determines if the standard output is connected to a
|
||||
/// "tty" or "console" window. That is, the output would be displayed to
|
||||
/// the user rather than being put on a pipe or stored in a file.
|
||||
static bool StandardOutIsDisplayed();
|
||||
|
||||
/// This function determines if the standard error is connected to a
|
||||
/// "tty" or "console" window. That is, the output would be displayed to
|
||||
/// the user rather than being put on a pipe or stored in a file.
|
||||
static bool StandardErrIsDisplayed();
|
||||
|
||||
/// This function determines if the given file descriptor is connected to
|
||||
/// a "tty" or "console" window. That is, the output would be displayed to
|
||||
/// the user rather than being put on a pipe or stored in a file.
|
||||
static bool FileDescriptorIsDisplayed(int fd);
|
||||
|
||||
/// This function determines if the given file descriptor is displayd and
|
||||
/// supports colors.
|
||||
static bool FileDescriptorHasColors(int fd);
|
||||
|
||||
/// This function determines the number of columns in the window
|
||||
/// if standard output is connected to a "tty" or "console"
|
||||
/// window. If standard output is not connected to a tty or
|
||||
/// console, or if the number of columns cannot be determined,
|
||||
/// this routine returns zero.
|
||||
static unsigned StandardOutColumns();
|
||||
|
||||
/// This function determines the number of columns in the window
|
||||
/// if standard error is connected to a "tty" or "console"
|
||||
/// window. If standard error is not connected to a tty or
|
||||
/// console, or if the number of columns cannot be determined,
|
||||
/// this routine returns zero.
|
||||
static unsigned StandardErrColumns();
|
||||
|
||||
/// This function determines whether the terminal connected to standard
|
||||
/// output supports colors. If standard output is not connected to a
|
||||
/// terminal, this function returns false.
|
||||
static bool StandardOutHasColors();
|
||||
|
||||
/// This function determines whether the terminal connected to standard
|
||||
/// error supports colors. If standard error is not connected to a
|
||||
/// terminal, this function returns false.
|
||||
static bool StandardErrHasColors();
|
||||
|
||||
/// Whether changing colors requires the output to be flushed.
|
||||
/// This is needed on systems that don't support escape sequences for
|
||||
/// changing colors.
|
||||
static bool ColorNeedsFlush();
|
||||
|
||||
/// This function returns the colorcode escape sequences.
|
||||
/// If ColorNeedsFlush() is true then this function will change the colors
|
||||
/// and return an empty escape sequence. In that case it is the
|
||||
/// responsibility of the client to flush the output stream prior to
|
||||
/// calling this function.
|
||||
static const char *OutputColor(char c, bool bold, bool bg);
|
||||
|
||||
/// Same as OutputColor, but only enables the bold attribute.
|
||||
static const char *OutputBold(bool bg);
|
||||
|
||||
/// This function returns the escape sequence to reverse forground and
|
||||
/// background colors.
|
||||
static const char *OutputReverse();
|
||||
|
||||
/// Resets the terminals colors, or returns an escape sequence to do so.
|
||||
static const char *ResetColor();
|
||||
|
||||
/// Get the result of a process wide random number generator. The
|
||||
/// generator will be automatically seeded in non-deterministic fashion.
|
||||
static unsigned GetRandomNumber();
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
151
thirdparty/clang/include/llvm/Support/Program.h
vendored
Normal file
151
thirdparty/clang/include/llvm/Support/Program.h
vendored
Normal file
@@ -0,0 +1,151 @@
|
||||
//===- llvm/Support/Program.h ------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file declares the llvm::sys::Program class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_PROGRAM_H
|
||||
#define LLVM_SUPPORT_PROGRAM_H
|
||||
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/Support/Path.h"
|
||||
|
||||
namespace llvm {
|
||||
class error_code;
|
||||
namespace sys {
|
||||
|
||||
// TODO: Add operations to communicate with the process, redirect its I/O,
|
||||
// etc.
|
||||
|
||||
/// This class provides an abstraction for programs that are executable by the
|
||||
/// operating system. It provides a platform generic way to find executable
|
||||
/// programs from the path and to execute them in various ways. The sys::Path
|
||||
/// class is used to specify the location of the Program.
|
||||
/// @since 1.4
|
||||
/// @brief An abstraction for finding and executing programs.
|
||||
class Program {
|
||||
/// Opaque handle for target specific data.
|
||||
void *Data_;
|
||||
|
||||
// Noncopyable.
|
||||
Program(const Program& other) LLVM_DELETED_FUNCTION;
|
||||
Program& operator=(const Program& other) LLVM_DELETED_FUNCTION;
|
||||
|
||||
/// @name Methods
|
||||
/// @{
|
||||
|
||||
Program();
|
||||
~Program();
|
||||
|
||||
/// This function executes the program using the \p arguments provided. The
|
||||
/// invoked program will inherit the stdin, stdout, and stderr file
|
||||
/// descriptors, the environment and other configuration settings of the
|
||||
/// invoking program. If Path::executable() does not return true when this
|
||||
/// function is called then a std::string is thrown.
|
||||
/// @returns false in case of error, true otherwise.
|
||||
/// @see FindProgramByName
|
||||
/// @brief Executes the program with the given set of \p args.
|
||||
bool Execute
|
||||
( const Path& path, ///< sys::Path object providing the path of the
|
||||
///< program to be executed. It is presumed this is the result of
|
||||
///< the FindProgramByName method.
|
||||
const char** args, ///< A vector of strings that are passed to the
|
||||
///< program. The first element should be the name of the program.
|
||||
///< The list *must* be terminated by a null char* entry.
|
||||
const char ** env = 0, ///< An optional vector of strings to use for
|
||||
///< the program's environment. If not provided, the current program's
|
||||
///< environment will be used.
|
||||
const sys::Path** redirects = 0, ///< An optional array of pointers to
|
||||
///< Paths. If the array is null, no redirection is done. The array
|
||||
///< should have a size of at least three. If the pointer in the array
|
||||
///< are not null, then the inferior process's stdin(0), stdout(1),
|
||||
///< and stderr(2) will be redirected to the corresponding Paths.
|
||||
///< When an empty Path is passed in, the corresponding file
|
||||
///< descriptor will be disconnected (ie, /dev/null'd) in a portable
|
||||
///< way.
|
||||
unsigned memoryLimit = 0, ///< If non-zero, this specifies max. amount
|
||||
///< of memory can be allocated by process. If memory usage will be
|
||||
///< higher limit, the child is killed and this call returns. If zero
|
||||
///< - no memory limit.
|
||||
std::string* ErrMsg = 0 ///< If non-zero, provides a pointer to a string
|
||||
///< instance in which error messages will be returned. If the string
|
||||
///< is non-empty upon return an error occurred while invoking the
|
||||
///< program.
|
||||
);
|
||||
|
||||
/// This function waits for the program to exit. This function will block
|
||||
/// the current program until the invoked program exits.
|
||||
/// @returns an integer result code indicating the status of the program.
|
||||
/// A zero or positive value indicates the result code of the program.
|
||||
/// -1 indicates failure to execute
|
||||
/// -2 indicates a crash during execution or timeout
|
||||
/// @see Execute
|
||||
/// @brief Waits for the program to exit.
|
||||
int Wait
|
||||
( const Path& path, ///< The path to the child process executable.
|
||||
unsigned secondsToWait, ///< If non-zero, this specifies the amount
|
||||
///< of time to wait for the child process to exit. If the time
|
||||
///< expires, the child is killed and this call returns. If zero,
|
||||
///< this function will wait until the child finishes or forever if
|
||||
///< it doesn't.
|
||||
std::string* ErrMsg ///< If non-zero, provides a pointer to a string
|
||||
///< instance in which error messages will be returned. If the string
|
||||
///< is non-empty upon return an error occurred while waiting.
|
||||
);
|
||||
|
||||
public:
|
||||
/// This static constructor (factory) will attempt to locate a program in
|
||||
/// the operating system's file system using some pre-determined set of
|
||||
/// locations to search (e.g. the PATH on Unix). Paths with slashes are
|
||||
/// returned unmodified.
|
||||
/// @returns A Path object initialized to the path of the program or a
|
||||
/// Path object that is empty (invalid) if the program could not be found.
|
||||
/// @brief Construct a Program by finding it by name.
|
||||
static Path FindProgramByName(const std::string& name);
|
||||
|
||||
// These methods change the specified standard stream (stdin, stdout, or
|
||||
// stderr) to binary mode. They return errc::success if the specified stream
|
||||
// was changed. Otherwise a platform dependent error is returned.
|
||||
static error_code ChangeStdinToBinary();
|
||||
static error_code ChangeStdoutToBinary();
|
||||
static error_code ChangeStderrToBinary();
|
||||
|
||||
/// A convenience function equivalent to Program prg; prg.Execute(..);
|
||||
/// prg.Wait(..);
|
||||
/// @see Execute, Wait
|
||||
static int ExecuteAndWait(const Path& path,
|
||||
const char** args,
|
||||
const char ** env = 0,
|
||||
const sys::Path** redirects = 0,
|
||||
unsigned secondsToWait = 0,
|
||||
unsigned memoryLimit = 0,
|
||||
std::string* ErrMsg = 0,
|
||||
bool *ExecutionFailed = 0);
|
||||
|
||||
/// A convenience function equivalent to Program prg; prg.Execute(..);
|
||||
/// @see Execute
|
||||
static void ExecuteNoWait(const Path& path,
|
||||
const char** args,
|
||||
const char ** env = 0,
|
||||
const sys::Path** redirects = 0,
|
||||
unsigned memoryLimit = 0,
|
||||
std::string* ErrMsg = 0);
|
||||
|
||||
/// @}
|
||||
|
||||
};
|
||||
|
||||
// Return true if the given arguments fit within system-specific
|
||||
// argument length limits.
|
||||
bool argumentsFitWithinSystemLimits(ArrayRef<const char*> Args);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
174
thirdparty/clang/include/llvm/Support/RWMutex.h
vendored
Normal file
174
thirdparty/clang/include/llvm/Support/RWMutex.h
vendored
Normal file
@@ -0,0 +1,174 @@
|
||||
//===- RWMutex.h - Reader/Writer Mutual Exclusion Lock ----------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file declares the llvm::sys::RWMutex class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SYSTEM_RWMUTEX_H
|
||||
#define LLVM_SYSTEM_RWMUTEX_H
|
||||
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Support/Threading.h"
|
||||
#include <cassert>
|
||||
|
||||
namespace llvm
|
||||
{
|
||||
namespace sys
|
||||
{
|
||||
/// @brief Platform agnostic RWMutex class.
|
||||
class RWMutexImpl
|
||||
{
|
||||
/// @name Constructors
|
||||
/// @{
|
||||
public:
|
||||
|
||||
/// Initializes the lock but doesn't acquire it.
|
||||
/// @brief Default Constructor.
|
||||
explicit RWMutexImpl();
|
||||
|
||||
/// Releases and removes the lock
|
||||
/// @brief Destructor
|
||||
~RWMutexImpl();
|
||||
|
||||
/// @}
|
||||
/// @name Methods
|
||||
/// @{
|
||||
public:
|
||||
|
||||
/// Attempts to unconditionally acquire the lock in reader mode. If the
|
||||
/// lock is held by a writer, this method will wait until it can acquire
|
||||
/// the lock.
|
||||
/// @returns false if any kind of error occurs, true otherwise.
|
||||
/// @brief Unconditionally acquire the lock in reader mode.
|
||||
bool reader_acquire();
|
||||
|
||||
/// Attempts to release the lock in reader mode.
|
||||
/// @returns false if any kind of error occurs, true otherwise.
|
||||
/// @brief Unconditionally release the lock in reader mode.
|
||||
bool reader_release();
|
||||
|
||||
/// Attempts to unconditionally acquire the lock in reader mode. If the
|
||||
/// lock is held by any readers, this method will wait until it can
|
||||
/// acquire the lock.
|
||||
/// @returns false if any kind of error occurs, true otherwise.
|
||||
/// @brief Unconditionally acquire the lock in writer mode.
|
||||
bool writer_acquire();
|
||||
|
||||
/// Attempts to release the lock in writer mode.
|
||||
/// @returns false if any kind of error occurs, true otherwise.
|
||||
/// @brief Unconditionally release the lock in write mode.
|
||||
bool writer_release();
|
||||
|
||||
//@}
|
||||
/// @name Platform Dependent Data
|
||||
/// @{
|
||||
private:
|
||||
void* data_; ///< We don't know what the data will be
|
||||
|
||||
/// @}
|
||||
/// @name Do Not Implement
|
||||
/// @{
|
||||
private:
|
||||
RWMutexImpl(const RWMutexImpl & original) LLVM_DELETED_FUNCTION;
|
||||
void operator=(const RWMutexImpl &) LLVM_DELETED_FUNCTION;
|
||||
/// @}
|
||||
};
|
||||
|
||||
/// SmartMutex - An R/W mutex with a compile time constant parameter that
|
||||
/// indicates whether this mutex should become a no-op when we're not
|
||||
/// running in multithreaded mode.
|
||||
template<bool mt_only>
|
||||
class SmartRWMutex : public RWMutexImpl {
|
||||
unsigned readers, writers;
|
||||
public:
|
||||
explicit SmartRWMutex() : RWMutexImpl(), readers(0), writers(0) { }
|
||||
|
||||
bool reader_acquire() {
|
||||
if (!mt_only || llvm_is_multithreaded())
|
||||
return RWMutexImpl::reader_acquire();
|
||||
|
||||
// Single-threaded debugging code. This would be racy in multithreaded
|
||||
// mode, but provides not sanity checks in single threaded mode.
|
||||
++readers;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool reader_release() {
|
||||
if (!mt_only || llvm_is_multithreaded())
|
||||
return RWMutexImpl::reader_release();
|
||||
|
||||
// Single-threaded debugging code. This would be racy in multithreaded
|
||||
// mode, but provides not sanity checks in single threaded mode.
|
||||
assert(readers > 0 && "Reader lock not acquired before release!");
|
||||
--readers;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool writer_acquire() {
|
||||
if (!mt_only || llvm_is_multithreaded())
|
||||
return RWMutexImpl::writer_acquire();
|
||||
|
||||
// Single-threaded debugging code. This would be racy in multithreaded
|
||||
// mode, but provides not sanity checks in single threaded mode.
|
||||
assert(writers == 0 && "Writer lock already acquired!");
|
||||
++writers;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool writer_release() {
|
||||
if (!mt_only || llvm_is_multithreaded())
|
||||
return RWMutexImpl::writer_release();
|
||||
|
||||
// Single-threaded debugging code. This would be racy in multithreaded
|
||||
// mode, but provides not sanity checks in single threaded mode.
|
||||
assert(writers == 1 && "Writer lock not acquired before release!");
|
||||
--writers;
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
SmartRWMutex(const SmartRWMutex<mt_only> & original);
|
||||
void operator=(const SmartRWMutex<mt_only> &);
|
||||
};
|
||||
typedef SmartRWMutex<false> RWMutex;
|
||||
|
||||
/// ScopedReader - RAII acquisition of a reader lock
|
||||
template<bool mt_only>
|
||||
struct SmartScopedReader {
|
||||
SmartRWMutex<mt_only>& mutex;
|
||||
|
||||
explicit SmartScopedReader(SmartRWMutex<mt_only>& m) : mutex(m) {
|
||||
mutex.reader_acquire();
|
||||
}
|
||||
|
||||
~SmartScopedReader() {
|
||||
mutex.reader_release();
|
||||
}
|
||||
};
|
||||
typedef SmartScopedReader<false> ScopedReader;
|
||||
|
||||
/// ScopedWriter - RAII acquisition of a writer lock
|
||||
template<bool mt_only>
|
||||
struct SmartScopedWriter {
|
||||
SmartRWMutex<mt_only>& mutex;
|
||||
|
||||
explicit SmartScopedWriter(SmartRWMutex<mt_only>& m) : mutex(m) {
|
||||
mutex.writer_acquire();
|
||||
}
|
||||
|
||||
~SmartScopedWriter() {
|
||||
mutex.writer_release();
|
||||
}
|
||||
};
|
||||
typedef SmartScopedWriter<false> ScopedWriter;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
129
thirdparty/clang/include/llvm/Support/Recycler.h
vendored
Normal file
129
thirdparty/clang/include/llvm/Support/Recycler.h
vendored
Normal file
@@ -0,0 +1,129 @@
|
||||
//==- llvm/Support/Recycler.h - Recycling Allocator --------------*- C++ -*-==//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the Recycler class template. See the doxygen comment for
|
||||
// Recycler for more details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_RECYCLER_H
|
||||
#define LLVM_SUPPORT_RECYCLER_H
|
||||
|
||||
#include "llvm/ADT/ilist.h"
|
||||
#include "llvm/Support/AlignOf.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include <cassert>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class BumpPtrAllocator;
|
||||
|
||||
/// PrintRecyclingAllocatorStats - Helper for RecyclingAllocator for
|
||||
/// printing statistics.
|
||||
///
|
||||
void PrintRecyclerStats(size_t Size, size_t Align, size_t FreeListSize);
|
||||
|
||||
/// RecyclerStruct - Implementation detail for Recycler. This is a
|
||||
/// class that the recycler imposes on free'd memory to carve out
|
||||
/// next/prev pointers.
|
||||
struct RecyclerStruct {
|
||||
RecyclerStruct *Prev, *Next;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct ilist_traits<RecyclerStruct> :
|
||||
public ilist_default_traits<RecyclerStruct> {
|
||||
static RecyclerStruct *getPrev(const RecyclerStruct *t) { return t->Prev; }
|
||||
static RecyclerStruct *getNext(const RecyclerStruct *t) { return t->Next; }
|
||||
static void setPrev(RecyclerStruct *t, RecyclerStruct *p) { t->Prev = p; }
|
||||
static void setNext(RecyclerStruct *t, RecyclerStruct *n) { t->Next = n; }
|
||||
|
||||
mutable RecyclerStruct Sentinel;
|
||||
RecyclerStruct *createSentinel() const {
|
||||
return &Sentinel;
|
||||
}
|
||||
static void destroySentinel(RecyclerStruct *) {}
|
||||
|
||||
RecyclerStruct *provideInitialHead() const { return createSentinel(); }
|
||||
RecyclerStruct *ensureHead(RecyclerStruct*) const { return createSentinel(); }
|
||||
static void noteHead(RecyclerStruct*, RecyclerStruct*) {}
|
||||
|
||||
static void deleteNode(RecyclerStruct *) {
|
||||
llvm_unreachable("Recycler's ilist_traits shouldn't see a deleteNode call!");
|
||||
}
|
||||
};
|
||||
|
||||
/// Recycler - This class manages a linked-list of deallocated nodes
|
||||
/// and facilitates reusing deallocated memory in place of allocating
|
||||
/// new memory.
|
||||
///
|
||||
template<class T, size_t Size = sizeof(T), size_t Align = AlignOf<T>::Alignment>
|
||||
class Recycler {
|
||||
/// FreeList - Doubly-linked list of nodes that have deleted contents and
|
||||
/// are not in active use.
|
||||
///
|
||||
iplist<RecyclerStruct> FreeList;
|
||||
|
||||
public:
|
||||
~Recycler() {
|
||||
// If this fails, either the callee has lost track of some allocation,
|
||||
// or the callee isn't tracking allocations and should just call
|
||||
// clear() before deleting the Recycler.
|
||||
assert(FreeList.empty() && "Non-empty recycler deleted!");
|
||||
}
|
||||
|
||||
/// clear - Release all the tracked allocations to the allocator. The
|
||||
/// recycler must be free of any tracked allocations before being
|
||||
/// deleted; calling clear is one way to ensure this.
|
||||
template<class AllocatorType>
|
||||
void clear(AllocatorType &Allocator) {
|
||||
while (!FreeList.empty()) {
|
||||
T *t = reinterpret_cast<T *>(FreeList.remove(FreeList.begin()));
|
||||
Allocator.Deallocate(t);
|
||||
}
|
||||
}
|
||||
|
||||
/// Special case for BumpPtrAllocator which has an empty Deallocate()
|
||||
/// function.
|
||||
///
|
||||
/// There is no need to traverse the free list, pulling all the objects into
|
||||
/// cache.
|
||||
void clear(BumpPtrAllocator&) {
|
||||
FreeList.clearAndLeakNodesUnsafely();
|
||||
}
|
||||
|
||||
template<class SubClass, class AllocatorType>
|
||||
SubClass *Allocate(AllocatorType &Allocator) {
|
||||
assert(sizeof(SubClass) <= Size &&
|
||||
"Recycler allocation size is less than object size!");
|
||||
assert(AlignOf<SubClass>::Alignment <= Align &&
|
||||
"Recycler allocation alignment is less than object alignment!");
|
||||
return !FreeList.empty() ?
|
||||
reinterpret_cast<SubClass *>(FreeList.remove(FreeList.begin())) :
|
||||
static_cast<SubClass *>(Allocator.Allocate(Size, Align));
|
||||
}
|
||||
|
||||
template<class AllocatorType>
|
||||
T *Allocate(AllocatorType &Allocator) {
|
||||
return Allocate<T>(Allocator);
|
||||
}
|
||||
|
||||
template<class SubClass, class AllocatorType>
|
||||
void Deallocate(AllocatorType & /*Allocator*/, SubClass* Element) {
|
||||
FreeList.push_front(reinterpret_cast<RecyclerStruct *>(Element));
|
||||
}
|
||||
|
||||
void PrintStats() {
|
||||
PrintRecyclerStats(Size, Align, FreeList.size());
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
73
thirdparty/clang/include/llvm/Support/RecyclingAllocator.h
vendored
Normal file
73
thirdparty/clang/include/llvm/Support/RecyclingAllocator.h
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
//==- llvm/Support/RecyclingAllocator.h - Recycling Allocator ----*- C++ -*-==//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the RecyclingAllocator class. See the doxygen comment for
|
||||
// RecyclingAllocator for more details on the implementation.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_RECYCLINGALLOCATOR_H
|
||||
#define LLVM_SUPPORT_RECYCLINGALLOCATOR_H
|
||||
|
||||
#include "llvm/Support/Recycler.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
/// RecyclingAllocator - This class wraps an Allocator, adding the
|
||||
/// functionality of recycling deleted objects.
|
||||
///
|
||||
template<class AllocatorType, class T,
|
||||
size_t Size = sizeof(T), size_t Align = AlignOf<T>::Alignment>
|
||||
class RecyclingAllocator {
|
||||
private:
|
||||
/// Base - Implementation details.
|
||||
///
|
||||
Recycler<T, Size, Align> Base;
|
||||
|
||||
/// Allocator - The wrapped allocator.
|
||||
///
|
||||
AllocatorType Allocator;
|
||||
|
||||
public:
|
||||
~RecyclingAllocator() { Base.clear(Allocator); }
|
||||
|
||||
/// Allocate - Return a pointer to storage for an object of type
|
||||
/// SubClass. The storage may be either newly allocated or recycled.
|
||||
///
|
||||
template<class SubClass>
|
||||
SubClass *Allocate() { return Base.template Allocate<SubClass>(Allocator); }
|
||||
|
||||
T *Allocate() { return Base.Allocate(Allocator); }
|
||||
|
||||
/// Deallocate - Release storage for the pointed-to object. The
|
||||
/// storage will be kept track of and may be recycled.
|
||||
///
|
||||
template<class SubClass>
|
||||
void Deallocate(SubClass* E) { return Base.Deallocate(Allocator, E); }
|
||||
|
||||
void PrintStats() { Base.PrintStats(); }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template<class AllocatorType, class T, size_t Size, size_t Align>
|
||||
inline void *operator new(size_t,
|
||||
llvm::RecyclingAllocator<AllocatorType,
|
||||
T, Size, Align> &Allocator) {
|
||||
return Allocator.Allocate();
|
||||
}
|
||||
|
||||
template<class AllocatorType, class T, size_t Size, size_t Align>
|
||||
inline void operator delete(void *E,
|
||||
llvm::RecyclingAllocator<AllocatorType,
|
||||
T, Size, Align> &A) {
|
||||
A.Deallocate(E);
|
||||
}
|
||||
|
||||
#endif
|
||||
86
thirdparty/clang/include/llvm/Support/Regex.h
vendored
Normal file
86
thirdparty/clang/include/llvm/Support/Regex.h
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
//===-- Regex.h - Regular Expression matcher implementation -*- C++ -*-----===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements a POSIX regular expression matcher. Both Basic and
|
||||
// Extended POSIX regular expressions (ERE) are supported. EREs were extended
|
||||
// to support backreferences in matches.
|
||||
// This implementation also supports matching strings with embedded NUL chars.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_REGEX_H
|
||||
#define LLVM_SUPPORT_REGEX_H
|
||||
|
||||
#include <string>
|
||||
|
||||
struct llvm_regex;
|
||||
|
||||
namespace llvm {
|
||||
class StringRef;
|
||||
template<typename T> class SmallVectorImpl;
|
||||
|
||||
class Regex {
|
||||
public:
|
||||
enum {
|
||||
NoFlags=0,
|
||||
/// Compile for matching that ignores upper/lower case distinctions.
|
||||
IgnoreCase=1,
|
||||
/// Compile for newline-sensitive matching. With this flag '[^' bracket
|
||||
/// expressions and '.' never match newline. A ^ anchor matches the
|
||||
/// null string after any newline in the string in addition to its normal
|
||||
/// function, and the $ anchor matches the null string before any
|
||||
/// newline in the string in addition to its normal function.
|
||||
Newline=2,
|
||||
/// By default, the POSIX extended regular expression (ERE) syntax is
|
||||
/// assumed. Pass this flag to turn on basic regular expressions (BRE)
|
||||
/// instead.
|
||||
BasicRegex=4
|
||||
};
|
||||
|
||||
/// Compiles the given regular expression \p Regex.
|
||||
Regex(StringRef Regex, unsigned Flags = NoFlags);
|
||||
~Regex();
|
||||
|
||||
/// isValid - returns the error encountered during regex compilation, or
|
||||
/// matching, if any.
|
||||
bool isValid(std::string &Error);
|
||||
|
||||
/// getNumMatches - In a valid regex, return the number of parenthesized
|
||||
/// matches it contains. The number filled in by match will include this
|
||||
/// many entries plus one for the whole regex (as element 0).
|
||||
unsigned getNumMatches() const;
|
||||
|
||||
/// matches - Match the regex against a given \p String.
|
||||
///
|
||||
/// \param Matches - If given, on a successful match this will be filled in
|
||||
/// with references to the matched group expressions (inside \p String),
|
||||
/// the first group is always the entire pattern.
|
||||
///
|
||||
/// This returns true on a successful match.
|
||||
bool match(StringRef String, SmallVectorImpl<StringRef> *Matches = 0);
|
||||
|
||||
/// sub - Return the result of replacing the first match of the regex in
|
||||
/// \p String with the \p Repl string. Backreferences like "\0" in the
|
||||
/// replacement string are replaced with the appropriate match substring.
|
||||
///
|
||||
/// Note that the replacement string has backslash escaping performed on
|
||||
/// it. Invalid backreferences are ignored (replaced by empty strings).
|
||||
///
|
||||
/// \param Error If non-null, any errors in the substitution (invalid
|
||||
/// backreferences, trailing backslashes) will be recorded as a non-empty
|
||||
/// string.
|
||||
std::string sub(StringRef Repl, StringRef String, std::string *Error = 0);
|
||||
|
||||
private:
|
||||
struct llvm_regex *preg;
|
||||
int error;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // LLVM_SUPPORT_REGEX_H
|
||||
224
thirdparty/clang/include/llvm/Support/Registry.h
vendored
Normal file
224
thirdparty/clang/include/llvm/Support/Registry.h
vendored
Normal file
@@ -0,0 +1,224 @@
|
||||
//=== Registry.h - Linker-supported plugin registries -----------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Defines a registry template for discovering pluggable modules.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_REGISTRY_H
|
||||
#define LLVM_SUPPORT_REGISTRY_H
|
||||
|
||||
namespace llvm {
|
||||
/// A simple registry entry which provides only a name, description, and
|
||||
/// no-argument constructor.
|
||||
template <typename T>
|
||||
class SimpleRegistryEntry {
|
||||
const char *Name, *Desc;
|
||||
T *(*Ctor)();
|
||||
|
||||
public:
|
||||
SimpleRegistryEntry(const char *N, const char *D, T *(*C)())
|
||||
: Name(N), Desc(D), Ctor(C)
|
||||
{}
|
||||
|
||||
const char *getName() const { return Name; }
|
||||
const char *getDesc() const { return Desc; }
|
||||
T *instantiate() const { return Ctor(); }
|
||||
};
|
||||
|
||||
|
||||
/// Traits for registry entries. If using other than SimpleRegistryEntry, it
|
||||
/// is necessary to define an alternate traits class.
|
||||
template <typename T>
|
||||
class RegistryTraits {
|
||||
RegistryTraits() LLVM_DELETED_FUNCTION;
|
||||
|
||||
public:
|
||||
typedef SimpleRegistryEntry<T> entry;
|
||||
|
||||
/// nameof/descof - Accessors for name and description of entries. These are
|
||||
// used to generate help for command-line options.
|
||||
static const char *nameof(const entry &Entry) { return Entry.getName(); }
|
||||
static const char *descof(const entry &Entry) { return Entry.getDesc(); }
|
||||
};
|
||||
|
||||
|
||||
/// A global registry used in conjunction with static constructors to make
|
||||
/// pluggable components (like targets or garbage collectors) "just work" when
|
||||
/// linked with an executable.
|
||||
template <typename T, typename U = RegistryTraits<T> >
|
||||
class Registry {
|
||||
public:
|
||||
typedef U traits;
|
||||
typedef typename U::entry entry;
|
||||
|
||||
class node;
|
||||
class listener;
|
||||
class iterator;
|
||||
|
||||
private:
|
||||
Registry() LLVM_DELETED_FUNCTION;
|
||||
|
||||
static void Announce(const entry &E) {
|
||||
for (listener *Cur = ListenerHead; Cur; Cur = Cur->Next)
|
||||
Cur->registered(E);
|
||||
}
|
||||
|
||||
friend class node;
|
||||
static node *Head, *Tail;
|
||||
|
||||
friend class listener;
|
||||
static listener *ListenerHead, *ListenerTail;
|
||||
|
||||
public:
|
||||
/// Node in linked list of entries.
|
||||
///
|
||||
class node {
|
||||
friend class iterator;
|
||||
|
||||
node *Next;
|
||||
const entry& Val;
|
||||
|
||||
public:
|
||||
node(const entry& V) : Next(0), Val(V) {
|
||||
if (Tail)
|
||||
Tail->Next = this;
|
||||
else
|
||||
Head = this;
|
||||
Tail = this;
|
||||
|
||||
Announce(V);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/// Iterators for registry entries.
|
||||
///
|
||||
class iterator {
|
||||
const node *Cur;
|
||||
|
||||
public:
|
||||
explicit iterator(const node *N) : Cur(N) {}
|
||||
|
||||
bool operator==(const iterator &That) const { return Cur == That.Cur; }
|
||||
bool operator!=(const iterator &That) const { return Cur != That.Cur; }
|
||||
iterator &operator++() { Cur = Cur->Next; return *this; }
|
||||
const entry &operator*() const { return Cur->Val; }
|
||||
const entry *operator->() const { return &Cur->Val; }
|
||||
};
|
||||
|
||||
static iterator begin() { return iterator(Head); }
|
||||
static iterator end() { return iterator(0); }
|
||||
|
||||
|
||||
/// Abstract base class for registry listeners, which are informed when new
|
||||
/// entries are added to the registry. Simply subclass and instantiate:
|
||||
///
|
||||
/// \code
|
||||
/// class CollectorPrinter : public Registry<Collector>::listener {
|
||||
/// protected:
|
||||
/// void registered(const Registry<Collector>::entry &e) {
|
||||
/// cerr << "collector now available: " << e->getName() << "\n";
|
||||
/// }
|
||||
///
|
||||
/// public:
|
||||
/// CollectorPrinter() { init(); } // Print those already registered.
|
||||
/// };
|
||||
///
|
||||
/// CollectorPrinter Printer;
|
||||
/// \endcode
|
||||
class listener {
|
||||
listener *Prev, *Next;
|
||||
|
||||
friend void Registry::Announce(const entry &E);
|
||||
|
||||
protected:
|
||||
/// Called when an entry is added to the registry.
|
||||
///
|
||||
virtual void registered(const entry &) = 0;
|
||||
|
||||
/// Calls 'registered' for each pre-existing entry.
|
||||
///
|
||||
void init() {
|
||||
for (iterator I = begin(), E = end(); I != E; ++I)
|
||||
registered(*I);
|
||||
}
|
||||
|
||||
public:
|
||||
listener() : Prev(ListenerTail), Next(0) {
|
||||
if (Prev)
|
||||
Prev->Next = this;
|
||||
else
|
||||
ListenerHead = this;
|
||||
ListenerTail = this;
|
||||
}
|
||||
|
||||
virtual ~listener() {
|
||||
if (Next)
|
||||
Next->Prev = Prev;
|
||||
else
|
||||
ListenerTail = Prev;
|
||||
if (Prev)
|
||||
Prev->Next = Next;
|
||||
else
|
||||
ListenerHead = Next;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/// A static registration template. Use like such:
|
||||
///
|
||||
/// Registry<Collector>::Add<FancyGC>
|
||||
/// X("fancy-gc", "Newfangled garbage collector.");
|
||||
///
|
||||
/// Use of this template requires that:
|
||||
///
|
||||
/// 1. The registered subclass has a default constructor.
|
||||
//
|
||||
/// 2. The registry entry type has a constructor compatible with this
|
||||
/// signature:
|
||||
///
|
||||
/// entry(const char *Name, const char *ShortDesc, T *(*Ctor)());
|
||||
///
|
||||
/// If you have more elaborate requirements, then copy and modify.
|
||||
///
|
||||
template <typename V>
|
||||
class Add {
|
||||
entry Entry;
|
||||
node Node;
|
||||
|
||||
static T *CtorFn() { return new V(); }
|
||||
|
||||
public:
|
||||
Add(const char *Name, const char *Desc)
|
||||
: Entry(Name, Desc, CtorFn), Node(Entry) {}
|
||||
};
|
||||
|
||||
/// Registry::Parser now lives in llvm/Support/RegistryParser.h.
|
||||
|
||||
};
|
||||
|
||||
// Since these are defined in a header file, plugins must be sure to export
|
||||
// these symbols.
|
||||
|
||||
template <typename T, typename U>
|
||||
typename Registry<T,U>::node *Registry<T,U>::Head;
|
||||
|
||||
template <typename T, typename U>
|
||||
typename Registry<T,U>::node *Registry<T,U>::Tail;
|
||||
|
||||
template <typename T, typename U>
|
||||
typename Registry<T,U>::listener *Registry<T,U>::ListenerHead;
|
||||
|
||||
template <typename T, typename U>
|
||||
typename Registry<T,U>::listener *Registry<T,U>::ListenerTail;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
55
thirdparty/clang/include/llvm/Support/RegistryParser.h
vendored
Normal file
55
thirdparty/clang/include/llvm/Support/RegistryParser.h
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
//=== RegistryParser.h - Linker-supported plugin registries -----*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Defines a command-line parser for a registry.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_REGISTRYPARSER_H
|
||||
#define LLVM_SUPPORT_REGISTRYPARSER_H
|
||||
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/Registry.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
/// A command-line parser for a registry. Use like such:
|
||||
///
|
||||
/// static cl::opt<Registry<Collector>::entry, false,
|
||||
/// RegistryParser<Collector> >
|
||||
/// GCOpt("gc", cl::desc("Garbage collector to use."),
|
||||
/// cl::value_desc());
|
||||
///
|
||||
/// To make use of the value:
|
||||
///
|
||||
/// Collector *TheCollector = GCOpt->instantiate();
|
||||
///
|
||||
template <typename T, typename U = RegistryTraits<T> >
|
||||
class RegistryParser :
|
||||
public cl::parser<const typename U::entry*>,
|
||||
public Registry<T, U>::listener {
|
||||
typedef U traits;
|
||||
typedef typename U::entry entry;
|
||||
typedef typename Registry<T, U>::listener listener;
|
||||
|
||||
protected:
|
||||
void registered(const entry &E) {
|
||||
addLiteralOption(traits::nameof(E), &E, traits::descof(E));
|
||||
}
|
||||
|
||||
public:
|
||||
void initialize(cl::Option &O) {
|
||||
listener::init();
|
||||
cl::parser<const typename U::entry*>::initialize(O);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // LLVM_SUPPORT_REGISTRYPARSER_H
|
||||
63
thirdparty/clang/include/llvm/Support/SMLoc.h
vendored
Normal file
63
thirdparty/clang/include/llvm/Support/SMLoc.h
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
//===- SMLoc.h - Source location for use with diagnostics -------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file declares the SMLoc class. This class encapsulates a location in
|
||||
// source code for use in diagnostics.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_SMLOC_H
|
||||
#define LLVM_SUPPORT_SMLOC_H
|
||||
|
||||
#include <cassert>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
/// Represents a location in source code.
|
||||
class SMLoc {
|
||||
const char *Ptr;
|
||||
public:
|
||||
SMLoc() : Ptr(0) {}
|
||||
|
||||
bool isValid() const { return Ptr != 0; }
|
||||
|
||||
bool operator==(const SMLoc &RHS) const { return RHS.Ptr == Ptr; }
|
||||
bool operator!=(const SMLoc &RHS) const { return RHS.Ptr != Ptr; }
|
||||
|
||||
const char *getPointer() const { return Ptr; }
|
||||
|
||||
static SMLoc getFromPointer(const char *Ptr) {
|
||||
SMLoc L;
|
||||
L.Ptr = Ptr;
|
||||
return L;
|
||||
}
|
||||
};
|
||||
|
||||
/// Represents a range in source code.
|
||||
///
|
||||
/// SMRange is implemented using a half-open range, as is the convention in C++.
|
||||
/// In the string "abc", the range (1,3] represents the substring "bc", and the
|
||||
/// range (2,2] represents an empty range between the characters "b" and "c".
|
||||
class SMRange {
|
||||
public:
|
||||
SMLoc Start, End;
|
||||
|
||||
SMRange() {}
|
||||
SMRange(SMLoc St, SMLoc En) : Start(St), End(En) {
|
||||
assert(Start.isValid() == End.isValid() &&
|
||||
"Start and end should either both be valid or both be invalid!");
|
||||
}
|
||||
|
||||
bool isValid() const { return Start.isValid(); }
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
|
||||
47
thirdparty/clang/include/llvm/Support/SaveAndRestore.h
vendored
Normal file
47
thirdparty/clang/include/llvm/Support/SaveAndRestore.h
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
//===-- SaveAndRestore.h - Utility -------------------------------*- 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 utility classes that uses RAII to save and restore
|
||||
// values.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_SAVEANDRESTORE_H
|
||||
#define LLVM_SUPPORT_SAVEANDRESTORE_H
|
||||
|
||||
namespace llvm {
|
||||
|
||||
// SaveAndRestore - A utility class that uses RAII to save and restore
|
||||
// the value of a variable.
|
||||
template<typename T>
|
||||
struct SaveAndRestore {
|
||||
SaveAndRestore(T& x) : X(x), old_value(x) {}
|
||||
SaveAndRestore(T& x, const T &new_value) : X(x), old_value(x) {
|
||||
X = new_value;
|
||||
}
|
||||
~SaveAndRestore() { X = old_value; }
|
||||
T get() { return old_value; }
|
||||
private:
|
||||
T& X;
|
||||
T old_value;
|
||||
};
|
||||
|
||||
// SaveOr - Similar to SaveAndRestore. Operates only on bools; the old
|
||||
// value of a variable is saved, and during the dstor the old value is
|
||||
// or'ed with the new value.
|
||||
struct SaveOr {
|
||||
SaveOr(bool& x) : X(x), old_value(x) { x = false; }
|
||||
~SaveOr() { X |= old_value; }
|
||||
private:
|
||||
bool& X;
|
||||
const bool old_value;
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
63
thirdparty/clang/include/llvm/Support/Signals.h
vendored
Normal file
63
thirdparty/clang/include/llvm/Support/Signals.h
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
//===- llvm/Support/Signals.h - Signal Handling support ----------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines some helpful functions for dealing with the possibility of
|
||||
// unix signals occurring while your program is running.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_SIGNALS_H
|
||||
#define LLVM_SUPPORT_SIGNALS_H
|
||||
|
||||
#include "llvm/Support/Path.h"
|
||||
#include <cstdio>
|
||||
|
||||
namespace llvm {
|
||||
namespace sys {
|
||||
|
||||
/// This function runs all the registered interrupt handlers, including the
|
||||
/// removal of files registered by RemoveFileOnSignal.
|
||||
void RunInterruptHandlers();
|
||||
|
||||
/// This function registers signal handlers to ensure that if a signal gets
|
||||
/// delivered that the named file is removed.
|
||||
/// @brief Remove a file if a fatal signal occurs.
|
||||
bool RemoveFileOnSignal(const Path &Filename, std::string* ErrMsg = 0);
|
||||
|
||||
/// This function removes a file from the list of files to be removed on
|
||||
/// signal delivery.
|
||||
void DontRemoveFileOnSignal(const Path &Filename);
|
||||
|
||||
/// When an error signal (such as SIBABRT or SIGSEGV) is delivered to the
|
||||
/// process, print a stack trace and then exit.
|
||||
/// @brief Print a stack trace if a fatal signal occurs.
|
||||
void PrintStackTraceOnErrorSignal();
|
||||
|
||||
/// \brief Print the stack trace using the given \c FILE object.
|
||||
void PrintStackTrace(FILE *);
|
||||
|
||||
/// AddSignalHandler - Add a function to be called when an abort/kill signal
|
||||
/// is delivered to the process. The handler can have a cookie passed to it
|
||||
/// to identify what instance of the handler it is.
|
||||
void AddSignalHandler(void (*FnPtr)(void *), void *Cookie);
|
||||
|
||||
/// This function registers a function to be called when the user "interrupts"
|
||||
/// the program (typically by pressing ctrl-c). When the user interrupts the
|
||||
/// program, the specified interrupt function is called instead of the program
|
||||
/// being killed, and the interrupt function automatically disabled. Note
|
||||
/// that interrupt functions are not allowed to call any non-reentrant
|
||||
/// functions. An null interrupt function pointer disables the current
|
||||
/// installed function. Note also that the handler may be executed on a
|
||||
/// different thread on some platforms.
|
||||
/// @brief Register a function to be called when ctrl-c is pressed.
|
||||
void SetInterruptFunction(void (*IF)());
|
||||
} // End sys namespace
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
||||
40
thirdparty/clang/include/llvm/Support/Solaris.h
vendored
Normal file
40
thirdparty/clang/include/llvm/Support/Solaris.h
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
/*===- llvm/Support/Solaris.h ------------------------------------*- C++ -*-===*
|
||||
*
|
||||
* The LLVM Compiler Infrastructure
|
||||
*
|
||||
* This file is distributed under the University of Illinois Open Source
|
||||
* License. See LICENSE.TXT for details.
|
||||
*
|
||||
*===----------------------------------------------------------------------===*
|
||||
*
|
||||
* This file contains portability fixes for Solaris hosts.
|
||||
*
|
||||
*===----------------------------------------------------------------------===*/
|
||||
|
||||
#ifndef LLVM_SUPPORT_SOLARIS_H
|
||||
#define LLVM_SUPPORT_SOLARIS_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/regset.h>
|
||||
|
||||
#undef CS
|
||||
#undef DS
|
||||
#undef ES
|
||||
#undef FS
|
||||
#undef GS
|
||||
#undef SS
|
||||
#undef EAX
|
||||
#undef ECX
|
||||
#undef EDX
|
||||
#undef EBX
|
||||
#undef ESP
|
||||
#undef EBP
|
||||
#undef ESI
|
||||
#undef EDI
|
||||
#undef EIP
|
||||
#undef UESP
|
||||
#undef EFL
|
||||
#undef ERR
|
||||
#undef TRAPNO
|
||||
|
||||
#endif
|
||||
258
thirdparty/clang/include/llvm/Support/SourceMgr.h
vendored
Normal file
258
thirdparty/clang/include/llvm/Support/SourceMgr.h
vendored
Normal file
@@ -0,0 +1,258 @@
|
||||
//===- SourceMgr.h - Manager for Source Buffers & Diagnostics ---*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file declares the SMDiagnostic and SourceMgr classes. This
|
||||
// provides a simple substrate for diagnostics, #include handling, and other low
|
||||
// level things for simple parsers.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_SOURCEMGR_H
|
||||
#define LLVM_SUPPORT_SOURCEMGR_H
|
||||
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ADT/Twine.h"
|
||||
#include "llvm/Support/SMLoc.h"
|
||||
#include <string>
|
||||
|
||||
namespace llvm {
|
||||
class MemoryBuffer;
|
||||
class SourceMgr;
|
||||
class SMDiagnostic;
|
||||
class SMFixIt;
|
||||
class Twine;
|
||||
class raw_ostream;
|
||||
|
||||
/// SourceMgr - This owns the files read by a parser, handles include stacks,
|
||||
/// and handles diagnostic wrangling.
|
||||
class SourceMgr {
|
||||
public:
|
||||
enum DiagKind {
|
||||
DK_Error,
|
||||
DK_Warning,
|
||||
DK_Note
|
||||
};
|
||||
|
||||
/// DiagHandlerTy - Clients that want to handle their own diagnostics in a
|
||||
/// custom way can register a function pointer+context as a diagnostic
|
||||
/// handler. It gets called each time PrintMessage is invoked.
|
||||
typedef void (*DiagHandlerTy)(const SMDiagnostic &, void *Context);
|
||||
private:
|
||||
struct SrcBuffer {
|
||||
/// Buffer - The memory buffer for the file.
|
||||
MemoryBuffer *Buffer;
|
||||
|
||||
/// IncludeLoc - This is the location of the parent include, or null if at
|
||||
/// the top level.
|
||||
SMLoc IncludeLoc;
|
||||
};
|
||||
|
||||
/// Buffers - This is all of the buffers that we are reading from.
|
||||
std::vector<SrcBuffer> Buffers;
|
||||
|
||||
// IncludeDirectories - This is the list of directories we should search for
|
||||
// include files in.
|
||||
std::vector<std::string> IncludeDirectories;
|
||||
|
||||
/// LineNoCache - This is a cache for line number queries, its implementation
|
||||
/// is really private to SourceMgr.cpp.
|
||||
mutable void *LineNoCache;
|
||||
|
||||
DiagHandlerTy DiagHandler;
|
||||
void *DiagContext;
|
||||
|
||||
SourceMgr(const SourceMgr&) LLVM_DELETED_FUNCTION;
|
||||
void operator=(const SourceMgr&) LLVM_DELETED_FUNCTION;
|
||||
public:
|
||||
SourceMgr() : LineNoCache(0), DiagHandler(0), DiagContext(0) {}
|
||||
~SourceMgr();
|
||||
|
||||
void setIncludeDirs(const std::vector<std::string> &Dirs) {
|
||||
IncludeDirectories = Dirs;
|
||||
}
|
||||
|
||||
/// setDiagHandler - Specify a diagnostic handler to be invoked every time
|
||||
/// PrintMessage is called. Ctx is passed into the handler when it is invoked.
|
||||
void setDiagHandler(DiagHandlerTy DH, void *Ctx = 0) {
|
||||
DiagHandler = DH;
|
||||
DiagContext = Ctx;
|
||||
}
|
||||
|
||||
DiagHandlerTy getDiagHandler() const { return DiagHandler; }
|
||||
void *getDiagContext() const { return DiagContext; }
|
||||
|
||||
const SrcBuffer &getBufferInfo(unsigned i) const {
|
||||
assert(i < Buffers.size() && "Invalid Buffer ID!");
|
||||
return Buffers[i];
|
||||
}
|
||||
|
||||
const MemoryBuffer *getMemoryBuffer(unsigned i) const {
|
||||
assert(i < Buffers.size() && "Invalid Buffer ID!");
|
||||
return Buffers[i].Buffer;
|
||||
}
|
||||
|
||||
unsigned getNumBuffers() const {
|
||||
return Buffers.size();
|
||||
}
|
||||
|
||||
SMLoc getParentIncludeLoc(unsigned i) const {
|
||||
assert(i < Buffers.size() && "Invalid Buffer ID!");
|
||||
return Buffers[i].IncludeLoc;
|
||||
}
|
||||
|
||||
/// AddNewSourceBuffer - Add a new source buffer to this source manager. This
|
||||
/// takes ownership of the memory buffer.
|
||||
unsigned AddNewSourceBuffer(MemoryBuffer *F, SMLoc IncludeLoc) {
|
||||
SrcBuffer NB;
|
||||
NB.Buffer = F;
|
||||
NB.IncludeLoc = IncludeLoc;
|
||||
Buffers.push_back(NB);
|
||||
return Buffers.size()-1;
|
||||
}
|
||||
|
||||
/// AddIncludeFile - Search for a file with the specified name in the current
|
||||
/// directory or in one of the IncludeDirs. If no file is found, this returns
|
||||
/// ~0, otherwise it returns the buffer ID of the stacked file.
|
||||
/// The full path to the included file can be found in IncludedFile.
|
||||
unsigned AddIncludeFile(const std::string &Filename, SMLoc IncludeLoc,
|
||||
std::string &IncludedFile);
|
||||
|
||||
/// FindBufferContainingLoc - Return the ID of the buffer containing the
|
||||
/// specified location, returning -1 if not found.
|
||||
int FindBufferContainingLoc(SMLoc Loc) const;
|
||||
|
||||
/// FindLineNumber - Find the line number for the specified location in the
|
||||
/// specified file. This is not a fast method.
|
||||
unsigned FindLineNumber(SMLoc Loc, int BufferID = -1) const {
|
||||
return getLineAndColumn(Loc, BufferID).first;
|
||||
}
|
||||
|
||||
/// getLineAndColumn - Find the line and column number for the specified
|
||||
/// location in the specified file. This is not a fast method.
|
||||
std::pair<unsigned, unsigned>
|
||||
getLineAndColumn(SMLoc Loc, int BufferID = -1) const;
|
||||
|
||||
/// PrintMessage - Emit a message about the specified location with the
|
||||
/// specified string.
|
||||
///
|
||||
/// @param ShowColors - Display colored messages if output is a terminal and
|
||||
/// the default error handler is used.
|
||||
void PrintMessage(SMLoc Loc, DiagKind Kind, const Twine &Msg,
|
||||
ArrayRef<SMRange> Ranges = ArrayRef<SMRange>(),
|
||||
ArrayRef<SMFixIt> FixIts = ArrayRef<SMFixIt>(),
|
||||
bool ShowColors = true) const;
|
||||
|
||||
|
||||
/// GetMessage - Return an SMDiagnostic at the specified location with the
|
||||
/// specified string.
|
||||
///
|
||||
/// @param Msg If non-null, the kind of message (e.g., "error") which is
|
||||
/// prefixed to the message.
|
||||
SMDiagnostic GetMessage(SMLoc Loc, DiagKind Kind, const Twine &Msg,
|
||||
ArrayRef<SMRange> Ranges = ArrayRef<SMRange>(),
|
||||
ArrayRef<SMFixIt> FixIts = ArrayRef<SMFixIt>()) const;
|
||||
|
||||
/// PrintIncludeStack - Prints the names of included files and the line of the
|
||||
/// file they were included from. A diagnostic handler can use this before
|
||||
/// printing its custom formatted message.
|
||||
///
|
||||
/// @param IncludeLoc - The line of the include.
|
||||
/// @param OS the raw_ostream to print on.
|
||||
void PrintIncludeStack(SMLoc IncludeLoc, raw_ostream &OS) const;
|
||||
};
|
||||
|
||||
|
||||
/// Represents a single fixit, a replacement of one range of text with another.
|
||||
class SMFixIt {
|
||||
SMRange Range;
|
||||
|
||||
std::string Text;
|
||||
|
||||
public:
|
||||
// FIXME: Twine.str() is not very efficient.
|
||||
SMFixIt(SMLoc Loc, const Twine &Insertion)
|
||||
: Range(Loc, Loc), Text(Insertion.str()) {
|
||||
assert(Loc.isValid());
|
||||
}
|
||||
|
||||
// FIXME: Twine.str() is not very efficient.
|
||||
SMFixIt(SMRange R, const Twine &Replacement)
|
||||
: Range(R), Text(Replacement.str()) {
|
||||
assert(R.isValid());
|
||||
}
|
||||
|
||||
StringRef getText() const { return Text; }
|
||||
SMRange getRange() const { return Range; }
|
||||
|
||||
bool operator<(const SMFixIt &Other) const {
|
||||
if (Range.Start.getPointer() != Other.Range.Start.getPointer())
|
||||
return Range.Start.getPointer() < Other.Range.Start.getPointer();
|
||||
if (Range.End.getPointer() != Other.Range.End.getPointer())
|
||||
return Range.End.getPointer() < Other.Range.End.getPointer();
|
||||
return Text < Other.Text;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/// SMDiagnostic - Instances of this class encapsulate one diagnostic report,
|
||||
/// allowing printing to a raw_ostream as a caret diagnostic.
|
||||
class SMDiagnostic {
|
||||
const SourceMgr *SM;
|
||||
SMLoc Loc;
|
||||
std::string Filename;
|
||||
int LineNo, ColumnNo;
|
||||
SourceMgr::DiagKind Kind;
|
||||
std::string Message, LineContents;
|
||||
std::vector<std::pair<unsigned, unsigned> > Ranges;
|
||||
SmallVector<SMFixIt, 4> FixIts;
|
||||
|
||||
public:
|
||||
// Null diagnostic.
|
||||
SMDiagnostic()
|
||||
: SM(0), LineNo(0), ColumnNo(0), Kind(SourceMgr::DK_Error) {}
|
||||
// Diagnostic with no location (e.g. file not found, command line arg error).
|
||||
SMDiagnostic(StringRef filename, SourceMgr::DiagKind Knd, StringRef Msg)
|
||||
: SM(0), Filename(filename), LineNo(-1), ColumnNo(-1), Kind(Knd),
|
||||
Message(Msg) {}
|
||||
|
||||
// Diagnostic with a location.
|
||||
SMDiagnostic(const SourceMgr &sm, SMLoc L, StringRef FN,
|
||||
int Line, int Col, SourceMgr::DiagKind Kind,
|
||||
StringRef Msg, StringRef LineStr,
|
||||
ArrayRef<std::pair<unsigned,unsigned> > Ranges,
|
||||
ArrayRef<SMFixIt> FixIts = ArrayRef<SMFixIt>());
|
||||
|
||||
const SourceMgr *getSourceMgr() const { return SM; }
|
||||
SMLoc getLoc() const { return Loc; }
|
||||
StringRef getFilename() const { return Filename; }
|
||||
int getLineNo() const { return LineNo; }
|
||||
int getColumnNo() const { return ColumnNo; }
|
||||
SourceMgr::DiagKind getKind() const { return Kind; }
|
||||
StringRef getMessage() const { return Message; }
|
||||
StringRef getLineContents() const { return LineContents; }
|
||||
ArrayRef<std::pair<unsigned, unsigned> > getRanges() const {
|
||||
return Ranges;
|
||||
}
|
||||
|
||||
void addFixIt(const SMFixIt &Hint) {
|
||||
FixIts.push_back(Hint);
|
||||
}
|
||||
|
||||
ArrayRef<SMFixIt> getFixIts() const {
|
||||
return FixIts;
|
||||
}
|
||||
|
||||
void print(const char *ProgName, raw_ostream &S,
|
||||
bool ShowColors = true) const;
|
||||
};
|
||||
|
||||
} // end llvm namespace
|
||||
|
||||
#endif
|
||||
183
thirdparty/clang/include/llvm/Support/StreamableMemoryObject.h
vendored
Normal file
183
thirdparty/clang/include/llvm/Support/StreamableMemoryObject.h
vendored
Normal file
@@ -0,0 +1,183 @@
|
||||
//===- StreamableMemoryObject.h - Streamable data interface -----*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
||||
#ifndef LLVM_SUPPORT_STREAMABLEMEMORYOBJECT_H
|
||||
#define LLVM_SUPPORT_STREAMABLEMEMORYOBJECT_H
|
||||
|
||||
#include "llvm/ADT/OwningPtr.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Support/DataStream.h"
|
||||
#include "llvm/Support/MemoryObject.h"
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
/// StreamableMemoryObject - Interface to data which might be streamed.
|
||||
/// Streamability has 2 important implications/restrictions. First, the data
|
||||
/// might not yet exist in memory when the request is made. This just means
|
||||
/// that readByte/readBytes might have to block or do some work to get it.
|
||||
/// More significantly, the exact size of the object might not be known until
|
||||
/// it has all been fetched. This means that to return the right result,
|
||||
/// getExtent must also wait for all the data to arrive; therefore it should
|
||||
/// not be called on objects which are actually streamed (this would defeat
|
||||
/// the purpose of streaming). Instead, isValidAddress and isObjectEnd can be
|
||||
/// used to test addresses without knowing the exact size of the stream.
|
||||
/// Finally, getPointer can be used instead of readBytes to avoid extra copying.
|
||||
class StreamableMemoryObject : public MemoryObject {
|
||||
public:
|
||||
/// Destructor - Override as necessary.
|
||||
virtual ~StreamableMemoryObject();
|
||||
|
||||
/// getBase - Returns the lowest valid address in the region.
|
||||
///
|
||||
/// @result - The lowest valid address.
|
||||
virtual uint64_t getBase() const = 0;
|
||||
|
||||
/// getExtent - Returns the size of the region in bytes. (The region is
|
||||
/// contiguous, so the highest valid address of the region
|
||||
/// is getBase() + getExtent() - 1).
|
||||
/// May block until all bytes in the stream have been read
|
||||
///
|
||||
/// @result - The size of the region.
|
||||
virtual uint64_t getExtent() const = 0;
|
||||
|
||||
/// readByte - Tries to read a single byte from the region.
|
||||
/// May block until (address - base) bytes have been read
|
||||
/// @param address - The address of the byte, in the same space as getBase().
|
||||
/// @param ptr - A pointer to a byte to be filled in. Must be non-NULL.
|
||||
/// @result - 0 if successful; -1 if not. Failure may be due to a
|
||||
/// bounds violation or an implementation-specific error.
|
||||
virtual int readByte(uint64_t address, uint8_t* ptr) const = 0;
|
||||
|
||||
/// readBytes - Tries to read a contiguous range of bytes from the
|
||||
/// region, up to the end of the region.
|
||||
/// May block until (address - base + size) bytes have
|
||||
/// been read. Additionally, StreamableMemoryObjects will
|
||||
/// not do partial reads - if size bytes cannot be read,
|
||||
/// readBytes will fail.
|
||||
///
|
||||
/// @param address - The address of the first byte, in the same space as
|
||||
/// getBase().
|
||||
/// @param size - The maximum number of bytes to copy.
|
||||
/// @param buf - A pointer to a buffer to be filled in. Must be non-NULL
|
||||
/// and large enough to hold size bytes.
|
||||
/// @param copied - A pointer to a nunber that is filled in with the number
|
||||
/// of bytes actually read. May be NULL.
|
||||
/// @result - 0 if successful; -1 if not. Failure may be due to a
|
||||
/// bounds violation or an implementation-specific error.
|
||||
virtual int readBytes(uint64_t address,
|
||||
uint64_t size,
|
||||
uint8_t* buf,
|
||||
uint64_t* copied) const = 0;
|
||||
|
||||
/// getPointer - Ensures that the requested data is in memory, and returns
|
||||
/// A pointer to it. More efficient than using readBytes if the
|
||||
/// data is already in memory.
|
||||
/// May block until (address - base + size) bytes have been read
|
||||
/// @param address - address of the byte, in the same space as getBase()
|
||||
/// @param size - amount of data that must be available on return
|
||||
/// @result - valid pointer to the requested data
|
||||
virtual const uint8_t *getPointer(uint64_t address, uint64_t size) const = 0;
|
||||
|
||||
/// isValidAddress - Returns true if the address is within the object
|
||||
/// (i.e. between base and base + extent - 1 inclusive)
|
||||
/// May block until (address - base) bytes have been read
|
||||
/// @param address - address of the byte, in the same space as getBase()
|
||||
/// @result - true if the address may be read with readByte()
|
||||
virtual bool isValidAddress(uint64_t address) const = 0;
|
||||
|
||||
/// isObjectEnd - Returns true if the address is one past the end of the
|
||||
/// object (i.e. if it is equal to base + extent)
|
||||
/// May block until (address - base) bytes have been read
|
||||
/// @param address - address of the byte, in the same space as getBase()
|
||||
/// @result - true if the address is equal to base + extent
|
||||
virtual bool isObjectEnd(uint64_t address) const = 0;
|
||||
};
|
||||
|
||||
/// StreamingMemoryObject - interface to data which is actually streamed from
|
||||
/// a DataStreamer. In addition to inherited members, it has the
|
||||
/// dropLeadingBytes and setKnownObjectSize methods which are not applicable
|
||||
/// to non-streamed objects.
|
||||
class StreamingMemoryObject : public StreamableMemoryObject {
|
||||
public:
|
||||
StreamingMemoryObject(DataStreamer *streamer);
|
||||
virtual uint64_t getBase() const LLVM_OVERRIDE { return 0; }
|
||||
virtual uint64_t getExtent() const LLVM_OVERRIDE;
|
||||
virtual int readByte(uint64_t address, uint8_t* ptr) const LLVM_OVERRIDE;
|
||||
virtual int readBytes(uint64_t address,
|
||||
uint64_t size,
|
||||
uint8_t* buf,
|
||||
uint64_t* copied) const LLVM_OVERRIDE;
|
||||
virtual const uint8_t *getPointer(uint64_t address,
|
||||
uint64_t size) const LLVM_OVERRIDE {
|
||||
// This could be fixed by ensuring the bytes are fetched and making a copy,
|
||||
// requiring that the bitcode size be known, or otherwise ensuring that
|
||||
// the memory doesn't go away/get reallocated, but it's
|
||||
// not currently necessary. Users that need the pointer don't stream.
|
||||
assert(0 && "getPointer in streaming memory objects not allowed");
|
||||
return NULL;
|
||||
}
|
||||
virtual bool isValidAddress(uint64_t address) const LLVM_OVERRIDE;
|
||||
virtual bool isObjectEnd(uint64_t address) const LLVM_OVERRIDE;
|
||||
|
||||
/// Drop s bytes from the front of the stream, pushing the positions of the
|
||||
/// remaining bytes down by s. This is used to skip past the bitcode header,
|
||||
/// since we don't know a priori if it's present, and we can't put bytes
|
||||
/// back into the stream once we've read them.
|
||||
bool dropLeadingBytes(size_t s);
|
||||
|
||||
/// If the data object size is known in advance, many of the operations can
|
||||
/// be made more efficient, so this method should be called before reading
|
||||
/// starts (although it can be called anytime).
|
||||
void setKnownObjectSize(size_t size);
|
||||
|
||||
private:
|
||||
const static uint32_t kChunkSize = 4096 * 4;
|
||||
mutable std::vector<unsigned char> Bytes;
|
||||
OwningPtr<DataStreamer> Streamer;
|
||||
mutable size_t BytesRead; // Bytes read from stream
|
||||
size_t BytesSkipped;// Bytes skipped at start of stream (e.g. wrapper/header)
|
||||
mutable size_t ObjectSize; // 0 if unknown, set if wrapper seen or EOF reached
|
||||
mutable bool EOFReached;
|
||||
|
||||
// Fetch enough bytes such that Pos can be read or EOF is reached
|
||||
// (i.e. BytesRead > Pos). Return true if Pos can be read.
|
||||
// Unlike most of the functions in BitcodeReader, returns true on success.
|
||||
// Most of the requests will be small, but we fetch at kChunkSize bytes
|
||||
// at a time to avoid making too many potentially expensive GetBytes calls
|
||||
bool fetchToPos(size_t Pos) const {
|
||||
if (EOFReached) return Pos < ObjectSize;
|
||||
while (Pos >= BytesRead) {
|
||||
Bytes.resize(BytesRead + BytesSkipped + kChunkSize);
|
||||
size_t bytes = Streamer->GetBytes(&Bytes[BytesRead + BytesSkipped],
|
||||
kChunkSize);
|
||||
BytesRead += bytes;
|
||||
if (bytes < kChunkSize) {
|
||||
if (ObjectSize && BytesRead < Pos)
|
||||
assert(0 && "Unexpected short read fetching bitcode");
|
||||
if (BytesRead <= Pos) { // reached EOF/ran out of bytes
|
||||
ObjectSize = BytesRead;
|
||||
EOFReached = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
StreamingMemoryObject(const StreamingMemoryObject&) LLVM_DELETED_FUNCTION;
|
||||
void operator=(const StreamingMemoryObject&) LLVM_DELETED_FUNCTION;
|
||||
};
|
||||
|
||||
StreamableMemoryObject *getNonStreamedMemoryObject(
|
||||
const unsigned char *Start, const unsigned char *End);
|
||||
|
||||
}
|
||||
#endif // STREAMABLEMEMORYOBJECT_H_
|
||||
139
thirdparty/clang/include/llvm/Support/StringPool.h
vendored
Normal file
139
thirdparty/clang/include/llvm/Support/StringPool.h
vendored
Normal file
@@ -0,0 +1,139 @@
|
||||
//===-- StringPool.h - Interned string pool ---------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file declares an interned string pool, which helps reduce the cost of
|
||||
// strings by using the same storage for identical strings.
|
||||
//
|
||||
// To intern a string:
|
||||
//
|
||||
// StringPool Pool;
|
||||
// PooledStringPtr Str = Pool.intern("wakka wakka");
|
||||
//
|
||||
// To use the value of an interned string, use operator bool and operator*:
|
||||
//
|
||||
// if (Str)
|
||||
// cerr << "the string is" << *Str << "\n";
|
||||
//
|
||||
// Pooled strings are immutable, but you can change a PooledStringPtr to point
|
||||
// to another instance. So that interned strings can eventually be freed,
|
||||
// strings in the string pool are reference-counted (automatically).
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_STRINGPOOL_H
|
||||
#define LLVM_SUPPORT_STRINGPOOL_H
|
||||
|
||||
#include "llvm/ADT/StringMap.h"
|
||||
#include <cassert>
|
||||
#include <new>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class PooledStringPtr;
|
||||
|
||||
/// StringPool - An interned string pool. Use the intern method to add a
|
||||
/// string. Strings are removed automatically as PooledStringPtrs are
|
||||
/// destroyed.
|
||||
class StringPool {
|
||||
/// PooledString - This is the value of an entry in the pool's interning
|
||||
/// table.
|
||||
struct PooledString {
|
||||
StringPool *Pool; ///< So the string can remove itself.
|
||||
unsigned Refcount; ///< Number of referencing PooledStringPtrs.
|
||||
|
||||
public:
|
||||
PooledString() : Pool(0), Refcount(0) { }
|
||||
};
|
||||
|
||||
friend class PooledStringPtr;
|
||||
|
||||
typedef StringMap<PooledString> table_t;
|
||||
typedef StringMapEntry<PooledString> entry_t;
|
||||
table_t InternTable;
|
||||
|
||||
public:
|
||||
StringPool();
|
||||
~StringPool();
|
||||
|
||||
/// intern - Adds a string to the pool and returns a reference-counted
|
||||
/// pointer to it. No additional memory is allocated if the string already
|
||||
/// exists in the pool.
|
||||
PooledStringPtr intern(StringRef Str);
|
||||
|
||||
/// empty - Checks whether the pool is empty. Returns true if so.
|
||||
///
|
||||
inline bool empty() const { return InternTable.empty(); }
|
||||
};
|
||||
|
||||
/// PooledStringPtr - A pointer to an interned string. Use operator bool to
|
||||
/// test whether the pointer is valid, and operator * to get the string if so.
|
||||
/// This is a lightweight value class with storage requirements equivalent to
|
||||
/// a single pointer, but it does have reference-counting overhead when
|
||||
/// copied.
|
||||
class PooledStringPtr {
|
||||
typedef StringPool::entry_t entry_t;
|
||||
entry_t *S;
|
||||
|
||||
public:
|
||||
PooledStringPtr() : S(0) {}
|
||||
|
||||
explicit PooledStringPtr(entry_t *E) : S(E) {
|
||||
if (S) ++S->getValue().Refcount;
|
||||
}
|
||||
|
||||
PooledStringPtr(const PooledStringPtr &That) : S(That.S) {
|
||||
if (S) ++S->getValue().Refcount;
|
||||
}
|
||||
|
||||
PooledStringPtr &operator=(const PooledStringPtr &That) {
|
||||
if (S != That.S) {
|
||||
clear();
|
||||
S = That.S;
|
||||
if (S) ++S->getValue().Refcount;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
void clear() {
|
||||
if (!S)
|
||||
return;
|
||||
if (--S->getValue().Refcount == 0) {
|
||||
S->getValue().Pool->InternTable.remove(S);
|
||||
S->Destroy();
|
||||
}
|
||||
S = 0;
|
||||
}
|
||||
|
||||
~PooledStringPtr() { clear(); }
|
||||
|
||||
inline const char *begin() const {
|
||||
assert(*this && "Attempt to dereference empty PooledStringPtr!");
|
||||
return S->getKeyData();
|
||||
}
|
||||
|
||||
inline const char *end() const {
|
||||
assert(*this && "Attempt to dereference empty PooledStringPtr!");
|
||||
return S->getKeyData() + S->getKeyLength();
|
||||
}
|
||||
|
||||
inline unsigned size() const {
|
||||
assert(*this && "Attempt to dereference empty PooledStringPtr!");
|
||||
return S->getKeyLength();
|
||||
}
|
||||
|
||||
inline const char *operator*() const { return begin(); }
|
||||
inline operator bool() const { return S != 0; }
|
||||
|
||||
inline bool operator==(const PooledStringPtr &That) { return S == That.S; }
|
||||
inline bool operator!=(const PooledStringPtr &That) { return S != That.S; }
|
||||
};
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
||||
101
thirdparty/clang/include/llvm/Support/SwapByteOrder.h
vendored
Normal file
101
thirdparty/clang/include/llvm/Support/SwapByteOrder.h
vendored
Normal file
@@ -0,0 +1,101 @@
|
||||
//===- SwapByteOrder.h - Generic and optimized byte swaps -------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file declares generic and optimized functions to swap the byte order of
|
||||
// an integral type.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_SWAPBYTEORDER_H
|
||||
#define LLVM_SUPPORT_SWAPBYTEORDER_H
|
||||
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include <cstddef>
|
||||
#include <limits>
|
||||
|
||||
namespace llvm {
|
||||
namespace sys {
|
||||
|
||||
/// SwapByteOrder_16 - This function returns a byte-swapped representation of
|
||||
/// the 16-bit argument.
|
||||
inline uint16_t SwapByteOrder_16(uint16_t value) {
|
||||
#if defined(_MSC_VER) && !defined(_DEBUG)
|
||||
// The DLL version of the runtime lacks these functions (bug!?), but in a
|
||||
// release build they're replaced with BSWAP instructions anyway.
|
||||
return _byteswap_ushort(value);
|
||||
#else
|
||||
uint16_t Hi = value << 8;
|
||||
uint16_t Lo = value >> 8;
|
||||
return Hi | Lo;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// SwapByteOrder_32 - This function returns a byte-swapped representation of
|
||||
/// the 32-bit argument.
|
||||
inline uint32_t SwapByteOrder_32(uint32_t value) {
|
||||
#if defined(__llvm__) || \
|
||||
(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) && !defined(__ICC)
|
||||
return __builtin_bswap32(value);
|
||||
#elif defined(_MSC_VER) && !defined(_DEBUG)
|
||||
return _byteswap_ulong(value);
|
||||
#else
|
||||
uint32_t Byte0 = value & 0x000000FF;
|
||||
uint32_t Byte1 = value & 0x0000FF00;
|
||||
uint32_t Byte2 = value & 0x00FF0000;
|
||||
uint32_t Byte3 = value & 0xFF000000;
|
||||
return (Byte0 << 24) | (Byte1 << 8) | (Byte2 >> 8) | (Byte3 >> 24);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// SwapByteOrder_64 - This function returns a byte-swapped representation of
|
||||
/// the 64-bit argument.
|
||||
inline uint64_t SwapByteOrder_64(uint64_t value) {
|
||||
#if defined(__llvm__) || \
|
||||
(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) && !defined(__ICC)
|
||||
return __builtin_bswap64(value);
|
||||
#elif defined(_MSC_VER) && !defined(_DEBUG)
|
||||
return _byteswap_uint64(value);
|
||||
#else
|
||||
uint64_t Hi = SwapByteOrder_32(uint32_t(value));
|
||||
uint32_t Lo = SwapByteOrder_32(uint32_t(value >> 32));
|
||||
return (Hi << 32) | Lo;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline unsigned char SwapByteOrder(unsigned char C) { return C; }
|
||||
inline signed char SwapByteOrder(signed char C) { return C; }
|
||||
inline char SwapByteOrder(char C) { return C; }
|
||||
|
||||
inline unsigned short SwapByteOrder(unsigned short C) { return SwapByteOrder_16(C); }
|
||||
inline signed short SwapByteOrder( signed short C) { return SwapByteOrder_16(C); }
|
||||
|
||||
inline unsigned int SwapByteOrder(unsigned int C) { return SwapByteOrder_32(C); }
|
||||
inline signed int SwapByteOrder( signed int C) { return SwapByteOrder_32(C); }
|
||||
|
||||
#if __LONG_MAX__ == __INT_MAX__
|
||||
inline unsigned long SwapByteOrder(unsigned long C) { return SwapByteOrder_32(C); }
|
||||
inline signed long SwapByteOrder( signed long C) { return SwapByteOrder_32(C); }
|
||||
#elif __LONG_MAX__ == __LONG_LONG_MAX__
|
||||
inline unsigned long SwapByteOrder(unsigned long C) { return SwapByteOrder_64(C); }
|
||||
inline signed long SwapByteOrder( signed long C) { return SwapByteOrder_64(C); }
|
||||
#else
|
||||
#error "Unknown long size!"
|
||||
#endif
|
||||
|
||||
inline unsigned long long SwapByteOrder(unsigned long long C) {
|
||||
return SwapByteOrder_64(C);
|
||||
}
|
||||
inline signed long long SwapByteOrder(signed long long C) {
|
||||
return SwapByteOrder_64(C);
|
||||
}
|
||||
|
||||
} // end namespace sys
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
44
thirdparty/clang/include/llvm/Support/SystemUtils.h
vendored
Normal file
44
thirdparty/clang/include/llvm/Support/SystemUtils.h
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
//===- SystemUtils.h - Utilities to do low-level system stuff ---*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file contains functions used to do a variety of low-level, often
|
||||
// system-specific, tasks.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_SYSTEMUTILS_H
|
||||
#define LLVM_SUPPORT_SYSTEMUTILS_H
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace llvm {
|
||||
class raw_ostream;
|
||||
namespace sys { class Path; }
|
||||
|
||||
/// Determine if the raw_ostream provided is connected to a terminal. If so,
|
||||
/// generate a warning message to errs() advising against display of bitcode
|
||||
/// and return true. Otherwise just return false.
|
||||
/// @brief Check for output written to a console
|
||||
bool CheckBitcodeOutputToConsole(
|
||||
raw_ostream &stream_to_check, ///< The stream to be checked
|
||||
bool print_warning = true ///< Control whether warnings are printed
|
||||
);
|
||||
|
||||
/// PrependMainExecutablePath - Prepend the path to the program being executed
|
||||
/// to \p ExeName, given the value of argv[0] and the address of main()
|
||||
/// itself. This allows us to find another LLVM tool if it is built in the same
|
||||
/// directory. An empty string is returned on error; note that this function
|
||||
/// just mainpulates the path and doesn't check for executability.
|
||||
/// @brief Find a named executable.
|
||||
sys::Path PrependMainExecutablePath(const std::string &ExeName,
|
||||
const char *Argv0, void *MainAddr);
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
||||
262
thirdparty/clang/include/llvm/Support/TargetFolder.h
vendored
Normal file
262
thirdparty/clang/include/llvm/Support/TargetFolder.h
vendored
Normal file
@@ -0,0 +1,262 @@
|
||||
//====-- llvm/Support/TargetFolder.h - Constant folding helper -*- C++ -*-====//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the TargetFolder class, a helper for IRBuilder.
|
||||
// It provides IRBuilder with a set of methods for creating constants with
|
||||
// target dependent folding, in addition to the same target-independent
|
||||
// folding that the ConstantFolder class provides. For general constant
|
||||
// creation and folding, use ConstantExpr and the routines in
|
||||
// llvm/Analysis/ConstantFolding.h.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_TARGETFOLDER_H
|
||||
#define LLVM_SUPPORT_TARGETFOLDER_H
|
||||
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/Analysis/ConstantFolding.h"
|
||||
#include "llvm/IR/Constants.h"
|
||||
#include "llvm/IR/InstrTypes.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class DataLayout;
|
||||
|
||||
/// TargetFolder - Create constants with target dependent folding.
|
||||
class TargetFolder {
|
||||
const DataLayout *TD;
|
||||
|
||||
/// Fold - Fold the constant using target specific information.
|
||||
Constant *Fold(Constant *C) const {
|
||||
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C))
|
||||
if (Constant *CF = ConstantFoldConstantExpression(CE, TD))
|
||||
return CF;
|
||||
return C;
|
||||
}
|
||||
|
||||
public:
|
||||
explicit TargetFolder(const DataLayout *TheTD) : TD(TheTD) {}
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Binary Operators
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
||||
Constant *CreateAdd(Constant *LHS, Constant *RHS,
|
||||
bool HasNUW = false, bool HasNSW = false) const {
|
||||
return Fold(ConstantExpr::getAdd(LHS, RHS, HasNUW, HasNSW));
|
||||
}
|
||||
Constant *CreateFAdd(Constant *LHS, Constant *RHS) const {
|
||||
return Fold(ConstantExpr::getFAdd(LHS, RHS));
|
||||
}
|
||||
Constant *CreateSub(Constant *LHS, Constant *RHS,
|
||||
bool HasNUW = false, bool HasNSW = false) const {
|
||||
return Fold(ConstantExpr::getSub(LHS, RHS, HasNUW, HasNSW));
|
||||
}
|
||||
Constant *CreateFSub(Constant *LHS, Constant *RHS) const {
|
||||
return Fold(ConstantExpr::getFSub(LHS, RHS));
|
||||
}
|
||||
Constant *CreateMul(Constant *LHS, Constant *RHS,
|
||||
bool HasNUW = false, bool HasNSW = false) const {
|
||||
return Fold(ConstantExpr::getMul(LHS, RHS, HasNUW, HasNSW));
|
||||
}
|
||||
Constant *CreateFMul(Constant *LHS, Constant *RHS) const {
|
||||
return Fold(ConstantExpr::getFMul(LHS, RHS));
|
||||
}
|
||||
Constant *CreateUDiv(Constant *LHS, Constant *RHS, bool isExact = false)const{
|
||||
return Fold(ConstantExpr::getUDiv(LHS, RHS, isExact));
|
||||
}
|
||||
Constant *CreateSDiv(Constant *LHS, Constant *RHS, bool isExact = false)const{
|
||||
return Fold(ConstantExpr::getSDiv(LHS, RHS, isExact));
|
||||
}
|
||||
Constant *CreateFDiv(Constant *LHS, Constant *RHS) const {
|
||||
return Fold(ConstantExpr::getFDiv(LHS, RHS));
|
||||
}
|
||||
Constant *CreateURem(Constant *LHS, Constant *RHS) const {
|
||||
return Fold(ConstantExpr::getURem(LHS, RHS));
|
||||
}
|
||||
Constant *CreateSRem(Constant *LHS, Constant *RHS) const {
|
||||
return Fold(ConstantExpr::getSRem(LHS, RHS));
|
||||
}
|
||||
Constant *CreateFRem(Constant *LHS, Constant *RHS) const {
|
||||
return Fold(ConstantExpr::getFRem(LHS, RHS));
|
||||
}
|
||||
Constant *CreateShl(Constant *LHS, Constant *RHS,
|
||||
bool HasNUW = false, bool HasNSW = false) const {
|
||||
return Fold(ConstantExpr::getShl(LHS, RHS, HasNUW, HasNSW));
|
||||
}
|
||||
Constant *CreateLShr(Constant *LHS, Constant *RHS, bool isExact = false)const{
|
||||
return Fold(ConstantExpr::getLShr(LHS, RHS, isExact));
|
||||
}
|
||||
Constant *CreateAShr(Constant *LHS, Constant *RHS, bool isExact = false)const{
|
||||
return Fold(ConstantExpr::getAShr(LHS, RHS, isExact));
|
||||
}
|
||||
Constant *CreateAnd(Constant *LHS, Constant *RHS) const {
|
||||
return Fold(ConstantExpr::getAnd(LHS, RHS));
|
||||
}
|
||||
Constant *CreateOr(Constant *LHS, Constant *RHS) const {
|
||||
return Fold(ConstantExpr::getOr(LHS, RHS));
|
||||
}
|
||||
Constant *CreateXor(Constant *LHS, Constant *RHS) const {
|
||||
return Fold(ConstantExpr::getXor(LHS, RHS));
|
||||
}
|
||||
|
||||
Constant *CreateBinOp(Instruction::BinaryOps Opc,
|
||||
Constant *LHS, Constant *RHS) const {
|
||||
return Fold(ConstantExpr::get(Opc, LHS, RHS));
|
||||
}
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Unary Operators
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
||||
Constant *CreateNeg(Constant *C,
|
||||
bool HasNUW = false, bool HasNSW = false) const {
|
||||
return Fold(ConstantExpr::getNeg(C, HasNUW, HasNSW));
|
||||
}
|
||||
Constant *CreateFNeg(Constant *C) const {
|
||||
return Fold(ConstantExpr::getFNeg(C));
|
||||
}
|
||||
Constant *CreateNot(Constant *C) const {
|
||||
return Fold(ConstantExpr::getNot(C));
|
||||
}
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Memory Instructions
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
||||
Constant *CreateGetElementPtr(Constant *C,
|
||||
ArrayRef<Constant *> IdxList) const {
|
||||
return Fold(ConstantExpr::getGetElementPtr(C, IdxList));
|
||||
}
|
||||
Constant *CreateGetElementPtr(Constant *C, Constant *Idx) const {
|
||||
// This form of the function only exists to avoid ambiguous overload
|
||||
// warnings about whether to convert Idx to ArrayRef<Constant *> or
|
||||
// ArrayRef<Value *>.
|
||||
return Fold(ConstantExpr::getGetElementPtr(C, Idx));
|
||||
}
|
||||
Constant *CreateGetElementPtr(Constant *C,
|
||||
ArrayRef<Value *> IdxList) const {
|
||||
return Fold(ConstantExpr::getGetElementPtr(C, IdxList));
|
||||
}
|
||||
|
||||
Constant *CreateInBoundsGetElementPtr(Constant *C,
|
||||
ArrayRef<Constant *> IdxList) const {
|
||||
return Fold(ConstantExpr::getInBoundsGetElementPtr(C, IdxList));
|
||||
}
|
||||
Constant *CreateInBoundsGetElementPtr(Constant *C, Constant *Idx) const {
|
||||
// This form of the function only exists to avoid ambiguous overload
|
||||
// warnings about whether to convert Idx to ArrayRef<Constant *> or
|
||||
// ArrayRef<Value *>.
|
||||
return Fold(ConstantExpr::getInBoundsGetElementPtr(C, Idx));
|
||||
}
|
||||
Constant *CreateInBoundsGetElementPtr(Constant *C,
|
||||
ArrayRef<Value *> IdxList) const {
|
||||
return Fold(ConstantExpr::getInBoundsGetElementPtr(C, IdxList));
|
||||
}
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Cast/Conversion Operators
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
||||
Constant *CreateCast(Instruction::CastOps Op, Constant *C,
|
||||
Type *DestTy) const {
|
||||
if (C->getType() == DestTy)
|
||||
return C; // avoid calling Fold
|
||||
return Fold(ConstantExpr::getCast(Op, C, DestTy));
|
||||
}
|
||||
Constant *CreateIntCast(Constant *C, Type *DestTy,
|
||||
bool isSigned) const {
|
||||
if (C->getType() == DestTy)
|
||||
return C; // avoid calling Fold
|
||||
return Fold(ConstantExpr::getIntegerCast(C, DestTy, isSigned));
|
||||
}
|
||||
Constant *CreatePointerCast(Constant *C, Type *DestTy) const {
|
||||
if (C->getType() == DestTy)
|
||||
return C; // avoid calling Fold
|
||||
return Fold(ConstantExpr::getPointerCast(C, DestTy));
|
||||
}
|
||||
Constant *CreateFPCast(Constant *C, Type *DestTy) const {
|
||||
if (C->getType() == DestTy)
|
||||
return C; // avoid calling Fold
|
||||
return Fold(ConstantExpr::getFPCast(C, DestTy));
|
||||
}
|
||||
Constant *CreateBitCast(Constant *C, Type *DestTy) const {
|
||||
return CreateCast(Instruction::BitCast, C, DestTy);
|
||||
}
|
||||
Constant *CreateIntToPtr(Constant *C, Type *DestTy) const {
|
||||
return CreateCast(Instruction::IntToPtr, C, DestTy);
|
||||
}
|
||||
Constant *CreatePtrToInt(Constant *C, Type *DestTy) const {
|
||||
return CreateCast(Instruction::PtrToInt, C, DestTy);
|
||||
}
|
||||
Constant *CreateZExtOrBitCast(Constant *C, Type *DestTy) const {
|
||||
if (C->getType() == DestTy)
|
||||
return C; // avoid calling Fold
|
||||
return Fold(ConstantExpr::getZExtOrBitCast(C, DestTy));
|
||||
}
|
||||
Constant *CreateSExtOrBitCast(Constant *C, Type *DestTy) const {
|
||||
if (C->getType() == DestTy)
|
||||
return C; // avoid calling Fold
|
||||
return Fold(ConstantExpr::getSExtOrBitCast(C, DestTy));
|
||||
}
|
||||
Constant *CreateTruncOrBitCast(Constant *C, Type *DestTy) const {
|
||||
if (C->getType() == DestTy)
|
||||
return C; // avoid calling Fold
|
||||
return Fold(ConstantExpr::getTruncOrBitCast(C, DestTy));
|
||||
}
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Compare Instructions
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
||||
Constant *CreateICmp(CmpInst::Predicate P, Constant *LHS,
|
||||
Constant *RHS) const {
|
||||
return Fold(ConstantExpr::getCompare(P, LHS, RHS));
|
||||
}
|
||||
Constant *CreateFCmp(CmpInst::Predicate P, Constant *LHS,
|
||||
Constant *RHS) const {
|
||||
return Fold(ConstantExpr::getCompare(P, LHS, RHS));
|
||||
}
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Other Instructions
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
||||
Constant *CreateSelect(Constant *C, Constant *True, Constant *False) const {
|
||||
return Fold(ConstantExpr::getSelect(C, True, False));
|
||||
}
|
||||
|
||||
Constant *CreateExtractElement(Constant *Vec, Constant *Idx) const {
|
||||
return Fold(ConstantExpr::getExtractElement(Vec, Idx));
|
||||
}
|
||||
|
||||
Constant *CreateInsertElement(Constant *Vec, Constant *NewElt,
|
||||
Constant *Idx) const {
|
||||
return Fold(ConstantExpr::getInsertElement(Vec, NewElt, Idx));
|
||||
}
|
||||
|
||||
Constant *CreateShuffleVector(Constant *V1, Constant *V2,
|
||||
Constant *Mask) const {
|
||||
return Fold(ConstantExpr::getShuffleVector(V1, V2, Mask));
|
||||
}
|
||||
|
||||
Constant *CreateExtractValue(Constant *Agg,
|
||||
ArrayRef<unsigned> IdxList) const {
|
||||
return Fold(ConstantExpr::getExtractValue(Agg, IdxList));
|
||||
}
|
||||
|
||||
Constant *CreateInsertValue(Constant *Agg, Constant *Val,
|
||||
ArrayRef<unsigned> IdxList) const {
|
||||
return Fold(ConstantExpr::getInsertValue(Agg, Val, IdxList));
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
1104
thirdparty/clang/include/llvm/Support/TargetRegistry.h
vendored
Normal file
1104
thirdparty/clang/include/llvm/Support/TargetRegistry.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
166
thirdparty/clang/include/llvm/Support/TargetSelect.h
vendored
Normal file
166
thirdparty/clang/include/llvm/Support/TargetSelect.h
vendored
Normal file
@@ -0,0 +1,166 @@
|
||||
//===- TargetSelect.h - Target Selection & Registration ---------*- 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 utilities to make sure that certain classes of targets are
|
||||
// linked into the main application executable, and initialize them as
|
||||
// appropriate.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_TARGETSELECT_H
|
||||
#define LLVM_SUPPORT_TARGETSELECT_H
|
||||
|
||||
#include "llvm/Config/llvm-config.h"
|
||||
|
||||
extern "C" {
|
||||
// Declare all of the target-initialization functions that are available.
|
||||
#define LLVM_TARGET(TargetName) void LLVMInitialize##TargetName##TargetInfo();
|
||||
#include "llvm/Config/Targets.def"
|
||||
|
||||
#define LLVM_TARGET(TargetName) void LLVMInitialize##TargetName##Target();
|
||||
#include "llvm/Config/Targets.def"
|
||||
|
||||
// Declare all of the target-MC-initialization functions that are available.
|
||||
#define LLVM_TARGET(TargetName) void LLVMInitialize##TargetName##TargetMC();
|
||||
#include "llvm/Config/Targets.def"
|
||||
|
||||
// Declare all of the available assembly printer initialization functions.
|
||||
#define LLVM_ASM_PRINTER(TargetName) void LLVMInitialize##TargetName##AsmPrinter();
|
||||
#include "llvm/Config/AsmPrinters.def"
|
||||
|
||||
// Declare all of the available assembly parser initialization functions.
|
||||
#define LLVM_ASM_PARSER(TargetName) void LLVMInitialize##TargetName##AsmParser();
|
||||
#include "llvm/Config/AsmParsers.def"
|
||||
|
||||
// Declare all of the available disassembler initialization functions.
|
||||
#define LLVM_DISASSEMBLER(TargetName) \
|
||||
void LLVMInitialize##TargetName##Disassembler();
|
||||
#include "llvm/Config/Disassemblers.def"
|
||||
}
|
||||
|
||||
namespace llvm {
|
||||
/// InitializeAllTargetInfos - The main program should call this function if
|
||||
/// it wants access to all available targets that LLVM is configured to
|
||||
/// support, to make them available via the TargetRegistry.
|
||||
///
|
||||
/// It is legal for a client to make multiple calls to this function.
|
||||
inline void InitializeAllTargetInfos() {
|
||||
#define LLVM_TARGET(TargetName) LLVMInitialize##TargetName##TargetInfo();
|
||||
#include "llvm/Config/Targets.def"
|
||||
}
|
||||
|
||||
/// InitializeAllTargets - The main program should call this function if it
|
||||
/// wants access to all available target machines that LLVM is configured to
|
||||
/// support, to make them available via the TargetRegistry.
|
||||
///
|
||||
/// It is legal for a client to make multiple calls to this function.
|
||||
inline void InitializeAllTargets() {
|
||||
// FIXME: Remove this, clients should do it.
|
||||
InitializeAllTargetInfos();
|
||||
|
||||
#define LLVM_TARGET(TargetName) LLVMInitialize##TargetName##Target();
|
||||
#include "llvm/Config/Targets.def"
|
||||
}
|
||||
|
||||
/// InitializeAllTargetMCs - The main program should call this function if it
|
||||
/// wants access to all available target MC that LLVM is configured to
|
||||
/// support, to make them available via the TargetRegistry.
|
||||
///
|
||||
/// It is legal for a client to make multiple calls to this function.
|
||||
inline void InitializeAllTargetMCs() {
|
||||
#define LLVM_TARGET(TargetName) LLVMInitialize##TargetName##TargetMC();
|
||||
#include "llvm/Config/Targets.def"
|
||||
}
|
||||
|
||||
/// InitializeAllAsmPrinters - The main program should call this function if
|
||||
/// it wants all asm printers that LLVM is configured to support, to make them
|
||||
/// available via the TargetRegistry.
|
||||
///
|
||||
/// It is legal for a client to make multiple calls to this function.
|
||||
inline void InitializeAllAsmPrinters() {
|
||||
#define LLVM_ASM_PRINTER(TargetName) LLVMInitialize##TargetName##AsmPrinter();
|
||||
#include "llvm/Config/AsmPrinters.def"
|
||||
}
|
||||
|
||||
/// InitializeAllAsmParsers - The main program should call this function if it
|
||||
/// wants all asm parsers that LLVM is configured to support, to make them
|
||||
/// available via the TargetRegistry.
|
||||
///
|
||||
/// It is legal for a client to make multiple calls to this function.
|
||||
inline void InitializeAllAsmParsers() {
|
||||
#define LLVM_ASM_PARSER(TargetName) LLVMInitialize##TargetName##AsmParser();
|
||||
#include "llvm/Config/AsmParsers.def"
|
||||
}
|
||||
|
||||
/// InitializeAllDisassemblers - The main program should call this function if
|
||||
/// it wants all disassemblers that LLVM is configured to support, to make
|
||||
/// them available via the TargetRegistry.
|
||||
///
|
||||
/// It is legal for a client to make multiple calls to this function.
|
||||
inline void InitializeAllDisassemblers() {
|
||||
#define LLVM_DISASSEMBLER(TargetName) LLVMInitialize##TargetName##Disassembler();
|
||||
#include "llvm/Config/Disassemblers.def"
|
||||
}
|
||||
|
||||
/// InitializeNativeTarget - The main program should call this function to
|
||||
/// initialize the native target corresponding to the host. This is useful
|
||||
/// for JIT applications to ensure that the target gets linked in correctly.
|
||||
///
|
||||
/// It is legal for a client to make multiple calls to this function.
|
||||
inline bool InitializeNativeTarget() {
|
||||
// If we have a native target, initialize it to ensure it is linked in.
|
||||
#ifdef LLVM_NATIVE_TARGET
|
||||
LLVM_NATIVE_TARGETINFO();
|
||||
LLVM_NATIVE_TARGET();
|
||||
LLVM_NATIVE_TARGETMC();
|
||||
return false;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// InitializeNativeTargetAsmPrinter - The main program should call
|
||||
/// this function to initialize the native target asm printer.
|
||||
inline bool InitializeNativeTargetAsmPrinter() {
|
||||
// If we have a native target, initialize the corresponding asm printer.
|
||||
#ifdef LLVM_NATIVE_ASMPRINTER
|
||||
LLVM_NATIVE_ASMPRINTER();
|
||||
return false;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// InitializeNativeTargetAsmParser - The main program should call
|
||||
/// this function to initialize the native target asm parser.
|
||||
inline bool InitializeNativeTargetAsmParser() {
|
||||
// If we have a native target, initialize the corresponding asm parser.
|
||||
#ifdef LLVM_NATIVE_ASMPARSER
|
||||
LLVM_NATIVE_ASMPARSER();
|
||||
return false;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// InitializeNativeTargetDisassembler - The main program should call
|
||||
/// this function to initialize the native target disassembler.
|
||||
inline bool InitializeNativeTargetDisassembler() {
|
||||
// If we have a native target, initialize the corresponding disassembler.
|
||||
#ifdef LLVM_NATIVE_DISASSEMBLER
|
||||
LLVM_NATIVE_DISASSEMBLER();
|
||||
return false;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
63
thirdparty/clang/include/llvm/Support/ThreadLocal.h
vendored
Normal file
63
thirdparty/clang/include/llvm/Support/ThreadLocal.h
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
//===- llvm/Support/ThreadLocal.h - Thread Local Data ------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file declares the llvm::sys::ThreadLocal class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_THREADLOCAL_H
|
||||
#define LLVM_SUPPORT_THREADLOCAL_H
|
||||
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/Support/Threading.h"
|
||||
#include <cassert>
|
||||
|
||||
namespace llvm {
|
||||
namespace sys {
|
||||
// ThreadLocalImpl - Common base class of all ThreadLocal instantiations.
|
||||
// YOU SHOULD NEVER USE THIS DIRECTLY.
|
||||
class ThreadLocalImpl {
|
||||
typedef uint64_t ThreadLocalDataTy;
|
||||
/// \brief Platform-specific thread local data.
|
||||
///
|
||||
/// This is embedded in the class and we avoid malloc'ing/free'ing it,
|
||||
/// to make this class more safe for use along with CrashRecoveryContext.
|
||||
union {
|
||||
char data[sizeof(ThreadLocalDataTy)];
|
||||
ThreadLocalDataTy align_data;
|
||||
};
|
||||
public:
|
||||
ThreadLocalImpl();
|
||||
virtual ~ThreadLocalImpl();
|
||||
void setInstance(const void* d);
|
||||
const void* getInstance();
|
||||
void removeInstance();
|
||||
};
|
||||
|
||||
/// ThreadLocal - A class used to abstract thread-local storage. It holds,
|
||||
/// for each thread, a pointer a single object of type T.
|
||||
template<class T>
|
||||
class ThreadLocal : public ThreadLocalImpl {
|
||||
public:
|
||||
ThreadLocal() : ThreadLocalImpl() { }
|
||||
|
||||
/// get - Fetches a pointer to the object associated with the current
|
||||
/// thread. If no object has yet been associated, it returns NULL;
|
||||
T* get() { return static_cast<T*>(getInstance()); }
|
||||
|
||||
// set - Associates a pointer to an object with the current thread.
|
||||
void set(T* d) { setInstance(d); }
|
||||
|
||||
// erase - Removes the pointer associated with the current thread.
|
||||
void erase() { removeInstance(); }
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
59
thirdparty/clang/include/llvm/Support/Threading.h
vendored
Normal file
59
thirdparty/clang/include/llvm/Support/Threading.h
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
//===-- llvm/Support/Threading.h - Control multithreading mode --*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// TThis file defines llvm_start_multithreaded() and friends.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_THREADING_H
|
||||
#define LLVM_SUPPORT_THREADING_H
|
||||
|
||||
namespace llvm {
|
||||
/// llvm_start_multithreaded - Allocate and initialize structures needed to
|
||||
/// make LLVM safe for multithreading. The return value indicates whether
|
||||
/// multithreaded initialization succeeded. LLVM will still be operational
|
||||
/// on "failed" return, and will still be safe for hosting threading
|
||||
/// applications in the JIT, but will not be safe for concurrent calls to the
|
||||
/// LLVM APIs.
|
||||
/// THIS MUST EXECUTE IN ISOLATION FROM ALL OTHER LLVM API CALLS.
|
||||
bool llvm_start_multithreaded();
|
||||
|
||||
/// llvm_stop_multithreaded - Deallocate structures necessary to make LLVM
|
||||
/// safe for multithreading.
|
||||
/// THIS MUST EXECUTE IN ISOLATION FROM ALL OTHER LLVM API CALLS.
|
||||
void llvm_stop_multithreaded();
|
||||
|
||||
/// llvm_is_multithreaded - Check whether LLVM is executing in thread-safe
|
||||
/// mode or not.
|
||||
bool llvm_is_multithreaded();
|
||||
|
||||
/// acquire_global_lock - Acquire the global lock. This is a no-op if called
|
||||
/// before llvm_start_multithreaded().
|
||||
void llvm_acquire_global_lock();
|
||||
|
||||
/// release_global_lock - Release the global lock. This is a no-op if called
|
||||
/// before llvm_start_multithreaded().
|
||||
void llvm_release_global_lock();
|
||||
|
||||
/// llvm_execute_on_thread - Execute the given \p UserFn on a separate
|
||||
/// thread, passing it the provided \p UserData.
|
||||
///
|
||||
/// This function does not guarantee that the code will actually be executed
|
||||
/// on a separate thread or honoring the requested stack size, but tries to do
|
||||
/// so where system support is available.
|
||||
///
|
||||
/// \param UserFn - The callback to execute.
|
||||
/// \param UserData - An argument to pass to the callback function.
|
||||
/// \param RequestedStackSize - If non-zero, a requested size (in bytes) for
|
||||
/// the thread stack.
|
||||
void llvm_execute_on_thread(void (*UserFn)(void*), void *UserData,
|
||||
unsigned RequestedStackSize = 0);
|
||||
}
|
||||
|
||||
#endif
|
||||
385
thirdparty/clang/include/llvm/Support/TimeValue.h
vendored
Normal file
385
thirdparty/clang/include/llvm/Support/TimeValue.h
vendored
Normal file
@@ -0,0 +1,385 @@
|
||||
//===-- TimeValue.h - Declare OS TimeValue Concept --------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This header file declares the operating system TimeValue concept.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_TIMEVALUE_H
|
||||
#define LLVM_SUPPORT_TIMEVALUE_H
|
||||
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include <string>
|
||||
|
||||
namespace llvm {
|
||||
namespace sys {
|
||||
/// This class is used where a precise fixed point in time is required. The
|
||||
/// range of TimeValue spans many hundreds of billions of years both past and
|
||||
/// present. The precision of TimeValue is to the nanosecond. However, the
|
||||
/// actual precision of its values will be determined by the resolution of
|
||||
/// the system clock. The TimeValue class is used in conjunction with several
|
||||
/// other lib/System interfaces to specify the time at which a call should
|
||||
/// timeout, etc.
|
||||
/// @since 1.4
|
||||
/// @brief Provides an abstraction for a fixed point in time.
|
||||
class TimeValue {
|
||||
|
||||
/// @name Constants
|
||||
/// @{
|
||||
public:
|
||||
|
||||
/// A constant TimeValue representing the smallest time
|
||||
/// value permissible by the class. MinTime is some point
|
||||
/// in the distant past, about 300 billion years BCE.
|
||||
/// @brief The smallest possible time value.
|
||||
static const TimeValue MinTime;
|
||||
|
||||
/// A constant TimeValue representing the largest time
|
||||
/// value permissible by the class. MaxTime is some point
|
||||
/// in the distant future, about 300 billion years AD.
|
||||
/// @brief The largest possible time value.
|
||||
static const TimeValue MaxTime;
|
||||
|
||||
/// A constant TimeValue representing the base time,
|
||||
/// or zero time of 00:00:00 (midnight) January 1st, 2000.
|
||||
/// @brief 00:00:00 Jan 1, 2000 UTC.
|
||||
static const TimeValue ZeroTime;
|
||||
|
||||
/// A constant TimeValue for the Posix base time which is
|
||||
/// 00:00:00 (midnight) January 1st, 1970.
|
||||
/// @brief 00:00:00 Jan 1, 1970 UTC.
|
||||
static const TimeValue PosixZeroTime;
|
||||
|
||||
/// A constant TimeValue for the Win32 base time which is
|
||||
/// 00:00:00 (midnight) January 1st, 1601.
|
||||
/// @brief 00:00:00 Jan 1, 1601 UTC.
|
||||
static const TimeValue Win32ZeroTime;
|
||||
|
||||
/// @}
|
||||
/// @name Types
|
||||
/// @{
|
||||
public:
|
||||
typedef int64_t SecondsType; ///< Type used for representing seconds.
|
||||
typedef int32_t NanoSecondsType;///< Type used for representing nanoseconds.
|
||||
|
||||
enum TimeConversions {
|
||||
NANOSECONDS_PER_SECOND = 1000000000, ///< One Billion
|
||||
MICROSECONDS_PER_SECOND = 1000000, ///< One Million
|
||||
MILLISECONDS_PER_SECOND = 1000, ///< One Thousand
|
||||
NANOSECONDS_PER_MICROSECOND = 1000, ///< One Thousand
|
||||
NANOSECONDS_PER_MILLISECOND = 1000000,///< One Million
|
||||
NANOSECONDS_PER_POSIX_TICK = 100, ///< Posix tick is 100 Hz (10ms)
|
||||
NANOSECONDS_PER_WIN32_TICK = 100 ///< Win32 tick is 100 Hz (10ms)
|
||||
};
|
||||
|
||||
/// @}
|
||||
/// @name Constructors
|
||||
/// @{
|
||||
public:
|
||||
/// \brief Default construct a time value, initializing to ZeroTime.
|
||||
TimeValue() : seconds_(0), nanos_(0) {}
|
||||
|
||||
/// Caller provides the exact value in seconds and nanoseconds. The
|
||||
/// \p nanos argument defaults to zero for convenience.
|
||||
/// @brief Explicit constructor
|
||||
explicit TimeValue (SecondsType seconds, NanoSecondsType nanos = 0)
|
||||
: seconds_( seconds ), nanos_( nanos ) { this->normalize(); }
|
||||
|
||||
/// Caller provides the exact value as a double in seconds with the
|
||||
/// fractional part representing nanoseconds.
|
||||
/// @brief Double Constructor.
|
||||
explicit TimeValue( double new_time )
|
||||
: seconds_( 0 ) , nanos_ ( 0 ) {
|
||||
SecondsType integer_part = static_cast<SecondsType>( new_time );
|
||||
seconds_ = integer_part;
|
||||
nanos_ = static_cast<NanoSecondsType>( (new_time -
|
||||
static_cast<double>(integer_part)) * NANOSECONDS_PER_SECOND );
|
||||
this->normalize();
|
||||
}
|
||||
|
||||
/// This is a static constructor that returns a TimeValue that represents
|
||||
/// the current time.
|
||||
/// @brief Creates a TimeValue with the current time (UTC).
|
||||
static TimeValue now();
|
||||
|
||||
/// @}
|
||||
/// @name Operators
|
||||
/// @{
|
||||
public:
|
||||
/// Add \p that to \p this.
|
||||
/// @returns this
|
||||
/// @brief Incrementing assignment operator.
|
||||
TimeValue& operator += (const TimeValue& that ) {
|
||||
this->seconds_ += that.seconds_ ;
|
||||
this->nanos_ += that.nanos_ ;
|
||||
this->normalize();
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Subtract \p that from \p this.
|
||||
/// @returns this
|
||||
/// @brief Decrementing assignment operator.
|
||||
TimeValue& operator -= (const TimeValue &that ) {
|
||||
this->seconds_ -= that.seconds_ ;
|
||||
this->nanos_ -= that.nanos_ ;
|
||||
this->normalize();
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Determine if \p this is less than \p that.
|
||||
/// @returns True iff *this < that.
|
||||
/// @brief True if this < that.
|
||||
int operator < (const TimeValue &that) const { return that > *this; }
|
||||
|
||||
/// Determine if \p this is greather than \p that.
|
||||
/// @returns True iff *this > that.
|
||||
/// @brief True if this > that.
|
||||
int operator > (const TimeValue &that) const {
|
||||
if ( this->seconds_ > that.seconds_ ) {
|
||||
return 1;
|
||||
} else if ( this->seconds_ == that.seconds_ ) {
|
||||
if ( this->nanos_ > that.nanos_ ) return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// Determine if \p this is less than or equal to \p that.
|
||||
/// @returns True iff *this <= that.
|
||||
/// @brief True if this <= that.
|
||||
int operator <= (const TimeValue &that) const { return that >= *this; }
|
||||
|
||||
/// Determine if \p this is greater than or equal to \p that.
|
||||
/// @returns True iff *this >= that.
|
||||
int operator >= (const TimeValue &that) const {
|
||||
if ( this->seconds_ > that.seconds_ ) {
|
||||
return 1;
|
||||
} else if ( this->seconds_ == that.seconds_ ) {
|
||||
if ( this->nanos_ >= that.nanos_ ) return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// Determines if two TimeValue objects represent the same moment in time.
|
||||
/// @returns True iff *this == that.
|
||||
int operator == (const TimeValue &that) const {
|
||||
return (this->seconds_ == that.seconds_) &&
|
||||
(this->nanos_ == that.nanos_);
|
||||
}
|
||||
|
||||
/// Determines if two TimeValue objects represent times that are not the
|
||||
/// same.
|
||||
/// @returns True iff *this != that.
|
||||
int operator != (const TimeValue &that) const { return !(*this == that); }
|
||||
|
||||
/// Adds two TimeValue objects together.
|
||||
/// @returns The sum of the two operands as a new TimeValue
|
||||
/// @brief Addition operator.
|
||||
friend TimeValue operator + (const TimeValue &tv1, const TimeValue &tv2);
|
||||
|
||||
/// Subtracts two TimeValue objects.
|
||||
/// @returns The difference of the two operands as a new TimeValue
|
||||
/// @brief Subtraction operator.
|
||||
friend TimeValue operator - (const TimeValue &tv1, const TimeValue &tv2);
|
||||
|
||||
/// @}
|
||||
/// @name Accessors
|
||||
/// @{
|
||||
public:
|
||||
|
||||
/// Returns only the seconds component of the TimeValue. The nanoseconds
|
||||
/// portion is ignored. No rounding is performed.
|
||||
/// @brief Retrieve the seconds component
|
||||
SecondsType seconds() const { return seconds_; }
|
||||
|
||||
/// Returns only the nanoseconds component of the TimeValue. The seconds
|
||||
/// portion is ignored.
|
||||
/// @brief Retrieve the nanoseconds component.
|
||||
NanoSecondsType nanoseconds() const { return nanos_; }
|
||||
|
||||
/// Returns only the fractional portion of the TimeValue rounded down to the
|
||||
/// nearest microsecond (divide by one thousand).
|
||||
/// @brief Retrieve the fractional part as microseconds;
|
||||
uint32_t microseconds() const {
|
||||
return nanos_ / NANOSECONDS_PER_MICROSECOND;
|
||||
}
|
||||
|
||||
/// Returns only the fractional portion of the TimeValue rounded down to the
|
||||
/// nearest millisecond (divide by one million).
|
||||
/// @brief Retrieve the fractional part as milliseconds;
|
||||
uint32_t milliseconds() const {
|
||||
return nanos_ / NANOSECONDS_PER_MILLISECOND;
|
||||
}
|
||||
|
||||
/// Returns the TimeValue as a number of microseconds. Note that the value
|
||||
/// returned can overflow because the range of a uint64_t is smaller than
|
||||
/// the range of a TimeValue. Nevertheless, this is useful on some operating
|
||||
/// systems and is therefore provided.
|
||||
/// @brief Convert to a number of microseconds (can overflow)
|
||||
uint64_t usec() const {
|
||||
return seconds_ * MICROSECONDS_PER_SECOND +
|
||||
( nanos_ / NANOSECONDS_PER_MICROSECOND );
|
||||
}
|
||||
|
||||
/// Returns the TimeValue as a number of milliseconds. Note that the value
|
||||
/// returned can overflow because the range of a uint64_t is smaller than
|
||||
/// the range of a TimeValue. Nevertheless, this is useful on some operating
|
||||
/// systems and is therefore provided.
|
||||
/// @brief Convert to a number of milliseconds (can overflow)
|
||||
uint64_t msec() const {
|
||||
return seconds_ * MILLISECONDS_PER_SECOND +
|
||||
( nanos_ / NANOSECONDS_PER_MILLISECOND );
|
||||
}
|
||||
|
||||
/// Converts the TimeValue into the corresponding number of "ticks" for
|
||||
/// Posix, correcting for the difference in Posix zero time.
|
||||
/// @brief Convert to unix time (100 nanoseconds since 12:00:00a Jan 1,1970)
|
||||
uint64_t toPosixTime() const {
|
||||
uint64_t result = seconds_ - PosixZeroTimeSeconds;
|
||||
result += nanos_ / NANOSECONDS_PER_POSIX_TICK;
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Converts the TimeValue into the corresponding number of seconds
|
||||
/// since the epoch (00:00:00 Jan 1,1970).
|
||||
uint64_t toEpochTime() const {
|
||||
return seconds_ - PosixZeroTimeSeconds;
|
||||
}
|
||||
|
||||
/// Converts the TimeValue into the corresponding number of "ticks" for
|
||||
/// Win32 platforms, correcting for the difference in Win32 zero time.
|
||||
/// @brief Convert to windows time (seconds since 12:00:00a Jan 1, 1601)
|
||||
uint64_t toWin32Time() const {
|
||||
uint64_t result = seconds_ - Win32ZeroTimeSeconds;
|
||||
result += nanos_ / NANOSECONDS_PER_WIN32_TICK;
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Provides the seconds and nanoseconds as results in its arguments after
|
||||
/// correction for the Posix zero time.
|
||||
/// @brief Convert to timespec time (ala POSIX.1b)
|
||||
void getTimespecTime( uint64_t& seconds, uint32_t& nanos ) const {
|
||||
seconds = seconds_ - PosixZeroTimeSeconds;
|
||||
nanos = nanos_;
|
||||
}
|
||||
|
||||
/// Provides conversion of the TimeValue into a readable time & date.
|
||||
/// @returns std::string containing the readable time value
|
||||
/// @brief Convert time to a string.
|
||||
std::string str() const;
|
||||
|
||||
/// @}
|
||||
/// @name Mutators
|
||||
/// @{
|
||||
public:
|
||||
/// The seconds component of the TimeValue is set to \p sec without
|
||||
/// modifying the nanoseconds part. This is useful for whole second
|
||||
/// arithmetic.
|
||||
/// @brief Set the seconds component.
|
||||
void seconds (SecondsType sec ) {
|
||||
this->seconds_ = sec;
|
||||
this->normalize();
|
||||
}
|
||||
|
||||
/// The nanoseconds component of the TimeValue is set to \p nanos without
|
||||
/// modifying the seconds part. This is useful for basic computations
|
||||
/// involving just the nanoseconds portion. Note that the TimeValue will be
|
||||
/// normalized after this call so that the fractional (nanoseconds) portion
|
||||
/// will have the smallest equivalent value.
|
||||
/// @brief Set the nanoseconds component using a number of nanoseconds.
|
||||
void nanoseconds ( NanoSecondsType nanos ) {
|
||||
this->nanos_ = nanos;
|
||||
this->normalize();
|
||||
}
|
||||
|
||||
/// The seconds component remains unchanged.
|
||||
/// @brief Set the nanoseconds component using a number of microseconds.
|
||||
void microseconds ( int32_t micros ) {
|
||||
this->nanos_ = micros * NANOSECONDS_PER_MICROSECOND;
|
||||
this->normalize();
|
||||
}
|
||||
|
||||
/// The seconds component remains unchanged.
|
||||
/// @brief Set the nanoseconds component using a number of milliseconds.
|
||||
void milliseconds ( int32_t millis ) {
|
||||
this->nanos_ = millis * NANOSECONDS_PER_MILLISECOND;
|
||||
this->normalize();
|
||||
}
|
||||
|
||||
/// @brief Converts from microsecond format to TimeValue format
|
||||
void usec( int64_t microseconds ) {
|
||||
this->seconds_ = microseconds / MICROSECONDS_PER_SECOND;
|
||||
this->nanos_ = NanoSecondsType(microseconds % MICROSECONDS_PER_SECOND) *
|
||||
NANOSECONDS_PER_MICROSECOND;
|
||||
this->normalize();
|
||||
}
|
||||
|
||||
/// @brief Converts from millisecond format to TimeValue format
|
||||
void msec( int64_t milliseconds ) {
|
||||
this->seconds_ = milliseconds / MILLISECONDS_PER_SECOND;
|
||||
this->nanos_ = NanoSecondsType(milliseconds % MILLISECONDS_PER_SECOND) *
|
||||
NANOSECONDS_PER_MILLISECOND;
|
||||
this->normalize();
|
||||
}
|
||||
|
||||
/// Converts the \p seconds argument from PosixTime to the corresponding
|
||||
/// TimeValue and assigns that value to \p this.
|
||||
/// @brief Convert seconds form PosixTime to TimeValue
|
||||
void fromEpochTime( SecondsType seconds ) {
|
||||
seconds_ = seconds + PosixZeroTimeSeconds;
|
||||
nanos_ = 0;
|
||||
this->normalize();
|
||||
}
|
||||
|
||||
/// Converts the \p win32Time argument from Windows FILETIME to the
|
||||
/// corresponding TimeValue and assigns that value to \p this.
|
||||
/// @brief Convert seconds form Windows FILETIME to TimeValue
|
||||
void fromWin32Time( uint64_t win32Time ) {
|
||||
this->seconds_ = win32Time / 10000000 + Win32ZeroTimeSeconds;
|
||||
this->nanos_ = NanoSecondsType(win32Time % 10000000) * 100;
|
||||
}
|
||||
|
||||
/// @}
|
||||
/// @name Implementation
|
||||
/// @{
|
||||
private:
|
||||
/// This causes the values to be represented so that the fractional
|
||||
/// part is minimized, possibly incrementing the seconds part.
|
||||
/// @brief Normalize to canonical form.
|
||||
void normalize();
|
||||
|
||||
/// @}
|
||||
/// @name Data
|
||||
/// @{
|
||||
private:
|
||||
/// Store the values as a <timeval>.
|
||||
SecondsType seconds_;///< Stores the seconds part of the TimeVal
|
||||
NanoSecondsType nanos_; ///< Stores the nanoseconds part of the TimeVal
|
||||
|
||||
static const SecondsType PosixZeroTimeSeconds;
|
||||
static const SecondsType Win32ZeroTimeSeconds;
|
||||
/// @}
|
||||
|
||||
};
|
||||
|
||||
inline TimeValue operator + (const TimeValue &tv1, const TimeValue &tv2) {
|
||||
TimeValue sum (tv1.seconds_ + tv2.seconds_, tv1.nanos_ + tv2.nanos_);
|
||||
sum.normalize ();
|
||||
return sum;
|
||||
}
|
||||
|
||||
inline TimeValue operator - (const TimeValue &tv1, const TimeValue &tv2) {
|
||||
TimeValue difference (tv1.seconds_ - tv2.seconds_, tv1.nanos_ - tv2.nanos_ );
|
||||
difference.normalize ();
|
||||
return difference;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
190
thirdparty/clang/include/llvm/Support/Timer.h
vendored
Normal file
190
thirdparty/clang/include/llvm/Support/Timer.h
vendored
Normal file
@@ -0,0 +1,190 @@
|
||||
//===-- llvm/Support/Timer.h - Interval Timing Support ----------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_TIMER_H
|
||||
#define LLVM_SUPPORT_TIMER_H
|
||||
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include <cassert>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class Timer;
|
||||
class TimerGroup;
|
||||
class raw_ostream;
|
||||
|
||||
class TimeRecord {
|
||||
double WallTime; // Wall clock time elapsed in seconds
|
||||
double UserTime; // User time elapsed
|
||||
double SystemTime; // System time elapsed
|
||||
ssize_t MemUsed; // Memory allocated (in bytes)
|
||||
public:
|
||||
TimeRecord() : WallTime(0), UserTime(0), SystemTime(0), MemUsed(0) {}
|
||||
|
||||
/// getCurrentTime - Get the current time and memory usage. If Start is true
|
||||
/// we get the memory usage before the time, otherwise we get time before
|
||||
/// memory usage. This matters if the time to get the memory usage is
|
||||
/// significant and shouldn't be counted as part of a duration.
|
||||
static TimeRecord getCurrentTime(bool Start = true);
|
||||
|
||||
double getProcessTime() const { return UserTime+SystemTime; }
|
||||
double getUserTime() const { return UserTime; }
|
||||
double getSystemTime() const { return SystemTime; }
|
||||
double getWallTime() const { return WallTime; }
|
||||
ssize_t getMemUsed() const { return MemUsed; }
|
||||
|
||||
|
||||
// operator< - Allow sorting.
|
||||
bool operator<(const TimeRecord &T) const {
|
||||
// Sort by Wall Time elapsed, as it is the only thing really accurate
|
||||
return WallTime < T.WallTime;
|
||||
}
|
||||
|
||||
void operator+=(const TimeRecord &RHS) {
|
||||
WallTime += RHS.WallTime;
|
||||
UserTime += RHS.UserTime;
|
||||
SystemTime += RHS.SystemTime;
|
||||
MemUsed += RHS.MemUsed;
|
||||
}
|
||||
void operator-=(const TimeRecord &RHS) {
|
||||
WallTime -= RHS.WallTime;
|
||||
UserTime -= RHS.UserTime;
|
||||
SystemTime -= RHS.SystemTime;
|
||||
MemUsed -= RHS.MemUsed;
|
||||
}
|
||||
|
||||
/// print - Print the current timer to standard error, and reset the "Started"
|
||||
/// flag.
|
||||
void print(const TimeRecord &Total, raw_ostream &OS) const;
|
||||
};
|
||||
|
||||
/// Timer - This class is used to track the amount of time spent between
|
||||
/// invocations of its startTimer()/stopTimer() methods. Given appropriate OS
|
||||
/// support it can also keep track of the RSS of the program at various points.
|
||||
/// By default, the Timer will print the amount of time it has captured to
|
||||
/// standard error when the last timer is destroyed, otherwise it is printed
|
||||
/// when its TimerGroup is destroyed. Timers do not print their information
|
||||
/// if they are never started.
|
||||
///
|
||||
class Timer {
|
||||
TimeRecord Time;
|
||||
std::string Name; // The name of this time variable.
|
||||
bool Started; // Has this time variable ever been started?
|
||||
TimerGroup *TG; // The TimerGroup this Timer is in.
|
||||
|
||||
Timer **Prev, *Next; // Doubly linked list of timers in the group.
|
||||
public:
|
||||
explicit Timer(StringRef N) : TG(0) { init(N); }
|
||||
Timer(StringRef N, TimerGroup &tg) : TG(0) { init(N, tg); }
|
||||
Timer(const Timer &RHS) : TG(0) {
|
||||
assert(RHS.TG == 0 && "Can only copy uninitialized timers");
|
||||
}
|
||||
const Timer &operator=(const Timer &T) {
|
||||
assert(TG == 0 && T.TG == 0 && "Can only assign uninit timers");
|
||||
return *this;
|
||||
}
|
||||
~Timer();
|
||||
|
||||
// Create an uninitialized timer, client must use 'init'.
|
||||
explicit Timer() : TG(0) {}
|
||||
void init(StringRef N);
|
||||
void init(StringRef N, TimerGroup &tg);
|
||||
|
||||
const std::string &getName() const { return Name; }
|
||||
bool isInitialized() const { return TG != 0; }
|
||||
|
||||
/// startTimer - Start the timer running. Time between calls to
|
||||
/// startTimer/stopTimer is counted by the Timer class. Note that these calls
|
||||
/// must be correctly paired.
|
||||
///
|
||||
void startTimer();
|
||||
|
||||
/// stopTimer - Stop the timer.
|
||||
///
|
||||
void stopTimer();
|
||||
|
||||
private:
|
||||
friend class TimerGroup;
|
||||
};
|
||||
|
||||
|
||||
/// The TimeRegion class is used as a helper class to call the startTimer() and
|
||||
/// stopTimer() methods of the Timer class. When the object is constructed, it
|
||||
/// starts the timer specified as its argument. When it is destroyed, it stops
|
||||
/// the relevant timer. This makes it easy to time a region of code.
|
||||
///
|
||||
class TimeRegion {
|
||||
Timer *T;
|
||||
TimeRegion(const TimeRegion &) LLVM_DELETED_FUNCTION;
|
||||
public:
|
||||
explicit TimeRegion(Timer &t) : T(&t) {
|
||||
T->startTimer();
|
||||
}
|
||||
explicit TimeRegion(Timer *t) : T(t) {
|
||||
if (T) T->startTimer();
|
||||
}
|
||||
~TimeRegion() {
|
||||
if (T) T->stopTimer();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/// NamedRegionTimer - This class is basically a combination of TimeRegion and
|
||||
/// Timer. It allows you to declare a new timer, AND specify the region to
|
||||
/// time, all in one statement. All timers with the same name are merged. This
|
||||
/// is primarily used for debugging and for hunting performance problems.
|
||||
///
|
||||
struct NamedRegionTimer : public TimeRegion {
|
||||
explicit NamedRegionTimer(StringRef Name,
|
||||
bool Enabled = true);
|
||||
explicit NamedRegionTimer(StringRef Name, StringRef GroupName,
|
||||
bool Enabled = true);
|
||||
};
|
||||
|
||||
|
||||
/// The TimerGroup class is used to group together related timers into a single
|
||||
/// report that is printed when the TimerGroup is destroyed. It is illegal to
|
||||
/// destroy a TimerGroup object before all of the Timers in it are gone. A
|
||||
/// TimerGroup can be specified for a newly created timer in its constructor.
|
||||
///
|
||||
class TimerGroup {
|
||||
std::string Name;
|
||||
Timer *FirstTimer; // First timer in the group.
|
||||
std::vector<std::pair<TimeRecord, std::string> > TimersToPrint;
|
||||
|
||||
TimerGroup **Prev, *Next; // Doubly linked list of TimerGroup's.
|
||||
TimerGroup(const TimerGroup &TG) LLVM_DELETED_FUNCTION;
|
||||
void operator=(const TimerGroup &TG) LLVM_DELETED_FUNCTION;
|
||||
public:
|
||||
explicit TimerGroup(StringRef name);
|
||||
~TimerGroup();
|
||||
|
||||
void setName(StringRef name) { Name.assign(name.begin(), name.end()); }
|
||||
|
||||
/// print - Print any started timers in this group and zero them.
|
||||
void print(raw_ostream &OS);
|
||||
|
||||
/// printAll - This static method prints all timers and clears them all out.
|
||||
static void printAll(raw_ostream &OS);
|
||||
|
||||
private:
|
||||
friend class Timer;
|
||||
void addTimer(Timer &T);
|
||||
void removeTimer(Timer &T);
|
||||
void PrintQueuedTimers(raw_ostream &OS);
|
||||
};
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
||||
62
thirdparty/clang/include/llvm/Support/ToolOutputFile.h
vendored
Normal file
62
thirdparty/clang/include/llvm/Support/ToolOutputFile.h
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
//===- ToolOutputFile.h - Output files for compiler-like tools -----------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the tool_output_file class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_TOOLOUTPUTFILE_H
|
||||
#define LLVM_SUPPORT_TOOLOUTPUTFILE_H
|
||||
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
/// tool_output_file - This class contains a raw_fd_ostream and adds a
|
||||
/// few extra features commonly needed for compiler-like tool output files:
|
||||
/// - The file is automatically deleted if the process is killed.
|
||||
/// - The file is automatically deleted when the tool_output_file
|
||||
/// object is destroyed unless the client calls keep().
|
||||
class tool_output_file {
|
||||
/// Installer - This class is declared before the raw_fd_ostream so that
|
||||
/// it is constructed before the raw_fd_ostream is constructed and
|
||||
/// destructed after the raw_fd_ostream is destructed. It installs
|
||||
/// cleanups in its constructor and uninstalls them in its destructor.
|
||||
class CleanupInstaller {
|
||||
/// Filename - The name of the file.
|
||||
std::string Filename;
|
||||
public:
|
||||
/// Keep - The flag which indicates whether we should not delete the file.
|
||||
bool Keep;
|
||||
|
||||
explicit CleanupInstaller(const char *filename);
|
||||
~CleanupInstaller();
|
||||
} Installer;
|
||||
|
||||
/// OS - The contained stream. This is intentionally declared after
|
||||
/// Installer.
|
||||
raw_fd_ostream OS;
|
||||
|
||||
public:
|
||||
/// tool_output_file - This constructor's arguments are passed to
|
||||
/// to raw_fd_ostream's constructor.
|
||||
tool_output_file(const char *filename, std::string &ErrorInfo,
|
||||
unsigned Flags = 0);
|
||||
|
||||
/// os - Return the contained raw_fd_ostream.
|
||||
raw_fd_ostream &os() { return OS; }
|
||||
|
||||
/// keep - Indicate that the tool's job wrt this output file has been
|
||||
/// successful and the file should not be deleted.
|
||||
void keep() { Installer.Keep = true; }
|
||||
};
|
||||
|
||||
} // end llvm namespace
|
||||
|
||||
#endif
|
||||
75
thirdparty/clang/include/llvm/Support/Valgrind.h
vendored
Normal file
75
thirdparty/clang/include/llvm/Support/Valgrind.h
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
//===- llvm/Support/Valgrind.h - Communication with Valgrind -----*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Methods for communicating with a valgrind instance this program is running
|
||||
// under. These are all no-ops unless LLVM was configured on a system with the
|
||||
// valgrind headers installed and valgrind is controlling this process.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SYSTEM_VALGRIND_H
|
||||
#define LLVM_SYSTEM_VALGRIND_H
|
||||
|
||||
#include "llvm/Config/llvm-config.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include <stddef.h>
|
||||
|
||||
#if LLVM_ENABLE_THREADS != 0 && !defined(NDEBUG)
|
||||
// tsan (Thread Sanitizer) is a valgrind-based tool that detects these exact
|
||||
// functions by name.
|
||||
extern "C" {
|
||||
LLVM_ATTRIBUTE_WEAK void AnnotateHappensAfter(const char *file, int line,
|
||||
const volatile void *cv);
|
||||
LLVM_ATTRIBUTE_WEAK void AnnotateHappensBefore(const char *file, int line,
|
||||
const volatile void *cv);
|
||||
LLVM_ATTRIBUTE_WEAK void AnnotateIgnoreWritesBegin(const char *file, int line);
|
||||
LLVM_ATTRIBUTE_WEAK void AnnotateIgnoreWritesEnd(const char *file, int line);
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace llvm {
|
||||
namespace sys {
|
||||
// True if Valgrind is controlling this process.
|
||||
bool RunningOnValgrind();
|
||||
|
||||
// Discard valgrind's translation of code in the range [Addr .. Addr + Len).
|
||||
// Otherwise valgrind may continue to execute the old version of the code.
|
||||
void ValgrindDiscardTranslations(const void *Addr, size_t Len);
|
||||
|
||||
#if LLVM_ENABLE_THREADS != 0 && !defined(NDEBUG)
|
||||
// Thread Sanitizer is a valgrind tool that finds races in code.
|
||||
// See http://code.google.com/p/data-race-test/wiki/DynamicAnnotations .
|
||||
|
||||
// This marker is used to define a happens-before arc. The race detector will
|
||||
// infer an arc from the begin to the end when they share the same pointer
|
||||
// argument.
|
||||
#define TsanHappensBefore(cv) \
|
||||
AnnotateHappensBefore(__FILE__, __LINE__, cv)
|
||||
|
||||
// This marker defines the destination of a happens-before arc.
|
||||
#define TsanHappensAfter(cv) \
|
||||
AnnotateHappensAfter(__FILE__, __LINE__, cv)
|
||||
|
||||
// Ignore any races on writes between here and the next TsanIgnoreWritesEnd.
|
||||
#define TsanIgnoreWritesBegin() \
|
||||
AnnotateIgnoreWritesBegin(__FILE__, __LINE__)
|
||||
|
||||
// Resume checking for racy writes.
|
||||
#define TsanIgnoreWritesEnd() \
|
||||
AnnotateIgnoreWritesEnd(__FILE__, __LINE__)
|
||||
#else
|
||||
#define TsanHappensBefore(cv)
|
||||
#define TsanHappensAfter(cv)
|
||||
#define TsanIgnoreWritesBegin()
|
||||
#define TsanIgnoreWritesEnd()
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
379
thirdparty/clang/include/llvm/Support/ValueHandle.h
vendored
Normal file
379
thirdparty/clang/include/llvm/Support/ValueHandle.h
vendored
Normal file
@@ -0,0 +1,379 @@
|
||||
//===- llvm/Support/ValueHandle.h - Value Smart Pointer classes -*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file declares the ValueHandle class and its sub-classes.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_VALUEHANDLE_H
|
||||
#define LLVM_SUPPORT_VALUEHANDLE_H
|
||||
|
||||
#include "llvm/ADT/DenseMapInfo.h"
|
||||
#include "llvm/ADT/PointerIntPair.h"
|
||||
#include "llvm/IR/Value.h"
|
||||
|
||||
namespace llvm {
|
||||
class ValueHandleBase;
|
||||
template<typename From> struct simplify_type;
|
||||
|
||||
// ValueHandleBase** is only 4-byte aligned.
|
||||
template<>
|
||||
class PointerLikeTypeTraits<ValueHandleBase**> {
|
||||
public:
|
||||
static inline void *getAsVoidPointer(ValueHandleBase** P) { return P; }
|
||||
static inline ValueHandleBase **getFromVoidPointer(void *P) {
|
||||
return static_cast<ValueHandleBase**>(P);
|
||||
}
|
||||
enum { NumLowBitsAvailable = 2 };
|
||||
};
|
||||
|
||||
/// ValueHandleBase - This is the common base class of value handles.
|
||||
/// ValueHandle's are smart pointers to Value's that have special behavior when
|
||||
/// the value is deleted or ReplaceAllUsesWith'd. See the specific handles
|
||||
/// below for details.
|
||||
///
|
||||
class ValueHandleBase {
|
||||
friend class Value;
|
||||
protected:
|
||||
/// HandleBaseKind - This indicates what sub class the handle actually is.
|
||||
/// This is to avoid having a vtable for the light-weight handle pointers. The
|
||||
/// fully general Callback version does have a vtable.
|
||||
enum HandleBaseKind {
|
||||
Assert,
|
||||
Callback,
|
||||
Tracking,
|
||||
Weak
|
||||
};
|
||||
|
||||
private:
|
||||
PointerIntPair<ValueHandleBase**, 2, HandleBaseKind> PrevPair;
|
||||
ValueHandleBase *Next;
|
||||
|
||||
// A subclass may want to store some information along with the value
|
||||
// pointer. Allow them to do this by making the value pointer a pointer-int
|
||||
// pair. The 'setValPtrInt' and 'getValPtrInt' methods below give them this
|
||||
// access.
|
||||
PointerIntPair<Value*, 2> VP;
|
||||
|
||||
ValueHandleBase(const ValueHandleBase&) LLVM_DELETED_FUNCTION;
|
||||
public:
|
||||
explicit ValueHandleBase(HandleBaseKind Kind)
|
||||
: PrevPair(0, Kind), Next(0), VP(0, 0) {}
|
||||
ValueHandleBase(HandleBaseKind Kind, Value *V)
|
||||
: PrevPair(0, Kind), Next(0), VP(V, 0) {
|
||||
if (isValid(VP.getPointer()))
|
||||
AddToUseList();
|
||||
}
|
||||
ValueHandleBase(HandleBaseKind Kind, const ValueHandleBase &RHS)
|
||||
: PrevPair(0, Kind), Next(0), VP(RHS.VP) {
|
||||
if (isValid(VP.getPointer()))
|
||||
AddToExistingUseList(RHS.getPrevPtr());
|
||||
}
|
||||
~ValueHandleBase() {
|
||||
if (isValid(VP.getPointer()))
|
||||
RemoveFromUseList();
|
||||
}
|
||||
|
||||
Value *operator=(Value *RHS) {
|
||||
if (VP.getPointer() == RHS) return RHS;
|
||||
if (isValid(VP.getPointer())) RemoveFromUseList();
|
||||
VP.setPointer(RHS);
|
||||
if (isValid(VP.getPointer())) AddToUseList();
|
||||
return RHS;
|
||||
}
|
||||
|
||||
Value *operator=(const ValueHandleBase &RHS) {
|
||||
if (VP.getPointer() == RHS.VP.getPointer()) return RHS.VP.getPointer();
|
||||
if (isValid(VP.getPointer())) RemoveFromUseList();
|
||||
VP.setPointer(RHS.VP.getPointer());
|
||||
if (isValid(VP.getPointer())) AddToExistingUseList(RHS.getPrevPtr());
|
||||
return VP.getPointer();
|
||||
}
|
||||
|
||||
Value *operator->() const { return getValPtr(); }
|
||||
Value &operator*() const { return *getValPtr(); }
|
||||
|
||||
protected:
|
||||
Value *getValPtr() const { return VP.getPointer(); }
|
||||
|
||||
void setValPtrInt(unsigned K) { VP.setInt(K); }
|
||||
unsigned getValPtrInt() const { return VP.getInt(); }
|
||||
|
||||
static bool isValid(Value *V) {
|
||||
return V &&
|
||||
V != DenseMapInfo<Value *>::getEmptyKey() &&
|
||||
V != DenseMapInfo<Value *>::getTombstoneKey();
|
||||
}
|
||||
|
||||
public:
|
||||
// Callbacks made from Value.
|
||||
static void ValueIsDeleted(Value *V);
|
||||
static void ValueIsRAUWd(Value *Old, Value *New);
|
||||
|
||||
private:
|
||||
// Internal implementation details.
|
||||
ValueHandleBase **getPrevPtr() const { return PrevPair.getPointer(); }
|
||||
HandleBaseKind getKind() const { return PrevPair.getInt(); }
|
||||
void setPrevPtr(ValueHandleBase **Ptr) { PrevPair.setPointer(Ptr); }
|
||||
|
||||
/// AddToExistingUseList - Add this ValueHandle to the use list for VP, where
|
||||
/// List is the address of either the head of the list or a Next node within
|
||||
/// the existing use list.
|
||||
void AddToExistingUseList(ValueHandleBase **List);
|
||||
|
||||
/// AddToExistingUseListAfter - Add this ValueHandle to the use list after
|
||||
/// Node.
|
||||
void AddToExistingUseListAfter(ValueHandleBase *Node);
|
||||
|
||||
/// AddToUseList - Add this ValueHandle to the use list for VP.
|
||||
void AddToUseList();
|
||||
/// RemoveFromUseList - Remove this ValueHandle from its current use list.
|
||||
void RemoveFromUseList();
|
||||
};
|
||||
|
||||
/// WeakVH - This is a value handle that tries hard to point to a Value, even
|
||||
/// across RAUW operations, but will null itself out if the value is destroyed.
|
||||
/// this is useful for advisory sorts of information, but should not be used as
|
||||
/// the key of a map (since the map would have to rearrange itself when the
|
||||
/// pointer changes).
|
||||
class WeakVH : public ValueHandleBase {
|
||||
public:
|
||||
WeakVH() : ValueHandleBase(Weak) {}
|
||||
WeakVH(Value *P) : ValueHandleBase(Weak, P) {}
|
||||
WeakVH(const WeakVH &RHS)
|
||||
: ValueHandleBase(Weak, RHS) {}
|
||||
|
||||
Value *operator=(Value *RHS) {
|
||||
return ValueHandleBase::operator=(RHS);
|
||||
}
|
||||
Value *operator=(const ValueHandleBase &RHS) {
|
||||
return ValueHandleBase::operator=(RHS);
|
||||
}
|
||||
|
||||
operator Value*() const {
|
||||
return getValPtr();
|
||||
}
|
||||
};
|
||||
|
||||
// Specialize simplify_type to allow WeakVH to participate in
|
||||
// dyn_cast, isa, etc.
|
||||
template<> struct simplify_type<WeakVH> {
|
||||
typedef Value* SimpleType;
|
||||
static SimpleType getSimplifiedValue(WeakVH &WVH) {
|
||||
return WVH;
|
||||
}
|
||||
};
|
||||
|
||||
/// AssertingVH - This is a Value Handle that points to a value and asserts out
|
||||
/// if the value is destroyed while the handle is still live. This is very
|
||||
/// useful for catching dangling pointer bugs and other things which can be
|
||||
/// non-obvious. One particularly useful place to use this is as the Key of a
|
||||
/// map. Dangling pointer bugs often lead to really subtle bugs that only occur
|
||||
/// if another object happens to get allocated to the same address as the old
|
||||
/// one. Using an AssertingVH ensures that an assert is triggered as soon as
|
||||
/// the bad delete occurs.
|
||||
///
|
||||
/// Note that an AssertingVH handle does *not* follow values across RAUW
|
||||
/// operations. This means that RAUW's need to explicitly update the
|
||||
/// AssertingVH's as it moves. This is required because in non-assert mode this
|
||||
/// class turns into a trivial wrapper around a pointer.
|
||||
template <typename ValueTy>
|
||||
class AssertingVH
|
||||
#ifndef NDEBUG
|
||||
: public ValueHandleBase
|
||||
#endif
|
||||
{
|
||||
|
||||
#ifndef NDEBUG
|
||||
ValueTy *getValPtr() const {
|
||||
return static_cast<ValueTy*>(ValueHandleBase::getValPtr());
|
||||
}
|
||||
void setValPtr(ValueTy *P) {
|
||||
ValueHandleBase::operator=(GetAsValue(P));
|
||||
}
|
||||
#else
|
||||
ValueTy *ThePtr;
|
||||
ValueTy *getValPtr() const { return ThePtr; }
|
||||
void setValPtr(ValueTy *P) { ThePtr = P; }
|
||||
#endif
|
||||
|
||||
// Convert a ValueTy*, which may be const, to the type the base
|
||||
// class expects.
|
||||
static Value *GetAsValue(Value *V) { return V; }
|
||||
static Value *GetAsValue(const Value *V) { return const_cast<Value*>(V); }
|
||||
|
||||
public:
|
||||
#ifndef NDEBUG
|
||||
AssertingVH() : ValueHandleBase(Assert) {}
|
||||
AssertingVH(ValueTy *P) : ValueHandleBase(Assert, GetAsValue(P)) {}
|
||||
AssertingVH(const AssertingVH &RHS) : ValueHandleBase(Assert, RHS) {}
|
||||
#else
|
||||
AssertingVH() : ThePtr(0) {}
|
||||
AssertingVH(ValueTy *P) : ThePtr(P) {}
|
||||
#endif
|
||||
|
||||
operator ValueTy*() const {
|
||||
return getValPtr();
|
||||
}
|
||||
|
||||
ValueTy *operator=(ValueTy *RHS) {
|
||||
setValPtr(RHS);
|
||||
return getValPtr();
|
||||
}
|
||||
ValueTy *operator=(const AssertingVH<ValueTy> &RHS) {
|
||||
setValPtr(RHS.getValPtr());
|
||||
return getValPtr();
|
||||
}
|
||||
|
||||
ValueTy *operator->() const { return getValPtr(); }
|
||||
ValueTy &operator*() const { return *getValPtr(); }
|
||||
};
|
||||
|
||||
// Specialize DenseMapInfo to allow AssertingVH to participate in DenseMap.
|
||||
template<typename T>
|
||||
struct DenseMapInfo<AssertingVH<T> > {
|
||||
typedef DenseMapInfo<T*> PointerInfo;
|
||||
static inline AssertingVH<T> getEmptyKey() {
|
||||
return AssertingVH<T>(PointerInfo::getEmptyKey());
|
||||
}
|
||||
static inline T* getTombstoneKey() {
|
||||
return AssertingVH<T>(PointerInfo::getTombstoneKey());
|
||||
}
|
||||
static unsigned getHashValue(const AssertingVH<T> &Val) {
|
||||
return PointerInfo::getHashValue(Val);
|
||||
}
|
||||
static bool isEqual(const AssertingVH<T> &LHS, const AssertingVH<T> &RHS) {
|
||||
return LHS == RHS;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct isPodLike<AssertingVH<T> > {
|
||||
#ifdef NDEBUG
|
||||
static const bool value = true;
|
||||
#else
|
||||
static const bool value = false;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
/// TrackingVH - This is a value handle that tracks a Value (or Value subclass),
|
||||
/// even across RAUW operations.
|
||||
///
|
||||
/// TrackingVH is designed for situations where a client needs to hold a handle
|
||||
/// to a Value (or subclass) across some operations which may move that value,
|
||||
/// but should never destroy it or replace it with some unacceptable type.
|
||||
///
|
||||
/// It is an error to do anything with a TrackingVH whose value has been
|
||||
/// destroyed, except to destruct it.
|
||||
///
|
||||
/// It is an error to attempt to replace a value with one of a type which is
|
||||
/// incompatible with any of its outstanding TrackingVHs.
|
||||
template<typename ValueTy>
|
||||
class TrackingVH : public ValueHandleBase {
|
||||
void CheckValidity() const {
|
||||
Value *VP = ValueHandleBase::getValPtr();
|
||||
|
||||
// Null is always ok.
|
||||
if (!VP) return;
|
||||
|
||||
// Check that this value is valid (i.e., it hasn't been deleted). We
|
||||
// explicitly delay this check until access to avoid requiring clients to be
|
||||
// unnecessarily careful w.r.t. destruction.
|
||||
assert(ValueHandleBase::isValid(VP) && "Tracked Value was deleted!");
|
||||
|
||||
// Check that the value is a member of the correct subclass. We would like
|
||||
// to check this property on assignment for better debugging, but we don't
|
||||
// want to require a virtual interface on this VH. Instead we allow RAUW to
|
||||
// replace this value with a value of an invalid type, and check it here.
|
||||
assert(isa<ValueTy>(VP) &&
|
||||
"Tracked Value was replaced by one with an invalid type!");
|
||||
}
|
||||
|
||||
ValueTy *getValPtr() const {
|
||||
CheckValidity();
|
||||
return (ValueTy*)ValueHandleBase::getValPtr();
|
||||
}
|
||||
void setValPtr(ValueTy *P) {
|
||||
CheckValidity();
|
||||
ValueHandleBase::operator=(GetAsValue(P));
|
||||
}
|
||||
|
||||
// Convert a ValueTy*, which may be const, to the type the base
|
||||
// class expects.
|
||||
static Value *GetAsValue(Value *V) { return V; }
|
||||
static Value *GetAsValue(const Value *V) { return const_cast<Value*>(V); }
|
||||
|
||||
public:
|
||||
TrackingVH() : ValueHandleBase(Tracking) {}
|
||||
TrackingVH(ValueTy *P) : ValueHandleBase(Tracking, GetAsValue(P)) {}
|
||||
TrackingVH(const TrackingVH &RHS) : ValueHandleBase(Tracking, RHS) {}
|
||||
|
||||
operator ValueTy*() const {
|
||||
return getValPtr();
|
||||
}
|
||||
|
||||
ValueTy *operator=(ValueTy *RHS) {
|
||||
setValPtr(RHS);
|
||||
return getValPtr();
|
||||
}
|
||||
ValueTy *operator=(const TrackingVH<ValueTy> &RHS) {
|
||||
setValPtr(RHS.getValPtr());
|
||||
return getValPtr();
|
||||
}
|
||||
|
||||
ValueTy *operator->() const { return getValPtr(); }
|
||||
ValueTy &operator*() const { return *getValPtr(); }
|
||||
};
|
||||
|
||||
/// CallbackVH - This is a value handle that allows subclasses to define
|
||||
/// callbacks that run when the underlying Value has RAUW called on it or is
|
||||
/// destroyed. This class can be used as the key of a map, as long as the user
|
||||
/// takes it out of the map before calling setValPtr() (since the map has to
|
||||
/// rearrange itself when the pointer changes). Unlike ValueHandleBase, this
|
||||
/// class has a vtable and a virtual destructor.
|
||||
class CallbackVH : public ValueHandleBase {
|
||||
protected:
|
||||
CallbackVH(const CallbackVH &RHS)
|
||||
: ValueHandleBase(Callback, RHS) {}
|
||||
|
||||
virtual ~CallbackVH() {}
|
||||
|
||||
void setValPtr(Value *P) {
|
||||
ValueHandleBase::operator=(P);
|
||||
}
|
||||
|
||||
public:
|
||||
CallbackVH() : ValueHandleBase(Callback) {}
|
||||
CallbackVH(Value *P) : ValueHandleBase(Callback, P) {}
|
||||
|
||||
operator Value*() const {
|
||||
return getValPtr();
|
||||
}
|
||||
|
||||
/// Called when this->getValPtr() is destroyed, inside ~Value(), so you may
|
||||
/// call any non-virtual Value method on getValPtr(), but no subclass methods.
|
||||
/// If WeakVH were implemented as a CallbackVH, it would use this method to
|
||||
/// call setValPtr(NULL). AssertingVH would use this method to cause an
|
||||
/// assertion failure.
|
||||
///
|
||||
/// All implementations must remove the reference from this object to the
|
||||
/// Value that's being destroyed.
|
||||
virtual void deleted();
|
||||
|
||||
/// Called when this->getValPtr()->replaceAllUsesWith(new_value) is called,
|
||||
/// _before_ any of the uses have actually been replaced. If WeakVH were
|
||||
/// implemented as a CallbackVH, it would use this method to call
|
||||
/// setValPtr(new_value). AssertingVH would do nothing in this method.
|
||||
virtual void allUsesReplacedWith(Value *);
|
||||
};
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
||||
38
thirdparty/clang/include/llvm/Support/Watchdog.h
vendored
Normal file
38
thirdparty/clang/include/llvm/Support/Watchdog.h
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
//===--- Watchdog.h - Watchdog timer ----------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file declares the llvm::sys::Watchdog class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_WATCHDOG_H
|
||||
#define LLVM_SUPPORT_WATCHDOG_H
|
||||
|
||||
#include "llvm/Support/Compiler.h"
|
||||
|
||||
namespace llvm {
|
||||
namespace sys {
|
||||
|
||||
/// This class provides an abstraction for a timeout around an operation
|
||||
/// that must complete in a given amount of time. Failure to complete before
|
||||
/// the timeout is an unrecoverable situation and no mechanisms to attempt
|
||||
/// to handle it are provided.
|
||||
class Watchdog {
|
||||
public:
|
||||
Watchdog(unsigned int seconds);
|
||||
~Watchdog();
|
||||
private:
|
||||
// Noncopyable.
|
||||
Watchdog(const Watchdog &other) LLVM_DELETED_FUNCTION;
|
||||
Watchdog &operator=(const Watchdog &other) LLVM_DELETED_FUNCTION;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user