summaryrefslogtreecommitdiffstats
path: root/include/llvm/Support
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/Support')
-rw-r--r--include/llvm/Support/AlignOf.h182
-rw-r--r--include/llvm/Support/Allocator.h4
-rw-r--r--include/llvm/Support/ArrayRecycler.h143
-rw-r--r--include/llvm/Support/Atomic.h4
-rw-r--r--include/llvm/Support/CFG.h20
-rw-r--r--include/llvm/Support/COFF.h7
-rw-r--r--include/llvm/Support/CallSite.h19
-rw-r--r--include/llvm/Support/Casting.h64
-rw-r--r--include/llvm/Support/CommandLine.h12
-rw-r--r--include/llvm/Support/Compiler.h189
-rw-r--r--include/llvm/Support/ConstantFolder.h4
-rw-r--r--include/llvm/Support/ConstantRange.h4
-rw-r--r--include/llvm/Support/ConvertUTF.h228
-rw-r--r--include/llvm/Support/DOTGraphTraits.h5
-rw-r--r--include/llvm/Support/DataExtractor.h20
-rw-r--r--include/llvm/Support/DataFlow.h2
-rw-r--r--include/llvm/Support/DataStream.h4
-rw-r--r--include/llvm/Support/DebugLoc.h28
-rw-r--r--include/llvm/Support/Dwarf.h46
-rw-r--r--include/llvm/Support/DynamicLibrary.h4
-rw-r--r--include/llvm/Support/ELF.h202
-rw-r--r--include/llvm/Support/Endian.h161
-rw-r--r--include/llvm/Support/Errno.h4
-rw-r--r--include/llvm/Support/ErrorHandling.h17
-rw-r--r--include/llvm/Support/ErrorOr.h514
-rw-r--r--include/llvm/Support/FEnv.h8
-rw-r--r--include/llvm/Support/FileOutputBuffer.h58
-rw-r--r--include/llvm/Support/FileSystem.h12
-rw-r--r--include/llvm/Support/FormattedStream.h234
-rw-r--r--include/llvm/Support/GCOV.h4
-rw-r--r--include/llvm/Support/GetElementPtrTypeIterator.h16
-rw-r--r--include/llvm/Support/GraphWriter.h18
-rw-r--r--include/llvm/Support/Host.h8
-rw-r--r--include/llvm/Support/IRReader.h112
-rw-r--r--include/llvm/Support/IncludeFile.h4
-rw-r--r--include/llvm/Support/InstIterator.h4
-rw-r--r--include/llvm/Support/InstVisitor.h288
-rw-r--r--include/llvm/Support/IntegersSubset.h13
-rw-r--r--include/llvm/Support/IntegersSubsetMapping.h6
-rw-r--r--include/llvm/Support/LEB128.h4
-rw-r--r--include/llvm/Support/Locale.h6
-rw-r--r--include/llvm/Support/LockFileManager.h1
-rw-r--r--include/llvm/Support/MathExtras.h22
-rw-r--r--include/llvm/Support/Memory.h4
-rw-r--r--include/llvm/Support/MemoryObject.h4
-rw-r--r--include/llvm/Support/Mutex.h4
-rw-r--r--include/llvm/Support/NoFolder.h4
-rw-r--r--include/llvm/Support/PassNameParser.h6
-rw-r--r--include/llvm/Support/PathV1.h4
-rw-r--r--include/llvm/Support/PatternMatch.h312
-rw-r--r--include/llvm/Support/PredIteratorCache.h4
-rw-r--r--include/llvm/Support/Process.h370
-rw-r--r--include/llvm/Support/Program.h23
-rw-r--r--include/llvm/Support/Recycler.h11
-rw-r--r--include/llvm/Support/Regex.h15
-rw-r--r--include/llvm/Support/RegistryParser.h6
-rw-r--r--include/llvm/Support/SMLoc.h14
-rw-r--r--include/llvm/Support/SaveAndRestore.h4
-rw-r--r--include/llvm/Support/Signals.h8
-rw-r--r--include/llvm/Support/Solaris.h4
-rw-r--r--include/llvm/Support/SourceMgr.h80
-rw-r--r--include/llvm/Support/StreamableMemoryObject.h6
-rw-r--r--include/llvm/Support/StringPool.h2
-rw-r--r--include/llvm/Support/SwapByteOrder.h4
-rw-r--r--include/llvm/Support/TargetFolder.h4
-rw-r--r--include/llvm/Support/TargetRegistry.h60
-rw-r--r--include/llvm/Support/ThreadLocal.h6
-rw-r--r--include/llvm/Support/Threading.h4
-rw-r--r--include/llvm/Support/TimeValue.h24
-rw-r--r--include/llvm/Support/Timer.h13
-rw-r--r--include/llvm/Support/ToolOutputFile.h4
-rw-r--r--include/llvm/Support/Valgrind.h2
-rw-r--r--include/llvm/Support/ValueHandle.h47
-rw-r--r--include/llvm/Support/Watchdog.h38
-rw-r--r--include/llvm/Support/Win64EH.h89
-rw-r--r--include/llvm/Support/YAMLParser.h11
-rw-r--r--include/llvm/Support/YAMLTraits.h1104
-rw-r--r--include/llvm/Support/circular_raw_ostream.h4
-rw-r--r--include/llvm/Support/raw_ostream.h1
-rw-r--r--include/llvm/Support/system_error.h4
-rw-r--r--include/llvm/Support/type_traits.h24
81 files changed, 3694 insertions, 1339 deletions
diff --git a/include/llvm/Support/AlignOf.h b/include/llvm/Support/AlignOf.h
index d6b0ab8..bba3424 100644
--- a/include/llvm/Support/AlignOf.h
+++ b/include/llvm/Support/AlignOf.h
@@ -19,7 +19,6 @@
#include <cstddef>
namespace llvm {
-
template <typename T>
struct AlignmentCalcImpl {
char x;
@@ -49,7 +48,6 @@ struct AlignOf {
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
@@ -59,112 +57,148 @@ struct AlignOf {
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 types. We have to build these up using a macro and explicit
+/// 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.
-template <size_t Alignment> struct AlignedCharArrayImpl;
// MSVC requires special handling here.
#ifndef _MSC_VER
#if __has_feature(cxx_alignas)
-#define LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(x) \
- template <> struct AlignedCharArrayImpl<x> { \
- char alignas(x) aligned; \
- }
+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 <> struct AlignedCharArrayImpl<x> { \
- char aligned __attribute__((aligned(x))); \
- }
-#else
-# error No supported align as directive.
-#endif
+ 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);
-LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(512);
-LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(1024);
-LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(2048);
-LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(4096);
-LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(8192);
+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.
-template <> struct AlignedCharArrayImpl<1> { char aligned; };
-template <> struct AlignedCharArrayImpl<2> { short aligned; };
-template <> struct AlignedCharArrayImpl<4> { int aligned; };
-template <> struct AlignedCharArrayImpl<8> { double aligned; };
+// 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 <> struct AlignedCharArrayImpl<x> { \
- __declspec(align(x)) char aligned; \
- }
-LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(16);
-LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(32);
-LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(64);
-LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(128);
-LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(512);
-LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(1024);
-LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(2048);
-LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(4096);
-LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(8192);
-// Any larger and MSVC complains.
+ 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
-/// produce a union type containing a character array which, when used, forms
-/// storage suitable to placement new any of these types over. Support for more
-/// than four types can be added at the cost of more boiler plate.
+/// 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>
-union AlignedCharArrayUnion {
-private:
- class AlignerImpl {
- T1 t1; T2 t2; T3 t3; T4 t4;
-
- AlignerImpl(); // Never defined or instantiated.
- };
- union SizerImpl {
- char arr1[sizeof(T1)], arr2[sizeof(T2)], arr3[sizeof(T3)], arr4[sizeof(T4)];
- };
-
-public:
- /// \brief The character array buffer for use by clients.
- ///
- /// No other member of this union should be referenced. The exist purely to
- /// constrain the layout of this character array.
- char buffer[sizeof(SizerImpl)];
-
-private:
- // Tests seem to indicate that both Clang and GCC will properly register the
- // alignment of a struct containing an aligned member, and this alignment
- // should carry over to the character array in the union.
- llvm::AlignedCharArrayImpl<AlignOf<AlignerImpl>::Alignment> nonce_member;
+ 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
diff --git a/include/llvm/Support/Allocator.h b/include/llvm/Support/Allocator.h
index a644b13..3243fd9 100644
--- a/include/llvm/Support/Allocator.h
+++ b/include/llvm/Support/Allocator.h
@@ -15,12 +15,12 @@
#define LLVM_SUPPORT_ALLOCATOR_H
#include "llvm/Support/AlignOf.h"
-#include "llvm/Support/MathExtras.h"
#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/MathExtras.h"
#include <algorithm>
#include <cassert>
-#include <cstdlib>
#include <cstddef>
+#include <cstdlib>
namespace llvm {
template <typename T> struct ReferenceAdder { typedef T& result; };
diff --git a/include/llvm/Support/ArrayRecycler.h b/include/llvm/Support/ArrayRecycler.h
new file mode 100644
index 0000000..c7e0cba
--- /dev/null
+++ b/include/llvm/Support/ArrayRecycler.h
@@ -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
diff --git a/include/llvm/Support/Atomic.h b/include/llvm/Support/Atomic.h
index 1a6c606..9ec23e8 100644
--- a/include/llvm/Support/Atomic.h
+++ b/include/llvm/Support/Atomic.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SYSTEM_ATOMIC_H
-#define LLVM_SYSTEM_ATOMIC_H
+#ifndef LLVM_SUPPORT_ATOMIC_H
+#define LLVM_SUPPORT_ATOMIC_H
#include "llvm/Support/DataTypes.h"
diff --git a/include/llvm/Support/CFG.h b/include/llvm/Support/CFG.h
index f5dc8ea..265b886 100644
--- a/include/llvm/Support/CFG.h
+++ b/include/llvm/Support/CFG.h
@@ -16,8 +16,8 @@
#define LLVM_SUPPORT_CFG_H
#include "llvm/ADT/GraphTraits.h"
-#include "llvm/Function.h"
-#include "llvm/InstrTypes.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/InstrTypes.h"
namespace llvm {
@@ -27,8 +27,9 @@ namespace llvm {
template <class Ptr, class USE_iterator> // Predecessor Iterator
class PredIterator : public std::iterator<std::forward_iterator_tag,
- Ptr, ptrdiff_t> {
- typedef std::iterator<std::forward_iterator_tag, Ptr, ptrdiff_t> super;
+ 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;
@@ -40,6 +41,7 @@ class PredIterator : public std::iterator<std::forward_iterator_tag,
public:
typedef typename super::pointer pointer;
+ typedef typename super::reference reference;
PredIterator() {}
explicit inline PredIterator(Ptr *bb) : It(bb->use_begin()) {
@@ -50,7 +52,7 @@ public:
inline bool operator==(const Self& x) const { return It == x.It; }
inline bool operator!=(const Self& x) const { return !operator==(x); }
- inline pointer operator*() const {
+ inline reference operator*() const {
assert(!It.atEnd() && "pred_iterator out of range!");
return cast<TerminatorInst>(*It)->getParent();
}
@@ -100,10 +102,11 @@ inline const_pred_iterator pred_end(const BasicBlock *BB) {
template <class Term_, class BB_> // Successor Iterator
class SuccIterator : public std::iterator<std::bidirectional_iterator_tag,
- BB_, ptrdiff_t> {
+ BB_, ptrdiff_t, BB_*, BB_*> {
const Term_ Term;
unsigned idx;
- typedef std::iterator<std::bidirectional_iterator_tag, BB_, ptrdiff_t> super;
+ 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) {
@@ -112,6 +115,7 @@ class SuccIterator : public std::iterator<std::bidirectional_iterator_tag,
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
@@ -142,7 +146,7 @@ public:
inline bool operator==(const Self& x) const { return idx == x.idx; }
inline bool operator!=(const Self& x) const { return !operator==(x); }
- inline pointer operator*() const { return Term->getSuccessor(idx); }
+ inline reference operator*() const { return Term->getSuccessor(idx); }
inline pointer operator->() const { return operator*(); }
inline Self& operator++() { ++idx; return *this; } // Preincrement
diff --git a/include/llvm/Support/COFF.h b/include/llvm/Support/COFF.h
index ba8adb0..823b43a 100644
--- a/include/llvm/Support/COFF.h
+++ b/include/llvm/Support/COFF.h
@@ -20,8 +20,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SUPPORT_WIN_COFF_H
-#define LLVM_SUPPORT_WIN_COFF_H
+#ifndef LLVM_SUPPORT_COFF_H
+#define LLVM_SUPPORT_COFF_H
#include "llvm/Support/DataTypes.h"
#include <cassert>
@@ -321,7 +321,8 @@ namespace COFF {
IMAGE_COMDAT_SELECT_SAME_SIZE,
IMAGE_COMDAT_SELECT_EXACT_MATCH,
IMAGE_COMDAT_SELECT_ASSOCIATIVE,
- IMAGE_COMDAT_SELECT_LARGEST
+ IMAGE_COMDAT_SELECT_LARGEST,
+ IMAGE_COMDAT_SELECT_NEWEST
};
// Auxiliary Symbol Formats
diff --git a/include/llvm/Support/CallSite.h b/include/llvm/Support/CallSite.h
index ad8d6d4..92107ac 100644
--- a/include/llvm/Support/CallSite.h
+++ b/include/llvm/Support/CallSite.h
@@ -26,11 +26,10 @@
#ifndef LLVM_SUPPORT_CALLSITE_H
#define LLVM_SUPPORT_CALLSITE_H
-#include "llvm/Attributes.h"
#include "llvm/ADT/PointerIntPair.h"
-#include "llvm/BasicBlock.h"
-#include "llvm/CallingConv.h"
-#include "llvm/Instructions.h"
+#include "llvm/IR/Attributes.h"
+#include "llvm/IR/CallingConv.h"
+#include "llvm/IR/Instructions.h"
namespace llvm {
@@ -177,20 +176,20 @@ public:
/// getAttributes/setAttributes - get or set the parameter attributes of
/// the call.
- const AttrListPtr &getAttributes() const {
+ const AttributeSet &getAttributes() const {
CALLSITE_DELEGATE_GETTER(getAttributes());
}
- void setAttributes(const AttrListPtr &PAL) {
+ void setAttributes(const AttributeSet &PAL) {
CALLSITE_DELEGATE_SETTER(setAttributes(PAL));
}
/// \brief Return true if this function has the given attribute.
- bool hasFnAttr(Attributes::AttrVal A) const {
+ 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, Attributes::AttrVal A) const {
+ bool paramHasAttr(unsigned i, Attribute::AttrKind A) const {
CALLSITE_DELEGATE_GETTER(paramHasAttr(i, A));
}
@@ -244,12 +243,12 @@ public:
/// @brief Determine whether this argument is not captured.
bool doesNotCapture(unsigned ArgNo) const {
- return paramHasAttr(ArgNo + 1, Attributes::NoCapture);
+ return paramHasAttr(ArgNo + 1, Attribute::NoCapture);
}
/// @brief Determine whether this argument is passed by value.
bool isByValArgument(unsigned ArgNo) const {
- return paramHasAttr(ArgNo + 1, Attributes::ByVal);
+ return paramHasAttr(ArgNo + 1, Attribute::ByVal);
}
/// hasArgument - Returns true if this CallSite passes the given Value* as an
diff --git a/include/llvm/Support/Casting.h b/include/llvm/Support/Casting.h
index 0c71882..0d2d6c9 100644
--- a/include/llvm/Support/Casting.h
+++ b/include/llvm/Support/Casting.h
@@ -36,9 +36,13 @@ template<typename From> struct simplify_type {
};
template<typename From> struct simplify_type<const From> {
- typedef const From SimpleType;
- static SimpleType &getSimplifiedValue(const From &Val) {
- return simplify_type<From>::getSimplifiedValue(static_cast<From&>(Val));
+ 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));
}
};
@@ -55,8 +59,8 @@ struct isa_impl {
/// \brief Always allow upcasts, and perform no dynamic check for them.
template <typename To, typename From>
struct isa_impl<To, From,
- typename llvm::enable_if_c<
- llvm::is_base_of<To, From>::value
+ typename enable_if<
+ llvm::is_base_of<To, From>
>::type
> {
static inline bool doit(const From &) { return true; }
@@ -81,6 +85,13 @@ template <typename To, typename From> struct isa_impl_cl<To, From*> {
}
};
+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");
@@ -102,7 +113,7 @@ struct isa_impl_wrap {
static bool doit(const From &Val) {
return isa_impl_wrap<To, SimpleFrom,
typename simplify_type<SimpleFrom>::SimpleType>::doit(
- simplify_type<From>::getSimplifiedValue(Val));
+ simplify_type<const From>::getSimplifiedValue(Val));
}
};
@@ -121,7 +132,8 @@ struct isa_impl_wrap<To, FromTy, FromTy> {
//
template <class X, class Y>
inline bool isa(const Y &Val) {
- return isa_impl_wrap<X, Y, typename simplify_type<Y>::SimpleType>::doit(Val);
+ return isa_impl_wrap<X, const Y,
+ typename simplify_type<const Y>::SimpleType>::doit(Val);
}
//===----------------------------------------------------------------------===//
@@ -178,7 +190,7 @@ struct cast_retty {
//
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(const From &Val) {
+ 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));
@@ -204,12 +216,29 @@ template<class To, class FromTy> struct cast_convert_val<To,FromTy,FromTy> {
// cast<Instruction>(myVal)->getParent()
//
template <class X, class Y>
-inline typename cast_retty<X, Y>::ret_type cast(const Y &Val) {
+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.
//
@@ -230,8 +259,21 @@ inline typename cast_retty<X, Y*>::ret_type cast_or_null(Y *Val) {
//
template <class X, class Y>
-inline typename cast_retty<X, Y>::ret_type dyn_cast(const Y &Val) {
- return isa<X>(Val) ? cast<X, Y>(Val) : 0;
+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
diff --git a/include/llvm/Support/CommandLine.h b/include/llvm/Support/CommandLine.h
index 872c579..2e84d7b 100644
--- a/include/llvm/Support/CommandLine.h
+++ b/include/llvm/Support/CommandLine.h
@@ -20,10 +20,10 @@
#ifndef LLVM_SUPPORT_COMMANDLINE_H
#define LLVM_SUPPORT_COMMANDLINE_H
-#include "llvm/Support/type_traits.h"
-#include "llvm/Support/Compiler.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Twine.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/type_traits.h"
#include <cassert>
#include <climits>
#include <cstdarg>
@@ -469,8 +469,7 @@ public:
template<class Opt>
void apply(Opt &O) const {
- for (unsigned i = 0, e = static_cast<unsigned>(Values.size());
- i != e; ++i)
+ for (size_t i = 0, e = Values.size(); i != e; ++i)
O.getParser().addLiteralOption(Values[i].first, Values[i].second.first,
Values[i].second.second);
}
@@ -629,8 +628,7 @@ public:
else
ArgVal = ArgName;
- for (unsigned i = 0, e = static_cast<unsigned>(Values.size());
- i != e; ++i)
+ for (size_t i = 0, e = Values.size(); i != e; ++i)
if (Values[i].Name == ArgVal) {
V = Values[i].V.getValue();
return false;
@@ -1092,7 +1090,7 @@ public:
// Make sure we initialize the value with the default constructor for the
// type.
- opt_storage() : Value(DataType()) {}
+ opt_storage() : Value(DataType()), Default(DataType()) {}
template<class T>
void setValue(const T &V, bool initial = false) {
diff --git a/include/llvm/Support/Compiler.h b/include/llvm/Support/Compiler.h
index 7ceeb32..13d057b 100644
--- a/include/llvm/Support/Compiler.h
+++ b/include/llvm/Support/Compiler.h
@@ -15,29 +15,90 @@
#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
-/// LLVM_HAS_RVALUE_REFERENCES - Does the compiler provide r-value references?
+/// \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_USE_RVALUE_REFERENCES 1
+#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_USE_RVALUE_REFERENCES 0
+#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_USE_RVALUE_REFERENCES
+#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.
@@ -59,7 +120,8 @@
/// 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))
+#if __has_feature(cxx_override_control) \
+ || (defined(_MSC_VER) && _MSC_VER >= 1700)
#define LLVM_FINAL final
#else
#define LLVM_FINAL
@@ -67,12 +129,19 @@
/// 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))
+#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
@@ -129,7 +198,6 @@
#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>);
@@ -143,8 +211,8 @@
#define TEMPLATE_INSTANTIATION(X)
#endif
-// LLVM_ATTRIBUTE_NOINLINE - On compilers where we have a directive to do so,
-// mark a method "not for inlining".
+/// 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)
@@ -153,10 +221,10 @@
#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.
+/// 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)
@@ -165,7 +233,6 @@
#define LLVM_ATTRIBUTE_ALWAYS_INLINE
#endif
-
#ifdef __GNUC__
#define LLVM_ATTRIBUTE_NORETURN __attribute__((noreturn))
#elif defined(_MSC_VER)
@@ -174,8 +241,8 @@
#define LLVM_ATTRIBUTE_NORETURN
#endif
-// LLVM_EXTENSION - Support compilers where we have a keyword to suppress
-// pedantic diagnostics.
+/// LLVM_EXTENSION - Support compilers where we have a keyword to suppress
+/// pedantic diagnostics.
#ifdef __GNUC__
#define LLVM_EXTENSION __extension__
#else
@@ -197,16 +264,18 @@
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.
+/// 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.
+/// 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()
@@ -214,4 +283,82 @@
# 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
diff --git a/include/llvm/Support/ConstantFolder.h b/include/llvm/Support/ConstantFolder.h
index 93aa343..4aad952 100644
--- a/include/llvm/Support/ConstantFolder.h
+++ b/include/llvm/Support/ConstantFolder.h
@@ -17,8 +17,8 @@
#ifndef LLVM_SUPPORT_CONSTANTFOLDER_H
#define LLVM_SUPPORT_CONSTANTFOLDER_H
-#include "llvm/Constants.h"
-#include "llvm/InstrTypes.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/InstrTypes.h"
namespace llvm {
diff --git a/include/llvm/Support/ConstantRange.h b/include/llvm/Support/ConstantRange.h
index 90dd69f..0f29256 100644
--- a/include/llvm/Support/ConstantRange.h
+++ b/include/llvm/Support/ConstantRange.h
@@ -29,8 +29,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SUPPORT_CONSTANT_RANGE_H
-#define LLVM_SUPPORT_CONSTANT_RANGE_H
+#ifndef LLVM_SUPPORT_CONSTANTRANGE_H
+#define LLVM_SUPPORT_CONSTANTRANGE_H
#include "llvm/ADT/APInt.h"
#include "llvm/Support/DataTypes.h"
diff --git a/include/llvm/Support/ConvertUTF.h b/include/llvm/Support/ConvertUTF.h
new file mode 100644
index 0000000..1eae6d6
--- /dev/null
+++ b/include/llvm/Support/ConvertUTF.h
@@ -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
diff --git a/include/llvm/Support/DOTGraphTraits.h b/include/llvm/Support/DOTGraphTraits.h
index 483f267..95e37c0 100644
--- a/include/llvm/Support/DOTGraphTraits.h
+++ b/include/llvm/Support/DOTGraphTraits.h
@@ -79,6 +79,11 @@ public:
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>
diff --git a/include/llvm/Support/DataExtractor.h b/include/llvm/Support/DataExtractor.h
index a3ae782..e8a19cd 100644
--- a/include/llvm/Support/DataExtractor.h
+++ b/include/llvm/Support/DataExtractor.h
@@ -18,22 +18,24 @@ namespace llvm {
class DataExtractor {
StringRef Data;
uint8_t IsLittleEndian;
- uint8_t PointerSize;
+ 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 PointerSize)
- : Data(Data), IsLittleEndian(IsLittleEndian), PointerSize(PointerSize) {}
+ DataExtractor(StringRef Data, bool IsLittleEndian, uint8_t AddressSize)
+ : Data(Data), IsLittleEndian(IsLittleEndian), AddressSize(AddressSize) {}
- /// getData - Get the data pointed to by this extractor.
+ /// \brief Get the data pointed to by this extractor.
StringRef getData() const { return Data; }
- /// isLittleEndian - Get the endianess for this extractor.
+ /// \brief Get the endianess for this extractor.
bool isLittleEndian() const { return IsLittleEndian; }
- /// getAddressSize - Get the address size for this extractor.
- uint8_t getAddressSize() const { return PointerSize; }
+ /// \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.
///
@@ -113,7 +115,7 @@ public:
///
/// Extract a single pointer from the data and update the offset
/// pointed to by \a offset_ptr. The size of the extracted pointer
- /// comes from the \a m_addr_size member variable and should be
+ /// is \a getAddressSize(), so the address size has to be
/// set correctly prior to extracting any pointer values.
///
/// @param[in,out] offset_ptr
@@ -126,7 +128,7 @@ public:
/// @return
/// The extracted pointer value as a 64 integer.
uint64_t getAddress(uint32_t *offset_ptr) const {
- return getUnsigned(offset_ptr, PointerSize);
+ return getUnsigned(offset_ptr, AddressSize);
}
/// Extract a uint8_t value from \a *offset_ptr.
diff --git a/include/llvm/Support/DataFlow.h b/include/llvm/Support/DataFlow.h
index 355c402..a09ccaa 100644
--- a/include/llvm/Support/DataFlow.h
+++ b/include/llvm/Support/DataFlow.h
@@ -14,8 +14,8 @@
#ifndef LLVM_SUPPORT_DATAFLOW_H
#define LLVM_SUPPORT_DATAFLOW_H
-#include "llvm/User.h"
#include "llvm/ADT/GraphTraits.h"
+#include "llvm/IR/User.h"
namespace llvm {
diff --git a/include/llvm/Support/DataStream.h b/include/llvm/Support/DataStream.h
index fedb0c9..8bc4133 100644
--- a/include/llvm/Support/DataStream.h
+++ b/include/llvm/Support/DataStream.h
@@ -14,8 +14,8 @@
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SUPPORT_DATASTREAM_H_
-#define LLVM_SUPPORT_DATASTREAM_H_
+#ifndef LLVM_SUPPORT_DATASTREAM_H
+#define LLVM_SUPPORT_DATASTREAM_H
#include <string>
diff --git a/include/llvm/Support/DebugLoc.h b/include/llvm/Support/DebugLoc.h
index 0498075..f35d407 100644
--- a/include/llvm/Support/DebugLoc.h
+++ b/include/llvm/Support/DebugLoc.h
@@ -9,7 +9,7 @@
//
// This file defines a number of light weight data structures used
// to describe and track debug location information.
-//
+//
//===----------------------------------------------------------------------===//
#ifndef LLVM_SUPPORT_DEBUGLOC_H
@@ -19,7 +19,7 @@ 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.
@@ -46,18 +46,18 @@ namespace llvm {
/// 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);
@@ -66,32 +66,32 @@ namespace llvm {
/// 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;
}
@@ -109,4 +109,4 @@ namespace llvm {
};
} // end namespace llvm
-#endif /* LLVM_DEBUGLOC_H */
+#endif /* LLVM_SUPPORT_DEBUGLOC_H */
diff --git a/include/llvm/Support/Dwarf.h b/include/llvm/Support/Dwarf.h
index 8f18a99..b52914f 100644
--- a/include/llvm/Support/Dwarf.h
+++ b/include/llvm/Support/Dwarf.h
@@ -16,6 +16,9 @@
#ifndef LLVM_SUPPORT_DWARF_H
#define LLVM_SUPPORT_DWARF_H
+#include "llvm/Support/DataTypes.h"
+
+
namespace llvm {
//===----------------------------------------------------------------------===//
@@ -37,7 +40,7 @@ enum {
namespace dwarf {
//===----------------------------------------------------------------------===//
-// Dwarf constants as gleaned from the DWARF Debugging Information Format V.3
+// Dwarf constants as gleaned from the DWARF Debugging Information Format V.4
// reference manual http://dwarf.freestandards.org .
//
@@ -50,15 +53,19 @@ enum llvm_dwarf_constants {
DW_TAG_auto_variable = 0x100, // Tag for local (auto) variables.
DW_TAG_arg_variable = 0x101, // Tag for argument variables.
- DW_TAG_return_variable = 0x102, // Tag for return variables.
- DW_TAG_vector_type = 0x103, // Tag for vector types.
DW_TAG_user_base = 0x1000, // Recommended base for user tags.
- DW_CIE_VERSION = 1, // Common frame information version.
- DW_CIE_ID = 0xffffffff // Common frame information mark.
+ 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,
@@ -231,6 +238,10 @@ enum dwarf_constants {
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,
@@ -246,6 +257,12 @@ enum dwarf_constants {
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,
@@ -254,9 +271,14 @@ enum dwarf_constants {
DW_AT_body_end = 0x2106,
DW_AT_GNU_vector = 0x2107,
DW_AT_GNU_template_name = 0x2110,
- DW_AT_MIPS_assumed_size = 0x2011,
- DW_AT_lo_user = 0x2000,
- DW_AT_hi_user = 0x3fff,
+
+ // 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,
@@ -300,6 +322,10 @@ enum dwarf_constants {
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,
@@ -458,6 +484,10 @@ enum dwarf_constants {
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,
diff --git a/include/llvm/Support/DynamicLibrary.h b/include/llvm/Support/DynamicLibrary.h
index 0f59cbf..1e2d16c 100644
--- a/include/llvm/Support/DynamicLibrary.h
+++ b/include/llvm/Support/DynamicLibrary.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SYSTEM_DYNAMIC_LIBRARY_H
-#define LLVM_SYSTEM_DYNAMIC_LIBRARY_H
+#ifndef LLVM_SYSTEM_DYNAMICLIBRARY_H
+#define LLVM_SYSTEM_DYNAMICLIBRARY_H
#include <string>
diff --git a/include/llvm/Support/ELF.h b/include/llvm/Support/ELF.h
index 2cd2671..ea597fc 100644
--- a/include/llvm/Support/ELF.h
+++ b/include/llvm/Support/ELF.h
@@ -271,6 +271,7 @@ enum {
EM_SLE9X = 179, // Infineon Technologies SLE9X core
EM_L10M = 180, // Intel L10M
EM_K10M = 181, // Intel K10M
+ EM_AARCH64 = 183, // ARM AArch64
EM_AVR32 = 185, // Atmel Corporation 32-bit microprocessor family
EM_STM8 = 186, // STMicroeletronics STM8 8-bit microcontroller
EM_TILE64 = 187, // Tilera TILE64 multicore architecture family
@@ -366,7 +367,8 @@ enum {
R_X86_64_SIZE64 = 33,
R_X86_64_GOTPC32_TLSDESC = 34,
R_X86_64_TLSDESC_CALL = 35,
- R_X86_64_TLSDESC = 36
+ R_X86_64_TLSDESC = 36,
+ R_X86_64_IRELATIVE = 37
};
// i386 relocations.
@@ -464,20 +466,140 @@ enum {
// ELF Relocation types for PPC64
enum {
+ R_PPC64_ADDR32 = 1,
R_PPC64_ADDR16_LO = 4,
R_PPC64_ADDR16_HI = 5,
R_PPC64_ADDR14 = 7,
R_PPC64_REL24 = 10,
+ R_PPC64_REL32 = 26,
R_PPC64_ADDR64 = 38,
R_PPC64_ADDR16_HIGHER = 39,
R_PPC64_ADDR16_HIGHEST = 41,
+ R_PPC64_REL64 = 44,
R_PPC64_TOC16 = 47,
+ R_PPC64_TOC16_LO = 48,
+ R_PPC64_TOC16_HA = 50,
R_PPC64_TOC = 51,
- R_PPC64_TOC16_DS = 63
+ R_PPC64_ADDR16_DS = 56,
+ R_PPC64_ADDR16_LO_DS = 57,
+ R_PPC64_TOC16_DS = 63,
+ R_PPC64_TOC16_LO_DS = 64,
+ R_PPC64_TLS = 67,
+ R_PPC64_TPREL16_LO = 70,
+ R_PPC64_DTPREL16_LO = 75,
+ R_PPC64_DTPREL16_HA = 77,
+ R_PPC64_GOT_TLSGD16_LO = 80,
+ R_PPC64_GOT_TLSGD16_HA = 82,
+ R_PPC64_GOT_TLSLD16_LO = 84,
+ R_PPC64_GOT_TLSLD16_HA = 86,
+ R_PPC64_GOT_TPREL16_LO_DS = 88,
+ R_PPC64_GOT_TPREL16_HA = 90,
+ R_PPC64_TLSGD = 107,
+ R_PPC64_TLSLD = 108
+};
+
+// ELF Relocation types for AArch64
+
+enum {
+ R_AARCH64_NONE = 0x100,
+
+ R_AARCH64_ABS64 = 0x101,
+ R_AARCH64_ABS32 = 0x102,
+ R_AARCH64_ABS16 = 0x103,
+ R_AARCH64_PREL64 = 0x104,
+ R_AARCH64_PREL32 = 0x105,
+ R_AARCH64_PREL16 = 0x106,
+
+ R_AARCH64_MOVW_UABS_G0 = 0x107,
+ R_AARCH64_MOVW_UABS_G0_NC = 0x108,
+ R_AARCH64_MOVW_UABS_G1 = 0x109,
+ R_AARCH64_MOVW_UABS_G1_NC = 0x10a,
+ R_AARCH64_MOVW_UABS_G2 = 0x10b,
+ R_AARCH64_MOVW_UABS_G2_NC = 0x10c,
+ R_AARCH64_MOVW_UABS_G3 = 0x10d,
+ R_AARCH64_MOVW_SABS_G0 = 0x10e,
+ R_AARCH64_MOVW_SABS_G1 = 0x10f,
+ R_AARCH64_MOVW_SABS_G2 = 0x110,
+
+ R_AARCH64_LD_PREL_LO19 = 0x111,
+ R_AARCH64_ADR_PREL_LO21 = 0x112,
+ R_AARCH64_ADR_PREL_PG_HI21 = 0x113,
+ R_AARCH64_ADD_ABS_LO12_NC = 0x115,
+ R_AARCH64_LDST8_ABS_LO12_NC = 0x116,
+
+ R_AARCH64_TSTBR14 = 0x117,
+ R_AARCH64_CONDBR19 = 0x118,
+ R_AARCH64_JUMP26 = 0x11a,
+ R_AARCH64_CALL26 = 0x11b,
+
+ R_AARCH64_LDST16_ABS_LO12_NC = 0x11c,
+ R_AARCH64_LDST32_ABS_LO12_NC = 0x11d,
+ R_AARCH64_LDST64_ABS_LO12_NC = 0x11e,
+
+ R_AARCH64_LDST128_ABS_LO12_NC = 0x12b,
+
+ R_AARCH64_ADR_GOT_PAGE = 0x137,
+ R_AARCH64_LD64_GOT_LO12_NC = 0x138,
+
+ R_AARCH64_TLSLD_MOVW_DTPREL_G2 = 0x20b,
+ R_AARCH64_TLSLD_MOVW_DTPREL_G1 = 0x20c,
+ R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC = 0x20d,
+ R_AARCH64_TLSLD_MOVW_DTPREL_G0 = 0x20e,
+ R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC = 0x20f,
+ R_AARCH64_TLSLD_ADD_DTPREL_HI12 = 0x210,
+ R_AARCH64_TLSLD_ADD_DTPREL_LO12 = 0x211,
+ R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC = 0x212,
+ R_AARCH64_TLSLD_LDST8_DTPREL_LO12 = 0x213,
+ R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC = 0x214,
+ R_AARCH64_TLSLD_LDST16_DTPREL_LO12 = 0x215,
+ R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC = 0x216,
+ R_AARCH64_TLSLD_LDST32_DTPREL_LO12 = 0x217,
+ R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC = 0x218,
+ R_AARCH64_TLSLD_LDST64_DTPREL_LO12 = 0x219,
+ R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC = 0x21a,
+
+ R_AARCH64_TLSIE_MOVW_GOTTPREL_G1 = 0x21b,
+ R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC = 0x21c,
+ R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 = 0x21d,
+ R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC = 0x21e,
+ R_AARCH64_TLSIE_LD_GOTTPREL_PREL19 = 0x21f,
+
+ R_AARCH64_TLSLE_MOVW_TPREL_G2 = 0x220,
+ R_AARCH64_TLSLE_MOVW_TPREL_G1 = 0x221,
+ R_AARCH64_TLSLE_MOVW_TPREL_G1_NC = 0x222,
+ R_AARCH64_TLSLE_MOVW_TPREL_G0 = 0x223,
+ R_AARCH64_TLSLE_MOVW_TPREL_G0_NC = 0x224,
+ R_AARCH64_TLSLE_ADD_TPREL_HI12 = 0x225,
+ R_AARCH64_TLSLE_ADD_TPREL_LO12 = 0x226,
+ R_AARCH64_TLSLE_ADD_TPREL_LO12_NC = 0x227,
+ R_AARCH64_TLSLE_LDST8_TPREL_LO12 = 0x228,
+ R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC = 0x229,
+ R_AARCH64_TLSLE_LDST16_TPREL_LO12 = 0x22a,
+ R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC = 0x22b,
+ R_AARCH64_TLSLE_LDST32_TPREL_LO12 = 0x22c,
+ R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC = 0x22d,
+ R_AARCH64_TLSLE_LDST64_TPREL_LO12 = 0x22e,
+ R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC = 0x22f,
+
+ R_AARCH64_TLSDESC_ADR_PAGE = 0x232,
+ R_AARCH64_TLSDESC_LD64_LO12_NC = 0x233,
+ R_AARCH64_TLSDESC_ADD_LO12_NC = 0x234,
+
+ R_AARCH64_TLSDESC_CALL = 0x239
};
// ARM Specific e_flags
-enum { EF_ARM_EABIMASK = 0xFF000000U };
+enum {
+ EF_ARM_SOFT_FLOAT = 0x00000200U,
+ EF_ARM_VFP_FLOAT = 0x00000400U,
+ EF_ARM_EABI_UNKNOWN = 0x00000000U,
+ EF_ARM_EABI_VER1 = 0x01000000U,
+ EF_ARM_EABI_VER2 = 0x02000000U,
+ EF_ARM_EABI_VER3 = 0x03000000U,
+ EF_ARM_EABI_VER4 = 0x04000000U,
+ EF_ARM_EABI_VER5 = 0x05000000U,
+ EF_ARM_EABIMASK = 0xFF000000U
+};
// ELF Relocation types for ARM
// Meets 2.08 ABI Specs.
@@ -621,6 +743,13 @@ enum {
EF_MIPS_NOREORDER = 0x00000001, // Don't reorder instructions
EF_MIPS_PIC = 0x00000002, // Position independent code
EF_MIPS_CPIC = 0x00000004, // Call object with Position independent code
+ EF_MIPS_ABI_O32 = 0x00001000, // This file follows the first MIPS 32 bit ABI
+
+ //ARCH_ASE
+ EF_MIPS_MICROMIPS = 0x02000000, // microMIPS
+ EF_MIPS_ARCH_ASE_M16 =
+ 0x04000000, // Has Mips-16 ISA extensions
+ //ARCH
EF_MIPS_ARCH_1 = 0x00000000, // MIPS1 instruction set
EF_MIPS_ARCH_2 = 0x10000000, // MIPS2 instruction set
EF_MIPS_ARCH_3 = 0x20000000, // MIPS3 instruction set
@@ -691,6 +820,11 @@ enum {
R_MIPS_NUM = 218
};
+// Special values for the st_other field in the symbol table entry for MIPS.
+enum {
+ STO_MIPS_MICROMIPS = 0x80 // MIPS Specific ISA for MicroMips
+};
+
// Hexagon Specific e_flags
// Release 5 ABI
enum {
@@ -710,14 +844,14 @@ enum {
};
// Hexagon specific Section indexes for common small data
-// Release 5 ABI
+// Release 5 ABI
enum {
SHN_HEXAGON_SCOMMON = 0xff00, // Other access sizes
SHN_HEXAGON_SCOMMON_1 = 0xff01, // Byte-sized access
SHN_HEXAGON_SCOMMON_2 = 0xff02, // Half-word-sized access
SHN_HEXAGON_SCOMMON_4 = 0xff03, // Word-sized access
SHN_HEXAGON_SCOMMON_8 = 0xff04 // Double-word-size access
-};
+};
// ELF Relocation types for Hexagon
// Release 5 ABI
@@ -878,7 +1012,7 @@ enum {
SHT_GNU_verneed = 0x6ffffffe, // GNU version references.
SHT_GNU_versym = 0x6fffffff, // GNU symbol versions table.
SHT_HIOS = 0x6fffffff, // Highest operating system-specific type.
- SHT_LOPROC = 0x70000000, // Lowest processor architecture-specific type.
+ SHT_LOPROC = 0x70000000, // Lowest processor arch-specific type.
// Fixme: All this is duplicated in MCSectionELF. Why??
// Exception Index table
SHT_ARM_EXIDX = 0x70000001U,
@@ -888,10 +1022,14 @@ enum {
SHT_ARM_ATTRIBUTES = 0x70000003U,
SHT_ARM_DEBUGOVERLAY = 0x70000004U,
SHT_ARM_OVERLAYSECTION = 0x70000005U,
-
+ SHT_HEX_ORDERED = 0x70000000, // Link editor is to sort the entries in
+ // this section based on their sizes
SHT_X86_64_UNWIND = 0x70000001, // Unwind information
- SHT_HIPROC = 0x7fffffff, // Highest processor architecture-specific type.
+ SHT_MIPS_REGINFO = 0x70000006, // Register usage information
+ SHT_MIPS_OPTIONS = 0x7000000d, // General options
+
+ SHT_HIPROC = 0x7fffffff, // Highest processor arch-specific type.
SHT_LOUSER = 0x80000000, // Lowest type reserved for applications.
SHT_HIUSER = 0xffffffff // Highest type reserved for applications.
};
@@ -953,7 +1091,14 @@ enum {
// sets this flag besides being able to refer to data in a section that does
// not set it; likewise, a small code model object can refer only to code in a
// section that does not set this flag.
- SHF_X86_64_LARGE = 0x10000000
+ SHF_X86_64_LARGE = 0x10000000,
+
+ // All sections with the GPREL flag are grouped into a global data area
+ // for faster accesses
+ SHF_HEX_GPREL = 0x10000000,
+
+ // Do not strip this section. FIXME: We need target specific SHF_ enums.
+ SHF_MIPS_NOSTRIP = 0x8000000
};
// Section Group Flags
@@ -988,7 +1133,7 @@ struct Elf64_Sym {
Elf64_Word st_name; // Symbol name (index into string table)
unsigned char st_info; // Symbol's type and binding attributes
unsigned char st_other; // Must be zero; reserved
- Elf64_Half st_shndx; // Which section (header table index) it's defined in
+ Elf64_Half st_shndx; // Which section (header tbl index) it's defined in
Elf64_Addr st_value; // Value or address associated with the symbol
Elf64_Xword st_size; // Size of the symbol
@@ -1043,6 +1188,11 @@ enum {
STV_PROTECTED = 3 // Visible in other components but not preemptable
};
+// Symbol number.
+enum {
+ STN_UNDEF = 0
+};
+
// Relocation entry, without explicit addend.
struct Elf32_Rel {
Elf32_Addr r_offset; // Location (file byte offset, or program virtual addr)
@@ -1083,14 +1233,14 @@ struct Elf64_Rel {
// These accessors and mutators correspond to the ELF64_R_SYM, ELF64_R_TYPE,
// and ELF64_R_INFO macros defined in the ELF specification:
- Elf64_Xword getSymbol() const { return (r_info >> 32); }
- unsigned char getType() const {
- return (unsigned char) (r_info & 0xffffffffL);
+ Elf64_Word getSymbol() const { return (r_info >> 32); }
+ Elf64_Word getType() const {
+ return (Elf64_Word) (r_info & 0xffffffffL);
}
- void setSymbol(Elf32_Word s) { setSymbolAndType(s, getType()); }
- void setType(unsigned char t) { setSymbolAndType(getSymbol(), t); }
- void setSymbolAndType(Elf64_Xword s, unsigned char t) {
- r_info = (s << 32) + (t&0xffffffffL);
+ void setSymbol(Elf64_Word s) { setSymbolAndType(s, getType()); }
+ void setType(Elf64_Word t) { setSymbolAndType(getSymbol(), t); }
+ void setSymbolAndType(Elf64_Word s, Elf64_Word t) {
+ r_info = ((Elf64_Xword)s << 32) + (t&0xffffffffL);
}
};
@@ -1102,14 +1252,14 @@ struct Elf64_Rela {
// These accessors and mutators correspond to the ELF64_R_SYM, ELF64_R_TYPE,
// and ELF64_R_INFO macros defined in the ELF specification:
- Elf64_Xword getSymbol() const { return (r_info >> 32); }
- unsigned char getType() const {
- return (unsigned char) (r_info & 0xffffffffL);
+ Elf64_Word getSymbol() const { return (r_info >> 32); }
+ Elf64_Word getType() const {
+ return (Elf64_Word) (r_info & 0xffffffffL);
}
- void setSymbol(Elf64_Xword s) { setSymbolAndType(s, getType()); }
- void setType(unsigned char t) { setSymbolAndType(getSymbol(), t); }
- void setSymbolAndType(Elf64_Xword s, unsigned char t) {
- r_info = (s << 32) + (t&0xffffffffL);
+ void setSymbol(Elf64_Word s) { setSymbolAndType(s, getType()); }
+ void setType(Elf64_Word t) { setSymbolAndType(getSymbol(), t); }
+ void setSymbolAndType(Elf64_Word s, Elf64_Word t) {
+ r_info = ((Elf64_Xword)s << 32) + (t&0xffffffffL);
}
};
@@ -1131,7 +1281,7 @@ struct Elf64_Phdr {
Elf64_Word p_flags; // Segment flags
Elf64_Off p_offset; // File offset where segment is located, in bytes
Elf64_Addr p_vaddr; // Virtual address of beginning of segment
- Elf64_Addr p_paddr; // Physical address of beginning of segment (OS-specific)
+ Elf64_Addr p_paddr; // Physical addr of beginning of segment (OS-specific)
Elf64_Xword p_filesz; // Num. of bytes in file image of segment (may be zero)
Elf64_Xword p_memsz; // Num. of bytes in mem image of segment (may be zero)
Elf64_Xword p_align; // Segment alignment constraint
@@ -1162,7 +1312,7 @@ enum {
PT_GNU_RELRO = 0x6474e552, // Read-only after relocation.
// ARM program header types.
- PT_ARM_ARCHEXT = 0x70000000, // Platform architecture compatibility information
+ PT_ARM_ARCHEXT = 0x70000000, // Platform architecture compatibility info
// These all contain stack unwind tables.
PT_ARM_EXIDX = 0x70000001,
PT_ARM_UNWIND = 0x70000001
diff --git a/include/llvm/Support/Endian.h b/include/llvm/Support/Endian.h
index 8d5649d..d438fac 100644
--- a/include/llvm/Support/Endian.h
+++ b/include/llvm/Support/Endian.h
@@ -14,136 +14,78 @@
#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};
-enum endianness {big, little};
-enum alignment {unaligned, aligned};
+// These are named values for common alignments.
+enum {aligned = 0, unaligned = 1};
namespace detail {
-
-template<typename value_type, alignment align>
-struct alignment_access_helper;
-
-template<typename value_type>
-struct alignment_access_helper<value_type, aligned>
-{
- value_type val;
-};
-
-// Provides unaligned loads and stores.
-#pragma pack(push)
-#pragma pack(1)
-template<typename value_type>
-struct alignment_access_helper<value_type, unaligned>
-{
- value_type val;
-};
-#pragma pack(pop)
-
+ /// \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, alignment align>
- inline value_type read_le(const void *memory) {
- value_type t =
- reinterpret_cast<const detail::alignment_access_helper
- <value_type, align> *>(memory)->val;
- if (sys::isBigEndianHost())
- return sys::SwapByteOrder(t);
- return t;
- }
-
- template<typename value_type, alignment align>
- inline void write_le(void *memory, value_type value) {
- if (sys::isBigEndianHost())
- value = sys::SwapByteOrder(value);
- reinterpret_cast<detail::alignment_access_helper<value_type, align> *>
- (memory)->val = value;
- }
+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, alignment align>
- inline value_type read_be(const void *memory) {
- value_type t =
- reinterpret_cast<const detail::alignment_access_helper
- <value_type, align> *>(memory)->val;
- if (sys::isLittleEndianHost())
- return sys::SwapByteOrder(t);
- return t;
- }
+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, alignment align>
- inline void write_be(void *memory, value_type value) {
- if (sys::isLittleEndianHost())
- value = sys::SwapByteOrder(value);
- reinterpret_cast<detail::alignment_access_helper<value_type, align> *>
- (memory)->val = value;
- }
+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,
- alignment align>
-class packed_endian_specific_integral;
-
-template<typename value_type>
-class packed_endian_specific_integral<value_type, little, unaligned> {
-public:
- operator value_type() const {
- return endian::read_le<value_type, unaligned>(Value);
- }
- void operator=(value_type newValue) {
- endian::write_le<value_type, unaligned>((void *)&Value, newValue);
- }
-private:
- uint8_t Value[sizeof(value_type)];
-};
-
-template<typename value_type>
-class packed_endian_specific_integral<value_type, big, unaligned> {
-public:
+ std::size_t alignment>
+struct packed_endian_specific_integral {
operator value_type() const {
- return endian::read_be<value_type, unaligned>(Value);
+ return endian::read<value_type, endian, alignment>(
+ (const void*)Value.buffer);
}
- void operator=(value_type newValue) {
- endian::write_be<value_type, unaligned>((void *)&Value, newValue);
- }
-private:
- uint8_t Value[sizeof(value_type)];
-};
-template<typename value_type>
-class packed_endian_specific_integral<value_type, little, aligned> {
-public:
- operator value_type() const {
- return endian::read_le<value_type, aligned>(&Value);
- }
void operator=(value_type newValue) {
- endian::write_le<value_type, aligned>((void *)&Value, newValue);
+ endian::write<value_type, endian, alignment>(
+ (void*)Value.buffer, newValue);
}
-private:
- value_type Value;
-};
-template<typename value_type>
-class packed_endian_specific_integral<value_type, big, aligned> {
-public:
- operator value_type() const {
- return endian::read_be<value_type, aligned>(&Value);
- }
- void operator=(value_type newValue) {
- endian::write_be<value_type, aligned>((void *)&Value, newValue);
- }
private:
- value_type Value;
+ AlignedCharArray<PickAlignment<value_type, alignment>::value,
+ sizeof(value_type)> Value;
};
-
} // end namespace detail
typedef detail::packed_endian_specific_integral
@@ -218,6 +160,19 @@ typedef detail::packed_endian_specific_integral
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
diff --git a/include/llvm/Support/Errno.h b/include/llvm/Support/Errno.h
index 150bdb7..8e145c7 100644
--- a/include/llvm/Support/Errno.h
+++ b/include/llvm/Support/Errno.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SYSTEM_ERRNO_H
-#define LLVM_SYSTEM_ERRNO_H
+#ifndef LLVM_SUPPORT_ERRNO_H
+#define LLVM_SUPPORT_ERRNO_H
#include <string>
diff --git a/include/llvm/Support/ErrorHandling.h b/include/llvm/Support/ErrorHandling.h
index 95b0109..b948d97 100644
--- a/include/llvm/Support/ErrorHandling.h
+++ b/include/llvm/Support/ErrorHandling.h
@@ -15,8 +15,8 @@
#ifndef LLVM_SUPPORT_ERRORHANDLING_H
#define LLVM_SUPPORT_ERRORHANDLING_H
-#include "llvm/Support/Compiler.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Compiler.h"
#include <string>
namespace llvm {
@@ -24,7 +24,8 @@ namespace llvm {
/// An error handler callback.
typedef void (*fatal_error_handler_t)(void *user_data,
- const std::string& reason);
+ 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.
@@ -73,10 +74,14 @@ namespace llvm {
/// 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);
- LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const std::string &reason);
- LLVM_ATTRIBUTE_NORETURN void report_fatal_error(StringRef reason);
- LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const Twine &reason);
+ 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
diff --git a/include/llvm/Support/ErrorOr.h b/include/llvm/Support/ErrorOr.h
new file mode 100644
index 0000000..f3ac305
--- /dev/null
+++ b/include/llvm/Support/ErrorOr.h
@@ -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
diff --git a/include/llvm/Support/FEnv.h b/include/llvm/Support/FEnv.h
index f6f4333..8560ee0 100644
--- a/include/llvm/Support/FEnv.h
+++ b/include/llvm/Support/FEnv.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SYSTEM_FENV_H
-#define LLVM_SYSTEM_FENV_H
+#ifndef LLVM_SUPPORT_FENV_H
+#define LLVM_SUPPORT_FENV_H
#include "llvm/Config/config.h"
#include <cerrno>
@@ -32,7 +32,7 @@ namespace sys {
/// llvm_fenv_clearexcept - Clear the floating-point exception state.
static inline void llvm_fenv_clearexcept() {
-#ifdef HAVE_FENV_H
+#if defined(HAVE_FENV_H) && HAVE_DECL_FE_ALL_EXCEPT
feclearexcept(FE_ALL_EXCEPT);
#endif
errno = 0;
@@ -43,7 +43,7 @@ static inline bool llvm_fenv_testexcept() {
int errno_val = errno;
if (errno_val == ERANGE || errno_val == EDOM)
return true;
-#ifdef HAVE_FENV_H
+#if defined(HAVE_FENV_H) && HAVE_DECL_FE_ALL_EXCEPT && HAVE_DECL_FE_INEXACT
if (fetestexcept(FE_ALL_EXCEPT & ~FE_INEXACT))
return true;
#endif
diff --git a/include/llvm/Support/FileOutputBuffer.h b/include/llvm/Support/FileOutputBuffer.h
index bcd35e3..cbc9c46 100644
--- a/include/llvm/Support/FileOutputBuffer.h
+++ b/include/llvm/Support/FileOutputBuffer.h
@@ -14,85 +14,79 @@
#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;
-template<class T> class OwningPtr;
/// FileOutputBuffer - This interface provides simple way to create an in-memory
-/// buffer which will be written to a file. During the lifetime of these
+/// 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
+/// 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);
-
+ /// 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() const {
- return BufferStart;
+ uint8_t *getBufferStart() {
+ return (uint8_t*)Region->data();
}
-
+
/// Returns a pointer to the end of the buffer.
- uint8_t *getBufferEnd() const {
- return BufferEnd;
+ uint8_t *getBufferEnd() {
+ return (uint8_t*)Region->data() + Region->size();
}
-
+
/// Returns size of the buffer.
size_t getBufferSize() const {
- return BufferEnd - BufferStart;
+ 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
+
+ /// 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;
-protected:
- FileOutputBuffer(uint8_t *Start, uint8_t *End,
- StringRef Path, StringRef TempPath);
-
- uint8_t *BufferStart;
- uint8_t *BufferEnd;
+
+ 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
diff --git a/include/llvm/Support/FileSystem.h b/include/llvm/Support/FileSystem.h
index b455b28..ffa6427 100644
--- a/include/llvm/Support/FileSystem.h
+++ b/include/llvm/Support/FileSystem.h
@@ -24,8 +24,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SUPPORT_FILE_SYSTEM_H
-#define LLVM_SUPPORT_FILE_SYSTEM_H
+#ifndef LLVM_SUPPORT_FILESYSTEM_H
+#define LLVM_SUPPORT_FILESYSTEM_H
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/OwningPtr.h"
@@ -602,12 +602,12 @@ private:
void *FileMappingHandle;
#endif
- error_code init(int FD, uint64_t Offset);
+ error_code init(int FD, bool CloseFD, uint64_t Offset);
public:
typedef char char_type;
-#if LLVM_USE_RVALUE_REFERENCES
+#if LLVM_HAS_RVALUE_REFERENCES
mapped_file_region(mapped_file_region&&);
mapped_file_region &operator =(mapped_file_region&&);
#endif
@@ -633,8 +633,10 @@ public:
error_code &ec);
/// \param fd An open file descriptor to map. mapped_file_region takes
- /// ownership. It must have been opended in the correct mode.
+ /// 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,
diff --git a/include/llvm/Support/FormattedStream.h b/include/llvm/Support/FormattedStream.h
index 21635dc..2e4bd5a 100644
--- a/include/llvm/Support/FormattedStream.h
+++ b/include/llvm/Support/FormattedStream.h
@@ -17,125 +17,125 @@
#include "llvm/Support/raw_ostream.h"
-namespace llvm
-{
- /// formatted_raw_ostream - Formatted raw_fd_ostream to handle
- /// asm-specific constructs.
+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.
///
- 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();
+ 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;
- 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();
- }
- };
+ /// 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";
diff --git a/include/llvm/Support/GCOV.h b/include/llvm/Support/GCOV.h
index e552315..f1040f5 100644
--- a/include/llvm/Support/GCOV.h
+++ b/include/llvm/Support/GCOV.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_GCOV_H
-#define LLVM_GCOV_H
+#ifndef LLVM_SUPPORT_GCOV_H
+#define LLVM_SUPPORT_GCOV_H
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
diff --git a/include/llvm/Support/GetElementPtrTypeIterator.h b/include/llvm/Support/GetElementPtrTypeIterator.h
index ef92c95..5a90553 100644
--- a/include/llvm/Support/GetElementPtrTypeIterator.h
+++ b/include/llvm/Support/GetElementPtrTypeIterator.h
@@ -12,11 +12,11 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SUPPORT_GETELEMENTPTRTYPE_H
-#define LLVM_SUPPORT_GETELEMENTPTRTYPE_H
+#ifndef LLVM_SUPPORT_GETELEMENTPTRTYPEITERATOR_H
+#define LLVM_SUPPORT_GETELEMENTPTRTYPEITERATOR_H
-#include "llvm/User.h"
-#include "llvm/DerivedTypes.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/User.h"
namespace llvm {
template<typename ItTy = User::const_op_iterator>
@@ -83,15 +83,15 @@ namespace llvm {
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(),
- GEP->op_begin()+1);
+ 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(),
- GEP.op_begin()+1);
+ 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());
diff --git a/include/llvm/Support/GraphWriter.h b/include/llvm/Support/GraphWriter.h
index f178b0c..22181d4 100644
--- a/include/llvm/Support/GraphWriter.h
+++ b/include/llvm/Support/GraphWriter.h
@@ -23,17 +23,21 @@
#ifndef LLVM_SUPPORT_GRAPHWRITER_H
#define LLVM_SUPPORT_GRAPHWRITER_H
-#include "llvm/Support/DOTGraphTraits.h"
-#include "llvm/Support/raw_ostream.h"
#include "llvm/ADT/GraphTraits.h"
+#include "llvm/Support/DOTGraphTraits.h"
#include "llvm/Support/Path.h"
-#include <vector>
+#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 {
@@ -173,6 +177,10 @@ public:
// 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;
@@ -193,6 +201,10 @@ public:
// 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()) {
diff --git a/include/llvm/Support/Host.h b/include/llvm/Support/Host.h
index b331016..3a44405 100644
--- a/include/llvm/Support/Host.h
+++ b/include/llvm/Support/Host.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SYSTEM_HOST_H
-#define LLVM_SYSTEM_HOST_H
+#ifndef LLVM_SUPPORT_HOST_H
+#define LLVM_SUPPORT_HOST_H
#include "llvm/ADT/StringMap.h"
#include <string>
@@ -42,6 +42,10 @@ namespace sys {
/// 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.
diff --git a/include/llvm/Support/IRReader.h b/include/llvm/Support/IRReader.h
deleted file mode 100644
index 6d8a9b3..0000000
--- a/include/llvm/Support/IRReader.h
+++ /dev/null
@@ -1,112 +0,0 @@
-//===---- 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
diff --git a/include/llvm/Support/IncludeFile.h b/include/llvm/Support/IncludeFile.h
index a931972..2067e34 100644
--- a/include/llvm/Support/IncludeFile.h
+++ b/include/llvm/Support/IncludeFile.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SYSTEM_INCLUDEFILE_H
-#define LLVM_SYSTEM_INCLUDEFILE_H
+#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
diff --git a/include/llvm/Support/InstIterator.h b/include/llvm/Support/InstIterator.h
index 7d3f883..ac936a1 100644
--- a/include/llvm/Support/InstIterator.h
+++ b/include/llvm/Support/InstIterator.h
@@ -19,8 +19,8 @@
#ifndef LLVM_SUPPORT_INSTITERATOR_H
#define LLVM_SUPPORT_INSTITERATOR_H
-#include "llvm/BasicBlock.h"
-#include "llvm/Function.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Function.h"
namespace llvm {
diff --git a/include/llvm/Support/InstVisitor.h b/include/llvm/Support/InstVisitor.h
deleted file mode 100644
index 6dfb4de..0000000
--- a/include/llvm/Support/InstVisitor.h
+++ /dev/null
@@ -1,288 +0,0 @@
-//===- 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 visitVAStartInst(VAStartInst &I) { DELEGATE(IntrinsicInst); }
- RetTy visitVAEndInst(VAEndInst &I) { DELEGATE(IntrinsicInst); }
- RetTy visitVACopyInst(VACopyInst &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::vastart: DELEGATE(VAStartInst);
- case Intrinsic::vaend: DELEGATE(VAEndInst);
- case Intrinsic::vacopy: DELEGATE(VACopyInst);
- 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
diff --git a/include/llvm/Support/IntegersSubset.h b/include/llvm/Support/IntegersSubset.h
index 03039fd..ce34d78 100644
--- a/include/llvm/Support/IntegersSubset.h
+++ b/include/llvm/Support/IntegersSubset.h
@@ -15,15 +15,14 @@
//
//===----------------------------------------------------------------------===//
-#ifndef CONSTANTRANGESSET_H_
-#define CONSTANTRANGESSET_H_
+#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>
-#include "llvm/Constants.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/LLVMContext.h"
-
namespace llvm {
// The IntItem is a wrapper for APInt.
@@ -538,4 +537,4 @@ public:
}
-#endif /* CONSTANTRANGESSET_H_ */
+#endif /* CLLVM_SUPPORT_INTEGERSSUBSET_H */
diff --git a/include/llvm/Support/IntegersSubsetMapping.h b/include/llvm/Support/IntegersSubsetMapping.h
index 7635d5e..641ce78 100644
--- a/include/llvm/Support/IntegersSubsetMapping.h
+++ b/include/llvm/Support/IntegersSubsetMapping.h
@@ -17,8 +17,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef CRSBUILDER_H_
-#define CRSBUILDER_H_
+#ifndef LLVM_SUPPORT_INTEGERSSUBSETMAPPING_H
+#define LLVM_SUPPORT_INTEGERSSUBSETMAPPING_H
#include "llvm/Support/IntegersSubset.h"
#include <list>
@@ -585,4 +585,4 @@ typedef IntegersSubsetMapping<BasicBlock> IntegersSubsetToBB;
}
-#endif /* CRSBUILDER_H_ */
+#endif /* LLVM_SUPPORT_INTEGERSSUBSETMAPPING_CRSBUILDER_H */
diff --git a/include/llvm/Support/LEB128.h b/include/llvm/Support/LEB128.h
index b52e5bc..802b4f3 100644
--- a/include/llvm/Support/LEB128.h
+++ b/include/llvm/Support/LEB128.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SYSTEM_LEB128_H
-#define LLVM_SYSTEM_LEB128_H
+#ifndef LLVM_SUPPORT_LEB128_H
+#define LLVM_SUPPORT_LEB128_H
#include "llvm/Support/raw_ostream.h"
diff --git a/include/llvm/Support/Locale.h b/include/llvm/Support/Locale.h
index b0f1295..b384d58 100644
--- a/include/llvm/Support/Locale.h
+++ b/include/llvm/Support/Locale.h
@@ -1,5 +1,5 @@
-#ifndef LLVM_SUPPORT_LOCALE
-#define LLVM_SUPPORT_LOCALE
+#ifndef LLVM_SUPPORT_LOCALE_H
+#define LLVM_SUPPORT_LOCALE_H
#include "llvm/ADT/StringRef.h"
@@ -14,4 +14,4 @@ bool isPrint(int c);
}
}
-#endif // LLVM_SUPPORT_LOCALE
+#endif // LLVM_SUPPORT_LOCALE_H
diff --git a/include/llvm/Support/LockFileManager.h b/include/llvm/Support/LockFileManager.h
index 8c4a760..9df8675 100644
--- a/include/llvm/Support/LockFileManager.h
+++ b/include/llvm/Support/LockFileManager.h
@@ -41,6 +41,7 @@ public:
};
private:
+ SmallString<128> FileName;
SmallString<128> LockFileName;
SmallString<128> UniqueLockFileName;
diff --git a/include/llvm/Support/MathExtras.h b/include/llvm/Support/MathExtras.h
index 11f9e63..d6ae58d 100644
--- a/include/llvm/Support/MathExtras.h
+++ b/include/llvm/Support/MathExtras.h
@@ -16,6 +16,10 @@
#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
@@ -61,7 +65,7 @@ inline bool isShiftedInt(int64_t x) {
/// 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);
+ return N >= 64 || x < (UINT64_C(1)<<(N));
}
// Template specializations to get better code for common cases.
template<>
@@ -254,7 +258,10 @@ inline unsigned CountTrailingZeros_32(uint32_t Value) {
4, 7, 17, 0, 25, 22, 31, 15, 29, 10, 12, 6, 0, 21, 14, 9,
5, 20, 8, 19, 18
};
- return Mod37BitPosition[(-Value & Value) % 37];
+ // 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
}
@@ -281,7 +288,10 @@ inline unsigned CountTrailingZeros_64(uint64_t Value) {
29, 50, 43, 46, 31, 37, 21, 57, 52, 8, 26, 49, 45, 36, 56,
7, 48, 35, 6, 34, 33, 0
};
- return Mod67Position[(-Value & Value) % 67];
+ // 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
}
@@ -416,7 +426,11 @@ int IsInf(double d);
/// 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.
- return (A | B) & -(A | 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)
diff --git a/include/llvm/Support/Memory.h b/include/llvm/Support/Memory.h
index 025eee7..a08c796 100644
--- a/include/llvm/Support/Memory.h
+++ b/include/llvm/Support/Memory.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SYSTEM_MEMORY_H
-#define LLVM_SYSTEM_MEMORY_H
+#ifndef LLVM_SUPPORT_MEMORY_H
+#define LLVM_SUPPORT_MEMORY_H
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/system_error.h"
diff --git a/include/llvm/Support/MemoryObject.h b/include/llvm/Support/MemoryObject.h
index b778b08..732b0f0 100644
--- a/include/llvm/Support/MemoryObject.h
+++ b/include/llvm/Support/MemoryObject.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef MEMORYOBJECT_H
-#define MEMORYOBJECT_H
+#ifndef LLVM_SUPPORT_MEMORYOBJECT_H
+#define LLVM_SUPPORT_MEMORYOBJECT_H
#include "llvm/Support/DataTypes.h"
diff --git a/include/llvm/Support/Mutex.h b/include/llvm/Support/Mutex.h
index 6abc533..496a438 100644
--- a/include/llvm/Support/Mutex.h
+++ b/include/llvm/Support/Mutex.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SYSTEM_MUTEX_H
-#define LLVM_SYSTEM_MUTEX_H
+#ifndef LLVM_SUPPORT_MUTEX_H
+#define LLVM_SUPPORT_MUTEX_H
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Threading.h"
diff --git a/include/llvm/Support/NoFolder.h b/include/llvm/Support/NoFolder.h
index 8e41a64..ecfbbaa 100644
--- a/include/llvm/Support/NoFolder.h
+++ b/include/llvm/Support/NoFolder.h
@@ -23,8 +23,8 @@
#define LLVM_SUPPORT_NOFOLDER_H
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/Constants.h"
-#include "llvm/Instructions.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/Instructions.h"
namespace llvm {
diff --git a/include/llvm/Support/PassNameParser.h b/include/llvm/Support/PassNameParser.h
index a24a6f0..317416c 100644
--- a/include/llvm/Support/PassNameParser.h
+++ b/include/llvm/Support/PassNameParser.h
@@ -20,11 +20,11 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SUPPORT_PASS_NAME_PARSER_H
-#define LLVM_SUPPORT_PASS_NAME_PARSER_H
+#ifndef LLVM_SUPPORT_PASSNAMEPARSER_H
+#define LLVM_SUPPORT_PASSNAMEPARSER_H
-#include "llvm/Pass.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"
diff --git a/include/llvm/Support/PathV1.h b/include/llvm/Support/PathV1.h
index 643ee8c..86328f0 100644
--- a/include/llvm/Support/PathV1.h
+++ b/include/llvm/Support/PathV1.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SYSTEM_PATH_H
-#define LLVM_SYSTEM_PATH_H
+#ifndef LLVM_SUPPORT_PATHV1_H
+#define LLVM_SUPPORT_PATHV1_H
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Compiler.h"
diff --git a/include/llvm/Support/PatternMatch.h b/include/llvm/Support/PatternMatch.h
index 221fa8b..9fbe434 100644
--- a/include/llvm/Support/PatternMatch.h
+++ b/include/llvm/Support/PatternMatch.h
@@ -29,9 +29,11 @@
#ifndef LLVM_SUPPORT_PATTERNMATCH_H
#define LLVM_SUPPORT_PATTERNMATCH_H
-#include "llvm/Constants.h"
-#include "llvm/Instructions.h"
-#include "llvm/Operator.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Operator.h"
+#include "llvm/Support/CallSite.h"
namespace llvm {
namespace PatternMatch {
@@ -41,13 +43,13 @@ bool match(Val *V, const Pattern &P) {
return const_cast<Pattern&>(P).match(V);
}
-
+
template<typename SubPattern_t>
struct OneUse_match {
SubPattern_t SubPattern;
-
+
OneUse_match(const SubPattern_t &SP) : SubPattern(SP) {}
-
+
template<typename OpTy>
bool match(OpTy *V) {
return V->hasOneUse() && SubPattern.match(V);
@@ -56,8 +58,8 @@ struct OneUse_match {
template<typename T>
inline OneUse_match<T> m_OneUse(const T &SubPattern) { return SubPattern; }
-
-
+
+
template<typename Class>
struct class_match {
template<typename ITy>
@@ -74,7 +76,53 @@ inline class_match<ConstantInt> m_ConstantInt() {
inline class_match<UndefValue> m_Undef() { return class_match<UndefValue>(); }
inline class_match<Constant> m_Constant() { return class_match<Constant>(); }
-
+
+/// Matching combinators
+template<typename LTy, typename RTy>
+struct match_combine_or {
+ LTy L;
+ RTy R;
+
+ match_combine_or(const LTy &Left, const RTy &Right) : L(Left), R(Right) { }
+
+ template<typename ITy>
+ bool match(ITy *V) {
+ if (L.match(V))
+ return true;
+ if (R.match(V))
+ return true;
+ return false;
+ }
+};
+
+template<typename LTy, typename RTy>
+struct match_combine_and {
+ LTy L;
+ RTy R;
+
+ match_combine_and(const LTy &Left, const RTy &Right) : L(Left), R(Right) { }
+
+ template<typename ITy>
+ bool match(ITy *V) {
+ if (L.match(V))
+ if (R.match(V))
+ return true;
+ return false;
+ }
+};
+
+/// Combine two pattern matchers matching L || R
+template<typename LTy, typename RTy>
+inline match_combine_or<LTy, RTy> m_CombineOr(const LTy &L, const RTy &R) {
+ return match_combine_or<LTy, RTy>(L, R);
+}
+
+/// Combine two pattern matchers matching L && R
+template<typename LTy, typename RTy>
+inline match_combine_and<LTy, RTy> m_CombineAnd(const LTy &L, const RTy &R) {
+ return match_combine_and<LTy, RTy>(L, R);
+}
+
struct match_zero {
template<typename ITy>
bool match(ITy *V) {
@@ -83,12 +131,33 @@ struct match_zero {
return false;
}
};
-
+
/// m_Zero() - Match an arbitrary zero/null constant. This includes
/// zero_initializer for vectors and ConstantPointerNull for pointers.
inline match_zero m_Zero() { return match_zero(); }
-
-
+
+struct match_neg_zero {
+ template<typename ITy>
+ bool match(ITy *V) {
+ if (const Constant *C = dyn_cast<Constant>(V))
+ return C->isNegativeZeroValue();
+ return false;
+ }
+};
+
+/// m_NegZero() - Match an arbitrary zero/null constant. This includes
+/// zero_initializer for vectors and ConstantPointerNull for pointers. For
+/// floating point constants, this will match negative zero but not positive
+/// zero
+inline match_neg_zero m_NegZero() { return match_neg_zero(); }
+
+/// m_AnyZero() - Match an arbitrary zero/null constant. This includes
+/// zero_initializer for vectors and ConstantPointerNull for pointers. For
+/// floating point constants, this will match negative zero and positive zero
+inline match_combine_or<match_zero, match_neg_zero> m_AnyZero() {
+ return m_CombineOr(m_Zero(), m_NegZero());
+}
+
struct apint_match {
const APInt *&Res;
apint_match(const APInt *&R) : Res(R) {}
@@ -98,28 +167,22 @@ struct apint_match {
Res = &CI->getValue();
return true;
}
- // FIXME: Remove this.
- if (ConstantVector *CV = dyn_cast<ConstantVector>(V))
- if (ConstantInt *CI =
- dyn_cast_or_null<ConstantInt>(CV->getSplatValue())) {
- Res = &CI->getValue();
- return true;
- }
- if (ConstantDataVector *CV = dyn_cast<ConstantDataVector>(V))
- if (ConstantInt *CI =
- dyn_cast_or_null<ConstantInt>(CV->getSplatValue())) {
- Res = &CI->getValue();
- return true;
- }
+ if (V->getType()->isVectorTy())
+ if (const Constant *C = dyn_cast<Constant>(V))
+ if (ConstantInt *CI =
+ dyn_cast_or_null<ConstantInt>(C->getSplatValue())) {
+ Res = &CI->getValue();
+ return true;
+ }
return false;
}
};
-
+
/// m_APInt - Match a ConstantInt or splatted ConstantVector, binding the
/// specified pointer to the contained APInt.
inline apint_match m_APInt(const APInt *&Res) { return Res; }
-
+
template<int64_t Val>
struct constantint_match {
template<typename ITy>
@@ -151,17 +214,15 @@ struct cst_pred_ty : public Predicate {
bool match(ITy *V) {
if (const ConstantInt *CI = dyn_cast<ConstantInt>(V))
return this->isValue(CI->getValue());
- // FIXME: Remove this.
- if (const ConstantVector *CV = dyn_cast<ConstantVector>(V))
- if (ConstantInt *CI = dyn_cast_or_null<ConstantInt>(CV->getSplatValue()))
- return this->isValue(CI->getValue());
- if (const ConstantDataVector *CV = dyn_cast<ConstantDataVector>(V))
- if (ConstantInt *CI = dyn_cast_or_null<ConstantInt>(CV->getSplatValue()))
- return this->isValue(CI->getValue());
+ if (V->getType()->isVectorTy())
+ if (const Constant *C = dyn_cast<Constant>(V))
+ if (const ConstantInt *CI =
+ dyn_cast_or_null<ConstantInt>(C->getSplatValue()))
+ return this->isValue(CI->getValue());
return false;
}
};
-
+
/// api_pred_ty - This helper class is used to match scalar and vector constants
/// that satisfy a specified predicate, and bind them to an APInt.
template<typename Predicate>
@@ -175,27 +236,19 @@ struct api_pred_ty : public Predicate {
Res = &CI->getValue();
return true;
}
-
- // FIXME: remove.
- if (const ConstantVector *CV = dyn_cast<ConstantVector>(V))
- if (ConstantInt *CI = dyn_cast_or_null<ConstantInt>(CV->getSplatValue()))
- if (this->isValue(CI->getValue())) {
- Res = &CI->getValue();
- return true;
- }
-
- if (const ConstantDataVector *CV = dyn_cast<ConstantDataVector>(V))
- if (ConstantInt *CI = dyn_cast_or_null<ConstantInt>(CV->getSplatValue()))
- if (this->isValue(CI->getValue())) {
- Res = &CI->getValue();
- return true;
- }
+ if (V->getType()->isVectorTy())
+ if (const Constant *C = dyn_cast<Constant>(V))
+ if (ConstantInt *CI = dyn_cast_or_null<ConstantInt>(C->getSplatValue()))
+ if (this->isValue(CI->getValue())) {
+ Res = &CI->getValue();
+ return true;
+ }
return false;
}
};
-
-
+
+
struct is_one {
bool isValue(const APInt &C) { return C == 1; }
};
@@ -203,11 +256,11 @@ struct is_one {
/// m_One() - Match an integer 1 or a vector with all elements equal to 1.
inline cst_pred_ty<is_one> m_One() { return cst_pred_ty<is_one>(); }
inline api_pred_ty<is_one> m_One(const APInt *&V) { return V; }
-
+
struct is_all_ones {
bool isValue(const APInt &C) { return C.isAllOnesValue(); }
};
-
+
/// m_AllOnes() - Match an integer or vector with all bits set to true.
inline cst_pred_ty<is_all_ones> m_AllOnes() {return cst_pred_ty<is_all_ones>();}
inline api_pred_ty<is_all_ones> m_AllOnes(const APInt *&V) { return V; }
@@ -252,6 +305,9 @@ inline bind_ty<ConstantInt> m_ConstantInt(ConstantInt *&CI) { return CI; }
/// m_Constant - Match a Constant, capturing the value if we match.
inline bind_ty<Constant> m_Constant(Constant *&C) { return C; }
+/// m_ConstantFP - Match a ConstantFP, capturing the value if we match.
+inline bind_ty<ConstantFP> m_ConstantFP(ConstantFP *&C) { return C; }
+
/// specificval_ty - Match a specified Value*.
struct specificval_ty {
const Value *Val;
@@ -266,10 +322,35 @@ struct specificval_ty {
/// m_Specific - Match if we have a specific specified value.
inline specificval_ty m_Specific(const Value *V) { return V; }
+/// Match a specified floating point value or vector of all elements of that
+/// value.
+struct specific_fpval {
+ double Val;
+ specific_fpval(double V) : Val(V) {}
+
+ template<typename ITy>
+ bool match(ITy *V) {
+ if (const ConstantFP *CFP = dyn_cast<ConstantFP>(V))
+ return CFP->isExactlyValue(Val);
+ if (V->getType()->isVectorTy())
+ if (const Constant *C = dyn_cast<Constant>(V))
+ if (ConstantFP *CFP = dyn_cast_or_null<ConstantFP>(C->getSplatValue()))
+ return CFP->isExactlyValue(Val);
+ return false;
+ }
+};
+
+/// Match a specific floating point value or vector with all elements equal to
+/// the value.
+inline specific_fpval m_SpecificFP(double V) { return specific_fpval(V); }
+
+/// Match a float 1.0 or vector with all elements equal to 1.0.
+inline specific_fpval m_FPOne() { return m_SpecificFP(1.0); }
+
struct bind_const_intval_ty {
uint64_t &VR;
bind_const_intval_ty(uint64_t &V) : VR(V) {}
-
+
template<typename ITy>
bool match(ITy *V) {
if (ConstantInt *CV = dyn_cast<ConstantInt>(V))
@@ -284,7 +365,7 @@ struct bind_const_intval_ty {
/// m_ConstantInt - Match a ConstantInt and bind to its value. This does not
/// match ConstantInts wider than 64-bits.
inline bind_const_intval_ty m_ConstantInt(uint64_t &V) { return V; }
-
+
//===----------------------------------------------------------------------===//
// Matchers for specific binary operators.
//
@@ -583,7 +664,7 @@ inline CastClass_match<OpTy, Instruction::BitCast>
m_BitCast(const OpTy &Op) {
return CastClass_match<OpTy, Instruction::BitCast>(Op);
}
-
+
/// m_PtrToInt
template<typename OpTy>
inline CastClass_match<OpTy, Instruction::PtrToInt>
@@ -611,7 +692,7 @@ inline CastClass_match<OpTy, Instruction::ZExt>
m_ZExt(const OpTy &Op) {
return CastClass_match<OpTy, Instruction::ZExt>(Op);
}
-
+
//===----------------------------------------------------------------------===//
// Matchers for unary operators
@@ -700,6 +781,25 @@ inline fneg_match<LHS> m_FNeg(const LHS &L) { return L; }
// Matchers for control flow.
//
+struct br_match {
+ BasicBlock *&Succ;
+ br_match(BasicBlock *&Succ)
+ : Succ(Succ) {
+ }
+
+ template<typename OpTy>
+ bool match(OpTy *V) {
+ if (BranchInst *BI = dyn_cast<BranchInst>(V))
+ if (BI->isUnconditional()) {
+ Succ = BI->getSuccessor(0);
+ return true;
+ }
+ return false;
+ }
+};
+
+inline br_match m_UnconditionalBr(BasicBlock *&Succ) { return br_match(Succ); }
+
template<typename Cond_t>
struct brc_match {
Cond_t Cond;
@@ -818,6 +918,102 @@ m_UMin(const LHS &L, const RHS &R) {
return MaxMin_match<LHS, RHS, umin_pred_ty>(L, R);
}
+template<typename Opnd_t>
+struct Argument_match {
+ unsigned OpI;
+ Opnd_t Val;
+ Argument_match(unsigned OpIdx, const Opnd_t &V) : OpI(OpIdx), Val(V) { }
+
+ template<typename OpTy>
+ bool match(OpTy *V) {
+ CallSite CS(V);
+ return CS.isCall() && Val.match(CS.getArgument(OpI));
+ }
+};
+
+/// Match an argument
+template<unsigned OpI, typename Opnd_t>
+inline Argument_match<Opnd_t> m_Argument(const Opnd_t &Op) {
+ return Argument_match<Opnd_t>(OpI, Op);
+}
+
+/// Intrinsic matchers.
+struct IntrinsicID_match {
+ unsigned ID;
+ IntrinsicID_match(unsigned IntrID) : ID(IntrID) { }
+
+ template<typename OpTy>
+ bool match(OpTy *V) {
+ IntrinsicInst *II = dyn_cast<IntrinsicInst>(V);
+ return II && II->getIntrinsicID() == ID;
+ }
+};
+
+/// Intrinsic matches are combinations of ID matchers, and argument
+/// matchers. Higher arity matcher are defined recursively in terms of and-ing
+/// them with lower arity matchers. Here's some convenient typedefs for up to
+/// several arguments, and more can be added as needed
+template <typename T0 = void, typename T1 = void, typename T2 = void,
+ typename T3 = void, typename T4 = void, typename T5 = void,
+ typename T6 = void, typename T7 = void, typename T8 = void,
+ typename T9 = void, typename T10 = void> struct m_Intrinsic_Ty;
+template <typename T0>
+struct m_Intrinsic_Ty<T0> {
+ typedef match_combine_and<IntrinsicID_match, Argument_match<T0> > Ty;
+};
+template <typename T0, typename T1>
+struct m_Intrinsic_Ty<T0, T1> {
+ typedef match_combine_and<typename m_Intrinsic_Ty<T0>::Ty,
+ Argument_match<T1> > Ty;
+};
+template <typename T0, typename T1, typename T2>
+struct m_Intrinsic_Ty<T0, T1, T2> {
+ typedef match_combine_and<typename m_Intrinsic_Ty<T0, T1>::Ty,
+ Argument_match<T2> > Ty;
+};
+template <typename T0, typename T1, typename T2, typename T3>
+struct m_Intrinsic_Ty<T0, T1, T2, T3> {
+ typedef match_combine_and<typename m_Intrinsic_Ty<T0, T1, T2>::Ty,
+ Argument_match<T3> > Ty;
+};
+
+/// Match intrinsic calls like this:
+/// m_Intrinsic<Intrinsic::fabs>(m_Value(X))
+template <unsigned IntrID>
+inline IntrinsicID_match
+m_Intrinsic() { return IntrinsicID_match(IntrID); }
+
+template<unsigned IntrID, typename T0>
+inline typename m_Intrinsic_Ty<T0>::Ty
+m_Intrinsic(const T0 &Op0) {
+ return m_CombineAnd(m_Intrinsic<IntrID>(), m_Argument<0>(Op0));
+}
+
+template<unsigned IntrID, typename T0, typename T1>
+inline typename m_Intrinsic_Ty<T0, T1>::Ty
+m_Intrinsic(const T0 &Op0, const T1 &Op1) {
+ return m_CombineAnd(m_Intrinsic<IntrID>(Op0), m_Argument<1>(Op1));
+}
+
+template<unsigned IntrID, typename T0, typename T1, typename T2>
+inline typename m_Intrinsic_Ty<T0, T1, T2>::Ty
+m_Intrinsic(const T0 &Op0, const T1 &Op1, const T2 &Op2) {
+ return m_CombineAnd(m_Intrinsic<IntrID>(Op0, Op1), m_Argument<2>(Op2));
+}
+
+template<unsigned IntrID, typename T0, typename T1, typename T2, typename T3>
+inline typename m_Intrinsic_Ty<T0, T1, T2, T3>::Ty
+m_Intrinsic(const T0 &Op0, const T1 &Op1, const T2 &Op2, const T3 &Op3) {
+ return m_CombineAnd(m_Intrinsic<IntrID>(Op0, Op1, Op2), m_Argument<3>(Op3));
+}
+
+// Helper intrinsic matching specializations
+template<typename Opnd0>
+inline typename m_Intrinsic_Ty<Opnd0>::Ty
+m_BSwap(const Opnd0 &Op0) {
+ return m_Intrinsic<Intrinsic::bswap>(Op0);
+}
+
} // end namespace PatternMatch
} // end namespace llvm
diff --git a/include/llvm/Support/PredIteratorCache.h b/include/llvm/Support/PredIteratorCache.h
index bb66a8e..c5fb780 100644
--- a/include/llvm/Support/PredIteratorCache.h
+++ b/include/llvm/Support/PredIteratorCache.h
@@ -11,10 +11,10 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/Support/Allocator.h"
-#include "llvm/Support/CFG.h"
#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
diff --git a/include/llvm/Support/Process.h b/include/llvm/Support/Process.h
index 088897c..4256d4a 100644
--- a/include/llvm/Support/Process.h
+++ b/include/llvm/Support/Process.h
@@ -6,152 +6,246 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-//
-// This file declares the llvm::sys::Process class.
-//
+/// \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_SYSTEM_PROCESS_H
-#define LLVM_SYSTEM_PROCESS_H
+#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 {
- /// This class provides an abstraction for getting information about the
- /// currently executing process.
- /// @since 1.4
- /// @brief An abstraction for operating system processes.
- class Process {
- /// @name Accessors
- /// @{
- public:
- /// This static function will return the operating system's virtual memory
- /// page size.
- /// @returns The number of bytes in a virtual memory page.
- /// @brief Get the virtual memory page size
- static unsigned GetPageSize();
-
- /// 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.
- /// @brief Return process memory usage.
- static size_t GetMallocUsage();
-
- /// This static function will return the total memory usage of the
- /// process. This includes code, data, stack and mapped pages usage. Notei
- /// that the value returned here is not necessarily the Running Set Size,
- /// it is the total virtual memory usage, regardless of mapped state of
- /// that memory.
- static size_t GetTotalMemoryUsage();
-
- /// 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.
- static void GetTimeUsage(
- TimeValue& elapsed,
- ///< Returns the TimeValue::now() giving current time
- TimeValue& user_time,
- ///< Returns the current amount of user time for the process
- TimeValue& sys_time
- ///< Returns the current amount of system time for the process
- );
-
- /// 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();
- /// @}
- };
+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();
+};
+
}
}
diff --git a/include/llvm/Support/Program.h b/include/llvm/Support/Program.h
index 7c9a951..bf65011 100644
--- a/include/llvm/Support/Program.h
+++ b/include/llvm/Support/Program.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SYSTEM_PROGRAM_H
-#define LLVM_SYSTEM_PROGRAM_H
+#ifndef LLVM_SUPPORT_PROGRAM_H
+#define LLVM_SUPPORT_PROGRAM_H
#include "llvm/Support/Path.h"
@@ -39,14 +39,10 @@ namespace sys {
/// @name Methods
/// @{
- public:
Program();
~Program();
- /// Return process ID of this program.
- unsigned GetPid() const;
-
/// 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
@@ -103,17 +99,7 @@ namespace sys {
///< is non-empty upon return an error occurred while waiting.
);
- /// This function terminates the program.
- /// @returns true if an error occurred.
- /// @see Execute
- /// @brief Terminates the program.
- bool Kill
- ( 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 killing the
- ///< program.
- );
-
+ 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
@@ -139,7 +125,8 @@ namespace sys {
const sys::Path** redirects = 0,
unsigned secondsToWait = 0,
unsigned memoryLimit = 0,
- std::string* ErrMsg = 0);
+ std::string* ErrMsg = 0,
+ bool *ExecutionFailed = 0);
/// A convenience function equivalent to Program prg; prg.Execute(..);
/// @see Execute
diff --git a/include/llvm/Support/Recycler.h b/include/llvm/Support/Recycler.h
index fa6e189..bcc561d 100644
--- a/include/llvm/Support/Recycler.h
+++ b/include/llvm/Support/Recycler.h
@@ -22,6 +22,8 @@
namespace llvm {
+class BumpPtrAllocator;
+
/// PrintRecyclingAllocatorStats - Helper for RecyclingAllocator for
/// printing statistics.
///
@@ -87,6 +89,15 @@ public:
}
}
+ /// 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 &&
diff --git a/include/llvm/Support/Regex.h b/include/llvm/Support/Regex.h
index ffe09b1..82df2c6 100644
--- a/include/llvm/Support/Regex.h
+++ b/include/llvm/Support/Regex.h
@@ -7,7 +7,10 @@
//
//===----------------------------------------------------------------------===//
//
-// This file implements a POSIX regular expression matcher.
+// 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.
//
//===----------------------------------------------------------------------===//
@@ -33,12 +36,14 @@ namespace llvm {
/// 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
+ 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 POSIX Extended Regular Expression \p Regex.
- /// This implementation supports regexes and matching strings with embedded
- /// NUL characters.
+ /// Compiles the given regular expression \p Regex.
Regex(StringRef Regex, unsigned Flags = NoFlags);
~Regex();
diff --git a/include/llvm/Support/RegistryParser.h b/include/llvm/Support/RegistryParser.h
index 2cc5783..a6997b6 100644
--- a/include/llvm/Support/RegistryParser.h
+++ b/include/llvm/Support/RegistryParser.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SUPPORT_REGISTRY_PARSER_H
-#define LLVM_SUPPORT_REGISTRY_PARSER_H
+#ifndef LLVM_SUPPORT_REGISTRYPARSER_H
+#define LLVM_SUPPORT_REGISTRYPARSER_H
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Registry.h"
@@ -52,4 +52,4 @@ namespace llvm {
}
-#endif // LLVM_SUPPORT_REGISTRY_PARSER_H
+#endif // LLVM_SUPPORT_REGISTRYPARSER_H
diff --git a/include/llvm/Support/SMLoc.h b/include/llvm/Support/SMLoc.h
index 1bf810b..0906471 100644
--- a/include/llvm/Support/SMLoc.h
+++ b/include/llvm/Support/SMLoc.h
@@ -12,14 +12,14 @@
//
//===----------------------------------------------------------------------===//
-#ifndef SUPPORT_SMLOC_H
-#define SUPPORT_SMLOC_H
+#ifndef LLVM_SUPPORT_SMLOC_H
+#define LLVM_SUPPORT_SMLOC_H
#include <cassert>
namespace llvm {
-/// SMLoc - Represents a location in source code.
+/// Represents a location in source code.
class SMLoc {
const char *Ptr;
public:
@@ -39,9 +39,11 @@ public:
}
};
-/// SMRange - Represents a range in source code. Note that unlike standard STL
-/// ranges, the locations specified are considered to be *inclusive*. For
-/// example, [X,X] *does* include X, it isn't an empty range.
+/// 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;
diff --git a/include/llvm/Support/SaveAndRestore.h b/include/llvm/Support/SaveAndRestore.h
index ffa99b9..6330bec 100644
--- a/include/llvm/Support/SaveAndRestore.h
+++ b/include/llvm/Support/SaveAndRestore.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_ADT_SAVERESTORE
-#define LLVM_ADT_SAVERESTORE
+#ifndef LLVM_SUPPORT_SAVEANDRESTORE_H
+#define LLVM_SUPPORT_SAVEANDRESTORE_H
namespace llvm {
diff --git a/include/llvm/Support/Signals.h b/include/llvm/Support/Signals.h
index 634f4cf..465656b 100644
--- a/include/llvm/Support/Signals.h
+++ b/include/llvm/Support/Signals.h
@@ -12,10 +12,11 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SYSTEM_SIGNALS_H
-#define LLVM_SYSTEM_SIGNALS_H
+#ifndef LLVM_SUPPORT_SIGNALS_H
+#define LLVM_SUPPORT_SIGNALS_H
#include "llvm/Support/Path.h"
+#include <cstdio>
namespace llvm {
namespace sys {
@@ -38,6 +39,9 @@ namespace sys {
/// @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.
diff --git a/include/llvm/Support/Solaris.h b/include/llvm/Support/Solaris.h
index 57eee2c..6228c4b 100644
--- a/include/llvm/Support/Solaris.h
+++ b/include/llvm/Support/Solaris.h
@@ -11,8 +11,8 @@
*
*===----------------------------------------------------------------------===*/
-#ifndef LLVM_SYSTEM_SOLARIS_H
-#define LLVM_SYSTEM_SOLARIS_H
+#ifndef LLVM_SUPPORT_SOLARIS_H
+#define LLVM_SUPPORT_SOLARIS_H
#include <sys/types.h>
#include <sys/regset.h>
diff --git a/include/llvm/Support/SourceMgr.h b/include/llvm/Support/SourceMgr.h
index bcf95f2..02abf92 100644
--- a/include/llvm/Support/SourceMgr.h
+++ b/include/llvm/Support/SourceMgr.h
@@ -13,17 +13,20 @@
//
//===----------------------------------------------------------------------===//
-#ifndef SUPPORT_SOURCEMGR_H
-#define SUPPORT_SOURCEMGR_H
+#ifndef LLVM_SUPPORT_SOURCEMGR_H
+#define LLVM_SUPPORT_SOURCEMGR_H
-#include "llvm/Support/SMLoc.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;
@@ -95,6 +98,10 @@ public:
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;
@@ -139,6 +146,7 @@ public:
/// 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;
@@ -148,7 +156,8 @@ public:
/// @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>()) const;
+ 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
@@ -160,6 +169,38 @@ public:
};
+/// 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 {
@@ -170,35 +211,46 @@ class SMDiagnostic {
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(const std::string &filename, SourceMgr::DiagKind Knd,
- const std::string &Msg)
+ 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, const std::string &FN,
+ SMDiagnostic(const SourceMgr &sm, SMLoc L, StringRef FN,
int Line, int Col, SourceMgr::DiagKind Kind,
- const std::string &Msg, const std::string &LineStr,
- ArrayRef<std::pair<unsigned,unsigned> > Ranges);
+ 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; }
- const std::string &getFilename() const { return Filename; }
+ StringRef getFilename() const { return Filename; }
int getLineNo() const { return LineNo; }
int getColumnNo() const { return ColumnNo; }
SourceMgr::DiagKind getKind() const { return Kind; }
- const std::string &getMessage() const { return Message; }
- const std::string &getLineContents() const { return LineContents; }
- const std::vector<std::pair<unsigned, unsigned> > &getRanges() const {
+ StringRef getMessage() const { return Message; }
+ StringRef getLineContents() const { return LineContents; }
+ ArrayRef<std::pair<unsigned, unsigned> > getRanges() const {
return Ranges;
}
- void print(const char *ProgName, raw_ostream &S, bool ShowColors = true) const;
+
+ 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
diff --git a/include/llvm/Support/StreamableMemoryObject.h b/include/llvm/Support/StreamableMemoryObject.h
index a2b4bcb..3855485 100644
--- a/include/llvm/Support/StreamableMemoryObject.h
+++ b/include/llvm/Support/StreamableMemoryObject.h
@@ -8,13 +8,13 @@
//===----------------------------------------------------------------------===//
-#ifndef STREAMABLEMEMORYOBJECT_H_
-#define STREAMABLEMEMORYOBJECT_H_
+#ifndef LLVM_SUPPORT_STREAMABLEMEMORYOBJECT_H
+#define LLVM_SUPPORT_STREAMABLEMEMORYOBJECT_H
#include "llvm/ADT/OwningPtr.h"
#include "llvm/Support/Compiler.h"
-#include "llvm/Support/MemoryObject.h"
#include "llvm/Support/DataStream.h"
+#include "llvm/Support/MemoryObject.h"
#include <vector>
namespace llvm {
diff --git a/include/llvm/Support/StringPool.h b/include/llvm/Support/StringPool.h
index de05e0b..71adbc5 100644
--- a/include/llvm/Support/StringPool.h
+++ b/include/llvm/Support/StringPool.h
@@ -30,8 +30,8 @@
#define LLVM_SUPPORT_STRINGPOOL_H
#include "llvm/ADT/StringMap.h"
-#include <new>
#include <cassert>
+#include <new>
namespace llvm {
diff --git a/include/llvm/Support/SwapByteOrder.h b/include/llvm/Support/SwapByteOrder.h
index 6c0592c..e65f9cc 100644
--- a/include/llvm/Support/SwapByteOrder.h
+++ b/include/llvm/Support/SwapByteOrder.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SYSTEM_SWAP_BYTE_ORDER_H
-#define LLVM_SYSTEM_SWAP_BYTE_ORDER_H
+#ifndef LLVM_SUPPORT_SWAPBYTEORDER_H
+#define LLVM_SUPPORT_SWAPBYTEORDER_H
#include "llvm/Support/DataTypes.h"
#include <cstddef>
diff --git a/include/llvm/Support/TargetFolder.h b/include/llvm/Support/TargetFolder.h
index 45f7816..5c1978d 100644
--- a/include/llvm/Support/TargetFolder.h
+++ b/include/llvm/Support/TargetFolder.h
@@ -19,10 +19,10 @@
#ifndef LLVM_SUPPORT_TARGETFOLDER_H
#define LLVM_SUPPORT_TARGETFOLDER_H
-#include "llvm/Constants.h"
-#include "llvm/InstrTypes.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Analysis/ConstantFolding.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/InstrTypes.h"
namespace llvm {
diff --git a/include/llvm/Support/TargetRegistry.h b/include/llvm/Support/TargetRegistry.h
index ca58bfb..b06676d 100644
--- a/include/llvm/Support/TargetRegistry.h
+++ b/include/llvm/Support/TargetRegistry.h
@@ -19,10 +19,10 @@
#ifndef LLVM_SUPPORT_TARGETREGISTRY_H
#define LLVM_SUPPORT_TARGETREGISTRY_H
-#include "llvm/Support/CodeGen.h"
#include "llvm/ADT/Triple.h"
-#include <string>
+#include "llvm/Support/CodeGen.h"
#include <cassert>
+#include <string>
namespace llvm {
class AsmPrinter;
@@ -41,7 +41,6 @@ namespace llvm {
class MCRegisterInfo;
class MCStreamer;
class MCSubtargetInfo;
- class MCTargetAsmLexer;
class MCTargetAsmParser;
class TargetMachine;
class TargetOptions;
@@ -96,9 +95,6 @@ namespace llvm {
typedef MCAsmBackend *(*MCAsmBackendCtorTy)(const Target &T,
StringRef TT,
StringRef CPU);
- typedef MCTargetAsmLexer *(*MCAsmLexerCtorTy)(const Target &T,
- const MCRegisterInfo &MRI,
- const MCAsmInfo &MAI);
typedef MCTargetAsmParser *(*MCAsmParserCtorTy)(MCSubtargetInfo &STI,
MCAsmParser &P);
typedef MCDisassembler *(*MCDisassemblerCtorTy)(const Target &T,
@@ -182,10 +178,6 @@ namespace llvm {
/// MCAsmBackend, if registered.
MCAsmBackendCtorTy MCAsmBackendCtorFn;
- /// MCAsmLexerCtorFn - Construction function for this target's
- /// MCTargetAsmLexer, if registered.
- MCAsmLexerCtorTy MCAsmLexerCtorFn;
-
/// MCAsmParserCtorFn - Construction function for this target's
/// MCTargetAsmParser, if registered.
MCAsmParserCtorTy MCAsmParserCtorFn;
@@ -242,9 +234,6 @@ namespace llvm {
/// hasMCAsmBackend - Check if this target supports .o generation.
bool hasMCAsmBackend() const { return MCAsmBackendCtorFn != 0; }
- /// hasMCAsmLexer - Check if this target supports .s lexing.
- bool hasMCAsmLexer() const { return MCAsmLexerCtorFn != 0; }
-
/// hasAsmParser - Check if this target supports .s parsing.
bool hasMCAsmParser() const { return MCAsmParserCtorFn != 0; }
@@ -360,15 +349,6 @@ namespace llvm {
return MCAsmBackendCtorFn(*this, Triple, CPU);
}
- /// createMCAsmLexer - Create a target specific assembly lexer.
- ///
- MCTargetAsmLexer *createMCAsmLexer(const MCRegisterInfo &MRI,
- const MCAsmInfo &MAI) const {
- if (!MCAsmLexerCtorFn)
- return 0;
- return MCAsmLexerCtorFn(*this, MRI, MAI);
- }
-
/// createMCAsmParser - Create a target specific assembly parser.
///
/// \param Parser The target independent parser implementation to use for
@@ -676,20 +656,6 @@ namespace llvm {
T.MCAsmBackendCtorFn = Fn;
}
- /// RegisterMCAsmLexer - Register a MCTargetAsmLexer implementation for the
- /// given target.
- ///
- /// Clients are responsible for ensuring that registration doesn't occur
- /// while another thread is attempting to access the registry. Typically
- /// this is done by initializing all targets at program startup.
- ///
- /// @param T - The target being registered.
- /// @param Fn - A function to construct an MCAsmLexer for the target.
- static void RegisterMCAsmLexer(Target &T, Target::MCAsmLexerCtorTy Fn) {
- if (!T.MCAsmLexerCtorFn)
- T.MCAsmLexerCtorFn = Fn;
- }
-
/// RegisterMCAsmParser - Register a MCTargetAsmParser implementation for
/// the given target.
///
@@ -1070,28 +1036,6 @@ namespace llvm {
}
};
- /// RegisterMCAsmLexer - Helper template for registering a target specific
- /// assembly lexer, for use in the target machine initialization
- /// function. Usage:
- ///
- /// extern "C" void LLVMInitializeFooMCAsmLexer() {
- /// extern Target TheFooTarget;
- /// RegisterMCAsmLexer<FooMCAsmLexer> X(TheFooTarget);
- /// }
- template<class MCAsmLexerImpl>
- struct RegisterMCAsmLexer {
- RegisterMCAsmLexer(Target &T) {
- TargetRegistry::RegisterMCAsmLexer(T, &Allocator);
- }
-
- private:
- static MCTargetAsmLexer *Allocator(const Target &T,
- const MCRegisterInfo &MRI,
- const MCAsmInfo &MAI) {
- return new MCAsmLexerImpl(T, MRI, MAI);
- }
- };
-
/// RegisterMCAsmParser - Helper template for registering a target specific
/// assembly parser, for use in the target machine initialization
/// function. Usage:
diff --git a/include/llvm/Support/ThreadLocal.h b/include/llvm/Support/ThreadLocal.h
index 62ec90a..7518626 100644
--- a/include/llvm/Support/ThreadLocal.h
+++ b/include/llvm/Support/ThreadLocal.h
@@ -11,11 +11,11 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SYSTEM_THREAD_LOCAL_H
-#define LLVM_SYSTEM_THREAD_LOCAL_H
+#ifndef LLVM_SUPPORT_THREADLOCAL_H
+#define LLVM_SUPPORT_THREADLOCAL_H
-#include "llvm/Support/Threading.h"
#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/Threading.h"
#include <cassert>
namespace llvm {
diff --git a/include/llvm/Support/Threading.h b/include/llvm/Support/Threading.h
index 9017afb..a7e8774 100644
--- a/include/llvm/Support/Threading.h
+++ b/include/llvm/Support/Threading.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SYSTEM_THREADING_H
-#define LLVM_SYSTEM_THREADING_H
+#ifndef LLVM_SUPPORT_THREADING_H
+#define LLVM_SUPPORT_THREADING_H
namespace llvm {
/// llvm_start_multithreaded - Allocate and initialize structures needed to
diff --git a/include/llvm/Support/TimeValue.h b/include/llvm/Support/TimeValue.h
index e780b50..4b48b84 100644
--- a/include/llvm/Support/TimeValue.h
+++ b/include/llvm/Support/TimeValue.h
@@ -11,12 +11,12 @@
//
//===----------------------------------------------------------------------===//
+#ifndef LLVM_SUPPORT_TIMEVALUE_H
+#define LLVM_SUPPORT_TIMEVALUE_H
+
#include "llvm/Support/DataTypes.h"
#include <string>
-#ifndef LLVM_SYSTEM_TIMEVALUE_H
-#define LLVM_SYSTEM_TIMEVALUE_H
-
namespace llvm {
namespace sys {
/// This class is used where a precise fixed point in time is required. The
@@ -82,6 +82,9 @@ namespace sys {
/// @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
@@ -237,7 +240,7 @@ namespace sys {
/// 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_ - PosixZeroTime.seconds_;
+ uint64_t result = seconds_ - PosixZeroTimeSeconds;
result += nanos_ / NANOSECONDS_PER_POSIX_TICK;
return result;
}
@@ -245,14 +248,14 @@ namespace sys {
/// Converts the TimeValue into the corresponding number of seconds
/// since the epoch (00:00:00 Jan 1,1970).
uint64_t toEpochTime() const {
- return seconds_ - PosixZeroTime.seconds_;
+ 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_ - Win32ZeroTime.seconds_;
+ uint64_t result = seconds_ - Win32ZeroTimeSeconds;
result += nanos_ / NANOSECONDS_PER_WIN32_TICK;
return result;
}
@@ -261,7 +264,7 @@ namespace sys {
/// 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_ - PosixZeroTime.seconds_;
+ seconds = seconds_ - PosixZeroTimeSeconds;
nanos = nanos_;
}
@@ -328,7 +331,7 @@ namespace sys {
/// TimeValue and assigns that value to \p this.
/// @brief Convert seconds form PosixTime to TimeValue
void fromEpochTime( SecondsType seconds ) {
- seconds_ = seconds + PosixZeroTime.seconds_;
+ seconds_ = seconds + PosixZeroTimeSeconds;
nanos_ = 0;
this->normalize();
}
@@ -337,7 +340,7 @@ namespace sys {
/// 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 + Win32ZeroTime.seconds_;
+ this->seconds_ = win32Time / 10000000 + Win32ZeroTimeSeconds;
this->nanos_ = NanoSecondsType(win32Time % 10000000) * 100;
}
@@ -357,6 +360,9 @@ namespace sys {
/// 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;
/// @}
};
diff --git a/include/llvm/Support/Timer.h b/include/llvm/Support/Timer.h
index a741882..d009d7f 100644
--- a/include/llvm/Support/Timer.h
+++ b/include/llvm/Support/Timer.h
@@ -6,22 +6,17 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-//
-// This file defines three classes: Timer, TimeRegion, and TimerGroup,
-// documented below.
-//
-//===----------------------------------------------------------------------===//
#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 "llvm/ADT/StringRef.h"
#include <cassert>
#include <string>
-#include <vector>
#include <utility>
+#include <vector>
namespace llvm {
@@ -78,7 +73,7 @@ public:
/// 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 laster timer is destroyed, otherwise it is printed
+/// 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.
///
@@ -126,7 +121,7 @@ private:
/// 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 it's argument. When it is destroyed, it stops
+/// 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 {
diff --git a/include/llvm/Support/ToolOutputFile.h b/include/llvm/Support/ToolOutputFile.h
index 65b182a..b3b7c57 100644
--- a/include/llvm/Support/ToolOutputFile.h
+++ b/include/llvm/Support/ToolOutputFile.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SUPPORT_TOOL_OUTPUT_FILE_H
-#define LLVM_SUPPORT_TOOL_OUTPUT_FILE_H
+#ifndef LLVM_SUPPORT_TOOLOUTPUTFILE_H
+#define LLVM_SUPPORT_TOOLOUTPUTFILE_H
#include "llvm/Support/raw_ostream.h"
diff --git a/include/llvm/Support/Valgrind.h b/include/llvm/Support/Valgrind.h
index e147647..a1397db 100644
--- a/include/llvm/Support/Valgrind.h
+++ b/include/llvm/Support/Valgrind.h
@@ -16,8 +16,8 @@
#ifndef LLVM_SYSTEM_VALGRIND_H
#define LLVM_SYSTEM_VALGRIND_H
-#include "llvm/Support/Compiler.h"
#include "llvm/Config/llvm-config.h"
+#include "llvm/Support/Compiler.h"
#include <stddef.h>
#if LLVM_ENABLE_THREADS != 0 && !defined(NDEBUG)
diff --git a/include/llvm/Support/ValueHandle.h b/include/llvm/Support/ValueHandle.h
index dbcf0fd..b49341c 100644
--- a/include/llvm/Support/ValueHandle.h
+++ b/include/llvm/Support/ValueHandle.h
@@ -16,10 +16,11 @@
#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/ADT/PointerIntPair.h"
-#include "llvm/Value.h"
+#include "llvm/IR/Value.h"
namespace llvm {
class ValueHandleBase;
+template<typename From> struct simplify_type;
// ValueHandleBase** is only 4-byte aligned.
template<>
@@ -162,14 +163,12 @@ public:
// Specialize simplify_type to allow WeakVH to participate in
// dyn_cast, isa, etc.
-template<typename From> struct simplify_type;
-template<> struct simplify_type<const WeakVH> {
+template<> struct simplify_type<WeakVH> {
typedef Value* SimpleType;
- static SimpleType getSimplifiedValue(const WeakVH &WVH) {
- return static_cast<Value *>(WVH);
+ static SimpleType getSimplifiedValue(WeakVH &WVH) {
+ return WVH;
}
};
-template<> struct simplify_type<WeakVH> : public simplify_type<const WeakVH> {};
/// 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
@@ -236,18 +235,6 @@ public:
ValueTy &operator*() const { return *getValPtr(); }
};
-// Specialize simplify_type to allow AssertingVH to participate in
-// dyn_cast, isa, etc.
-template<typename From> struct simplify_type;
-template<> struct simplify_type<const AssertingVH<Value> > {
- typedef Value* SimpleType;
- static SimpleType getSimplifiedValue(const AssertingVH<Value> &AVH) {
- return static_cast<Value *>(AVH);
- }
-};
-template<> struct simplify_type<AssertingVH<Value> >
- : public simplify_type<const AssertingVH<Value> > {};
-
// Specialize DenseMapInfo to allow AssertingVH to participate in DenseMap.
template<typename T>
struct DenseMapInfo<AssertingVH<T> > {
@@ -345,18 +332,6 @@ public:
ValueTy &operator*() const { return *getValPtr(); }
};
-// Specialize simplify_type to allow TrackingVH to participate in
-// dyn_cast, isa, etc.
-template<typename From> struct simplify_type;
-template<> struct simplify_type<const TrackingVH<Value> > {
- typedef Value* SimpleType;
- static SimpleType getSimplifiedValue(const TrackingVH<Value> &AVH) {
- return static_cast<Value *>(AVH);
- }
-};
-template<> struct simplify_type<TrackingVH<Value> >
- : public simplify_type<const TrackingVH<Value> > {};
-
/// 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
@@ -399,18 +374,6 @@ public:
virtual void allUsesReplacedWith(Value *);
};
-// Specialize simplify_type to allow CallbackVH to participate in
-// dyn_cast, isa, etc.
-template<typename From> struct simplify_type;
-template<> struct simplify_type<const CallbackVH> {
- typedef Value* SimpleType;
- static SimpleType getSimplifiedValue(const CallbackVH &CVH) {
- return static_cast<Value *>(CVH);
- }
-};
-template<> struct simplify_type<CallbackVH>
- : public simplify_type<const CallbackVH> {};
-
} // End llvm namespace
#endif
diff --git a/include/llvm/Support/Watchdog.h b/include/llvm/Support/Watchdog.h
new file mode 100644
index 0000000..b58496b
--- /dev/null
+++ b/include/llvm/Support/Watchdog.h
@@ -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
diff --git a/include/llvm/Support/Win64EH.h b/include/llvm/Support/Win64EH.h
index 8d74e10..ecce713 100644
--- a/include/llvm/Support/Win64EH.h
+++ b/include/llvm/Support/Win64EH.h
@@ -17,6 +17,7 @@
#define LLVM_SUPPORT_WIN64EH_H
#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/Endian.h"
namespace llvm {
namespace Win64EH {
@@ -39,11 +40,17 @@ enum UnwindOpcodes {
/// or part thereof.
union UnwindCode {
struct {
- uint8_t codeOffset;
- uint8_t unwindOp:4,
- opInfo:4;
+ support::ulittle8_t CodeOffset;
+ support::ulittle8_t UnwindOpAndOpInfo;
} u;
- uint16_t frameOffset;
+ support::ulittle16_t FrameOffset;
+
+ uint8_t getUnwindOp() const {
+ return u.UnwindOpAndOpInfo & 0x0F;
+ }
+ uint8_t getOpInfo() const {
+ return (u.UnwindOpAndOpInfo >> 4) & 0x0F;
+ }
};
enum {
@@ -60,37 +67,75 @@ enum {
/// RuntimeFunction - An entry in the table of functions with unwind info.
struct RuntimeFunction {
- uint64_t startAddress;
- uint64_t endAddress;
- uint64_t unwindInfoOffset;
+ support::ulittle32_t StartAddress;
+ support::ulittle32_t EndAddress;
+ support::ulittle32_t UnwindInfoOffset;
};
/// UnwindInfo - An entry in the exception table.
struct UnwindInfo {
- uint8_t version:3,
- flags:5;
- uint8_t prologSize;
- uint8_t numCodes;
- uint8_t frameRegister:4,
- frameOffset:4;
- UnwindCode unwindCodes[1];
+ support::ulittle8_t VersionAndFlags;
+ support::ulittle8_t PrologSize;
+ support::ulittle8_t NumCodes;
+ support::ulittle8_t FrameRegisterAndOffset;
+ UnwindCode UnwindCodes[1];
+ uint8_t getVersion() const {
+ return VersionAndFlags & 0x07;
+ }
+ uint8_t getFlags() const {
+ return (VersionAndFlags >> 3) & 0x1f;
+ }
+ uint8_t getFrameRegister() const {
+ return FrameRegisterAndOffset & 0x0f;
+ }
+ uint8_t getFrameOffset() const {
+ return (FrameRegisterAndOffset >> 4) & 0x0f;
+ }
+
+ // The data after unwindCodes depends on flags.
+ // If UNW_ExceptionHandler or UNW_TerminateHandler is set then follows
+ // the address of the language-specific exception handler.
+ // If UNW_ChainInfo is set then follows a RuntimeFunction which defines
+ // the chained unwind info.
+ // For more information please see MSDN at:
+ // http://msdn.microsoft.com/en-us/library/ddssxxy8.aspx
+
+ /// \brief Return pointer to language specific data part of UnwindInfo.
void *getLanguageSpecificData() {
- return reinterpret_cast<void *>(&unwindCodes[(numCodes+1) & ~1]);
+ return reinterpret_cast<void *>(&UnwindCodes[(NumCodes+1) & ~1]);
}
- uint64_t getLanguageSpecificHandlerOffset() {
- return *reinterpret_cast<uint64_t *>(getLanguageSpecificData());
+
+ /// \brief Return pointer to language specific data part of UnwindInfo.
+ const void *getLanguageSpecificData() const {
+ return reinterpret_cast<const void *>(&UnwindCodes[(NumCodes+1) & ~1]);
}
- void setLanguageSpecificHandlerOffset(uint64_t offset) {
- *reinterpret_cast<uint64_t *>(getLanguageSpecificData()) = offset;
+
+ /// \brief Return image-relative offset of language-specific exception handler.
+ uint32_t getLanguageSpecificHandlerOffset() const {
+ return *reinterpret_cast<const uint32_t *>(getLanguageSpecificData());
}
- RuntimeFunction *getChainedFunctionEntry() {
- return reinterpret_cast<RuntimeFunction *>(getLanguageSpecificData());
+
+ /// \brief Set image-relative offset of language-specific exception handler.
+ void setLanguageSpecificHandlerOffset(uint32_t offset) {
+ *reinterpret_cast<uint32_t *>(getLanguageSpecificData()) = offset;
}
+
+ /// \brief Return pointer to exception-specific data.
void *getExceptionData() {
- return reinterpret_cast<void *>(reinterpret_cast<uint64_t *>(
+ return reinterpret_cast<void *>(reinterpret_cast<uint32_t *>(
getLanguageSpecificData())+1);
}
+
+ /// \brief Return pointer to chained unwind info.
+ RuntimeFunction *getChainedFunctionEntry() {
+ return reinterpret_cast<RuntimeFunction *>(getLanguageSpecificData());
+ }
+
+ /// \brief Return pointer to chained unwind info.
+ const RuntimeFunction *getChainedFunctionEntry() const {
+ return reinterpret_cast<const RuntimeFunction *>(getLanguageSpecificData());
+ }
};
diff --git a/include/llvm/Support/YAMLParser.h b/include/llvm/Support/YAMLParser.h
index 12958fa..6e4f57f 100644
--- a/include/llvm/Support/YAMLParser.h
+++ b/include/llvm/Support/YAMLParser.h
@@ -35,15 +35,14 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SUPPORT_YAML_PARSER_H
-#define LLVM_SUPPORT_YAML_PARSER_H
+#ifndef LLVM_SUPPORT_YAMLPARSER_H
+#define LLVM_SUPPORT_YAMLPARSER_H
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/SMLoc.h"
-
#include <limits>
#include <utility>
@@ -77,7 +76,11 @@ std::string escape(StringRef Input);
/// documents.
class Stream {
public:
+ /// @brief This keeps a reference to the string referenced by \p Input.
Stream(StringRef Input, SourceMgr &);
+
+ /// @brief This takes ownership of \p InputBuffer.
+ Stream(MemoryBuffer *InputBuffer, SourceMgr &);
~Stream();
document_iterator begin();
@@ -181,7 +184,7 @@ public:
: Node(NK_Scalar, D, Anchor)
, Value(Val) {
SMLoc Start = SMLoc::getFromPointer(Val.begin());
- SMLoc End = SMLoc::getFromPointer(Val.end() - 1);
+ SMLoc End = SMLoc::getFromPointer(Val.end());
SourceRange = SMRange(Start, End);
}
diff --git a/include/llvm/Support/YAMLTraits.h b/include/llvm/Support/YAMLTraits.h
new file mode 100644
index 0000000..801868f
--- /dev/null
+++ b/include/llvm/Support/YAMLTraits.h
@@ -0,0 +1,1104 @@
+//===- llvm/Supporrt/YAMLTraits.h -------------------------------*- C++ -*-===//
+//
+// The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_YAMLTRAITS_H
+#define LLVM_SUPPORT_YAMLTRAITS_H
+
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseMapInfo.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/YAMLParser.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/system_error.h"
+#include "llvm/Support/type_traits.h"
+
+
+namespace llvm {
+namespace yaml {
+
+
+/// This class should be specialized by any type that needs to be converted
+/// to/from a YAML mapping. For example:
+///
+/// struct ScalarBitSetTraits<MyStruct> {
+/// static void mapping(IO &io, MyStruct &s) {
+/// io.mapRequired("name", s.name);
+/// io.mapRequired("size", s.size);
+/// io.mapOptional("age", s.age);
+/// }
+/// };
+template<class T>
+struct MappingTraits {
+ // Must provide:
+ // static void mapping(IO &io, T &fields);
+};
+
+
+/// This class should be specialized by any integral type that converts
+/// to/from a YAML scalar where there is a one-to-one mapping between
+/// in-memory values and a string in YAML. For example:
+///
+/// struct ScalarEnumerationTraits<Colors> {
+/// static void enumeration(IO &io, Colors &value) {
+/// io.enumCase(value, "red", cRed);
+/// io.enumCase(value, "blue", cBlue);
+/// io.enumCase(value, "green", cGreen);
+/// }
+/// };
+template<typename T>
+struct ScalarEnumerationTraits {
+ // Must provide:
+ // static void enumeration(IO &io, T &value);
+};
+
+
+/// This class should be specialized by any integer type that is a union
+/// of bit values and the YAML representation is a flow sequence of
+/// strings. For example:
+///
+/// struct ScalarBitSetTraits<MyFlags> {
+/// static void bitset(IO &io, MyFlags &value) {
+/// io.bitSetCase(value, "big", flagBig);
+/// io.bitSetCase(value, "flat", flagFlat);
+/// io.bitSetCase(value, "round", flagRound);
+/// }
+/// };
+template<typename T>
+struct ScalarBitSetTraits {
+ // Must provide:
+ // static void bitset(IO &io, T &value);
+};
+
+
+/// This class should be specialized by type that requires custom conversion
+/// to/from a yaml scalar. For example:
+///
+/// template<>
+/// struct ScalarTraits<MyType> {
+/// static void output(const MyType &val, void*, llvm::raw_ostream &out) {
+/// // stream out custom formatting
+/// out << llvm::format("%x", val);
+/// }
+/// static StringRef input(StringRef scalar, void*, MyType &value) {
+/// // parse scalar and set `value`
+/// // return empty string on success, or error string
+/// return StringRef();
+/// }
+/// };
+template<typename T>
+struct ScalarTraits {
+ // Must provide:
+ //
+ // Function to write the value as a string:
+ //static void output(const T &value, void *ctxt, llvm::raw_ostream &out);
+ //
+ // Function to convert a string to a value. Returns the empty
+ // StringRef on success or an error string if string is malformed:
+ //static StringRef input(StringRef scalar, void *ctxt, T &value);
+};
+
+
+/// This class should be specialized by any type that needs to be converted
+/// to/from a YAML sequence. For example:
+///
+/// template<>
+/// struct SequenceTraits< std::vector<MyType> > {
+/// static size_t size(IO &io, std::vector<MyType> &seq) {
+/// return seq.size();
+/// }
+/// static MyType& element(IO &, std::vector<MyType> &seq, size_t index) {
+/// if ( index >= seq.size() )
+/// seq.resize(index+1);
+/// return seq[index];
+/// }
+/// };
+template<typename T>
+struct SequenceTraits {
+ // Must provide:
+ // static size_t size(IO &io, T &seq);
+ // static T::value_type& element(IO &io, T &seq, size_t index);
+ //
+ // The following is option and will cause generated YAML to use
+ // a flow sequence (e.g. [a,b,c]).
+ // static const bool flow = true;
+};
+
+
+/// This class should be specialized by any type that needs to be converted
+/// to/from a list of YAML documents.
+template<typename T>
+struct DocumentListTraits {
+ // Must provide:
+ // static size_t size(IO &io, T &seq);
+ // static T::value_type& element(IO &io, T &seq, size_t index);
+};
+
+
+// Only used by compiler if both template types are the same
+template <typename T, T>
+struct SameType;
+
+// Only used for better diagnostics of missing traits
+template <typename T>
+struct MissingTrait;
+
+
+
+// Test if ScalarEnumerationTraits<T> is defined on type T.
+template <class T>
+struct has_ScalarEnumerationTraits
+{
+ typedef void (*Signature_enumeration)(class IO&, T&);
+
+ template <typename U>
+ static char test(SameType<Signature_enumeration, &U::enumeration>*);
+
+ template <typename U>
+ static double test(...);
+
+public:
+ static bool const value = (sizeof(test<ScalarEnumerationTraits<T> >(0)) == 1);
+};
+
+
+// Test if ScalarBitSetTraits<T> is defined on type T.
+template <class T>
+struct has_ScalarBitSetTraits
+{
+ typedef void (*Signature_bitset)(class IO&, T&);
+
+ template <typename U>
+ static char test(SameType<Signature_bitset, &U::bitset>*);
+
+ template <typename U>
+ static double test(...);
+
+public:
+ static bool const value = (sizeof(test<ScalarBitSetTraits<T> >(0)) == 1);
+};
+
+
+// Test if ScalarTraits<T> is defined on type T.
+template <class T>
+struct has_ScalarTraits
+{
+ typedef StringRef (*Signature_input)(StringRef, void*, T&);
+ typedef void (*Signature_output)(const T&, void*, llvm::raw_ostream&);
+
+ template <typename U>
+ static char test(SameType<Signature_input, &U::input>*,
+ SameType<Signature_output, &U::output>*);
+
+ template <typename U>
+ static double test(...);
+
+public:
+ static bool const value = (sizeof(test<ScalarTraits<T> >(0,0)) == 1);
+};
+
+
+// Test if MappingTraits<T> is defined on type T.
+template <class T>
+struct has_MappingTraits
+{
+ typedef void (*Signature_mapping)(class IO&, T&);
+
+ template <typename U>
+ static char test(SameType<Signature_mapping, &U::mapping>*);
+
+ template <typename U>
+ static double test(...);
+
+public:
+ static bool const value = (sizeof(test<MappingTraits<T> >(0)) == 1);
+};
+
+
+// Test if SequenceTraits<T> is defined on type T.
+template <class T>
+struct has_SequenceMethodTraits
+{
+ typedef size_t (*Signature_size)(class IO&, T&);
+
+ template <typename U>
+ static char test(SameType<Signature_size, &U::size>*);
+
+ template <typename U>
+ static double test(...);
+
+public:
+ static bool const value = (sizeof(test<SequenceTraits<T> >(0)) == 1);
+};
+
+
+// has_FlowTraits<int> will cause an error with some compilers because
+// it subclasses int. Using this wrapper only instantiates the
+// real has_FlowTraits only if the template type is a class.
+template <typename T, bool Enabled = llvm::is_class<T>::value>
+class has_FlowTraits
+{
+public:
+ static const bool value = false;
+};
+
+// Some older gcc compilers don't support straight forward tests
+// for members, so test for ambiguity cause by the base and derived
+// classes both defining the member.
+template <class T>
+struct has_FlowTraits<T, true>
+{
+ struct Fallback { bool flow; };
+ struct Derived : T, Fallback { };
+
+ template<typename C>
+ static char (&f(SameType<bool Fallback::*, &C::flow>*))[1];
+
+ template<typename C>
+ static char (&f(...))[2];
+
+public:
+ static bool const value = sizeof(f<Derived>(0)) == 2;
+};
+
+
+
+// Test if SequenceTraits<T> is defined on type T
+template<typename T>
+struct has_SequenceTraits : public llvm::integral_constant<bool,
+ has_SequenceMethodTraits<T>::value > { };
+
+
+// Test if DocumentListTraits<T> is defined on type T
+template <class T>
+struct has_DocumentListTraits
+{
+ typedef size_t (*Signature_size)(class IO&, T&);
+
+ template <typename U>
+ static char test(SameType<Signature_size, &U::size>*);
+
+ template <typename U>
+ static double test(...);
+
+public:
+ static bool const value = (sizeof(test<DocumentListTraits<T> >(0)) == 1);
+};
+
+
+
+
+template<typename T>
+struct missingTraits : public llvm::integral_constant<bool,
+ !has_ScalarEnumerationTraits<T>::value
+ && !has_ScalarBitSetTraits<T>::value
+ && !has_ScalarTraits<T>::value
+ && !has_MappingTraits<T>::value
+ && !has_SequenceTraits<T>::value
+ && !has_DocumentListTraits<T>::value > {};
+
+
+// Base class for Input and Output.
+class IO {
+public:
+
+ IO(void *Ctxt=NULL);
+ virtual ~IO();
+
+ virtual bool outputting() = 0;
+
+ virtual unsigned beginSequence() = 0;
+ virtual bool preflightElement(unsigned, void *&) = 0;
+ virtual void postflightElement(void*) = 0;
+ virtual void endSequence() = 0;
+
+ virtual unsigned beginFlowSequence() = 0;
+ virtual bool preflightFlowElement(unsigned, void *&) = 0;
+ virtual void postflightFlowElement(void*) = 0;
+ virtual void endFlowSequence() = 0;
+
+ virtual void beginMapping() = 0;
+ virtual void endMapping() = 0;
+ virtual bool preflightKey(const char*, bool, bool, bool &, void *&) = 0;
+ virtual void postflightKey(void*) = 0;
+
+ virtual void beginEnumScalar() = 0;
+ virtual bool matchEnumScalar(const char*, bool) = 0;
+ virtual void endEnumScalar() = 0;
+
+ virtual bool beginBitSetScalar(bool &) = 0;
+ virtual bool bitSetMatch(const char*, bool) = 0;
+ virtual void endBitSetScalar() = 0;
+
+ virtual void scalarString(StringRef &) = 0;
+
+ virtual void setError(const Twine &) = 0;
+
+ template <typename T>
+ void enumCase(T &Val, const char* Str, const T ConstVal) {
+ if ( matchEnumScalar(Str, outputting() && Val == ConstVal) ) {
+ Val = ConstVal;
+ }
+ }
+
+ // allow anonymous enum values to be used with LLVM_YAML_STRONG_TYPEDEF
+ template <typename T>
+ void enumCase(T &Val, const char* Str, const uint32_t ConstVal) {
+ if ( matchEnumScalar(Str, outputting() && Val == static_cast<T>(ConstVal)) ) {
+ Val = ConstVal;
+ }
+ }
+
+ template <typename T>
+ void bitSetCase(T &Val, const char* Str, const T ConstVal) {
+ if ( bitSetMatch(Str, outputting() && (Val & ConstVal) == ConstVal) ) {
+ Val = Val | ConstVal;
+ }
+ }
+
+ // allow anonymous enum values to be used with LLVM_YAML_STRONG_TYPEDEF
+ template <typename T>
+ void bitSetCase(T &Val, const char* Str, const uint32_t ConstVal) {
+ if ( bitSetMatch(Str, outputting() && (Val & ConstVal) == ConstVal) ) {
+ Val = Val | ConstVal;
+ }
+ }
+
+ void *getContext();
+ void setContext(void *);
+
+ template <typename T>
+ void mapRequired(const char* Key, T& Val) {
+ this->processKey(Key, Val, true);
+ }
+
+ template <typename T>
+ typename llvm::enable_if_c<has_SequenceTraits<T>::value,void>::type
+ mapOptional(const char* Key, T& Val) {
+ // omit key/value instead of outputting empty sequence
+ if ( this->outputting() && !(Val.begin() != Val.end()) )
+ return;
+ this->processKey(Key, Val, false);
+ }
+
+ template <typename T>
+ typename llvm::enable_if_c<!has_SequenceTraits<T>::value,void>::type
+ mapOptional(const char* Key, T& Val) {
+ this->processKey(Key, Val, false);
+ }
+
+ template <typename T>
+ void mapOptional(const char* Key, T& Val, const T& Default) {
+ this->processKeyWithDefault(Key, Val, Default, false);
+ }
+
+
+private:
+ template <typename T>
+ void processKeyWithDefault(const char *Key, T &Val, const T& DefaultValue,
+ bool Required) {
+ void *SaveInfo;
+ bool UseDefault;
+ const bool sameAsDefault = outputting() && Val == DefaultValue;
+ if ( this->preflightKey(Key, Required, sameAsDefault, UseDefault,
+ SaveInfo) ) {
+ yamlize(*this, Val, Required);
+ this->postflightKey(SaveInfo);
+ }
+ else {
+ if ( UseDefault )
+ Val = DefaultValue;
+ }
+ }
+
+ template <typename T>
+ void processKey(const char *Key, T &Val, bool Required) {
+ void *SaveInfo;
+ bool UseDefault;
+ if ( this->preflightKey(Key, Required, false, UseDefault, SaveInfo) ) {
+ yamlize(*this, Val, Required);
+ this->postflightKey(SaveInfo);
+ }
+ }
+
+private:
+ void *Ctxt;
+};
+
+
+
+template<typename T>
+typename llvm::enable_if_c<has_ScalarEnumerationTraits<T>::value,void>::type
+yamlize(IO &io, T &Val, bool) {
+ io.beginEnumScalar();
+ ScalarEnumerationTraits<T>::enumeration(io, Val);
+ io.endEnumScalar();
+}
+
+template<typename T>
+typename llvm::enable_if_c<has_ScalarBitSetTraits<T>::value,void>::type
+yamlize(IO &io, T &Val, bool) {
+ bool DoClear;
+ if ( io.beginBitSetScalar(DoClear) ) {
+ if ( DoClear )
+ Val = static_cast<T>(0);
+ ScalarBitSetTraits<T>::bitset(io, Val);
+ io.endBitSetScalar();
+ }
+}
+
+
+template<typename T>
+typename llvm::enable_if_c<has_ScalarTraits<T>::value,void>::type
+yamlize(IO &io, T &Val, bool) {
+ if ( io.outputting() ) {
+ std::string Storage;
+ llvm::raw_string_ostream Buffer(Storage);
+ ScalarTraits<T>::output(Val, io.getContext(), Buffer);
+ StringRef Str = Buffer.str();
+ io.scalarString(Str);
+ }
+ else {
+ StringRef Str;
+ io.scalarString(Str);
+ StringRef Result = ScalarTraits<T>::input(Str, io.getContext(), Val);
+ if ( !Result.empty() ) {
+ io.setError(llvm::Twine(Result));
+ }
+ }
+}
+
+
+template<typename T>
+typename llvm::enable_if_c<has_MappingTraits<T>::value, void>::type
+yamlize(IO &io, T &Val, bool) {
+ io.beginMapping();
+ MappingTraits<T>::mapping(io, Val);
+ io.endMapping();
+}
+
+template<typename T>
+typename llvm::enable_if_c<missingTraits<T>::value, void>::type
+yamlize(IO &io, T &Val, bool) {
+ char missing_yaml_trait_for_type[sizeof(MissingTrait<T>)];
+}
+
+template<typename T>
+typename llvm::enable_if_c<has_SequenceTraits<T>::value,void>::type
+yamlize(IO &io, T &Seq, bool) {
+ if ( has_FlowTraits< SequenceTraits<T> >::value ) {
+ unsigned incnt = io.beginFlowSequence();
+ unsigned count = io.outputting() ? SequenceTraits<T>::size(io, Seq) : incnt;
+ for(unsigned i=0; i < count; ++i) {
+ void *SaveInfo;
+ if ( io.preflightFlowElement(i, SaveInfo) ) {
+ yamlize(io, SequenceTraits<T>::element(io, Seq, i), true);
+ io.postflightFlowElement(SaveInfo);
+ }
+ }
+ io.endFlowSequence();
+ }
+ else {
+ unsigned incnt = io.beginSequence();
+ unsigned count = io.outputting() ? SequenceTraits<T>::size(io, Seq) : incnt;
+ for(unsigned i=0; i < count; ++i) {
+ void *SaveInfo;
+ if ( io.preflightElement(i, SaveInfo) ) {
+ yamlize(io, SequenceTraits<T>::element(io, Seq, i), true);
+ io.postflightElement(SaveInfo);
+ }
+ }
+ io.endSequence();
+ }
+}
+
+
+template<>
+struct ScalarTraits<bool> {
+ static void output(const bool &, void*, llvm::raw_ostream &);
+ static StringRef input(StringRef, void*, bool &);
+};
+
+template<>
+struct ScalarTraits<StringRef> {
+ static void output(const StringRef &, void*, llvm::raw_ostream &);
+ static StringRef input(StringRef, void*, StringRef &);
+};
+
+template<>
+struct ScalarTraits<uint8_t> {
+ static void output(const uint8_t &, void*, llvm::raw_ostream &);
+ static StringRef input(StringRef, void*, uint8_t &);
+};
+
+template<>
+struct ScalarTraits<uint16_t> {
+ static void output(const uint16_t &, void*, llvm::raw_ostream &);
+ static StringRef input(StringRef, void*, uint16_t &);
+};
+
+template<>
+struct ScalarTraits<uint32_t> {
+ static void output(const uint32_t &, void*, llvm::raw_ostream &);
+ static StringRef input(StringRef, void*, uint32_t &);
+};
+
+template<>
+struct ScalarTraits<uint64_t> {
+ static void output(const uint64_t &, void*, llvm::raw_ostream &);
+ static StringRef input(StringRef, void*, uint64_t &);
+};
+
+template<>
+struct ScalarTraits<int8_t> {
+ static void output(const int8_t &, void*, llvm::raw_ostream &);
+ static StringRef input(StringRef, void*, int8_t &);
+};
+
+template<>
+struct ScalarTraits<int16_t> {
+ static void output(const int16_t &, void*, llvm::raw_ostream &);
+ static StringRef input(StringRef, void*, int16_t &);
+};
+
+template<>
+struct ScalarTraits<int32_t> {
+ static void output(const int32_t &, void*, llvm::raw_ostream &);
+ static StringRef input(StringRef, void*, int32_t &);
+};
+
+template<>
+struct ScalarTraits<int64_t> {
+ static void output(const int64_t &, void*, llvm::raw_ostream &);
+ static StringRef input(StringRef, void*, int64_t &);
+};
+
+template<>
+struct ScalarTraits<float> {
+ static void output(const float &, void*, llvm::raw_ostream &);
+ static StringRef input(StringRef, void*, float &);
+};
+
+template<>
+struct ScalarTraits<double> {
+ static void output(const double &, void*, llvm::raw_ostream &);
+ static StringRef input(StringRef, void*, double &);
+};
+
+
+
+// Utility for use within MappingTraits<>::mapping() method
+// to [de]normalize an object for use with YAML conversion.
+template <typename TNorm, typename TFinal>
+struct MappingNormalization {
+ MappingNormalization(IO &i_o, TFinal &Obj)
+ : io(i_o), BufPtr(NULL), Result(Obj) {
+ if ( io.outputting() ) {
+ BufPtr = new (&Buffer) TNorm(io, Obj);
+ }
+ else {
+ BufPtr = new (&Buffer) TNorm(io);
+ }
+ }
+
+ ~MappingNormalization() {
+ if ( ! io.outputting() ) {
+ Result = BufPtr->denormalize(io);
+ }
+ BufPtr->~TNorm();
+ }
+
+ TNorm* operator->() { return BufPtr; }
+
+private:
+ typedef llvm::AlignedCharArrayUnion<TNorm> Storage;
+
+ Storage Buffer;
+ IO &io;
+ TNorm *BufPtr;
+ TFinal &Result;
+};
+
+
+
+// Utility for use within MappingTraits<>::mapping() method
+// to [de]normalize an object for use with YAML conversion.
+template <typename TNorm, typename TFinal>
+struct MappingNormalizationHeap {
+ MappingNormalizationHeap(IO &i_o, TFinal &Obj)
+ : io(i_o), BufPtr(NULL), Result(Obj) {
+ if ( io.outputting() ) {
+ BufPtr = new (&Buffer) TNorm(io, Obj);
+ }
+ else {
+ BufPtr = new TNorm(io);
+ }
+ }
+
+ ~MappingNormalizationHeap() {
+ if ( io.outputting() ) {
+ BufPtr->~TNorm();
+ }
+ else {
+ Result = BufPtr->denormalize(io);
+ }
+ }
+
+ TNorm* operator->() { return BufPtr; }
+
+private:
+ typedef llvm::AlignedCharArrayUnion<TNorm> Storage;
+
+ Storage Buffer;
+ IO &io;
+ TNorm *BufPtr;
+ TFinal &Result;
+};
+
+
+
+///
+/// The Input class is used to parse a yaml document into in-memory structs
+/// and vectors.
+///
+/// It works by using YAMLParser to do a syntax parse of the entire yaml
+/// document, then the Input class builds a graph of HNodes which wraps
+/// each yaml Node. The extra layer is buffering. The low level yaml
+/// parser only lets you look at each node once. The buffering layer lets
+/// you search and interate multiple times. This is necessary because
+/// the mapRequired() method calls may not be in the same order
+/// as the keys in the document.
+///
+class Input : public IO {
+public:
+ // Construct a yaml Input object from a StringRef and optional user-data.
+ Input(StringRef InputContent, void *Ctxt=NULL);
+ ~Input();
+
+ // Check if there was an syntax or semantic error during parsing.
+ llvm::error_code error();
+
+ // To set alternate error reporting.
+ void setDiagHandler(llvm::SourceMgr::DiagHandlerTy Handler, void *Ctxt = 0);
+
+private:
+ virtual bool outputting();
+ virtual void beginMapping();
+ virtual void endMapping();
+ virtual bool preflightKey(const char *, bool, bool, bool &, void *&);
+ virtual void postflightKey(void *);
+ virtual unsigned beginSequence();
+ virtual void endSequence();
+ virtual bool preflightElement(unsigned index, void *&);
+ virtual void postflightElement(void *);
+ virtual unsigned beginFlowSequence();
+ virtual bool preflightFlowElement(unsigned , void *&);
+ virtual void postflightFlowElement(void *);
+ virtual void endFlowSequence();
+ virtual void beginEnumScalar();
+ virtual bool matchEnumScalar(const char*, bool);
+ virtual void endEnumScalar();
+ virtual bool beginBitSetScalar(bool &);
+ virtual bool bitSetMatch(const char *, bool );
+ virtual void endBitSetScalar();
+ virtual void scalarString(StringRef &);
+ virtual void setError(const Twine &message);
+
+ class HNode {
+ public:
+ HNode(Node *n) : _node(n) { }
+ virtual ~HNode() { }
+ static inline bool classof(const HNode *) { return true; }
+
+ Node *_node;
+ };
+
+ class EmptyHNode : public HNode {
+ public:
+ EmptyHNode(Node *n) : HNode(n) { }
+ virtual ~EmptyHNode() {}
+ static inline bool classof(const HNode *n) {
+ return NullNode::classof(n->_node);
+ }
+ static inline bool classof(const EmptyHNode *) { return true; }
+ };
+
+ class ScalarHNode : public HNode {
+ public:
+ ScalarHNode(Node *n, StringRef s) : HNode(n), _value(s) { }
+ virtual ~ScalarHNode() { }
+
+ StringRef value() const { return _value; }
+
+ static inline bool classof(const HNode *n) {
+ return ScalarNode::classof(n->_node);
+ }
+ static inline bool classof(const ScalarHNode *) { return true; }
+ protected:
+ StringRef _value;
+ };
+
+ class MapHNode : public HNode {
+ public:
+ MapHNode(Node *n) : HNode(n) { }
+ virtual ~MapHNode();
+
+ static inline bool classof(const HNode *n) {
+ return MappingNode::classof(n->_node);
+ }
+ static inline bool classof(const MapHNode *) { return true; }
+
+ struct StrMappingInfo {
+ static StringRef getEmptyKey() { return StringRef(); }
+ static StringRef getTombstoneKey() { return StringRef(" ", 0); }
+ static unsigned getHashValue(StringRef const val) {
+ return llvm::HashString(val); }
+ static bool isEqual(StringRef const lhs,
+ StringRef const rhs) { return lhs.equals(rhs); }
+ };
+ typedef llvm::DenseMap<StringRef, HNode*, StrMappingInfo> NameToNode;
+
+ bool isValidKey(StringRef key);
+
+ NameToNode Mapping;
+ llvm::SmallVector<const char*, 6> ValidKeys;
+ };
+
+ class SequenceHNode : public HNode {
+ public:
+ SequenceHNode(Node *n) : HNode(n) { }
+ virtual ~SequenceHNode();
+
+ static inline bool classof(const HNode *n) {
+ return SequenceNode::classof(n->_node);
+ }
+ static inline bool classof(const SequenceHNode *) { return true; }
+
+ std::vector<HNode*> Entries;
+ };
+
+ Input::HNode *createHNodes(Node *node);
+ void setError(HNode *hnode, const Twine &message);
+ void setError(Node *node, const Twine &message);
+
+
+public:
+ // These are only used by operator>>. They could be private
+ // if those templated things could be made friends.
+ bool setCurrentDocument();
+ void nextDocument();
+
+private:
+ llvm::SourceMgr SrcMgr; // must be before Strm
+ OwningPtr<llvm::yaml::Stream> Strm;
+ OwningPtr<HNode> TopNode;
+ llvm::error_code EC;
+ llvm::BumpPtrAllocator StringAllocator;
+ llvm::yaml::document_iterator DocIterator;
+ std::vector<bool> BitValuesUsed;
+ HNode *CurrentNode;
+ bool ScalarMatchFound;
+};
+
+
+
+
+///
+/// The Output class is used to generate a yaml document from in-memory structs
+/// and vectors.
+///
+class Output : public IO {
+public:
+ Output(llvm::raw_ostream &, void *Ctxt=NULL);
+ virtual ~Output();
+
+ virtual bool outputting();
+ virtual void beginMapping();
+ virtual void endMapping();
+ virtual bool preflightKey(const char *key, bool, bool, bool &, void *&);
+ virtual void postflightKey(void *);
+ virtual unsigned beginSequence();
+ virtual void endSequence();
+ virtual bool preflightElement(unsigned, void *&);
+ virtual void postflightElement(void *);
+ virtual unsigned beginFlowSequence();
+ virtual bool preflightFlowElement(unsigned, void *&);
+ virtual void postflightFlowElement(void *);
+ virtual void endFlowSequence();
+ virtual void beginEnumScalar();
+ virtual bool matchEnumScalar(const char*, bool);
+ virtual void endEnumScalar();
+ virtual bool beginBitSetScalar(bool &);
+ virtual bool bitSetMatch(const char *, bool );
+ virtual void endBitSetScalar();
+ virtual void scalarString(StringRef &);
+ virtual void setError(const Twine &message);
+
+public:
+ // These are only used by operator<<. They could be private
+ // if that templated operator could be made a friend.
+ void beginDocuments();
+ bool preflightDocument(unsigned);
+ void postflightDocument();
+ void endDocuments();
+
+private:
+ void output(StringRef s);
+ void outputUpToEndOfLine(StringRef s);
+ void newLineCheck();
+ void outputNewLine();
+ void paddedKey(StringRef key);
+
+ enum InState { inSeq, inFlowSeq, inMapFirstKey, inMapOtherKey };
+
+ llvm::raw_ostream &Out;
+ SmallVector<InState, 8> StateStack;
+ int Column;
+ int ColumnAtFlowStart;
+ bool NeedBitValueComma;
+ bool NeedFlowSequenceComma;
+ bool EnumerationMatchFound;
+ bool NeedsNewLine;
+};
+
+
+
+
+/// YAML I/O does conversion based on types. But often native data types
+/// are just a typedef of built in intergral types (e.g. int). But the C++
+/// type matching system sees through the typedef and all the typedefed types
+/// look like a built in type. This will cause the generic YAML I/O conversion
+/// to be used. To provide better control over the YAML conversion, you can
+/// use this macro instead of typedef. It will create a class with one field
+/// and automatic conversion operators to and from the base type.
+/// Based on BOOST_STRONG_TYPEDEF
+#define LLVM_YAML_STRONG_TYPEDEF(_base, _type) \
+ struct _type { \
+ _type() { } \
+ _type(const _base v) : value(v) { } \
+ _type(const _type &v) : value(v.value) {} \
+ _type &operator=(const _type &rhs) { value = rhs.value; return *this; }\
+ _type &operator=(const _base &rhs) { value = rhs; return *this; } \
+ operator const _base & () const { return value; } \
+ bool operator==(const _type &rhs) const { return value == rhs.value; } \
+ bool operator==(const _base &rhs) const { return value == rhs; } \
+ bool operator<(const _type &rhs) const { return value < rhs.value; } \
+ _base value; \
+ };
+
+
+
+///
+/// Use these types instead of uintXX_t in any mapping to have
+/// its yaml output formatted as hexadecimal.
+///
+LLVM_YAML_STRONG_TYPEDEF(uint8_t, Hex8)
+LLVM_YAML_STRONG_TYPEDEF(uint16_t, Hex16)
+LLVM_YAML_STRONG_TYPEDEF(uint32_t, Hex32)
+LLVM_YAML_STRONG_TYPEDEF(uint64_t, Hex64)
+
+
+template<>
+struct ScalarTraits<Hex8> {
+ static void output(const Hex8 &, void*, llvm::raw_ostream &);
+ static StringRef input(StringRef, void*, Hex8 &);
+};
+
+template<>
+struct ScalarTraits<Hex16> {
+ static void output(const Hex16 &, void*, llvm::raw_ostream &);
+ static StringRef input(StringRef, void*, Hex16 &);
+};
+
+template<>
+struct ScalarTraits<Hex32> {
+ static void output(const Hex32 &, void*, llvm::raw_ostream &);
+ static StringRef input(StringRef, void*, Hex32 &);
+};
+
+template<>
+struct ScalarTraits<Hex64> {
+ static void output(const Hex64 &, void*, llvm::raw_ostream &);
+ static StringRef input(StringRef, void*, Hex64 &);
+};
+
+
+// Define non-member operator>> so that Input can stream in a document list.
+template <typename T>
+inline
+typename llvm::enable_if_c<has_DocumentListTraits<T>::value,Input &>::type
+operator>>(Input &yin, T &docList) {
+ int i = 0;
+ while ( yin.setCurrentDocument() ) {
+ yamlize(yin, DocumentListTraits<T>::element(yin, docList, i), true);
+ if ( yin.error() )
+ return yin;
+ yin.nextDocument();
+ ++i;
+ }
+ return yin;
+}
+
+// Define non-member operator>> so that Input can stream in a map as a document.
+template <typename T>
+inline
+typename llvm::enable_if_c<has_MappingTraits<T>::value,Input &>::type
+operator>>(Input &yin, T &docMap) {
+ yin.setCurrentDocument();
+ yamlize(yin, docMap, true);
+ return yin;
+}
+
+// Define non-member operator>> so that Input can stream in a sequence as
+// a document.
+template <typename T>
+inline
+typename llvm::enable_if_c<has_SequenceTraits<T>::value,Input &>::type
+operator>>(Input &yin, T &docSeq) {
+ yin.setCurrentDocument();
+ yamlize(yin, docSeq, true);
+ return yin;
+}
+
+// Provide better error message about types missing a trait specialization
+template <typename T>
+inline
+typename llvm::enable_if_c<missingTraits<T>::value,Input &>::type
+operator>>(Input &yin, T &docSeq) {
+ char missing_yaml_trait_for_type[sizeof(MissingTrait<T>)];
+ return yin;
+}
+
+
+// Define non-member operator<< so that Output can stream out document list.
+template <typename T>
+inline
+typename llvm::enable_if_c<has_DocumentListTraits<T>::value,Output &>::type
+operator<<(Output &yout, T &docList) {
+ yout.beginDocuments();
+ const size_t count = DocumentListTraits<T>::size(yout, docList);
+ for(size_t i=0; i < count; ++i) {
+ if ( yout.preflightDocument(i) ) {
+ yamlize(yout, DocumentListTraits<T>::element(yout, docList, i), true);
+ yout.postflightDocument();
+ }
+ }
+ yout.endDocuments();
+ return yout;
+}
+
+// Define non-member operator<< so that Output can stream out a map.
+template <typename T>
+inline
+typename llvm::enable_if_c<has_MappingTraits<T>::value,Output &>::type
+operator<<(Output &yout, T &map) {
+ yout.beginDocuments();
+ if ( yout.preflightDocument(0) ) {
+ yamlize(yout, map, true);
+ yout.postflightDocument();
+ }
+ yout.endDocuments();
+ return yout;
+}
+
+// Define non-member operator<< so that Output can stream out a sequence.
+template <typename T>
+inline
+typename llvm::enable_if_c<has_SequenceTraits<T>::value,Output &>::type
+operator<<(Output &yout, T &seq) {
+ yout.beginDocuments();
+ if ( yout.preflightDocument(0) ) {
+ yamlize(yout, seq, true);
+ yout.postflightDocument();
+ }
+ yout.endDocuments();
+ return yout;
+}
+
+// Provide better error message about types missing a trait specialization
+template <typename T>
+inline
+typename llvm::enable_if_c<missingTraits<T>::value,Output &>::type
+operator<<(Output &yout, T &seq) {
+ char missing_yaml_trait_for_type[sizeof(MissingTrait<T>)];
+ return yout;
+}
+
+
+} // namespace yaml
+} // namespace llvm
+
+
+/// Utility for declaring that a std::vector of a particular type
+/// should be considered a YAML sequence.
+#define LLVM_YAML_IS_SEQUENCE_VECTOR(_type) \
+ namespace llvm { \
+ namespace yaml { \
+ template<> \
+ struct SequenceTraits< std::vector<_type> > { \
+ static size_t size(IO &io, std::vector<_type> &seq) { \
+ return seq.size(); \
+ } \
+ static _type& element(IO &io, std::vector<_type> &seq, size_t index) {\
+ if ( index >= seq.size() ) \
+ seq.resize(index+1); \
+ return seq[index]; \
+ } \
+ }; \
+ } \
+ }
+
+/// Utility for declaring that a std::vector of a particular type
+/// should be considered a YAML flow sequence.
+#define LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(_type) \
+ namespace llvm { \
+ namespace yaml { \
+ template<> \
+ struct SequenceTraits< std::vector<_type> > { \
+ static size_t size(IO &io, std::vector<_type> &seq) { \
+ return seq.size(); \
+ } \
+ static _type& element(IO &io, std::vector<_type> &seq, size_t index) {\
+ if ( index >= seq.size() ) \
+ seq.resize(index+1); \
+ return seq[index]; \
+ } \
+ static const bool flow = true; \
+ }; \
+ } \
+ }
+
+/// Utility for declaring that a std::vector of a particular type
+/// should be considered a YAML document list.
+#define LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(_type) \
+ namespace llvm { \
+ namespace yaml { \
+ template<> \
+ struct DocumentListTraits< std::vector<_type> > { \
+ static size_t size(IO &io, std::vector<_type> &seq) { \
+ return seq.size(); \
+ } \
+ static _type& element(IO &io, std::vector<_type> &seq, size_t index) {\
+ if ( index >= seq.size() ) \
+ seq.resize(index+1); \
+ return seq[index]; \
+ } \
+ }; \
+ } \
+ }
+
+
+
+#endif // LLVM_SUPPORT_YAMLTRAITS_H
diff --git a/include/llvm/Support/circular_raw_ostream.h b/include/llvm/Support/circular_raw_ostream.h
index 2823af3..9000306 100644
--- a/include/llvm/Support/circular_raw_ostream.h
+++ b/include/llvm/Support/circular_raw_ostream.h
@@ -71,7 +71,7 @@ namespace llvm
/// flushBuffer - Dump the contents of the buffer to Stream.
///
- void flushBuffer(void) {
+ void flushBuffer() {
if (Filled)
// Write the older portion of the buffer.
TheStream->write(Cur, BufferArray + BufferSize - Cur);
@@ -151,7 +151,7 @@ namespace llvm
/// flushBufferWithBanner - Force output of the buffer along with
/// a small header.
///
- void flushBufferWithBanner(void);
+ void flushBufferWithBanner();
private:
/// releaseStream - Delete the held stream if needed. Otherwise,
diff --git a/include/llvm/Support/raw_ostream.h b/include/llvm/Support/raw_ostream.h
index eab0f2d..d2b4a2a 100644
--- a/include/llvm/Support/raw_ostream.h
+++ b/include/llvm/Support/raw_ostream.h
@@ -29,7 +29,6 @@ namespace llvm {
/// a chunk at a time.
class raw_ostream {
private:
- // Do not implement. raw_ostream is noncopyable.
void operator=(const raw_ostream &) LLVM_DELETED_FUNCTION;
raw_ostream(const raw_ostream &) LLVM_DELETED_FUNCTION;
diff --git a/include/llvm/Support/system_error.h b/include/llvm/Support/system_error.h
index 0d164f6..43dace6 100644
--- a/include/llvm/Support/system_error.h
+++ b/include/llvm/Support/system_error.h
@@ -14,8 +14,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SYSTEM_SYSTEM_ERROR_H
-#define LLVM_SYSTEM_SYSTEM_ERROR_H
+#ifndef LLVM_SUPPORT_SYSTEM_ERROR_H
+#define LLVM_SUPPORT_SYSTEM_ERROR_H
#include "llvm/Support/Compiler.h"
diff --git a/include/llvm/Support/type_traits.h b/include/llvm/Support/type_traits.h
index f930639..906e97c 100644
--- a/include/llvm/Support/type_traits.h
+++ b/include/llvm/Support/type_traits.h
@@ -145,6 +145,10 @@ template <typename T> struct is_pointer<T* const> : true_type {};
template <typename T> struct is_pointer<T* volatile> : true_type {};
template <typename T> struct is_pointer<T* const volatile> : true_type {};
+/// \brief Metafunction that determines wheather the given type is a reference.
+template <typename T> struct is_reference : false_type {};
+template <typename T> struct is_reference<T&> : true_type {};
+
/// \brief Metafunction that determines whether the given type is either an
/// integral type or an enumeration type.
///
@@ -205,6 +209,26 @@ template <typename T> struct remove_pointer<T*volatile> { typedef T type; };
template <typename T> struct remove_pointer<T*const volatile> {
typedef T type; };
+// If T is a pointer, just return it. If it is not, return T&.
+template<typename T, typename Enable = void>
+struct add_lvalue_reference_if_not_pointer { typedef T &type; };
+
+template<typename T>
+struct add_lvalue_reference_if_not_pointer<T,
+ typename enable_if<is_pointer<T> >::type> {
+ typedef T type;
+};
+
+// If T is a pointer to X, return a pointer to const X. If it is not, return
+// const T.
+template<typename T, typename Enable = void>
+struct add_const_past_pointer { typedef const T type; };
+
+template<typename T>
+struct add_const_past_pointer<T, typename enable_if<is_pointer<T> >::type> {
+ typedef const typename remove_pointer<T>::type *type;
+};
+
template <bool, typename T, typename F>
struct conditional { typedef T type; };
OpenPOWER on IntegriCloud