aboutsummaryrefslogtreecommitdiffstats
path: root/include/llvm/Support
diff options
context:
space:
mode:
authorStephen Hines <srhines@google.com>2014-04-23 16:57:46 -0700
committerStephen Hines <srhines@google.com>2014-04-24 15:53:16 -0700
commit36b56886974eae4f9c5ebc96befd3e7bfe5de338 (patch)
treee6cfb69fbbd937f450eeb83bfb83b9da3b01275a /include/llvm/Support
parent69a8640022b04415ae9fac62f8ab090601d8f889 (diff)
downloadexternal_llvm-36b56886974eae4f9c5ebc96befd3e7bfe5de338.zip
external_llvm-36b56886974eae4f9c5ebc96befd3e7bfe5de338.tar.gz
external_llvm-36b56886974eae4f9c5ebc96befd3e7bfe5de338.tar.bz2
Update to LLVM 3.5a.
Change-Id: Ifadecab779f128e62e430c2b4f6ddd84953ed617
Diffstat (limited to 'include/llvm/Support')
-rw-r--r--include/llvm/Support/ARMBuildAttributes.h189
-rw-r--r--include/llvm/Support/ARMEHABI.h134
-rw-r--r--include/llvm/Support/AlignOf.h20
-rw-r--r--include/llvm/Support/Allocator.h332
-rw-r--r--include/llvm/Support/ArrayRecycler.h8
-rw-r--r--include/llvm/Support/BlockFrequency.h11
-rw-r--r--include/llvm/Support/CFG.h365
-rw-r--r--include/llvm/Support/COFF.h56
-rw-r--r--include/llvm/Support/CallSite.h330
-rw-r--r--include/llvm/Support/Casting.h32
-rw-r--r--include/llvm/Support/CommandLine.h141
-rw-r--r--include/llvm/Support/Compiler.h137
-rw-r--r--include/llvm/Support/Compression.h16
-rw-r--r--include/llvm/Support/ConstantFolder.h238
-rw-r--r--include/llvm/Support/ConstantRange.h277
-rw-r--r--include/llvm/Support/CrashRecoveryContext.h21
-rw-r--r--include/llvm/Support/DataFlow.h103
-rw-r--r--include/llvm/Support/DebugLoc.h114
-rw-r--r--include/llvm/Support/Dwarf.h48
-rw-r--r--include/llvm/Support/ELF.h111
-rw-r--r--include/llvm/Support/Endian.h13
-rw-r--r--include/llvm/Support/EndianStream.h39
-rw-r--r--include/llvm/Support/ErrorOr.h89
-rw-r--r--include/llvm/Support/FileOutputBuffer.h5
-rw-r--r--include/llvm/Support/FileSystem.h142
-rw-r--r--include/llvm/Support/FileUtilities.h6
-rw-r--r--include/llvm/Support/Format.h10
-rw-r--r--include/llvm/Support/FormattedStream.h22
-rw-r--r--include/llvm/Support/GCOV.h244
-rw-r--r--include/llvm/Support/GenericDomTree.h717
-rw-r--r--include/llvm/Support/GenericDomTreeConstruction.h289
-rw-r--r--include/llvm/Support/GetElementPtrTypeIterator.h113
-rw-r--r--include/llvm/Support/Host.h2
-rw-r--r--include/llvm/Support/InstIterator.h147
-rw-r--r--include/llvm/Support/LEB128.h6
-rw-r--r--include/llvm/Support/LeakDetector.h92
-rw-r--r--include/llvm/Support/LineIterator.h84
-rw-r--r--include/llvm/Support/MD5.h3
-rw-r--r--include/llvm/Support/MachO.h69
-rw-r--r--include/llvm/Support/MathExtras.h55
-rw-r--r--include/llvm/Support/Memory.h2
-rw-r--r--include/llvm/Support/MemoryBuffer.h24
-rw-r--r--include/llvm/Support/NoFolder.h298
-rw-r--r--include/llvm/Support/PassNameParser.h136
-rw-r--r--include/llvm/Support/Path.h6
-rw-r--r--include/llvm/Support/PatternMatch.h1121
-rw-r--r--include/llvm/Support/PredIteratorCache.h70
-rw-r--r--include/llvm/Support/PrettyStackTrace.h4
-rw-r--r--include/llvm/Support/Process.h10
-rw-r--r--include/llvm/Support/Program.h26
-rw-r--r--include/llvm/Support/Recycler.h11
-rw-r--r--include/llvm/Support/Regex.h15
-rw-r--r--include/llvm/Support/StreamableMemoryObject.h34
-rw-r--r--include/llvm/Support/StringRefMemoryObject.h8
-rw-r--r--include/llvm/Support/TargetFolder.h262
-rw-r--r--include/llvm/Support/TargetRegistry.h42
-rw-r--r--include/llvm/Support/TimeValue.h12
-rw-r--r--include/llvm/Support/ToolOutputFile.h2
-rw-r--r--include/llvm/Support/UnicodeCharRanges.h19
-rw-r--r--include/llvm/Support/Valgrind.h10
-rw-r--r--include/llvm/Support/ValueHandle.h380
-rw-r--r--include/llvm/Support/Win64EH.h8
-rw-r--r--include/llvm/Support/YAMLParser.h57
-rw-r--r--include/llvm/Support/YAMLTraits.h243
-rw-r--r--include/llvm/Support/circular_raw_ostream.h4
-rw-r--r--include/llvm/Support/raw_os_ostream.h4
-rw-r--r--include/llvm/Support/raw_ostream.h32
-rw-r--r--include/llvm/Support/system_error.h52
-rw-r--r--include/llvm/Support/type_traits.h196
69 files changed, 2832 insertions, 5086 deletions
diff --git a/include/llvm/Support/ARMBuildAttributes.h b/include/llvm/Support/ARMBuildAttributes.h
new file mode 100644
index 0000000..69732fc
--- /dev/null
+++ b/include/llvm/Support/ARMBuildAttributes.h
@@ -0,0 +1,189 @@
+//===-- ARMBuildAttributes.h - ARM Build Attributes -------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains enumerations and support routines for ARM build attributes
+// as defined in ARM ABI addenda document (ABI release 2.08).
+//
+// ELF for the ARM Architecture r2.09 - November 30, 2012
+//
+// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0044e/IHI0044E_aaelf.pdf
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_ARM_BUILD_ATTRIBUTES_H
+#define LLVM_SUPPORT_ARM_BUILD_ATTRIBUTES_H
+
+namespace llvm {
+class StringRef;
+
+namespace ARMBuildAttrs {
+
+enum SpecialAttr {
+ // This is for the .cpu asm attr. It translates into one or more
+ // AttrType (below) entries in the .ARM.attributes section in the ELF.
+ SEL_CPU
+};
+
+enum AttrType {
+ // Rest correspond to ELF/.ARM.attributes
+ File = 1,
+ CPU_raw_name = 4,
+ CPU_name = 5,
+ CPU_arch = 6,
+ CPU_arch_profile = 7,
+ ARM_ISA_use = 8,
+ THUMB_ISA_use = 9,
+ FP_arch = 10,
+ WMMX_arch = 11,
+ Advanced_SIMD_arch = 12,
+ PCS_config = 13,
+ ABI_PCS_R9_use = 14,
+ ABI_PCS_RW_data = 15,
+ ABI_PCS_RO_data = 16,
+ ABI_PCS_GOT_use = 17,
+ ABI_PCS_wchar_t = 18,
+ ABI_FP_rounding = 19,
+ ABI_FP_denormal = 20,
+ ABI_FP_exceptions = 21,
+ ABI_FP_user_exceptions = 22,
+ ABI_FP_number_model = 23,
+ ABI_align_needed = 24,
+ ABI_align_preserved = 25,
+ ABI_enum_size = 26,
+ ABI_HardFP_use = 27,
+ ABI_VFP_args = 28,
+ ABI_WMMX_args = 29,
+ ABI_optimization_goals = 30,
+ ABI_FP_optimization_goals = 31,
+ compatibility = 32,
+ CPU_unaligned_access = 34,
+ FP_HP_extension = 36,
+ ABI_FP_16bit_format = 38,
+ MPextension_use = 42, // recoded from 70 (ABI r2.08)
+ DIV_use = 44,
+ also_compatible_with = 65,
+ conformance = 67,
+ Virtualization_use = 68,
+
+ /// Legacy Tags
+ Section = 2, // deprecated (ABI r2.09)
+ Symbol = 3, // deprecated (ABI r2.09)
+ ABI_align8_needed = 24, // renamed to ABI_align_needed (ABI r2.09)
+ ABI_align8_preserved = 25, // renamed to ABI_align_preserved (ABI r2.09)
+ nodefaults = 64, // deprecated (ABI r2.09)
+ T2EE_use = 66, // deprecated (ABI r2.09)
+ MPextension_use_old = 70 // recoded to MPextension_use (ABI r2.08)
+};
+
+StringRef AttrTypeAsString(unsigned Attr, bool HasTagPrefix = true);
+StringRef AttrTypeAsString(AttrType Attr, bool HasTagPrefix = true);
+int AttrTypeFromString(StringRef Tag);
+
+// Magic numbers for .ARM.attributes
+enum AttrMagic {
+ Format_Version = 0x41
+};
+
+// Legal Values for CPU_arch, (=6), uleb128
+enum CPUArch {
+ Pre_v4 = 0,
+ v4 = 1, // e.g. SA110
+ v4T = 2, // e.g. ARM7TDMI
+ v5T = 3, // e.g. ARM9TDMI
+ v5TE = 4, // e.g. ARM946E_S
+ v5TEJ = 5, // e.g. ARM926EJ_S
+ v6 = 6, // e.g. ARM1136J_S
+ v6KZ = 7, // e.g. ARM1176JZ_S
+ v6T2 = 8, // e.g. ARM1156T2F_S
+ v6K = 9, // e.g. ARM1136J_S
+ v7 = 10, // e.g. Cortex A8, Cortex M3
+ v6_M = 11, // e.g. Cortex M1
+ v6S_M = 12, // v6_M with the System extensions
+ v7E_M = 13, // v7_M with DSP extensions
+ v8 = 14 // v8, AArch32
+};
+
+enum CPUArchProfile { // (=7), uleb128
+ Not_Applicable = 0, // pre v7, or cross-profile code
+ ApplicationProfile = (0x41), // 'A' (e.g. for Cortex A8)
+ RealTimeProfile = (0x52), // 'R' (e.g. for Cortex R4)
+ MicroControllerProfile = (0x4D), // 'M' (e.g. for Cortex M3)
+ SystemProfile = (0x53) // 'S' Application or real-time profile
+};
+
+// The following have a lot of common use cases
+enum {
+ Not_Allowed = 0,
+ Allowed = 1,
+
+ // Tag_ARM_ISA_use (=8), uleb128
+
+ // Tag_THUMB_ISA_use, (=9), uleb128
+ AllowThumb32 = 2, // 32-bit Thumb (implies 16-bit instructions)
+
+ // Tag_FP_arch (=10), uleb128 (formerly Tag_VFP_arch = 10)
+ AllowFPv2 = 2, // v2 FP ISA permitted (implies use of the v1 FP ISA)
+ AllowFPv3A = 3, // v3 FP ISA permitted (implies use of the v2 FP ISA)
+ AllowFPv3B = 4, // v3 FP ISA permitted, but only D0-D15, S0-S31
+ AllowFPv4A = 5, // v4 FP ISA permitted (implies use of v3 FP ISA)
+ AllowFPv4B = 6, // v4 FP ISA was permitted, but only D0-D15, S0-S31
+ AllowFPARMv8A = 7, // Use of the ARM v8-A FP ISA was permitted
+ AllowFPARMv8B = 8, // Use of the ARM v8-A FP ISA was permitted, but only
+ // D0-D15, S0-S31
+
+ // Tag_WMMX_arch, (=11), uleb128
+ AllowWMMXv1 = 1, // The user permitted this entity to use WMMX v1
+ AllowWMMXv2 = 2, // The user permitted this entity to use WMMX v2
+
+ // Tag_Advanced_SIMD_arch, (=12), uleb128
+ AllowNeon = 1, // SIMDv1 was permitted
+ AllowNeon2 = 2, // SIMDv2 was permitted (Half-precision FP, MAC operations)
+ AllowNeonARMv8 = 3, // ARM v8-A SIMD was permitted
+
+ // Tag_ABI_FP_denormal, (=20), uleb128
+ PreserveFPSign = 2, // sign when flushed-to-zero is preserved
+
+ // Tag_ABI_FP_number_model, (=23), uleb128
+ AllowRTABI = 2, // numbers, infinities, and one quiet NaN (see [RTABI])
+ AllowIEE754 = 3, // this code to use all the IEEE 754-defined FP encodings
+
+ // Tag_ABI_HardFP_use, (=27), uleb128
+ HardFPImplied = 0, // FP use should be implied by Tag_FP_arch
+ HardFPSinglePrecision = 1, // Single-precision only
+
+ // Tag_ABI_VFP_args, (=28), uleb128
+ BaseAAPCS = 0,
+ HardFPAAPCS = 1,
+
+ // Tag_FP_HP_extension, (=36), uleb128
+ AllowHPFP = 1, // Allow use of Half Precision FP
+
+ // Tag_MPextension_use, (=42), uleb128
+ AllowMP = 1, // Allow use of MP extensions
+
+ // Tag_DIV_use, (=44), uleb128
+ // Note: AllowDIVExt must be emitted if and only if the permission to use
+ // hardware divide cannot be conveyed using AllowDIVIfExists or DisallowDIV
+ AllowDIVIfExists = 0, // Allow hardware divide if available in arch, or no
+ // info exists.
+ DisallowDIV = 1, // Hardware divide explicitly disallowed.
+ AllowDIVExt = 2, // Allow hardware divide as optional architecture
+ // extension above the base arch specified by
+ // Tag_CPU_arch and Tag_CPU_arch_profile.
+
+ // Tag_Virtualization_use, (=68), uleb128
+ AllowTZ = 1,
+ AllowVirtualization = 2,
+ AllowTZVirtualization = 3
+};
+
+} // namespace ARMBuildAttrs
+} // namespace llvm
+
+#endif // LLVM_SUPPORT_ARM_BUILD_ATTRIBUTES_H
diff --git a/include/llvm/Support/ARMEHABI.h b/include/llvm/Support/ARMEHABI.h
new file mode 100644
index 0000000..c7ac54a
--- /dev/null
+++ b/include/llvm/Support/ARMEHABI.h
@@ -0,0 +1,134 @@
+//===--- ARMEHABI.h - ARM Exception Handling ABI ----------------*- 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 constants for the ARM unwind opcodes and exception
+// handling table entry kinds.
+//
+// The enumerations and constants in this file reflect the ARM EHABI
+// Specification as published by ARM.
+//
+// Exception Handling ABI for the ARM Architecture r2.09 - November 30, 2012
+//
+// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0038a/IHI0038A_ehabi.pdf
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_ARM_EHABI_H
+#define LLVM_SUPPORT_ARM_EHABI_H
+
+namespace llvm {
+namespace ARM {
+namespace EHABI {
+ /// ARM exception handling table entry kinds
+ enum EHTEntryKind {
+ EHT_GENERIC = 0x00,
+ EHT_COMPACT = 0x80
+ };
+
+ enum {
+ /// Special entry for the function never unwind
+ EXIDX_CANTUNWIND = 0x1
+ };
+
+ /// ARM-defined frame unwinding opcodes
+ enum UnwindOpcodes {
+ // Format: 00xxxxxx
+ // Purpose: vsp = vsp + ((x << 2) + 4)
+ UNWIND_OPCODE_INC_VSP = 0x00,
+
+ // Format: 01xxxxxx
+ // Purpose: vsp = vsp - ((x << 2) + 4)
+ UNWIND_OPCODE_DEC_VSP = 0x40,
+
+ // Format: 10000000 00000000
+ // Purpose: refuse to unwind
+ UNWIND_OPCODE_REFUSE = 0x8000,
+
+ // Format: 1000xxxx xxxxxxxx
+ // Purpose: pop r[15:12], r[11:4]
+ // Constraint: x != 0
+ UNWIND_OPCODE_POP_REG_MASK_R4 = 0x8000,
+
+ // Format: 1001xxxx
+ // Purpose: vsp = r[x]
+ // Constraint: x != 13 && x != 15
+ UNWIND_OPCODE_SET_VSP = 0x90,
+
+ // Format: 10100xxx
+ // Purpose: pop r[(4+x):4]
+ UNWIND_OPCODE_POP_REG_RANGE_R4 = 0xa0,
+
+ // Format: 10101xxx
+ // Purpose: pop r14, r[(4+x):4]
+ UNWIND_OPCODE_POP_REG_RANGE_R4_R14 = 0xa8,
+
+ // Format: 10110000
+ // Purpose: finish
+ UNWIND_OPCODE_FINISH = 0xb0,
+
+ // Format: 10110001 0000xxxx
+ // Purpose: pop r[3:0]
+ // Constraint: x != 0
+ UNWIND_OPCODE_POP_REG_MASK = 0xb100,
+
+ // Format: 10110010 x(uleb128)
+ // Purpose: vsp = vsp + ((x << 2) + 0x204)
+ UNWIND_OPCODE_INC_VSP_ULEB128 = 0xb2,
+
+ // Format: 10110011 xxxxyyyy
+ // Purpose: pop d[(x+y):x]
+ UNWIND_OPCODE_POP_VFP_REG_RANGE_FSTMFDX = 0xb300,
+
+ // Format: 10111xxx
+ // Purpose: pop d[(8+x):8]
+ UNWIND_OPCODE_POP_VFP_REG_RANGE_FSTMFDX_D8 = 0xb8,
+
+ // Format: 11000xxx
+ // Purpose: pop wR[(10+x):10]
+ UNWIND_OPCODE_POP_WIRELESS_MMX_REG_RANGE_WR10 = 0xc0,
+
+ // Format: 11000110 xxxxyyyy
+ // Purpose: pop wR[(x+y):x]
+ UNWIND_OPCODE_POP_WIRELESS_MMX_REG_RANGE = 0xc600,
+
+ // Format: 11000111 0000xxxx
+ // Purpose: pop wCGR[3:0]
+ // Constraint: x != 0
+ UNWIND_OPCODE_POP_WIRELESS_MMX_REG_MASK = 0xc700,
+
+ // Format: 11001000 xxxxyyyy
+ // Purpose: pop d[(16+x+y):(16+x)]
+ UNWIND_OPCODE_POP_VFP_REG_RANGE_FSTMFDD_D16 = 0xc800,
+
+ // Format: 11001001 xxxxyyyy
+ // Purpose: pop d[(x+y):x]
+ UNWIND_OPCODE_POP_VFP_REG_RANGE_FSTMFDD = 0xc900,
+
+ // Format: 11010xxx
+ // Purpose: pop d[(8+x):8]
+ UNWIND_OPCODE_POP_VFP_REG_RANGE_FSTMFDD_D8 = 0xd0
+ };
+
+ /// ARM-defined Personality Routine Index
+ enum PersonalityRoutineIndex {
+ // To make the exception handling table become more compact, ARM defined
+ // several personality routines in EHABI. There are 3 different
+ // personality routines in ARM EHABI currently. It is possible to have 16
+ // pre-defined personality routines at most.
+ AEABI_UNWIND_CPP_PR0 = 0,
+ AEABI_UNWIND_CPP_PR1 = 1,
+ AEABI_UNWIND_CPP_PR2 = 2,
+
+ NUM_PERSONALITY_INDEX
+ };
+}
+}
+}
+
+#endif // ARM_UNWIND_OP_H
diff --git a/include/llvm/Support/AlignOf.h b/include/llvm/Support/AlignOf.h
index bba3424..061d5ac 100644
--- a/include/llvm/Support/AlignOf.h
+++ b/include/llvm/Support/AlignOf.h
@@ -170,19 +170,22 @@ LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(128)
namespace detail {
template <typename T1,
typename T2 = char, typename T3 = char, typename T4 = char,
- typename T5 = char, typename T6 = char, typename T7 = char>
+ typename T5 = char, typename T6 = char, typename T7 = char,
+ typename T8 = char, typename T9 = char, typename T10 = char>
class AlignerImpl {
- T1 t1; T2 t2; T3 t3; T4 t4; T5 t5; T6 t6; T7 t7;
+ T1 t1; T2 t2; T3 t3; T4 t4; T5 t5; T6 t6; T7 t7; T8 t8; T9 t9; T10 t10;
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>
+ typename T5 = char, typename T6 = char, typename T7 = char,
+ typename T8 = char, typename T9 = char, typename T10 = 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)];
+ arr5[sizeof(T5)], arr6[sizeof(T6)], arr7[sizeof(T7)], arr8[sizeof(T8)],
+ arr9[sizeof(T9)], arr10[sizeof(T10)];
};
} // end namespace detail
@@ -195,10 +198,13 @@ union SizerImpl {
/// be added at the cost of more boiler plate.
template <typename T1,
typename T2 = char, typename T3 = char, typename T4 = char,
- typename T5 = char, typename T6 = char, typename T7 = char>
+ typename T5 = char, typename T6 = char, typename T7 = char,
+ typename T8 = char, typename T9 = char, typename T10 = 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>)> {
+ AlignOf<detail::AlignerImpl<T1, T2, T3, T4, T5,
+ T6, T7, T8, T9, T10> >::Alignment,
+ sizeof(detail::SizerImpl<T1, T2, T3, T4, T5,
+ T6, T7, T8, T9, T10>)> {
};
} // end namespace llvm
#endif
diff --git a/include/llvm/Support/Allocator.h b/include/llvm/Support/Allocator.h
index 397f50f..0641322 100644
--- a/include/llvm/Support/Allocator.h
+++ b/include/llvm/Support/Allocator.h
@@ -17,14 +17,19 @@
#include "llvm/Support/AlignOf.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/Memory.h"
#include <algorithm>
#include <cassert>
#include <cstddef>
#include <cstdlib>
namespace llvm {
-template <typename T> struct ReferenceAdder { typedef T& result; };
-template <typename T> struct ReferenceAdder<T&> { typedef T result; };
+template <typename T> struct ReferenceAdder {
+ typedef T &result;
+};
+template <typename T> struct ReferenceAdder<T &> {
+ typedef T result;
+};
class MallocAllocator {
public:
@@ -35,15 +40,15 @@ public:
void *Allocate(size_t Size, size_t /*Alignment*/) { return malloc(Size); }
- template <typename T>
- T *Allocate() { return static_cast<T*>(malloc(sizeof(T))); }
+ template <typename T> T *Allocate() {
+ return static_cast<T *>(malloc(sizeof(T)));
+ }
- template <typename T>
- T *Allocate(size_t Num) {
- return static_cast<T*>(malloc(sizeof(T)*Num));
+ template <typename T> T *Allocate(size_t Num) {
+ return static_cast<T *>(malloc(sizeof(T) * Num));
}
- void Deallocate(const void *Ptr) { free(const_cast<void*>(Ptr)); }
+ void Deallocate(const void *Ptr) { free(const_cast<void *>(Ptr)); }
void PrintStats() const {}
};
@@ -77,128 +82,224 @@ class MallocSlabAllocator : public SlabAllocator {
MallocAllocator Allocator;
public:
- MallocSlabAllocator() : Allocator() { }
+ MallocSlabAllocator() : Allocator() {}
virtual ~MallocSlabAllocator();
- virtual MemSlab *Allocate(size_t Size) LLVM_OVERRIDE;
- virtual void Deallocate(MemSlab *Slab) LLVM_OVERRIDE;
+ MemSlab *Allocate(size_t Size) override;
+ void Deallocate(MemSlab *Slab) override;
};
-/// BumpPtrAllocator - This allocator is useful for containers that need
-/// very simple memory allocation strategies. In particular, this just keeps
-/// allocating memory, and never deletes it until the entire block is dead. This
-/// makes allocation speedy, but must only be used when the trade-off is ok.
-class BumpPtrAllocator {
- BumpPtrAllocator(const BumpPtrAllocator &) LLVM_DELETED_FUNCTION;
- void operator=(const BumpPtrAllocator &) LLVM_DELETED_FUNCTION;
-
- /// SlabSize - Allocate data into slabs of this size unless we get an
- /// allocation above SizeThreshold.
- size_t SlabSize;
-
- /// SizeThreshold - For any allocation larger than this threshold, we should
- /// allocate a separate slab.
- size_t SizeThreshold;
-
- /// \brief the default allocator used if one is not provided
- MallocSlabAllocator DefaultSlabAllocator;
+/// \brief Non-templated base class for the \c BumpPtrAllocatorImpl template.
+class BumpPtrAllocatorBase {
+public:
+ void Deallocate(const void * /*Ptr*/) {}
+ void PrintStats() const;
- /// Allocator - The underlying allocator we use to get slabs of memory. This
- /// defaults to MallocSlabAllocator, which wraps malloc, but it could be
- /// changed to use a custom allocator.
- SlabAllocator &Allocator;
+ /// \brief Returns the total physical memory allocated by this allocator.
+ size_t getTotalMemory() const;
- /// CurSlab - The slab that we are currently allocating into.
- ///
+protected:
+ /// \brief The slab that we are currently allocating into.
MemSlab *CurSlab;
- /// CurPtr - The current pointer into the current slab. This points to the
- /// next free byte in the slab.
- char *CurPtr;
-
- /// End - The end of the current slab.
+ /// \brief How many bytes we've allocated.
///
- char *End;
-
- /// BytesAllocated - This field tracks how many bytes we've allocated, so
- /// that we can compute how much space was wasted.
+ /// Used so that we can compute how much space was wasted.
size_t BytesAllocated;
- /// AlignPtr - Align Ptr to Alignment bytes, rounding up. Alignment should
- /// be a power of two. This method rounds up, so AlignPtr(7, 4) == 8 and
- /// AlignPtr(8, 4) == 8.
- static char *AlignPtr(char *Ptr, size_t Alignment);
-
- /// StartNewSlab - Allocate a new slab and move the bump pointers over into
- /// the new slab. Modifies CurPtr and End.
- void StartNewSlab();
+ BumpPtrAllocatorBase() : CurSlab(0), BytesAllocated(0) {}
+};
- /// DeallocateSlabs - Deallocate all memory slabs after and including this
- /// one.
- void DeallocateSlabs(MemSlab *Slab);
+/// \brief Allocate memory in an ever growing pool, as if by bump-pointer.
+///
+/// This isn't strictly a bump-pointer allocator as it uses backing slabs of
+/// memory rather than relying on boundless contiguous heap. However, it has
+/// bump-pointer semantics in that is a monotonically growing pool of memory
+/// where every allocation is found by merely allocating the next N bytes in
+/// the slab, or the next N bytes in the next slab.
+///
+/// Note that this also has a threshold for forcing allocations above a certain
+/// size into their own slab.
+template <size_t SlabSize = 4096, size_t SizeThreshold = SlabSize>
+class BumpPtrAllocatorImpl : public BumpPtrAllocatorBase {
+ BumpPtrAllocatorImpl(const BumpPtrAllocatorImpl &) LLVM_DELETED_FUNCTION;
+ void operator=(const BumpPtrAllocatorImpl &) LLVM_DELETED_FUNCTION;
- template<typename T> friend class SpecificBumpPtrAllocator;
public:
- BumpPtrAllocator(size_t size = 4096, size_t threshold = 4096);
- BumpPtrAllocator(size_t size, size_t threshold, SlabAllocator &allocator);
- ~BumpPtrAllocator();
-
- /// Reset - Deallocate all but the current slab and reset the current pointer
+ static_assert(SizeThreshold <= SlabSize,
+ "The SizeThreshold must be at most the SlabSize to ensure "
+ "that objects larger than a slab go into their own memory "
+ "allocation.");
+
+ BumpPtrAllocatorImpl()
+ : Allocator(DefaultSlabAllocator), NumSlabs(0) {}
+ BumpPtrAllocatorImpl(SlabAllocator &Allocator)
+ : Allocator(Allocator), NumSlabs(0) {}
+ ~BumpPtrAllocatorImpl() { DeallocateSlabs(CurSlab); }
+
+ /// \brief Deallocate all but the current slab and reset the current pointer
/// to the beginning of it, freeing all memory allocated so far.
- void Reset();
+ void Reset() {
+ if (!CurSlab)
+ return;
+ DeallocateSlabs(CurSlab->NextPtr);
+ CurSlab->NextPtr = 0;
+ CurPtr = (char *)(CurSlab + 1);
+ End = ((char *)CurSlab) + CurSlab->Size;
+ BytesAllocated = 0;
+ }
- /// Allocate - Allocate space at the specified alignment.
- ///
- void *Allocate(size_t Size, size_t Alignment);
+ /// \brief Allocate space at the specified alignment.
+ void *Allocate(size_t Size, size_t Alignment) {
+ if (!CurSlab) // Start a new slab if we haven't allocated one already.
+ StartNewSlab();
+
+ // Keep track of how many bytes we've allocated.
+ BytesAllocated += Size;
+
+ // 0-byte alignment means 1-byte alignment.
+ if (Alignment == 0)
+ Alignment = 1;
+
+ // Allocate the aligned space, going forwards from CurPtr.
+ char *Ptr = alignPtr(CurPtr, Alignment);
+
+ // Check if we can hold it.
+ if (Ptr + Size <= End) {
+ CurPtr = Ptr + Size;
+ // Update the allocation point of this memory block in MemorySanitizer.
+ // Without this, MemorySanitizer messages for values originated from here
+ // will point to the allocation of the entire slab.
+ __msan_allocated_memory(Ptr, Size);
+ return Ptr;
+ }
- /// Allocate space, but do not construct, one object.
- ///
- template <typename T>
- T *Allocate() {
- return static_cast<T*>(Allocate(sizeof(T),AlignOf<T>::Alignment));
+ // If Size is really big, allocate a separate slab for it.
+ size_t PaddedSize = Size + sizeof(MemSlab) + Alignment - 1;
+ if (PaddedSize > SizeThreshold) {
+ ++NumSlabs;
+ MemSlab *NewSlab = Allocator.Allocate(PaddedSize);
+
+ // Put the new slab after the current slab, since we are not allocating
+ // into it.
+ NewSlab->NextPtr = CurSlab->NextPtr;
+ CurSlab->NextPtr = NewSlab;
+
+ Ptr = alignPtr((char *)(NewSlab + 1), Alignment);
+ assert((uintptr_t)Ptr + Size <= (uintptr_t)NewSlab + NewSlab->Size);
+ __msan_allocated_memory(Ptr, Size);
+ return Ptr;
+ }
+
+ // Otherwise, start a new slab and try again.
+ StartNewSlab();
+ Ptr = alignPtr(CurPtr, Alignment);
+ CurPtr = Ptr + Size;
+ assert(CurPtr <= End && "Unable to allocate memory!");
+ __msan_allocated_memory(Ptr, Size);
+ return Ptr;
}
- /// Allocate space for an array of objects. This does not construct the
- /// objects though.
- template <typename T>
- T *Allocate(size_t Num) {
- return static_cast<T*>(Allocate(Num * sizeof(T), AlignOf<T>::Alignment));
+ /// \brief Allocate space for one object without constructing it.
+ template <typename T> T *Allocate() {
+ return static_cast<T *>(Allocate(sizeof(T), AlignOf<T>::Alignment));
}
- /// Allocate space for a specific count of elements and with a specified
- /// alignment.
- template <typename T>
- T *Allocate(size_t Num, size_t Alignment) {
+ /// \brief Allocate space for an array of objects without constructing them.
+ template <typename T> T *Allocate(size_t Num) {
+ return static_cast<T *>(Allocate(Num * sizeof(T), AlignOf<T>::Alignment));
+ }
+
+ /// \brief Allocate space for an array of objects with the specified alignment
+ /// and without constructing them.
+ template <typename T> T *Allocate(size_t Num, size_t Alignment) {
// Round EltSize up to the specified alignment.
- size_t EltSize = (sizeof(T)+Alignment-1)&(-Alignment);
- return static_cast<T*>(Allocate(Num * EltSize, Alignment));
+ size_t EltSize = (sizeof(T) + Alignment - 1) & (-Alignment);
+ return static_cast<T *>(Allocate(Num * EltSize, Alignment));
}
- void Deallocate(const void * /*Ptr*/) {}
+ size_t GetNumSlabs() const { return NumSlabs; }
- unsigned GetNumSlabs() const;
+private:
+ /// \brief The default allocator used if one is not provided.
+ MallocSlabAllocator DefaultSlabAllocator;
- void PrintStats() const;
-
- /// Compute the total physical memory allocated by this allocator.
- size_t getTotalMemory() const;
+ /// \brief The underlying allocator we use to get slabs of memory.
+ ///
+ /// This defaults to MallocSlabAllocator, which wraps malloc, but it could be
+ /// changed to use a custom allocator.
+ SlabAllocator &Allocator;
+
+ /// \brief The current pointer into the current slab.
+ ///
+ /// This points to the next free byte in the slab.
+ char *CurPtr;
+
+ /// \brief The end of the current slab.
+ char *End;
+
+ /// \brief How many slabs we've allocated.
+ ///
+ /// Used to scale the size of each slab and reduce the number of allocations
+ /// for extremely heavy memory use scenarios.
+ size_t NumSlabs;
+
+ /// \brief Allocate a new slab and move the bump pointers over into the new
+ /// slab, modifying CurPtr and End.
+ void StartNewSlab() {
+ ++NumSlabs;
+ // Scale the actual allocated slab size based on the number of slabs
+ // allocated. Every 128 slabs allocated, we double the allocated size to
+ // reduce allocation frequency, but saturate at multiplying the slab size by
+ // 2^30.
+ // FIXME: Currently, this count includes special slabs for objects above the
+ // size threshold. That will be fixed in a subsequent commit to make the
+ // growth even more predictable.
+ size_t AllocatedSlabSize =
+ SlabSize * ((size_t)1 << std::min<size_t>(30, NumSlabs / 128));
+
+ MemSlab *NewSlab = Allocator.Allocate(AllocatedSlabSize);
+ NewSlab->NextPtr = CurSlab;
+ CurSlab = NewSlab;
+ CurPtr = (char *)(CurSlab + 1);
+ End = ((char *)CurSlab) + CurSlab->Size;
+ }
+
+ /// \brief Deallocate all memory slabs after and including this one.
+ void DeallocateSlabs(MemSlab *Slab) {
+ while (Slab) {
+ MemSlab *NextSlab = Slab->NextPtr;
+#ifndef NDEBUG
+ // Poison the memory so stale pointers crash sooner. Note we must
+ // preserve the Size and NextPtr fields at the beginning.
+ sys::Memory::setRangeWritable(Slab + 1, Slab->Size - sizeof(MemSlab));
+ memset(Slab + 1, 0xCD, Slab->Size - sizeof(MemSlab));
+#endif
+ Allocator.Deallocate(Slab);
+ Slab = NextSlab;
+ --NumSlabs;
+ }
+ }
+
+ template <typename T> friend class SpecificBumpPtrAllocator;
};
-/// SpecificBumpPtrAllocator - Same as BumpPtrAllocator but allows only
-/// elements of one type to be allocated. This allows calling the destructor
-/// in DestroyAll() and when the allocator is destroyed.
-template <typename T>
-class SpecificBumpPtrAllocator {
+/// \brief The standard BumpPtrAllocator which just uses the default template
+/// paramaters.
+typedef BumpPtrAllocatorImpl<> BumpPtrAllocator;
+
+/// \brief A BumpPtrAllocator that allows only elements of a specific type to be
+/// allocated.
+///
+/// This allows calling the destructor in DestroyAll() and when the allocator is
+/// destroyed.
+template <typename T> class SpecificBumpPtrAllocator {
BumpPtrAllocator Allocator;
+
public:
- SpecificBumpPtrAllocator(size_t size = 4096, size_t threshold = 4096)
- : Allocator(size, threshold) {}
- SpecificBumpPtrAllocator(size_t size, size_t threshold,
- SlabAllocator &allocator)
- : Allocator(size, threshold, allocator) {}
-
- ~SpecificBumpPtrAllocator() {
- DestroyAll();
- }
+ SpecificBumpPtrAllocator() : Allocator() {}
+ SpecificBumpPtrAllocator(SlabAllocator &allocator) : Allocator(allocator) {}
+
+ ~SpecificBumpPtrAllocator() { DestroyAll(); }
/// Call the destructor of each allocated object and deallocate all but the
/// current slab and reset the current pointer to the beginning of it, freeing
@@ -206,27 +307,28 @@ public:
void DestroyAll() {
MemSlab *Slab = Allocator.CurSlab;
while (Slab) {
- char *End = Slab == Allocator.CurSlab ? Allocator.CurPtr :
- (char *)Slab + Slab->Size;
- for (char *Ptr = (char*)(Slab+1); Ptr < End; Ptr += sizeof(T)) {
- Ptr = Allocator.AlignPtr(Ptr, alignOf<T>());
+ char *End = Slab == Allocator.CurSlab ? Allocator.CurPtr
+ : (char *)Slab + Slab->Size;
+ for (char *Ptr = (char *)(Slab + 1); Ptr < End; Ptr += sizeof(T)) {
+ Ptr = alignPtr(Ptr, alignOf<T>());
if (Ptr + sizeof(T) <= End)
- reinterpret_cast<T*>(Ptr)->~T();
+ reinterpret_cast<T *>(Ptr)->~T();
}
Slab = Slab->NextPtr;
}
Allocator.Reset();
}
- /// Allocate space for a specific count of elements.
- T *Allocate(size_t num = 1) {
- return Allocator.Allocate<T>(num);
- }
+ /// \brief Allocate space for an array of objects without constructing them.
+ T *Allocate(size_t num = 1) { return Allocator.Allocate<T>(num); }
};
} // end namespace llvm
-inline void *operator new(size_t Size, llvm::BumpPtrAllocator &Allocator) {
+template <size_t SlabSize, size_t SizeThreshold>
+void *
+operator new(size_t Size,
+ llvm::BumpPtrAllocatorImpl<SlabSize, SizeThreshold> &Allocator) {
struct S {
char c;
union {
@@ -236,10 +338,12 @@ inline void *operator new(size_t Size, llvm::BumpPtrAllocator &Allocator) {
void *P;
} x;
};
- return Allocator.Allocate(Size, std::min((size_t)llvm::NextPowerOf2(Size),
- offsetof(S, x)));
+ return Allocator.Allocate(
+ Size, std::min((size_t)llvm::NextPowerOf2(Size), offsetof(S, x)));
}
-inline void operator delete(void *, llvm::BumpPtrAllocator &) {}
+template <size_t SlabSize, size_t SizeThreshold>
+void operator delete(void *,
+ llvm::BumpPtrAllocatorImpl<SlabSize, SizeThreshold> &) {}
#endif // LLVM_SUPPORT_ALLOCATOR_H
diff --git a/include/llvm/Support/ArrayRecycler.h b/include/llvm/Support/ArrayRecycler.h
index c7e0cba..e974332 100644
--- a/include/llvm/Support/ArrayRecycler.h
+++ b/include/llvm/Support/ArrayRecycler.h
@@ -16,12 +16,11 @@
#define LLVM_SUPPORT_ARRAYRECYCLER_H
#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Allocator.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
@@ -35,6 +34,9 @@ class ArrayRecycler {
FreeList *Next;
};
+ static_assert(Align >= AlignOf<FreeList>::Alignment, "Object underaligned");
+ static_assert(sizeof(T) >= sizeof(FreeList), "Objects are too small");
+
// Keep a free list for each array size.
SmallVector<FreeList*, 8> Bucket;
@@ -53,8 +55,6 @@ class ArrayRecycler {
// 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);
diff --git a/include/llvm/Support/BlockFrequency.h b/include/llvm/Support/BlockFrequency.h
index 21879e7..dae520b 100644
--- a/include/llvm/Support/BlockFrequency.h
+++ b/include/llvm/Support/BlockFrequency.h
@@ -25,7 +25,6 @@ class BranchProbability;
class BlockFrequency {
uint64_t Frequency;
- static const int64_t ENTRY_FREQ = 1 << 14;
/// \brief Scale the given BlockFrequency by N/D. Return the remainder from
/// the division by D. Upon overflow, the routine will saturate and
@@ -35,9 +34,6 @@ class BlockFrequency {
public:
BlockFrequency(uint64_t Freq = 0) : Frequency(Freq) { }
- /// \brief Returns the frequency of the entry block of the function.
- static uint64_t getEntryFrequency() { return ENTRY_FREQ; }
-
/// \brief Returns the maximum possible frequency, the saturation value.
static uint64_t getMaxFrequency() { return -1ULL; }
@@ -59,6 +55,9 @@ public:
BlockFrequency &operator+=(const BlockFrequency &Freq);
const BlockFrequency operator+(const BlockFrequency &Freq) const;
+ /// \brief Shift block frequency to the right by count digits saturating to 1.
+ BlockFrequency &operator>>=(const unsigned count);
+
/// \brief Scale the given BlockFrequency by N/D. Return the remainder from
/// the division by D. Upon overflow, the routine will saturate.
uint32_t scale(const BranchProbability &Prob);
@@ -78,12 +77,8 @@ public:
bool operator>=(const BlockFrequency &RHS) const {
return Frequency >= RHS.Frequency;
}
-
- void print(raw_ostream &OS) const;
};
-raw_ostream &operator<<(raw_ostream &OS, const BlockFrequency &Freq);
-
}
#endif
diff --git a/include/llvm/Support/CFG.h b/include/llvm/Support/CFG.h
deleted file mode 100644
index 74ec726..0000000
--- a/include/llvm/Support/CFG.h
+++ /dev/null
@@ -1,365 +0,0 @@
-//===-- llvm/Support/CFG.h - Process LLVM structures as graphs --*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines specializations of GraphTraits that allow Function and
-// BasicBlock graphs to be treated as proper graphs for generic algorithms.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SUPPORT_CFG_H
-#define LLVM_SUPPORT_CFG_H
-
-#include "llvm/ADT/GraphTraits.h"
-#include "llvm/IR/Function.h"
-#include "llvm/IR/InstrTypes.h"
-
-namespace llvm {
-
-//===----------------------------------------------------------------------===//
-// BasicBlock pred_iterator definition
-//===----------------------------------------------------------------------===//
-
-template <class Ptr, class USE_iterator> // Predecessor Iterator
-class PredIterator : public std::iterator<std::forward_iterator_tag,
- Ptr, ptrdiff_t, Ptr*, Ptr*> {
- typedef std::iterator<std::forward_iterator_tag, Ptr, ptrdiff_t, Ptr*,
- Ptr*> super;
- typedef PredIterator<Ptr, USE_iterator> Self;
- USE_iterator It;
-
- inline void advancePastNonTerminators() {
- // Loop to ignore non terminator uses (for example BlockAddresses).
- while (!It.atEnd() && !isa<TerminatorInst>(*It))
- ++It;
- }
-
-public:
- typedef typename super::pointer pointer;
- typedef typename super::reference reference;
-
- PredIterator() {}
- explicit inline PredIterator(Ptr *bb) : It(bb->use_begin()) {
- advancePastNonTerminators();
- }
- inline PredIterator(Ptr *bb, bool) : It(bb->use_end()) {}
-
- inline bool operator==(const Self& x) const { return It == x.It; }
- inline bool operator!=(const Self& x) const { return !operator==(x); }
-
- inline reference operator*() const {
- assert(!It.atEnd() && "pred_iterator out of range!");
- return cast<TerminatorInst>(*It)->getParent();
- }
- inline pointer *operator->() const { return &operator*(); }
-
- inline Self& operator++() { // Preincrement
- assert(!It.atEnd() && "pred_iterator out of range!");
- ++It; advancePastNonTerminators();
- return *this;
- }
-
- inline Self operator++(int) { // Postincrement
- Self tmp = *this; ++*this; return tmp;
- }
-
- /// getOperandNo - Return the operand number in the predecessor's
- /// terminator of the successor.
- unsigned getOperandNo() const {
- return It.getOperandNo();
- }
-
- /// getUse - Return the operand Use in the predecessor's terminator
- /// of the successor.
- Use &getUse() const {
- return It.getUse();
- }
-};
-
-typedef PredIterator<BasicBlock, Value::use_iterator> pred_iterator;
-typedef PredIterator<const BasicBlock,
- Value::const_use_iterator> const_pred_iterator;
-
-inline pred_iterator pred_begin(BasicBlock *BB) { return pred_iterator(BB); }
-inline const_pred_iterator pred_begin(const BasicBlock *BB) {
- return const_pred_iterator(BB);
-}
-inline pred_iterator pred_end(BasicBlock *BB) { return pred_iterator(BB, true);}
-inline const_pred_iterator pred_end(const BasicBlock *BB) {
- return const_pred_iterator(BB, true);
-}
-
-
-
-//===----------------------------------------------------------------------===//
-// BasicBlock succ_iterator definition
-//===----------------------------------------------------------------------===//
-
-template <class Term_, class BB_> // Successor Iterator
-class SuccIterator : public std::iterator<std::bidirectional_iterator_tag,
- BB_, ptrdiff_t, BB_*, BB_*> {
- const Term_ Term;
- unsigned idx;
- typedef std::iterator<std::bidirectional_iterator_tag, BB_, ptrdiff_t, BB_*,
- BB_*> super;
- typedef SuccIterator<Term_, BB_> Self;
-
- inline bool index_is_valid(int idx) {
- return idx >= 0 && (unsigned) idx < Term->getNumSuccessors();
- }
-
-public:
- typedef typename super::pointer pointer;
- typedef typename super::reference reference;
- // TODO: This can be random access iterator, only operator[] missing.
-
- explicit inline SuccIterator(Term_ T) : Term(T), idx(0) {// begin iterator
- }
- inline SuccIterator(Term_ T, bool) // end iterator
- : Term(T) {
- if (Term)
- idx = Term->getNumSuccessors();
- else
- // Term == NULL happens, if a basic block is not fully constructed and
- // consequently getTerminator() returns NULL. In this case we construct a
- // SuccIterator which describes a basic block that has zero successors.
- // Defining SuccIterator for incomplete and malformed CFGs is especially
- // useful for debugging.
- idx = 0;
- }
-
- inline const Self &operator=(const Self &I) {
- assert(Term == I.Term &&"Cannot assign iterators to two different blocks!");
- idx = I.idx;
- return *this;
- }
-
- /// getSuccessorIndex - This is used to interface between code that wants to
- /// operate on terminator instructions directly.
- unsigned getSuccessorIndex() const { return idx; }
-
- inline bool operator==(const Self& x) const { return idx == x.idx; }
- inline bool operator!=(const Self& x) const { return !operator==(x); }
-
- inline reference operator*() const { return Term->getSuccessor(idx); }
- inline pointer operator->() const { return operator*(); }
-
- inline Self& operator++() { ++idx; return *this; } // Preincrement
-
- inline Self operator++(int) { // Postincrement
- Self tmp = *this; ++*this; return tmp;
- }
-
- inline Self& operator--() { --idx; return *this; } // Predecrement
- inline Self operator--(int) { // Postdecrement
- Self tmp = *this; --*this; return tmp;
- }
-
- inline bool operator<(const Self& x) const {
- assert(Term == x.Term && "Cannot compare iterators of different blocks!");
- return idx < x.idx;
- }
-
- inline bool operator<=(const Self& x) const {
- assert(Term == x.Term && "Cannot compare iterators of different blocks!");
- return idx <= x.idx;
- }
- inline bool operator>=(const Self& x) const {
- assert(Term == x.Term && "Cannot compare iterators of different blocks!");
- return idx >= x.idx;
- }
-
- inline bool operator>(const Self& x) const {
- assert(Term == x.Term && "Cannot compare iterators of different blocks!");
- return idx > x.idx;
- }
-
- inline Self& operator+=(int Right) {
- unsigned new_idx = idx + Right;
- assert(index_is_valid(new_idx) && "Iterator index out of bound");
- idx = new_idx;
- return *this;
- }
-
- inline Self operator+(int Right) {
- Self tmp = *this;
- tmp += Right;
- return tmp;
- }
-
- inline Self& operator-=(int Right) {
- return operator+=(-Right);
- }
-
- inline Self operator-(int Right) {
- return operator+(-Right);
- }
-
- inline int operator-(const Self& x) {
- assert(Term == x.Term && "Cannot work on iterators of different blocks!");
- int distance = idx - x.idx;
- return distance;
- }
-
- // This works for read access, however write access is difficult as changes
- // to Term are only possible with Term->setSuccessor(idx). Pointers that can
- // be modified are not available.
- //
- // inline pointer operator[](int offset) {
- // Self tmp = *this;
- // tmp += offset;
- // return tmp.operator*();
- // }
-
- /// Get the source BB of this iterator.
- inline BB_ *getSource() {
- assert(Term && "Source not available, if basic block was malformed");
- return Term->getParent();
- }
-};
-
-typedef SuccIterator<TerminatorInst*, BasicBlock> succ_iterator;
-typedef SuccIterator<const TerminatorInst*,
- const BasicBlock> succ_const_iterator;
-
-inline succ_iterator succ_begin(BasicBlock *BB) {
- return succ_iterator(BB->getTerminator());
-}
-inline succ_const_iterator succ_begin(const BasicBlock *BB) {
- return succ_const_iterator(BB->getTerminator());
-}
-inline succ_iterator succ_end(BasicBlock *BB) {
- return succ_iterator(BB->getTerminator(), true);
-}
-inline succ_const_iterator succ_end(const BasicBlock *BB) {
- return succ_const_iterator(BB->getTerminator(), true);
-}
-
-template <typename T, typename U> struct isPodLike<SuccIterator<T, U> > {
- static const bool value = isPodLike<T>::value;
-};
-
-
-
-//===--------------------------------------------------------------------===//
-// GraphTraits specializations for basic block graphs (CFGs)
-//===--------------------------------------------------------------------===//
-
-// Provide specializations of GraphTraits to be able to treat a function as a
-// graph of basic blocks...
-
-template <> struct GraphTraits<BasicBlock*> {
- typedef BasicBlock NodeType;
- typedef succ_iterator ChildIteratorType;
-
- static NodeType *getEntryNode(BasicBlock *BB) { return BB; }
- static inline ChildIteratorType child_begin(NodeType *N) {
- return succ_begin(N);
- }
- static inline ChildIteratorType child_end(NodeType *N) {
- return succ_end(N);
- }
-};
-
-template <> struct GraphTraits<const BasicBlock*> {
- typedef const BasicBlock NodeType;
- typedef succ_const_iterator ChildIteratorType;
-
- static NodeType *getEntryNode(const BasicBlock *BB) { return BB; }
-
- static inline ChildIteratorType child_begin(NodeType *N) {
- return succ_begin(N);
- }
- static inline ChildIteratorType child_end(NodeType *N) {
- return succ_end(N);
- }
-};
-
-// Provide specializations of GraphTraits to be able to treat a function as a
-// graph of basic blocks... and to walk it in inverse order. Inverse order for
-// a function is considered to be when traversing the predecessor edges of a BB
-// instead of the successor edges.
-//
-template <> struct GraphTraits<Inverse<BasicBlock*> > {
- typedef BasicBlock NodeType;
- typedef pred_iterator ChildIteratorType;
- static NodeType *getEntryNode(Inverse<BasicBlock *> G) { return G.Graph; }
- static inline ChildIteratorType child_begin(NodeType *N) {
- return pred_begin(N);
- }
- static inline ChildIteratorType child_end(NodeType *N) {
- return pred_end(N);
- }
-};
-
-template <> struct GraphTraits<Inverse<const BasicBlock*> > {
- typedef const BasicBlock NodeType;
- typedef const_pred_iterator ChildIteratorType;
- static NodeType *getEntryNode(Inverse<const BasicBlock*> G) {
- return G.Graph;
- }
- static inline ChildIteratorType child_begin(NodeType *N) {
- return pred_begin(N);
- }
- static inline ChildIteratorType child_end(NodeType *N) {
- return pred_end(N);
- }
-};
-
-
-
-//===--------------------------------------------------------------------===//
-// GraphTraits specializations for function basic block graphs (CFGs)
-//===--------------------------------------------------------------------===//
-
-// Provide specializations of GraphTraits to be able to treat a function as a
-// graph of basic blocks... these are the same as the basic block iterators,
-// except that the root node is implicitly the first node of the function.
-//
-template <> struct GraphTraits<Function*> : public GraphTraits<BasicBlock*> {
- static NodeType *getEntryNode(Function *F) { return &F->getEntryBlock(); }
-
- // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
- typedef Function::iterator nodes_iterator;
- static nodes_iterator nodes_begin(Function *F) { return F->begin(); }
- static nodes_iterator nodes_end (Function *F) { return F->end(); }
- static size_t size (Function *F) { return F->size(); }
-};
-template <> struct GraphTraits<const Function*> :
- public GraphTraits<const BasicBlock*> {
- static NodeType *getEntryNode(const Function *F) {return &F->getEntryBlock();}
-
- // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
- typedef Function::const_iterator nodes_iterator;
- static nodes_iterator nodes_begin(const Function *F) { return F->begin(); }
- static nodes_iterator nodes_end (const Function *F) { return F->end(); }
- static size_t size (const Function *F) { return F->size(); }
-};
-
-
-// Provide specializations of GraphTraits to be able to treat a function as a
-// graph of basic blocks... and to walk it in inverse order. Inverse order for
-// a function is considered to be when traversing the predecessor edges of a BB
-// instead of the successor edges.
-//
-template <> struct GraphTraits<Inverse<Function*> > :
- public GraphTraits<Inverse<BasicBlock*> > {
- static NodeType *getEntryNode(Inverse<Function*> G) {
- return &G.Graph->getEntryBlock();
- }
-};
-template <> struct GraphTraits<Inverse<const Function*> > :
- public GraphTraits<Inverse<const BasicBlock*> > {
- static NodeType *getEntryNode(Inverse<const Function *> G) {
- return &G.Graph->getEntryBlock();
- }
-};
-
-} // End llvm namespace
-
-#endif
diff --git a/include/llvm/Support/COFF.h b/include/llvm/Support/COFF.h
index 9cc3989..dca7fc6 100644
--- a/include/llvm/Support/COFF.h
+++ b/include/llvm/Support/COFF.h
@@ -30,6 +30,9 @@
namespace llvm {
namespace COFF {
+ // The maximum number of sections that a COFF object can have (inclusive).
+ const int MaxNumberOfSections = 65299;
+
// The PE signature bytes that follows the DOS stub header.
static const char PEMagic[] = { 'P', 'E', '\0', '\0' };
@@ -59,7 +62,7 @@ namespace COFF {
IMAGE_FILE_MACHINE_AM33 = 0x13,
IMAGE_FILE_MACHINE_AMD64 = 0x8664,
IMAGE_FILE_MACHINE_ARM = 0x1C0,
- IMAGE_FILE_MACHINE_ARMV7 = 0x1C4,
+ IMAGE_FILE_MACHINE_ARMNT = 0x1C4,
IMAGE_FILE_MACHINE_EBC = 0xEBC,
IMAGE_FILE_MACHINE_I386 = 0x14C,
IMAGE_FILE_MACHINE_IA64 = 0x200,
@@ -138,8 +141,8 @@ namespace COFF {
};
enum SymbolSectionNumber {
- IMAGE_SYM_DEBUG = -2,
- IMAGE_SYM_ABSOLUTE = -1,
+ IMAGE_SYM_DEBUG = 0xFFFE,
+ IMAGE_SYM_ABSOLUTE = 0xFFFF,
IMAGE_SYM_UNDEFINED = 0
};
@@ -209,6 +212,10 @@ namespace COFF {
SCT_COMPLEX_TYPE_SHIFT = 4
};
+ enum AuxSymbolType {
+ IMAGE_AUX_SYMBOL_TYPE_TOKEN_DEF = 1
+ };
+
struct section {
char Name[NameSize];
uint32_t VirtualSize;
@@ -222,7 +229,7 @@ namespace COFF {
uint32_t Characteristics;
};
- enum SectionCharacteristics LLVM_ENUM_INT_TYPE(uint32_t) {
+ enum SectionCharacteristics : uint32_t {
SC_Invalid = 0xffffffff,
IMAGE_SCN_TYPE_NO_PAD = 0x00000008,
@@ -334,7 +341,7 @@ namespace COFF {
uint32_t TotalSize;
uint32_t PointerToLinenumber;
uint32_t PointerToNextFunction;
- uint8_t unused[2];
+ char unused[2];
};
struct AuxiliarybfAndefSymbol {
@@ -369,7 +376,14 @@ namespace COFF {
uint32_t CheckSum;
uint16_t Number;
uint8_t Selection;
- uint8_t unused[3];
+ char unused[3];
+ };
+
+ struct AuxiliaryCLRToken {
+ uint8_t AuxType;
+ uint8_t unused1;
+ uint32_t SymbolTableIndex;
+ char unused2[12];
};
union Auxiliary {
@@ -450,7 +464,12 @@ namespace COFF {
uint32_t AddressOfNewExeHeader;
};
- struct PEHeader {
+ struct PE32Header {
+ enum {
+ PE32 = 0x10b,
+ PE32_PLUS = 0x20b
+ };
+
uint16_t Magic;
uint8_t MajorLinkerVersion;
uint8_t MinorLinkerVersion;
@@ -460,7 +479,7 @@ namespace COFF {
uint32_t AddressOfEntryPoint; // RVA
uint32_t BaseOfCode; // RVA
uint32_t BaseOfData; // RVA
- uint64_t ImageBase;
+ uint32_t ImageBase;
uint32_t SectionAlignment;
uint32_t FileAlignment;
uint16_t MajorOperatingSystemVersion;
@@ -475,10 +494,10 @@ namespace COFF {
uint32_t CheckSum;
uint16_t Subsystem;
uint16_t DLLCharacteristics;
- uint64_t SizeOfStackReserve;
- uint64_t SizeOfStackCommit;
- uint64_t SizeOfHeapReserve;
- uint64_t SizeOfHeapCommit;
+ uint32_t SizeOfStackReserve;
+ uint32_t SizeOfStackCommit;
+ uint32_t SizeOfHeapReserve;
+ uint32_t SizeOfHeapCommit;
uint32_t LoaderFlags;
uint32_t NumberOfRvaAndSize;
};
@@ -526,6 +545,8 @@ namespace COFF {
};
enum DLLCharacteristics {
+ /// ASLR with 64 bit address space.
+ IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA = 0x0020,
/// DLL can be relocated at load time.
IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE = 0x0040,
/// Code integrity checks are enforced.
@@ -611,6 +632,17 @@ namespace COFF {
}
};
+ enum CodeViewLineTableIdentifiers {
+ DEBUG_SECTION_MAGIC = 0x4,
+ DEBUG_LINE_TABLE_SUBSECTION = 0xF2,
+ DEBUG_STRING_TABLE_SUBSECTION = 0xF3,
+ DEBUG_INDEX_SUBSECTION = 0xF4
+ };
+
+ inline bool isReservedSectionNumber(int N) {
+ return N == IMAGE_SYM_UNDEFINED || N > MaxNumberOfSections;
+ }
+
} // End namespace COFF.
} // End namespace llvm.
diff --git a/include/llvm/Support/CallSite.h b/include/llvm/Support/CallSite.h
deleted file mode 100644
index 2a1c5ca..0000000
--- a/include/llvm/Support/CallSite.h
+++ /dev/null
@@ -1,330 +0,0 @@
-//===-- llvm/Support/CallSite.h - Abstract Call & Invoke instrs -*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the CallSite class, which is a handy wrapper for code that
-// wants to treat Call and Invoke instructions in a generic way. When in non-
-// mutation context (e.g. an analysis) ImmutableCallSite should be used.
-// Finally, when some degree of customization is necessary between these two
-// extremes, CallSiteBase<> can be supplied with fine-tuned parameters.
-//
-// NOTE: These classes are supposed to have "value semantics". So they should be
-// passed by value, not by reference; they should not be "new"ed or "delete"d.
-// They are efficiently copyable, assignable and constructable, with cost
-// equivalent to copying a pointer (notice that they have only a single data
-// member). The internal representation carries a flag which indicates which of
-// the two variants is enclosed. This allows for cheaper checks when various
-// accessors of CallSite are employed.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SUPPORT_CALLSITE_H
-#define LLVM_SUPPORT_CALLSITE_H
-
-#include "llvm/ADT/PointerIntPair.h"
-#include "llvm/IR/Attributes.h"
-#include "llvm/IR/CallingConv.h"
-#include "llvm/IR/Instructions.h"
-
-namespace llvm {
-
-class CallInst;
-class InvokeInst;
-
-template <typename FunTy = const Function,
- typename ValTy = const Value,
- typename UserTy = const User,
- typename InstrTy = const Instruction,
- typename CallTy = const CallInst,
- typename InvokeTy = const InvokeInst,
- typename IterTy = User::const_op_iterator>
-class CallSiteBase {
-protected:
- PointerIntPair<InstrTy*, 1, bool> I;
-public:
- CallSiteBase() : I(0, false) {}
- CallSiteBase(CallTy *CI) : I(CI, true) { assert(CI); }
- CallSiteBase(InvokeTy *II) : I(II, false) { assert(II); }
- CallSiteBase(ValTy *II) { *this = get(II); }
-protected:
- /// CallSiteBase::get - This static method is sort of like a constructor. It
- /// will create an appropriate call site for a Call or Invoke instruction, but
- /// it can also create a null initialized CallSiteBase object for something
- /// which is NOT a call site.
- ///
- static CallSiteBase get(ValTy *V) {
- if (InstrTy *II = dyn_cast<InstrTy>(V)) {
- if (II->getOpcode() == Instruction::Call)
- return CallSiteBase(static_cast<CallTy*>(II));
- else if (II->getOpcode() == Instruction::Invoke)
- return CallSiteBase(static_cast<InvokeTy*>(II));
- }
- return CallSiteBase();
- }
-public:
- /// isCall - true if a CallInst is enclosed.
- /// Note that !isCall() does not mean it is an InvokeInst enclosed,
- /// it also could signify a NULL Instruction pointer.
- bool isCall() const { return I.getInt(); }
-
- /// isInvoke - true if a InvokeInst is enclosed.
- ///
- bool isInvoke() const { return getInstruction() && !I.getInt(); }
-
- InstrTy *getInstruction() const { return I.getPointer(); }
- InstrTy *operator->() const { return I.getPointer(); }
- LLVM_EXPLICIT operator bool() const { return I.getPointer(); }
-
- /// getCalledValue - Return the pointer to function that is being called.
- ///
- ValTy *getCalledValue() const {
- assert(getInstruction() && "Not a call or invoke instruction!");
- return *getCallee();
- }
-
- /// getCalledFunction - Return the function being called if this is a direct
- /// call, otherwise return null (if it's an indirect call).
- ///
- FunTy *getCalledFunction() const {
- return dyn_cast<FunTy>(getCalledValue());
- }
-
- /// setCalledFunction - Set the callee to the specified value.
- ///
- void setCalledFunction(Value *V) {
- assert(getInstruction() && "Not a call or invoke instruction!");
- *getCallee() = V;
- }
-
- /// isCallee - Determine whether the passed iterator points to the
- /// callee operand's Use.
- ///
- bool isCallee(value_use_iterator<UserTy> UI) const {
- return getCallee() == &UI.getUse();
- }
-
- ValTy *getArgument(unsigned ArgNo) const {
- assert(arg_begin() + ArgNo < arg_end() && "Argument # out of range!");
- return *(arg_begin() + ArgNo);
- }
-
- void setArgument(unsigned ArgNo, Value* newVal) {
- assert(getInstruction() && "Not a call or invoke instruction!");
- assert(arg_begin() + ArgNo < arg_end() && "Argument # out of range!");
- getInstruction()->setOperand(ArgNo, newVal);
- }
-
- /// Given a value use iterator, returns the argument that corresponds to it.
- /// Iterator must actually correspond to an argument.
- unsigned getArgumentNo(value_use_iterator<UserTy> I) const {
- assert(getInstruction() && "Not a call or invoke instruction!");
- assert(arg_begin() <= &I.getUse() && &I.getUse() < arg_end()
- && "Argument # out of range!");
- return &I.getUse() - arg_begin();
- }
-
- /// arg_iterator - The type of iterator to use when looping over actual
- /// arguments at this call site.
- typedef IterTy arg_iterator;
-
- /// arg_begin/arg_end - Return iterators corresponding to the actual argument
- /// list for a call site.
- IterTy arg_begin() const {
- assert(getInstruction() && "Not a call or invoke instruction!");
- // Skip non-arguments
- return (*this)->op_begin();
- }
-
- IterTy arg_end() const { return (*this)->op_end() - getArgumentEndOffset(); }
- bool arg_empty() const { return arg_end() == arg_begin(); }
- unsigned arg_size() const { return unsigned(arg_end() - arg_begin()); }
-
- /// getType - Return the type of the instruction that generated this call site
- ///
- Type *getType() const { return (*this)->getType(); }
-
- /// getCaller - Return the caller function for this call site
- ///
- FunTy *getCaller() const { return (*this)->getParent()->getParent(); }
-
-#define CALLSITE_DELEGATE_GETTER(METHOD) \
- InstrTy *II = getInstruction(); \
- return isCall() \
- ? cast<CallInst>(II)->METHOD \
- : cast<InvokeInst>(II)->METHOD
-
-#define CALLSITE_DELEGATE_SETTER(METHOD) \
- InstrTy *II = getInstruction(); \
- if (isCall()) \
- cast<CallInst>(II)->METHOD; \
- else \
- cast<InvokeInst>(II)->METHOD
-
- /// getCallingConv/setCallingConv - get or set the calling convention of the
- /// call.
- CallingConv::ID getCallingConv() const {
- CALLSITE_DELEGATE_GETTER(getCallingConv());
- }
- void setCallingConv(CallingConv::ID CC) {
- CALLSITE_DELEGATE_SETTER(setCallingConv(CC));
- }
-
- /// getAttributes/setAttributes - get or set the parameter attributes of
- /// the call.
- const AttributeSet &getAttributes() const {
- CALLSITE_DELEGATE_GETTER(getAttributes());
- }
- void setAttributes(const AttributeSet &PAL) {
- CALLSITE_DELEGATE_SETTER(setAttributes(PAL));
- }
-
- /// \brief Return true if this function has the given attribute.
- bool hasFnAttr(Attribute::AttrKind A) const {
- CALLSITE_DELEGATE_GETTER(hasFnAttr(A));
- }
-
- /// \brief Return true if the call or the callee has the given attribute.
- bool paramHasAttr(unsigned i, Attribute::AttrKind A) const {
- CALLSITE_DELEGATE_GETTER(paramHasAttr(i, A));
- }
-
- /// @brief Extract the alignment for a call or parameter (0=unknown).
- uint16_t getParamAlignment(uint16_t i) const {
- CALLSITE_DELEGATE_GETTER(getParamAlignment(i));
- }
-
- /// \brief Return true if the call should not be treated as a call to a
- /// builtin.
- bool isNoBuiltin() const {
- CALLSITE_DELEGATE_GETTER(isNoBuiltin());
- }
-
- /// @brief Return true if the call should not be inlined.
- bool isNoInline() const {
- CALLSITE_DELEGATE_GETTER(isNoInline());
- }
- void setIsNoInline(bool Value = true) {
- CALLSITE_DELEGATE_SETTER(setIsNoInline(Value));
- }
-
- /// @brief Determine if the call does not access memory.
- bool doesNotAccessMemory() const {
- CALLSITE_DELEGATE_GETTER(doesNotAccessMemory());
- }
- void setDoesNotAccessMemory() {
- CALLSITE_DELEGATE_SETTER(setDoesNotAccessMemory());
- }
-
- /// @brief Determine if the call does not access or only reads memory.
- bool onlyReadsMemory() const {
- CALLSITE_DELEGATE_GETTER(onlyReadsMemory());
- }
- void setOnlyReadsMemory() {
- CALLSITE_DELEGATE_SETTER(setOnlyReadsMemory());
- }
-
- /// @brief Determine if the call cannot return.
- bool doesNotReturn() const {
- CALLSITE_DELEGATE_GETTER(doesNotReturn());
- }
- void setDoesNotReturn() {
- CALLSITE_DELEGATE_SETTER(setDoesNotReturn());
- }
-
- /// @brief Determine if the call cannot unwind.
- bool doesNotThrow() const {
- CALLSITE_DELEGATE_GETTER(doesNotThrow());
- }
- void setDoesNotThrow() {
- CALLSITE_DELEGATE_SETTER(setDoesNotThrow());
- }
-
-#undef CALLSITE_DELEGATE_GETTER
-#undef CALLSITE_DELEGATE_SETTER
-
- /// @brief Determine whether this argument is not captured.
- bool doesNotCapture(unsigned ArgNo) const {
- return paramHasAttr(ArgNo + 1, Attribute::NoCapture);
- }
-
- /// @brief Determine whether this argument is passed by value.
- bool isByValArgument(unsigned ArgNo) const {
- return paramHasAttr(ArgNo + 1, Attribute::ByVal);
- }
-
- bool doesNotAccessMemory(unsigned ArgNo) const {
- return paramHasAttr(ArgNo + 1, Attribute::ReadNone);
- }
-
- bool onlyReadsMemory(unsigned ArgNo) const {
- return paramHasAttr(ArgNo + 1, Attribute::ReadOnly) ||
- paramHasAttr(ArgNo + 1, Attribute::ReadNone);
- }
-
- /// hasArgument - Returns true if this CallSite passes the given Value* as an
- /// argument to the called function.
- bool hasArgument(const Value *Arg) const {
- for (arg_iterator AI = this->arg_begin(), E = this->arg_end(); AI != E;
- ++AI)
- if (AI->get() == Arg)
- return true;
- return false;
- }
-
-private:
- unsigned getArgumentEndOffset() const {
- if (isCall())
- return 1; // Skip Callee
- else
- return 3; // Skip BB, BB, Callee
- }
-
- IterTy getCallee() const {
- if (isCall()) // Skip Callee
- return cast<CallInst>(getInstruction())->op_end() - 1;
- else // Skip BB, BB, Callee
- return cast<InvokeInst>(getInstruction())->op_end() - 3;
- }
-};
-
-class CallSite : public CallSiteBase<Function, Value, User, Instruction,
- CallInst, InvokeInst, User::op_iterator> {
- typedef CallSiteBase<Function, Value, User, Instruction,
- CallInst, InvokeInst, User::op_iterator> Base;
-public:
- CallSite() {}
- CallSite(Base B) : Base(B) {}
- CallSite(Value* V) : Base(V) {}
- CallSite(CallInst *CI) : Base(CI) {}
- CallSite(InvokeInst *II) : Base(II) {}
- CallSite(Instruction *II) : Base(II) {}
-
- bool operator==(const CallSite &CS) const { return I == CS.I; }
- bool operator!=(const CallSite &CS) const { return I != CS.I; }
- bool operator<(const CallSite &CS) const {
- return getInstruction() < CS.getInstruction();
- }
-
-private:
- User::op_iterator getCallee() const;
-};
-
-/// ImmutableCallSite - establish a view to a call site for examination
-class ImmutableCallSite : public CallSiteBase<> {
- typedef CallSiteBase<> Base;
-public:
- ImmutableCallSite(const Value* V) : Base(V) {}
- ImmutableCallSite(const CallInst *CI) : Base(CI) {}
- ImmutableCallSite(const InvokeInst *II) : Base(II) {}
- ImmutableCallSite(const Instruction *II) : Base(II) {}
- ImmutableCallSite(CallSite CS) : Base(CS.getInstruction()) {}
-};
-
-} // End llvm namespace
-
-#endif
diff --git a/include/llvm/Support/Casting.h b/include/llvm/Support/Casting.h
index d70acbf..689f590 100644
--- a/include/llvm/Support/Casting.h
+++ b/include/llvm/Support/Casting.h
@@ -15,6 +15,7 @@
#ifndef LLVM_SUPPORT_CASTING_H
#define LLVM_SUPPORT_CASTING_H
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/type_traits.h"
#include <cassert>
@@ -58,11 +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 enable_if<
- llvm::is_base_of<To, From>
- >::type
- > {
+struct isa_impl<
+ To, From, typename std::enable_if<std::is_base_of<To, From>::value>::type> {
static inline bool doit(const From &) { return true; }
};
@@ -131,7 +129,7 @@ struct isa_impl_wrap<To, FromTy, FromTy> {
// if (isa<Type>(myVal)) { ... }
//
template <class X, class Y>
-inline bool isa(const Y &Val) {
+LLVM_ATTRIBUTE_UNUSED_RESULT inline bool isa(const Y &Val) {
return isa_impl_wrap<X, const Y,
typename simplify_type<const Y>::SimpleType>::doit(Val);
}
@@ -208,7 +206,7 @@ template<class To, class FromTy> struct cast_convert_val<To,FromTy,FromTy> {
template <class X> struct is_simple_type {
static const bool value =
- is_same<X, typename simplify_type<X>::SimpleType>::value;
+ std::is_same<X, typename simplify_type<X>::SimpleType>::value;
};
// cast<X> - Return the argument parameter cast to the specified type. This
@@ -219,8 +217,8 @@ template <class X> struct is_simple_type {
// cast<Instruction>(myVal)->getParent()
//
template <class X, class Y>
-inline typename enable_if_c<!is_simple_type<Y>::value,
- typename cast_retty<X, const Y>::ret_type>::type
+inline typename std::enable_if<!is_simple_type<Y>::value,
+ typename cast_retty<X, const Y>::ret_type>::type
cast(const Y &Val) {
assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!");
return cast_convert_val<
@@ -245,7 +243,8 @@ inline typename cast_retty<X, Y *>::ret_type cast(Y *Val) {
// accepted.
//
template <class X, class Y>
-inline typename cast_retty<X, Y*>::ret_type cast_or_null(Y *Val) {
+LLVM_ATTRIBUTE_UNUSED_RESULT inline typename cast_retty<X, Y *>::ret_type
+cast_or_null(Y *Val) {
if (Val == 0) return 0;
assert(isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!");
return cast<X>(Val);
@@ -261,19 +260,21 @@ inline typename cast_retty<X, Y*>::ret_type cast_or_null(Y *Val) {
//
template <class X, class Y>
-inline typename enable_if_c<!is_simple_type<Y>::value,
- typename cast_retty<X, const Y>::ret_type>::type
+LLVM_ATTRIBUTE_UNUSED_RESULT inline typename std::enable_if<
+ !is_simple_type<Y>::value, typename cast_retty<X, const Y>::ret_type>::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) {
+LLVM_ATTRIBUTE_UNUSED_RESULT 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 cast_retty<X, Y *>::ret_type dyn_cast(Y *Val) {
+LLVM_ATTRIBUTE_UNUSED_RESULT inline typename cast_retty<X, Y *>::ret_type
+dyn_cast(Y *Val) {
return isa<X>(Val) ? cast<X>(Val) : 0;
}
@@ -281,7 +282,8 @@ inline typename cast_retty<X, Y *>::ret_type dyn_cast(Y *Val) {
// value is accepted.
//
template <class X, class Y>
-inline typename cast_retty<X, Y*>::ret_type dyn_cast_or_null(Y *Val) {
+LLVM_ATTRIBUTE_UNUSED_RESULT inline typename cast_retty<X, Y *>::ret_type
+dyn_cast_or_null(Y *Val) {
return (Val && isa<X>(Val)) ? cast<X>(Val) : 0;
}
diff --git a/include/llvm/Support/CommandLine.h b/include/llvm/Support/CommandLine.h
index 4efb6a6..e49a97e 100644
--- a/include/llvm/Support/CommandLine.h
+++ b/include/llvm/Support/CommandLine.h
@@ -21,10 +21,9 @@
#define LLVM_SUPPORT_COMMANDLINE_H
#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/Twine.h"
#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/Twine.h"
#include "llvm/Support/Compiler.h"
-#include "llvm/Support/type_traits.h"
#include <cassert>
#include <climits>
#include <cstdarg>
@@ -149,8 +148,8 @@ private:
public:
OptionCategory(const char *const Name, const char *const Description = 0)
: Name(Name), Description(Description) { registerCategory(); }
- const char *getName() { return Name; }
- const char *getDescription() { return Description; }
+ const char *getName() const { return Name; }
+ const char *getDescription() const { return Description; }
};
// The general Option Category (used as default category).
@@ -249,6 +248,12 @@ public:
//
void addArgument();
+ /// Unregisters this option from the CommandLine system.
+ ///
+ /// This option must have been the last option registered.
+ /// For testing purposes only.
+ void removeArgument();
+
Option *getNextRegisteredOption() const { return NextRegistered; }
// Return the width of the option tag for printing...
@@ -374,7 +379,9 @@ struct OptionValueBase : public GenericOptionValue {
bool compare(const DataType &/*V*/) const { return false; }
- virtual bool compare(const GenericOptionValue& /*V*/) const { return false; }
+ bool compare(const GenericOptionValue& /*V*/) const override {
+ return false;
+ }
};
// Simple copy of the option value.
@@ -398,7 +405,7 @@ public:
return Valid && (Value != V);
}
- virtual bool compare(const GenericOptionValue &V) const {
+ bool compare(const GenericOptionValue &V) const override {
const OptionValueCopy<DataType> &VC =
static_cast< const OptionValueCopy<DataType>& >(V);
if (!VC.hasValue()) return false;
@@ -414,7 +421,7 @@ struct OptionValueBase<DataType, false> : OptionValueCopy<DataType> {
// Top-level option class.
template<class DataType>
-struct OptionValue : OptionValueBase<DataType, is_class<DataType>::value> {
+struct OptionValue : OptionValueBase<DataType, std::is_class<DataType>::value> {
OptionValue() {}
OptionValue(const DataType& V) {
@@ -444,7 +451,7 @@ struct OptionValue<cl::boolOrDefault> : OptionValueCopy<cl::boolOrDefault> {
return *this;
}
private:
- virtual void anchor();
+ void anchor() override;
};
template<>
@@ -461,7 +468,7 @@ struct OptionValue<std::string> : OptionValueCopy<std::string> {
return *this;
}
private:
- virtual void anchor();
+ void anchor() override;
};
//===----------------------------------------------------------------------===//
@@ -640,14 +647,14 @@ public:
typedef DataType parser_data_type;
// Implement virtual functions needed by generic_parser_base
- unsigned getNumOptions() const { return unsigned(Values.size()); }
- const char *getOption(unsigned N) const { return Values[N].Name; }
- const char *getDescription(unsigned N) const {
+ unsigned getNumOptions() const override { return unsigned(Values.size()); }
+ const char *getOption(unsigned N) const override { return Values[N].Name; }
+ const char *getDescription(unsigned N) const override {
return Values[N].HelpStr;
}
// getOptionValue - Return the value of option name N.
- virtual const GenericOptionValue &getOptionValue(unsigned N) const {
+ const GenericOptionValue &getOptionValue(unsigned N) const override {
return Values[N].V;
}
@@ -756,13 +763,13 @@ public:
}
// getValueName - Do not print =<value> at all.
- virtual const char *getValueName() const { return 0; }
+ const char *getValueName() const override { return 0; }
void printOptionDiff(const Option &O, bool V, OptVal Default,
size_t GlobalWidth) const;
// An out-of-line virtual method to provide a 'home' for this class.
- virtual void anchor();
+ void anchor() override;
};
EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<bool>);
@@ -780,13 +787,13 @@ public:
}
// getValueName - Do not print =<value> at all.
- virtual const char *getValueName() const { return 0; }
+ const char *getValueName() const override { return 0; }
void printOptionDiff(const Option &O, boolOrDefault V, OptVal Default,
size_t GlobalWidth) const;
// An out-of-line virtual method to provide a 'home' for this class.
- virtual void anchor();
+ void anchor() override;
};
EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<boolOrDefault>);
@@ -801,13 +808,13 @@ public:
bool parse(Option &O, StringRef ArgName, StringRef Arg, int &Val);
// getValueName - Overload in subclass to provide a better default value.
- virtual const char *getValueName() const { return "int"; }
+ const char *getValueName() const override { return "int"; }
void printOptionDiff(const Option &O, int V, OptVal Default,
size_t GlobalWidth) const;
// An out-of-line virtual method to provide a 'home' for this class.
- virtual void anchor();
+ void anchor() override;
};
EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<int>);
@@ -823,13 +830,13 @@ public:
bool parse(Option &O, StringRef ArgName, StringRef Arg, unsigned &Val);
// getValueName - Overload in subclass to provide a better default value.
- virtual const char *getValueName() const { return "uint"; }
+ const char *getValueName() const override { return "uint"; }
void printOptionDiff(const Option &O, unsigned V, OptVal Default,
size_t GlobalWidth) const;
// An out-of-line virtual method to provide a 'home' for this class.
- virtual void anchor();
+ void anchor() override;
};
EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<unsigned>);
@@ -845,13 +852,13 @@ public:
unsigned long long &Val);
// getValueName - Overload in subclass to provide a better default value.
- virtual const char *getValueName() const { return "uint"; }
+ const char *getValueName() const override { return "uint"; }
void printOptionDiff(const Option &O, unsigned long long V, OptVal Default,
size_t GlobalWidth) const;
// An out-of-line virtual method to provide a 'home' for this class.
- virtual void anchor();
+ void anchor() override;
};
EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<unsigned long long>);
@@ -866,13 +873,13 @@ public:
bool parse(Option &O, StringRef ArgName, StringRef Arg, double &Val);
// getValueName - Overload in subclass to provide a better default value.
- virtual const char *getValueName() const { return "number"; }
+ const char *getValueName() const override { return "number"; }
void printOptionDiff(const Option &O, double V, OptVal Default,
size_t GlobalWidth) const;
// An out-of-line virtual method to provide a 'home' for this class.
- virtual void anchor();
+ void anchor() override;
};
EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<double>);
@@ -887,13 +894,13 @@ public:
bool parse(Option &O, StringRef ArgName, StringRef Arg, float &Val);
// getValueName - Overload in subclass to provide a better default value.
- virtual const char *getValueName() const { return "number"; }
+ const char *getValueName() const override { return "number"; }
void printOptionDiff(const Option &O, float V, OptVal Default,
size_t GlobalWidth) const;
// An out-of-line virtual method to provide a 'home' for this class.
- virtual void anchor();
+ void anchor() override;
};
EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<float>);
@@ -911,13 +918,13 @@ public:
}
// getValueName - Overload in subclass to provide a better default value.
- virtual const char *getValueName() const { return "string"; }
+ const char *getValueName() const override { return "string"; }
void printOptionDiff(const Option &O, StringRef V, OptVal Default,
size_t GlobalWidth) const;
// An out-of-line virtual method to provide a 'home' for this class.
- virtual void anchor();
+ void anchor() override;
};
EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<std::string>);
@@ -935,13 +942,13 @@ public:
}
// getValueName - Overload in subclass to provide a better default value.
- virtual const char *getValueName() const { return "char"; }
+ const char *getValueName() const override { return "char"; }
void printOptionDiff(const Option &O, char V, OptVal Default,
size_t GlobalWidth) const;
// An out-of-line virtual method to provide a 'home' for this class.
- virtual void anchor();
+ void anchor() override;
};
EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<char>);
@@ -1020,8 +1027,8 @@ template<> struct applicator<const char*> {
};
template<> struct applicator<NumOccurrencesFlag> {
- static void opt(NumOccurrencesFlag NO, Option &O) {
- O.setNumOccurrencesFlag(NO);
+ static void opt(NumOccurrencesFlag N, Option &O) {
+ O.setNumOccurrencesFlag(N);
}
};
template<> struct applicator<ValueExpected> {
@@ -1055,7 +1062,7 @@ class opt_storage {
DataType *Location; // Where to store the object...
OptionValue<DataType> Default;
- void check() const {
+ void check_location() const {
assert(Location != 0 && "cl::location(...) not specified for a command "
"line option with external storage, "
"or cl::init specified before cl::location()!!");
@@ -1073,14 +1080,14 @@ public:
template<class T>
void setValue(const T &V, bool initial = false) {
- check();
+ check_location();
*Location = V;
if (initial)
Default = V;
}
- DataType &getValue() { check(); return *Location; }
- const DataType &getValue() const { check(); return *Location; }
+ DataType &getValue() { check_location(); return *Location; }
+ const DataType &getValue() const { check_location(); return *Location; }
operator DataType() const { return this->getValue(); }
@@ -1148,11 +1155,11 @@ template <class DataType, bool ExternalStorage = false,
class ParserClass = parser<DataType> >
class opt : public Option,
public opt_storage<DataType, ExternalStorage,
- is_class<DataType>::value> {
+ std::is_class<DataType>::value> {
ParserClass Parser;
- virtual bool handleOccurrence(unsigned pos, StringRef ArgName,
- StringRef Arg) {
+ bool handleOccurrence(unsigned pos, StringRef ArgName,
+ StringRef Arg) override {
typename ParserClass::parser_data_type Val =
typename ParserClass::parser_data_type();
if (Parser.parse(*this, ArgName, Arg, Val))
@@ -1162,20 +1169,20 @@ class opt : public Option,
return false;
}
- virtual enum ValueExpected getValueExpectedFlagDefault() const {
+ enum ValueExpected getValueExpectedFlagDefault() const override {
return Parser.getValueExpectedFlagDefault();
}
- virtual void getExtraOptionNames(SmallVectorImpl<const char*> &OptionNames) {
+ void getExtraOptionNames(SmallVectorImpl<const char*> &OptionNames) override {
return Parser.getExtraOptionNames(OptionNames);
}
// Forward printing stuff to the parser...
- virtual size_t getOptionWidth() const {return Parser.getOptionWidth(*this);}
- virtual void printOptionInfo(size_t GlobalWidth) const {
+ size_t getOptionWidth() const override {return Parser.getOptionWidth(*this);}
+ void printOptionInfo(size_t GlobalWidth) const override {
Parser.printOptionInfo(*this, GlobalWidth);
}
- virtual void printOptionValue(size_t GlobalWidth, bool Force) const {
+ void printOptionValue(size_t GlobalWidth, bool Force) const override {
if (Force || this->getDefault().compare(this->getValue())) {
cl::printOptionDiff<ParserClass>(
*this, Parser, this->getValue(), this->getDefault(), GlobalWidth);
@@ -1322,14 +1329,15 @@ class list : public Option, public list_storage<DataType, Storage> {
std::vector<unsigned> Positions;
ParserClass Parser;
- virtual enum ValueExpected getValueExpectedFlagDefault() const {
+ enum ValueExpected getValueExpectedFlagDefault() const override {
return Parser.getValueExpectedFlagDefault();
}
- virtual void getExtraOptionNames(SmallVectorImpl<const char*> &OptionNames) {
+ void getExtraOptionNames(SmallVectorImpl<const char*> &OptionNames) override {
return Parser.getExtraOptionNames(OptionNames);
}
- virtual bool handleOccurrence(unsigned pos, StringRef ArgName, StringRef Arg){
+ bool handleOccurrence(unsigned pos, StringRef ArgName,
+ StringRef Arg) override {
typename ParserClass::parser_data_type Val =
typename ParserClass::parser_data_type();
if (Parser.parse(*this, ArgName, Arg, Val))
@@ -1341,13 +1349,14 @@ class list : public Option, public list_storage<DataType, Storage> {
}
// Forward printing stuff to the parser...
- virtual size_t getOptionWidth() const {return Parser.getOptionWidth(*this);}
- virtual void printOptionInfo(size_t GlobalWidth) const {
+ size_t getOptionWidth() const override {return Parser.getOptionWidth(*this);}
+ void printOptionInfo(size_t GlobalWidth) const override {
Parser.printOptionInfo(*this, GlobalWidth);
}
// Unimplemented: list options don't currently store their default value.
- virtual void printOptionValue(size_t /*GlobalWidth*/, bool /*Force*/) const {}
+ void printOptionValue(size_t /*GlobalWidth*/,
+ bool /*Force*/) const override {}
void done() {
addArgument();
@@ -1524,14 +1533,15 @@ class bits : public Option, public bits_storage<DataType, Storage> {
std::vector<unsigned> Positions;
ParserClass Parser;
- virtual enum ValueExpected getValueExpectedFlagDefault() const {
+ enum ValueExpected getValueExpectedFlagDefault() const override {
return Parser.getValueExpectedFlagDefault();
}
- virtual void getExtraOptionNames(SmallVectorImpl<const char*> &OptionNames) {
+ void getExtraOptionNames(SmallVectorImpl<const char*> &OptionNames) override {
return Parser.getExtraOptionNames(OptionNames);
}
- virtual bool handleOccurrence(unsigned pos, StringRef ArgName, StringRef Arg){
+ bool handleOccurrence(unsigned pos, StringRef ArgName,
+ StringRef Arg) override {
typename ParserClass::parser_data_type Val =
typename ParserClass::parser_data_type();
if (Parser.parse(*this, ArgName, Arg, Val))
@@ -1543,13 +1553,14 @@ class bits : public Option, public bits_storage<DataType, Storage> {
}
// Forward printing stuff to the parser...
- virtual size_t getOptionWidth() const {return Parser.getOptionWidth(*this);}
- virtual void printOptionInfo(size_t GlobalWidth) const {
+ size_t getOptionWidth() const override {return Parser.getOptionWidth(*this);}
+ void printOptionInfo(size_t GlobalWidth) const override {
Parser.printOptionInfo(*this, GlobalWidth);
}
// Unimplemented: bits options don't currently store their default values.
- virtual void printOptionValue(size_t /*GlobalWidth*/, bool /*Force*/) const {}
+ void printOptionValue(size_t /*GlobalWidth*/,
+ bool /*Force*/) const override {}
void done() {
addArgument();
@@ -1634,17 +1645,21 @@ public:
class alias : public Option {
Option *AliasFor;
- virtual bool handleOccurrence(unsigned pos, StringRef /*ArgName*/,
- StringRef Arg) LLVM_OVERRIDE {
+ bool handleOccurrence(unsigned pos, StringRef /*ArgName*/,
+ StringRef Arg) override {
return AliasFor->handleOccurrence(pos, AliasFor->ArgStr, Arg);
}
// Handle printing stuff...
- virtual size_t getOptionWidth() const LLVM_OVERRIDE;
- virtual void printOptionInfo(size_t GlobalWidth) const LLVM_OVERRIDE;
+ size_t getOptionWidth() const override;
+ void printOptionInfo(size_t GlobalWidth) const override;
// Aliases do not need to print their values.
- virtual void printOptionValue(size_t /*GlobalWidth*/,
- bool /*Force*/) const LLVM_OVERRIDE {}
+ void printOptionValue(size_t /*GlobalWidth*/,
+ bool /*Force*/) const override {}
+
+ ValueExpected getValueExpectedFlagDefault() const override {
+ return AliasFor->getValueExpectedFlag();
+ }
void done() {
if (!hasArgStr())
diff --git a/include/llvm/Support/Compiler.h b/include/llvm/Support/Compiler.h
index 860f43e..1edcd45 100644
--- a/include/llvm/Support/Compiler.h
+++ b/include/llvm/Support/Compiler.h
@@ -21,6 +21,10 @@
# define __has_feature(x) 0
#endif
+#ifndef __has_extension
+# define __has_extension(x) 0
+#endif
+
#ifndef __has_attribute
# define __has_attribute(x) 0
#endif
@@ -40,15 +44,21 @@
# endif
#endif
-/// \brief Does the compiler support r-value references?
-/// This implies that <utility> provides the one-argument std::move; it
-/// does not imply the existence of any other C++ library features.
-#if (__has_feature(cxx_rvalue_references) \
- || defined(__GXX_EXPERIMENTAL_CXX0X__) \
- || (defined(_MSC_VER) && _MSC_VER >= 1600))
-#define LLVM_HAS_RVALUE_REFERENCES 1
+/// \macro LLVM_MSC_PREREQ
+/// \brief Is the compiler MSVC of at least the specified version?
+/// The common \param version values to check for are:
+/// * 1700: Microsoft Visual Studio 2012 / 11.0
+/// * 1800: Microsoft Visual Studio 2013 / 12.0
+#ifdef _MSC_VER
+#define LLVM_MSC_PREREQ(version) (_MSC_VER >= (version))
+
+// We require at least MSVC 2012.
+#if !LLVM_MSC_PREREQ(1700)
+#error LLVM requires at least MSVC 2012.
+#endif
+
#else
-#define LLVM_HAS_RVALUE_REFERENCES 0
+#define LLVM_MSC_PREREQ(version) 0
#endif
/// \brief Does the compiler support r-value reference *this?
@@ -63,51 +73,16 @@
#define LLVM_HAS_RVALUE_REFERENCE_THIS 0
#endif
-/// \macro LLVM_HAS_CXX11_TYPETRAITS
-/// \brief Does the compiler have the C++11 type traits.
-///
-/// #include <type_traits>
-///
-/// * enable_if
-/// * {true,false}_type
-/// * is_constructible
-/// * etc...
-#if defined(__GXX_EXPERIMENTAL_CXX0X__) \
- || (defined(_MSC_VER) && _MSC_VER >= 1700)
-#define LLVM_HAS_CXX11_TYPETRAITS 1
-#else
-#define LLVM_HAS_CXX11_TYPETRAITS 0
-#endif
-
-/// \macro LLVM_HAS_CXX11_STDLIB
-/// \brief Does the compiler have the C++11 standard library.
-///
-/// Implies LLVM_HAS_RVALUE_REFERENCES, LLVM_HAS_CXX11_TYPETRAITS
-#if defined(__GXX_EXPERIMENTAL_CXX0X__) \
- || (defined(_MSC_VER) && _MSC_VER >= 1700)
-#define LLVM_HAS_CXX11_STDLIB 1
-#else
-#define LLVM_HAS_CXX11_STDLIB 0
-#endif
-
/// \macro LLVM_HAS_VARIADIC_TEMPLATES
/// \brief Does this compiler support variadic templates.
///
/// Implies LLVM_HAS_RVALUE_REFERENCES and the existence of std::forward.
-#if __has_feature(cxx_variadic_templates)
+#if __has_feature(cxx_variadic_templates) || LLVM_MSC_PREREQ(1800)
# define LLVM_HAS_VARIADIC_TEMPLATES 1
#else
# define LLVM_HAS_VARIADIC_TEMPLATES 0
#endif
-/// llvm_move - Expands to ::std::move if the compiler supports
-/// r-value references; otherwise, expands to the argument.
-#if LLVM_HAS_RVALUE_REFERENCES
-#define llvm_move(value) (::std::move(value))
-#else
-#define llvm_move(value) (value)
-#endif
-
/// Expands to '&' if r-value references are supported.
///
/// This can be used to provide l-value/r-value overrides of member functions.
@@ -129,32 +104,13 @@
/// public:
/// ...
/// };
-#if (__has_feature(cxx_deleted_functions) \
- || defined(__GXX_EXPERIMENTAL_CXX0X__))
- // No version of MSVC currently supports this.
+#if __has_feature(cxx_deleted_functions) || \
+ defined(__GXX_EXPERIMENTAL_CXX0X__) || LLVM_MSC_PREREQ(1800)
#define LLVM_DELETED_FUNCTION = delete
#else
#define LLVM_DELETED_FUNCTION
#endif
-/// LLVM_FINAL - Expands to 'final' if the compiler supports it.
-/// Use to mark classes or virtual methods as final.
-#if __has_feature(cxx_override_control) \
- || (defined(_MSC_VER) && _MSC_VER >= 1700)
-#define LLVM_FINAL final
-#else
-#define LLVM_FINAL
-#endif
-
-/// LLVM_OVERRIDE - Expands to 'override' if the compiler supports it.
-/// Use to mark virtual methods as overriding a base class method.
-#if __has_feature(cxx_override_control) \
- || (defined(_MSC_VER) && _MSC_VER >= 1700)
-#define LLVM_OVERRIDE override
-#else
-#define LLVM_OVERRIDE
-#endif
-
#if __has_feature(cxx_constexpr) || defined(__GXX_EXPERIMENTAL_CXX0X__)
# define LLVM_CONSTEXPR constexpr
#else
@@ -335,19 +291,15 @@
# 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
+# include <sanitizer/msan_interface.h>
#else
# define LLVM_MEMORY_SANITIZER_BUILD 0
+# define __msan_allocated_memory(p, size)
+# define __msan_unpoison(p, size)
#endif
/// \macro LLVM_ADDRESS_SANITIZER_BUILD
@@ -374,41 +326,30 @@
/// \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__))
+#if __has_feature(cxx_explicit_conversions) || \
+ defined(__GXX_EXPERIMENTAL_CXX0X__) || LLVM_MSC_PREREQ(1800)
#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
-
-/// \macro LLVM_ENUM_INT_TYPE
-/// \brief Expands to colon followed by the given integral type on compilers
-/// which support C++11 strong enums. This can be used to make enums unsigned
-/// with MSVC.
-#if __has_feature(cxx_strong_enums)
-# define LLVM_ENUM_INT_TYPE(intty) : intty
-#elif defined(_MSC_VER) && _MSC_VER >= 1600 // Added in MSVC 2010.
-# define LLVM_ENUM_INT_TYPE(intty) : intty
-#else
-# define LLVM_ENUM_INT_TYPE(intty)
-#endif
-
/// \brief Does the compiler support generalized initializers (using braced
-/// lists and std::initializer_list).
-#if __has_feature(cxx_generalized_initializers)
+/// lists and std::initializer_list). While clang may claim it supports general
+/// initializers, if we're using MSVC's headers, we might not have a usable
+/// std::initializer list type from the STL. Disable this for now.
+#if __has_feature(cxx_generalized_initializers) && !defined(_MSC_VER)
#define LLVM_HAS_INITIALIZER_LISTS 1
#else
#define LLVM_HAS_INITIALIZER_LISTS 0
#endif
+/// \brief Mark debug helper function definitions like dump() that should not be
+/// stripped from debug builds.
+// FIXME: Move this to a private config.h as it's not usable in public headers.
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
+#define LLVM_DUMP_METHOD LLVM_ATTRIBUTE_NOINLINE LLVM_ATTRIBUTE_USED
+#else
+#define LLVM_DUMP_METHOD LLVM_ATTRIBUTE_NOINLINE
+#endif
+
#endif
diff --git a/include/llvm/Support/Compression.h b/include/llvm/Support/Compression.h
index bef9146..80eff5c 100644
--- a/include/llvm/Support/Compression.h
+++ b/include/llvm/Support/Compression.h
@@ -15,11 +15,11 @@
#define LLVM_SUPPORT_COMPRESSION_H
#include "llvm/Support/DataTypes.h"
+#include <memory>
namespace llvm {
class MemoryBuffer;
-template<typename T> class OwningPtr;
class StringRef;
namespace zlib {
@@ -33,21 +33,21 @@ enum CompressionLevel {
enum Status {
StatusOK,
- StatusUnsupported, // zlib is unavaliable
- StatusOutOfMemory, // there was not enough memory
- StatusBufferTooShort, // there was not enough room in the output buffer
- StatusInvalidArg, // invalid input parameter
- StatusInvalidData // data was corrupted or incomplete
+ StatusUnsupported, // zlib is unavailable
+ StatusOutOfMemory, // there was not enough memory
+ StatusBufferTooShort, // there was not enough room in the output buffer
+ StatusInvalidArg, // invalid input parameter
+ StatusInvalidData // data was corrupted or incomplete
};
bool isAvailable();
Status compress(StringRef InputBuffer,
- OwningPtr<MemoryBuffer> &CompressedBuffer,
+ std::unique_ptr<MemoryBuffer> &CompressedBuffer,
CompressionLevel Level = DefaultCompression);
Status uncompress(StringRef InputBuffer,
- OwningPtr<MemoryBuffer> &UncompressedBuffer,
+ std::unique_ptr<MemoryBuffer> &UncompressedBuffer,
size_t UncompressedSize);
uint32_t crc32(StringRef Buffer);
diff --git a/include/llvm/Support/ConstantFolder.h b/include/llvm/Support/ConstantFolder.h
deleted file mode 100644
index 4aad952..0000000
--- a/include/llvm/Support/ConstantFolder.h
+++ /dev/null
@@ -1,238 +0,0 @@
-//===-- llvm/Support/ConstantFolder.h - Constant folding helper -*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the ConstantFolder class, a helper for IRBuilder.
-// It provides IRBuilder with a set of methods for creating constants
-// with minimal folding. For general constant creation and folding,
-// use ConstantExpr and the routines in llvm/Analysis/ConstantFolding.h.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SUPPORT_CONSTANTFOLDER_H
-#define LLVM_SUPPORT_CONSTANTFOLDER_H
-
-#include "llvm/IR/Constants.h"
-#include "llvm/IR/InstrTypes.h"
-
-namespace llvm {
-
-/// ConstantFolder - Create constants with minimum, target independent, folding.
-class ConstantFolder {
-public:
- explicit ConstantFolder() {}
-
- //===--------------------------------------------------------------------===//
- // Binary Operators
- //===--------------------------------------------------------------------===//
-
- Constant *CreateAdd(Constant *LHS, Constant *RHS,
- bool HasNUW = false, bool HasNSW = false) const {
- return ConstantExpr::getAdd(LHS, RHS, HasNUW, HasNSW);
- }
- Constant *CreateFAdd(Constant *LHS, Constant *RHS) const {
- return ConstantExpr::getFAdd(LHS, RHS);
- }
- Constant *CreateSub(Constant *LHS, Constant *RHS,
- bool HasNUW = false, bool HasNSW = false) const {
- return ConstantExpr::getSub(LHS, RHS, HasNUW, HasNSW);
- }
- Constant *CreateFSub(Constant *LHS, Constant *RHS) const {
- return ConstantExpr::getFSub(LHS, RHS);
- }
- Constant *CreateMul(Constant *LHS, Constant *RHS,
- bool HasNUW = false, bool HasNSW = false) const {
- return ConstantExpr::getMul(LHS, RHS, HasNUW, HasNSW);
- }
- Constant *CreateFMul(Constant *LHS, Constant *RHS) const {
- return ConstantExpr::getFMul(LHS, RHS);
- }
- Constant *CreateUDiv(Constant *LHS, Constant *RHS,
- bool isExact = false) const {
- return ConstantExpr::getUDiv(LHS, RHS, isExact);
- }
- Constant *CreateSDiv(Constant *LHS, Constant *RHS,
- bool isExact = false) const {
- return ConstantExpr::getSDiv(LHS, RHS, isExact);
- }
- Constant *CreateFDiv(Constant *LHS, Constant *RHS) const {
- return ConstantExpr::getFDiv(LHS, RHS);
- }
- Constant *CreateURem(Constant *LHS, Constant *RHS) const {
- return ConstantExpr::getURem(LHS, RHS);
- }
- Constant *CreateSRem(Constant *LHS, Constant *RHS) const {
- return ConstantExpr::getSRem(LHS, RHS);
- }
- Constant *CreateFRem(Constant *LHS, Constant *RHS) const {
- return ConstantExpr::getFRem(LHS, RHS);
- }
- Constant *CreateShl(Constant *LHS, Constant *RHS,
- bool HasNUW = false, bool HasNSW = false) const {
- return ConstantExpr::getShl(LHS, RHS, HasNUW, HasNSW);
- }
- Constant *CreateLShr(Constant *LHS, Constant *RHS,
- bool isExact = false) const {
- return ConstantExpr::getLShr(LHS, RHS, isExact);
- }
- Constant *CreateAShr(Constant *LHS, Constant *RHS,
- bool isExact = false) const {
- return ConstantExpr::getAShr(LHS, RHS, isExact);
- }
- Constant *CreateAnd(Constant *LHS, Constant *RHS) const {
- return ConstantExpr::getAnd(LHS, RHS);
- }
- Constant *CreateOr(Constant *LHS, Constant *RHS) const {
- return ConstantExpr::getOr(LHS, RHS);
- }
- Constant *CreateXor(Constant *LHS, Constant *RHS) const {
- return ConstantExpr::getXor(LHS, RHS);
- }
-
- Constant *CreateBinOp(Instruction::BinaryOps Opc,
- Constant *LHS, Constant *RHS) const {
- return ConstantExpr::get(Opc, LHS, RHS);
- }
-
- //===--------------------------------------------------------------------===//
- // Unary Operators
- //===--------------------------------------------------------------------===//
-
- Constant *CreateNeg(Constant *C,
- bool HasNUW = false, bool HasNSW = false) const {
- return ConstantExpr::getNeg(C, HasNUW, HasNSW);
- }
- Constant *CreateFNeg(Constant *C) const {
- return ConstantExpr::getFNeg(C);
- }
- Constant *CreateNot(Constant *C) const {
- return ConstantExpr::getNot(C);
- }
-
- //===--------------------------------------------------------------------===//
- // Memory Instructions
- //===--------------------------------------------------------------------===//
-
- Constant *CreateGetElementPtr(Constant *C,
- ArrayRef<Constant *> IdxList) const {
- return ConstantExpr::getGetElementPtr(C, IdxList);
- }
- Constant *CreateGetElementPtr(Constant *C, Constant *Idx) const {
- // This form of the function only exists to avoid ambiguous overload
- // warnings about whether to convert Idx to ArrayRef<Constant *> or
- // ArrayRef<Value *>.
- return ConstantExpr::getGetElementPtr(C, Idx);
- }
- Constant *CreateGetElementPtr(Constant *C,
- ArrayRef<Value *> IdxList) const {
- return ConstantExpr::getGetElementPtr(C, IdxList);
- }
-
- Constant *CreateInBoundsGetElementPtr(Constant *C,
- ArrayRef<Constant *> IdxList) const {
- return ConstantExpr::getInBoundsGetElementPtr(C, IdxList);
- }
- Constant *CreateInBoundsGetElementPtr(Constant *C, Constant *Idx) const {
- // This form of the function only exists to avoid ambiguous overload
- // warnings about whether to convert Idx to ArrayRef<Constant *> or
- // ArrayRef<Value *>.
- return ConstantExpr::getInBoundsGetElementPtr(C, Idx);
- }
- Constant *CreateInBoundsGetElementPtr(Constant *C,
- ArrayRef<Value *> IdxList) const {
- return ConstantExpr::getInBoundsGetElementPtr(C, IdxList);
- }
-
- //===--------------------------------------------------------------------===//
- // Cast/Conversion Operators
- //===--------------------------------------------------------------------===//
-
- Constant *CreateCast(Instruction::CastOps Op, Constant *C,
- Type *DestTy) const {
- return ConstantExpr::getCast(Op, C, DestTy);
- }
- Constant *CreatePointerCast(Constant *C, Type *DestTy) const {
- return ConstantExpr::getPointerCast(C, DestTy);
- }
- Constant *CreateIntCast(Constant *C, Type *DestTy,
- bool isSigned) const {
- return ConstantExpr::getIntegerCast(C, DestTy, isSigned);
- }
- Constant *CreateFPCast(Constant *C, Type *DestTy) const {
- return ConstantExpr::getFPCast(C, DestTy);
- }
-
- Constant *CreateBitCast(Constant *C, Type *DestTy) const {
- return CreateCast(Instruction::BitCast, C, DestTy);
- }
- Constant *CreateIntToPtr(Constant *C, Type *DestTy) const {
- return CreateCast(Instruction::IntToPtr, C, DestTy);
- }
- Constant *CreatePtrToInt(Constant *C, Type *DestTy) const {
- return CreateCast(Instruction::PtrToInt, C, DestTy);
- }
- Constant *CreateZExtOrBitCast(Constant *C, Type *DestTy) const {
- return ConstantExpr::getZExtOrBitCast(C, DestTy);
- }
- Constant *CreateSExtOrBitCast(Constant *C, Type *DestTy) const {
- return ConstantExpr::getSExtOrBitCast(C, DestTy);
- }
-
- Constant *CreateTruncOrBitCast(Constant *C, Type *DestTy) const {
- return ConstantExpr::getTruncOrBitCast(C, DestTy);
- }
-
- //===--------------------------------------------------------------------===//
- // Compare Instructions
- //===--------------------------------------------------------------------===//
-
- Constant *CreateICmp(CmpInst::Predicate P, Constant *LHS,
- Constant *RHS) const {
- return ConstantExpr::getCompare(P, LHS, RHS);
- }
- Constant *CreateFCmp(CmpInst::Predicate P, Constant *LHS,
- Constant *RHS) const {
- return ConstantExpr::getCompare(P, LHS, RHS);
- }
-
- //===--------------------------------------------------------------------===//
- // Other Instructions
- //===--------------------------------------------------------------------===//
-
- Constant *CreateSelect(Constant *C, Constant *True, Constant *False) const {
- return ConstantExpr::getSelect(C, True, False);
- }
-
- Constant *CreateExtractElement(Constant *Vec, Constant *Idx) const {
- return ConstantExpr::getExtractElement(Vec, Idx);
- }
-
- Constant *CreateInsertElement(Constant *Vec, Constant *NewElt,
- Constant *Idx) const {
- return ConstantExpr::getInsertElement(Vec, NewElt, Idx);
- }
-
- Constant *CreateShuffleVector(Constant *V1, Constant *V2,
- Constant *Mask) const {
- return ConstantExpr::getShuffleVector(V1, V2, Mask);
- }
-
- Constant *CreateExtractValue(Constant *Agg,
- ArrayRef<unsigned> IdxList) const {
- return ConstantExpr::getExtractValue(Agg, IdxList);
- }
-
- Constant *CreateInsertValue(Constant *Agg, Constant *Val,
- ArrayRef<unsigned> IdxList) const {
- return ConstantExpr::getInsertValue(Agg, Val, IdxList);
- }
-};
-
-}
-
-#endif
diff --git a/include/llvm/Support/ConstantRange.h b/include/llvm/Support/ConstantRange.h
deleted file mode 100644
index f757c6e..0000000
--- a/include/llvm/Support/ConstantRange.h
+++ /dev/null
@@ -1,277 +0,0 @@
-//===-- llvm/Support/ConstantRange.h - Represent a range --------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Represent a range of possible values that may occur when the program is run
-// for an integral value. This keeps track of a lower and upper bound for the
-// constant, which MAY wrap around the end of the numeric range. To do this, it
-// keeps track of a [lower, upper) bound, which specifies an interval just like
-// STL iterators. When used with boolean values, the following are important
-// ranges: :
-//
-// [F, F) = {} = Empty set
-// [T, F) = {T}
-// [F, T) = {F}
-// [T, T) = {F, T} = Full set
-//
-// The other integral ranges use min/max values for special range values. For
-// example, for 8-bit types, it uses:
-// [0, 0) = {} = Empty set
-// [255, 255) = {0..255} = Full Set
-//
-// Note that ConstantRange can be used to represent either signed or
-// unsigned ranges.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SUPPORT_CONSTANTRANGE_H
-#define LLVM_SUPPORT_CONSTANTRANGE_H
-
-#include "llvm/ADT/APInt.h"
-#include "llvm/Support/DataTypes.h"
-
-namespace llvm {
-
-/// ConstantRange - This class represents an range of values.
-///
-class ConstantRange {
- APInt Lower, Upper;
-
-#if LLVM_HAS_RVALUE_REFERENCES
- // If we have move semantics, pass APInts by value and move them into place.
- typedef APInt APIntMoveTy;
-#else
- // Otherwise pass by const ref to save one copy.
- typedef const APInt &APIntMoveTy;
-#endif
-
-public:
- /// Initialize a full (the default) or empty set for the specified bit width.
- ///
- explicit ConstantRange(uint32_t BitWidth, bool isFullSet = true);
-
- /// Initialize a range to hold the single specified value.
- ///
- ConstantRange(APIntMoveTy Value);
-
- /// @brief Initialize a range of values explicitly. This will assert out if
- /// Lower==Upper and Lower != Min or Max value for its type. It will also
- /// assert out if the two APInt's are not the same bit width.
- ConstantRange(APIntMoveTy Lower, APIntMoveTy Upper);
-
- /// makeICmpRegion - Produce the smallest range that contains all values that
- /// might satisfy the comparison specified by Pred when compared to any value
- /// contained within Other.
- ///
- /// Solves for range X in 'for all x in X, there exists a y in Y such that
- /// icmp op x, y is true'. Every value that might make the comparison true
- /// is included in the resulting range.
- static ConstantRange makeICmpRegion(unsigned Pred,
- const ConstantRange &Other);
-
- /// getLower - Return the lower value for this range...
- ///
- const APInt &getLower() const { return Lower; }
-
- /// getUpper - Return the upper value for this range...
- ///
- const APInt &getUpper() const { return Upper; }
-
- /// getBitWidth - get the bit width of this ConstantRange
- ///
- uint32_t getBitWidth() const { return Lower.getBitWidth(); }
-
- /// isFullSet - Return true if this set contains all of the elements possible
- /// for this data-type
- ///
- bool isFullSet() const;
-
- /// isEmptySet - Return true if this set contains no members.
- ///
- bool isEmptySet() const;
-
- /// isWrappedSet - Return true if this set wraps around the top of the range,
- /// for example: [100, 8)
- ///
- bool isWrappedSet() const;
-
- /// isSignWrappedSet - Return true if this set wraps around the INT_MIN of
- /// its bitwidth, for example: i8 [120, 140).
- ///
- bool isSignWrappedSet() const;
-
- /// contains - Return true if the specified value is in the set.
- ///
- bool contains(const APInt &Val) const;
-
- /// contains - Return true if the other range is a subset of this one.
- ///
- bool contains(const ConstantRange &CR) const;
-
- /// getSingleElement - If this set contains a single element, return it,
- /// otherwise return null.
- ///
- const APInt *getSingleElement() const {
- if (Upper == Lower + 1)
- return &Lower;
- return 0;
- }
-
- /// isSingleElement - Return true if this set contains exactly one member.
- ///
- bool isSingleElement() const { return getSingleElement() != 0; }
-
- /// getSetSize - Return the number of elements in this set.
- ///
- APInt getSetSize() const;
-
- /// getUnsignedMax - Return the largest unsigned value contained in the
- /// ConstantRange.
- ///
- APInt getUnsignedMax() const;
-
- /// getUnsignedMin - Return the smallest unsigned value contained in the
- /// ConstantRange.
- ///
- APInt getUnsignedMin() const;
-
- /// getSignedMax - Return the largest signed value contained in the
- /// ConstantRange.
- ///
- APInt getSignedMax() const;
-
- /// getSignedMin - Return the smallest signed value contained in the
- /// ConstantRange.
- ///
- APInt getSignedMin() const;
-
- /// operator== - Return true if this range is equal to another range.
- ///
- bool operator==(const ConstantRange &CR) const {
- return Lower == CR.Lower && Upper == CR.Upper;
- }
- bool operator!=(const ConstantRange &CR) const {
- return !operator==(CR);
- }
-
- /// subtract - Subtract the specified constant from the endpoints of this
- /// constant range.
- ConstantRange subtract(const APInt &CI) const;
-
- /// \brief Subtract the specified range from this range (aka relative
- /// complement of the sets).
- ConstantRange difference(const ConstantRange &CR) const;
-
- /// intersectWith - Return the range that results from the intersection of
- /// this range with another range. The resultant range is guaranteed to
- /// include all elements contained in both input ranges, and to have the
- /// smallest possible set size that does so. Because there may be two
- /// intersections with the same set size, A.intersectWith(B) might not
- /// be equal to B.intersectWith(A).
- ///
- ConstantRange intersectWith(const ConstantRange &CR) const;
-
- /// unionWith - Return the range that results from the union of this range
- /// with another range. The resultant range is guaranteed to include the
- /// elements of both sets, but may contain more. For example, [3, 9) union
- /// [12,15) is [3, 15), which includes 9, 10, and 11, which were not included
- /// in either set before.
- ///
- ConstantRange unionWith(const ConstantRange &CR) const;
-
- /// zeroExtend - Return a new range in the specified integer type, which must
- /// be strictly larger than the current type. The returned range will
- /// correspond to the possible range of values if the source range had been
- /// zero extended to BitWidth.
- ConstantRange zeroExtend(uint32_t BitWidth) const;
-
- /// signExtend - Return a new range in the specified integer type, which must
- /// be strictly larger than the current type. The returned range will
- /// correspond to the possible range of values if the source range had been
- /// sign extended to BitWidth.
- ConstantRange signExtend(uint32_t BitWidth) const;
-
- /// truncate - Return a new range in the specified integer type, which must be
- /// strictly smaller than the current type. The returned range will
- /// correspond to the possible range of values if the source range had been
- /// truncated to the specified type.
- ConstantRange truncate(uint32_t BitWidth) const;
-
- /// zextOrTrunc - make this range have the bit width given by \p BitWidth. The
- /// value is zero extended, truncated, or left alone to make it that width.
- ConstantRange zextOrTrunc(uint32_t BitWidth) const;
-
- /// sextOrTrunc - make this range have the bit width given by \p BitWidth. The
- /// value is sign extended, truncated, or left alone to make it that width.
- ConstantRange sextOrTrunc(uint32_t BitWidth) const;
-
- /// add - Return a new range representing the possible values resulting
- /// from an addition of a value in this range and a value in \p Other.
- ConstantRange add(const ConstantRange &Other) const;
-
- /// sub - Return a new range representing the possible values resulting
- /// from a subtraction of a value in this range and a value in \p Other.
- ConstantRange sub(const ConstantRange &Other) const;
-
- /// multiply - Return a new range representing the possible values resulting
- /// from a multiplication of a value in this range and a value in \p Other.
- /// TODO: This isn't fully implemented yet.
- ConstantRange multiply(const ConstantRange &Other) const;
-
- /// smax - Return a new range representing the possible values resulting
- /// from a signed maximum of a value in this range and a value in \p Other.
- ConstantRange smax(const ConstantRange &Other) const;
-
- /// umax - Return a new range representing the possible values resulting
- /// from an unsigned maximum of a value in this range and a value in \p Other.
- ConstantRange umax(const ConstantRange &Other) const;
-
- /// udiv - Return a new range representing the possible values resulting
- /// from an unsigned division of a value in this range and a value in
- /// \p Other.
- ConstantRange udiv(const ConstantRange &Other) const;
-
- /// binaryAnd - return a new range representing the possible values resulting
- /// from a binary-and of a value in this range by a value in \p Other.
- ConstantRange binaryAnd(const ConstantRange &Other) const;
-
- /// binaryOr - return a new range representing the possible values resulting
- /// from a binary-or of a value in this range by a value in \p Other.
- ConstantRange binaryOr(const ConstantRange &Other) const;
-
- /// shl - Return a new range representing the possible values resulting
- /// from a left shift of a value in this range by a value in \p Other.
- /// TODO: This isn't fully implemented yet.
- ConstantRange shl(const ConstantRange &Other) const;
-
- /// lshr - Return a new range representing the possible values resulting
- /// from a logical right shift of a value in this range and a value in
- /// \p Other.
- ConstantRange lshr(const ConstantRange &Other) const;
-
- /// inverse - Return a new range that is the logical not of the current set.
- ///
- ConstantRange inverse() const;
-
- /// print - Print out the bounds to a stream...
- ///
- void print(raw_ostream &OS) const;
-
- /// dump - Allow printing from a debugger easily...
- ///
- void dump() const;
-};
-
-inline raw_ostream &operator<<(raw_ostream &OS, const ConstantRange &CR) {
- CR.print(OS);
- return OS;
-}
-
-} // End llvm namespace
-
-#endif
diff --git a/include/llvm/Support/CrashRecoveryContext.h b/include/llvm/Support/CrashRecoveryContext.h
index 4c0a5e2..4500efe 100644
--- a/include/llvm/Support/CrashRecoveryContext.h
+++ b/include/llvm/Support/CrashRecoveryContext.h
@@ -46,6 +46,17 @@ class CrashRecoveryContext {
void *Impl;
CrashRecoveryContextCleanup *head;
+ /// An adaptor to convert an arbitrary functor into a void(void*), void* pair.
+ template<typename T> struct FunctorAdaptor {
+ T Fn;
+ static void invoke(void *Data) {
+ return static_cast<FunctorAdaptor<T>*>(Data)->Fn();
+ }
+ typedef void Callback(void*);
+ Callback *fn() { return &invoke; }
+ void *arg() { return this; }
+ };
+
public:
CrashRecoveryContext() : Impl(0), head(0) {}
~CrashRecoveryContext();
@@ -76,6 +87,11 @@ public:
/// RunSafely has returned false. Clients can use getBacktrace() to retrieve
/// the backtrace of the crash on failures.
bool RunSafely(void (*Fn)(void*), void *UserData);
+ template<typename Functor>
+ bool RunSafely(Functor Fn) {
+ FunctorAdaptor<Functor> Adaptor = { Fn };
+ return RunSafely(Adaptor.fn(), Adaptor.arg());
+ }
/// \brief Execute the provide callback function (with the given arguments) in
/// a protected context which is run in another thread (optionally with a
@@ -84,6 +100,11 @@ public:
/// See RunSafely() and llvm_execute_on_thread().
bool RunSafelyOnThread(void (*Fn)(void*), void *UserData,
unsigned RequestedStackSize = 0);
+ template<typename Functor>
+ bool RunSafelyOnThread(Functor Fn, unsigned RequestedStackSize = 0) {
+ FunctorAdaptor<Functor> Adaptor = { Fn };
+ return RunSafelyOnThread(Adaptor.fn(), Adaptor.arg(), RequestedStackSize);
+ }
/// \brief Explicitly trigger a crash recovery in the current process, and
/// return failure from RunSafely(). This function does not return.
diff --git a/include/llvm/Support/DataFlow.h b/include/llvm/Support/DataFlow.h
deleted file mode 100644
index a09ccaa..0000000
--- a/include/llvm/Support/DataFlow.h
+++ /dev/null
@@ -1,103 +0,0 @@
-//===-- llvm/Support/DataFlow.h - dataflow as graphs ------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines specializations of GraphTraits that allows Use-Def and
-// Def-Use relations to be treated as proper graphs for generic algorithms.
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SUPPORT_DATAFLOW_H
-#define LLVM_SUPPORT_DATAFLOW_H
-
-#include "llvm/ADT/GraphTraits.h"
-#include "llvm/IR/User.h"
-
-namespace llvm {
-
-//===----------------------------------------------------------------------===//
-// Provide specializations of GraphTraits to be able to treat def-use/use-def
-// chains as graphs
-
-template <> struct GraphTraits<const Value*> {
- typedef const Value NodeType;
- typedef Value::const_use_iterator ChildIteratorType;
-
- static NodeType *getEntryNode(const Value *G) {
- return G;
- }
-
- static inline ChildIteratorType child_begin(NodeType *N) {
- return N->use_begin();
- }
-
- static inline ChildIteratorType child_end(NodeType *N) {
- return N->use_end();
- }
-};
-
-template <> struct GraphTraits<Value*> {
- typedef Value NodeType;
- typedef Value::use_iterator ChildIteratorType;
-
- static NodeType *getEntryNode(Value *G) {
- return G;
- }
-
- static inline ChildIteratorType child_begin(NodeType *N) {
- return N->use_begin();
- }
-
- static inline ChildIteratorType child_end(NodeType *N) {
- return N->use_end();
- }
-};
-
-template <> struct GraphTraits<Inverse<const User*> > {
- typedef const Value NodeType;
- typedef User::const_op_iterator ChildIteratorType;
-
- static NodeType *getEntryNode(Inverse<const User*> G) {
- return G.Graph;
- }
-
- static inline ChildIteratorType child_begin(NodeType *N) {
- if (const User *U = dyn_cast<User>(N))
- return U->op_begin();
- return NULL;
- }
-
- static inline ChildIteratorType child_end(NodeType *N) {
- if(const User *U = dyn_cast<User>(N))
- return U->op_end();
- return NULL;
- }
-};
-
-template <> struct GraphTraits<Inverse<User*> > {
- typedef Value NodeType;
- typedef User::op_iterator ChildIteratorType;
-
- static NodeType *getEntryNode(Inverse<User*> G) {
- return G.Graph;
- }
-
- static inline ChildIteratorType child_begin(NodeType *N) {
- if (User *U = dyn_cast<User>(N))
- return U->op_begin();
- return NULL;
- }
-
- static inline ChildIteratorType child_end(NodeType *N) {
- if (User *U = dyn_cast<User>(N))
- return U->op_end();
- return NULL;
- }
-};
-
-}
-#endif
diff --git a/include/llvm/Support/DebugLoc.h b/include/llvm/Support/DebugLoc.h
deleted file mode 100644
index 05f31d7..0000000
--- a/include/llvm/Support/DebugLoc.h
+++ /dev/null
@@ -1,114 +0,0 @@
-//===---- llvm/Support/DebugLoc.h - Debug Location Information --*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines a number of light weight data structures used
-// to describe and track debug location information.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SUPPORT_DEBUGLOC_H
-#define LLVM_SUPPORT_DEBUGLOC_H
-
-#include "llvm/Support/DataTypes.h"
-
-namespace llvm {
- template <typename T> struct DenseMapInfo;
- class MDNode;
- class LLVMContext;
-
- /// DebugLoc - Debug location id. This is carried by Instruction, SDNode,
- /// and MachineInstr to compactly encode file/line/scope information for an
- /// operation.
- class DebugLoc {
- friend struct DenseMapInfo<DebugLoc>;
-
- /// getEmptyKey() - A private constructor that returns an unknown that is
- /// not equal to the tombstone key or DebugLoc().
- static DebugLoc getEmptyKey() {
- DebugLoc DL;
- DL.LineCol = 1;
- return DL;
- }
-
- /// getTombstoneKey() - A private constructor that returns an unknown that
- /// is not equal to the empty key or DebugLoc().
- static DebugLoc getTombstoneKey() {
- DebugLoc DL;
- DL.LineCol = 2;
- return DL;
- }
-
- /// LineCol - This 32-bit value encodes the line and column number for the
- /// location, encoded as 24-bits for line and 8 bits for col. A value of 0
- /// for either means unknown.
- uint32_t LineCol;
-
- /// ScopeIdx - This is an opaque ID# for Scope/InlinedAt information,
- /// decoded by LLVMContext. 0 is unknown.
- int ScopeIdx;
- public:
- DebugLoc() : LineCol(0), ScopeIdx(0) {} // Defaults to unknown.
-
- /// get - Get a new DebugLoc that corresponds to the specified line/col
- /// scope/inline location.
- static DebugLoc get(unsigned Line, unsigned Col,
- MDNode *Scope, MDNode *InlinedAt = 0);
-
- /// getFromDILocation - Translate the DILocation quad into a DebugLoc.
- static DebugLoc getFromDILocation(MDNode *N);
-
- /// getFromDILexicalBlock - Translate the DILexicalBlock into a DebugLoc.
- static DebugLoc getFromDILexicalBlock(MDNode *N);
-
- /// isUnknown - Return true if this is an unknown location.
- bool isUnknown() const { return ScopeIdx == 0; }
-
- unsigned getLine() const {
- return (LineCol << 8) >> 8; // Mask out column.
- }
-
- unsigned getCol() const {
- return LineCol >> 24;
- }
-
- /// getScope - This returns the scope pointer for this DebugLoc, or null if
- /// invalid.
- MDNode *getScope(const LLVMContext &Ctx) const;
-
- /// getInlinedAt - This returns the InlinedAt pointer for this DebugLoc, or
- /// null if invalid or not present.
- MDNode *getInlinedAt(const LLVMContext &Ctx) const;
-
- /// getScopeAndInlinedAt - Return both the Scope and the InlinedAt values.
- void getScopeAndInlinedAt(MDNode *&Scope, MDNode *&IA,
- const LLVMContext &Ctx) const;
-
-
- /// getAsMDNode - This method converts the compressed DebugLoc node into a
- /// DILocation compatible MDNode.
- MDNode *getAsMDNode(const LLVMContext &Ctx) const;
-
- bool operator==(const DebugLoc &DL) const {
- return LineCol == DL.LineCol && ScopeIdx == DL.ScopeIdx;
- }
- bool operator!=(const DebugLoc &DL) const { return !(*this == DL); }
-
- void dump(const LLVMContext &Ctx) const;
- };
-
- template <>
- struct DenseMapInfo<DebugLoc> {
- static DebugLoc getEmptyKey() { return DebugLoc::getEmptyKey(); }
- static DebugLoc getTombstoneKey() { return DebugLoc::getTombstoneKey(); }
- static unsigned getHashValue(const DebugLoc &Key);
- static bool isEqual(DebugLoc LHS, DebugLoc RHS) { return LHS == RHS; }
- };
-} // end namespace llvm
-
-#endif /* LLVM_SUPPORT_DEBUGLOC_H */
diff --git a/include/llvm/Support/Dwarf.h b/include/llvm/Support/Dwarf.h
index 23bbd1c..ca31644 100644
--- a/include/llvm/Support/Dwarf.h
+++ b/include/llvm/Support/Dwarf.h
@@ -24,7 +24,7 @@ namespace llvm {
//===----------------------------------------------------------------------===//
// Debug info constants.
-enum LLVM_ENUM_INT_TYPE(uint32_t) {
+enum : uint32_t {
LLVMDebugVersion = (12 << 16), // Current version of debug information.
LLVMDebugVersion11 = (11 << 16), // Constant for version 11.
LLVMDebugVersion10 = (10 << 16), // Constant for version 10.
@@ -41,13 +41,13 @@ namespace dwarf {
//===----------------------------------------------------------------------===//
// Dwarf constants as gleaned from the DWARF Debugging Information Format V.4
-// reference manual http://dwarf.freestandards.org.
+// reference manual http://www.dwarfstd.org/.
//
// Do not mix the following two enumerations sets. DW_TAG_invalid changes the
// enumeration base type.
-enum LLVMConstants LLVM_ENUM_INT_TYPE(uint32_t) {
+enum LLVMConstants : uint32_t {
// llvm mock tags
DW_TAG_invalid = ~0U, // Tag for invalid results.
@@ -68,7 +68,7 @@ enum LLVMConstants LLVM_ENUM_INT_TYPE(uint32_t) {
const uint32_t DW_CIE_ID = UINT32_MAX;
const uint64_t DW64_CIE_ID = UINT64_MAX;
-enum Tag LLVM_ENUM_INT_TYPE(uint16_t) {
+enum Tag : uint16_t {
DW_TAG_array_type = 0x01,
DW_TAG_class_type = 0x02,
DW_TAG_entry_point = 0x03,
@@ -129,6 +129,12 @@ enum Tag LLVM_ENUM_INT_TYPE(uint16_t) {
DW_TAG_type_unit = 0x41,
DW_TAG_rvalue_reference_type = 0x42,
DW_TAG_template_alias = 0x43,
+
+ // New in DWARF 5:
+ DW_TAG_coarray_type = 0x44,
+ DW_TAG_generic_subrange = 0x45,
+ DW_TAG_dynamic_type = 0x46,
+
DW_TAG_MIPS_loop = 0x4081,
DW_TAG_format_label = 0x4101,
DW_TAG_function_template = 0x4102,
@@ -169,7 +175,7 @@ inline bool isType(Tag T) {
}
}
-enum Attribute LLVM_ENUM_INT_TYPE(uint16_t) {
+enum Attribute : uint16_t {
// Attributes
DW_AT_sibling = 0x01,
DW_AT_location = 0x02,
@@ -264,6 +270,18 @@ enum Attribute LLVM_ENUM_INT_TYPE(uint16_t) {
DW_AT_enum_class = 0x6d,
DW_AT_linkage_name = 0x6e,
+ // New in DWARF 5:
+ DW_AT_string_length_bit_size = 0x6f,
+ DW_AT_string_length_byte_size = 0x70,
+ DW_AT_rank = 0x71,
+ DW_AT_str_offsets_base = 0x72,
+ DW_AT_addr_base = 0x73,
+ DW_AT_ranges_base = 0x74,
+ DW_AT_dwo_id = 0x75,
+ DW_AT_dwo_name = 0x76,
+ DW_AT_reference = 0x77,
+ DW_AT_rvalue_reference = 0x78,
+
DW_AT_lo_user = 0x2000,
DW_AT_hi_user = 0x3fff,
@@ -323,7 +341,7 @@ enum Attribute LLVM_ENUM_INT_TYPE(uint16_t) {
DW_AT_APPLE_property = 0x3fed
};
-enum Form LLVM_ENUM_INT_TYPE(uint16_t) {
+enum Form : uint16_t {
// Attribute form encodings
DW_FORM_addr = 0x01,
DW_FORM_block2 = 0x03,
@@ -605,7 +623,16 @@ enum SourceLanguage {
DW_LANG_ObjC_plus_plus = 0x0011,
DW_LANG_UPC = 0x0012,
DW_LANG_D = 0x0013,
+ // New in DWARF 5:
DW_LANG_Python = 0x0014,
+ DW_LANG_OpenCL = 0x0015,
+ DW_LANG_Go = 0x0016,
+ DW_LANG_Modula3 = 0x0017,
+ DW_LANG_Haskell = 0x0018,
+ DW_LANG_C_plus_plus_03 = 0x0019,
+ DW_LANG_C_plus_plus_11 = 0x001a,
+ DW_LANG_OCaml = 0x001b,
+
DW_LANG_lo_user = 0x8000,
DW_LANG_Mips_Assembler = 0x8001,
DW_LANG_hi_user = 0xffff
@@ -744,6 +771,15 @@ enum Constants {
DW_EH_PE_indirect = 0x80
};
+// Constants for debug_loc.dwo in the DWARF5 Split Debug Info Proposal
+enum LocationListEntry : unsigned char {
+ DW_LLE_end_of_list_entry,
+ DW_LLE_base_address_selection_entry,
+ DW_LLE_start_end_entry,
+ DW_LLE_start_length_entry,
+ DW_LLE_offset_pair_entry
+};
+
enum ApplePropertyAttributes {
// Apple Objective-C Property Attributes
DW_APPLE_PROPERTY_readonly = 0x01,
diff --git a/include/llvm/Support/ELF.h b/include/llvm/Support/ELF.h
index 2868f35..7b10ebd 100644
--- a/include/llvm/Support/ELF.h
+++ b/include/llvm/Support/ELF.h
@@ -651,7 +651,7 @@ enum {
};
// ARM Specific e_flags
-enum LLVM_ENUM_INT_TYPE(unsigned) {
+enum : unsigned {
EF_ARM_SOFT_FLOAT = 0x00000200U,
EF_ARM_VFP_FLOAT = 0x00000400U,
EF_ARM_EABI_UNKNOWN = 0x00000000U,
@@ -801,10 +801,12 @@ enum {
};
// Mips Specific e_flags
-enum LLVM_ENUM_INT_TYPE(unsigned) {
+enum : unsigned {
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_ABI2 = 0x00000020,
+ EF_MIPS_32BITMODE = 0x00000100,
EF_MIPS_ABI_O32 = 0x00001000, // This file follows the first MIPS 32 bit ABI
//ARCH_ASE
@@ -837,7 +839,6 @@ enum {
R_MIPS_GPREL16 = 7,
R_MIPS_LITERAL = 8,
R_MIPS_GOT16 = 9,
- R_MIPS_GOT = 9,
R_MIPS_PC16 = 10,
R_MIPS_CALL16 = 11,
R_MIPS_GPREL32 = 12,
@@ -879,6 +880,9 @@ enum {
R_MIPS_TLS_TPREL_HI16 = 49,
R_MIPS_TLS_TPREL_LO16 = 50,
R_MIPS_GLOB_DAT = 51,
+ R_MIPS16_GOT16 = 102,
+ R_MIPS16_HI16 = 104,
+ R_MIPS16_LO16 = 105,
R_MIPS_COPY = 126,
R_MIPS_JUMP_SLOT = 127,
R_MICROMIPS_26_S1 = 133,
@@ -890,11 +894,14 @@ enum {
R_MICROMIPS_GOT_DISP = 145,
R_MICROMIPS_GOT_PAGE = 146,
R_MICROMIPS_GOT_OFST = 147,
+ R_MICROMIPS_TLS_GD = 162,
+ R_MICROMIPS_TLS_LDM = 163,
R_MICROMIPS_TLS_DTPREL_HI16 = 164,
R_MICROMIPS_TLS_DTPREL_LO16 = 165,
R_MICROMIPS_TLS_TPREL_HI16 = 169,
R_MICROMIPS_TLS_TPREL_LO16 = 170,
- R_MIPS_NUM = 218
+ R_MIPS_NUM = 218,
+ R_MIPS_PC32 = 248
};
// Special values for the st_other field in the symbol table entry for MIPS.
@@ -1087,6 +1094,94 @@ enum {
R_390_IRELATIVE = 61
};
+// ELF Relocation type for Sparc.
+enum {
+ R_SPARC_NONE = 0,
+ R_SPARC_8 = 1,
+ R_SPARC_16 = 2,
+ R_SPARC_32 = 3,
+ R_SPARC_DISP8 = 4,
+ R_SPARC_DISP16 = 5,
+ R_SPARC_DISP32 = 6,
+ R_SPARC_WDISP30 = 7,
+ R_SPARC_WDISP22 = 8,
+ R_SPARC_HI22 = 9,
+ R_SPARC_22 = 10,
+ R_SPARC_13 = 11,
+ R_SPARC_LO10 = 12,
+ R_SPARC_GOT10 = 13,
+ R_SPARC_GOT13 = 14,
+ R_SPARC_GOT22 = 15,
+ R_SPARC_PC10 = 16,
+ R_SPARC_PC22 = 17,
+ R_SPARC_WPLT30 = 18,
+ R_SPARC_COPY = 19,
+ R_SPARC_GLOB_DAT = 20,
+ R_SPARC_JMP_SLOT = 21,
+ R_SPARC_RELATIVE = 22,
+ R_SPARC_UA32 = 23,
+ R_SPARC_PLT32 = 24,
+ R_SPARC_HIPLT22 = 25,
+ R_SPARC_LOPLT10 = 26,
+ R_SPARC_PCPLT32 = 27,
+ R_SPARC_PCPLT22 = 28,
+ R_SPARC_PCPLT10 = 29,
+ R_SPARC_10 = 30,
+ R_SPARC_11 = 31,
+ R_SPARC_64 = 32,
+ R_SPARC_OLO10 = 33,
+ R_SPARC_HH22 = 34,
+ R_SPARC_HM10 = 35,
+ R_SPARC_LM22 = 36,
+ R_SPARC_PC_HH22 = 37,
+ R_SPARC_PC_HM10 = 38,
+ R_SPARC_PC_LM22 = 39,
+ R_SPARC_WDISP16 = 40,
+ R_SPARC_WDISP19 = 41,
+ R_SPARC_7 = 43,
+ R_SPARC_5 = 44,
+ R_SPARC_6 = 45,
+ R_SPARC_DISP64 = 46,
+ R_SPARC_PLT64 = 47,
+ R_SPARC_HIX22 = 48,
+ R_SPARC_LOX10 = 49,
+ R_SPARC_H44 = 50,
+ R_SPARC_M44 = 51,
+ R_SPARC_L44 = 52,
+ R_SPARC_REGISTER = 53,
+ R_SPARC_UA64 = 54,
+ R_SPARC_UA16 = 55,
+ R_SPARC_TLS_GD_HI22 = 56,
+ R_SPARC_TLS_GD_LO10 = 57,
+ R_SPARC_TLS_GD_ADD = 58,
+ R_SPARC_TLS_GD_CALL = 59,
+ R_SPARC_TLS_LDM_HI22 = 60,
+ R_SPARC_TLS_LDM_LO10 = 61,
+ R_SPARC_TLS_LDM_ADD = 62,
+ R_SPARC_TLS_LDM_CALL = 63,
+ R_SPARC_TLS_LDO_HIX22 = 64,
+ R_SPARC_TLS_LDO_LOX10 = 65,
+ R_SPARC_TLS_LDO_ADD = 66,
+ R_SPARC_TLS_IE_HI22 = 67,
+ R_SPARC_TLS_IE_LO10 = 68,
+ R_SPARC_TLS_IE_LD = 69,
+ R_SPARC_TLS_IE_LDX = 70,
+ R_SPARC_TLS_IE_ADD = 71,
+ R_SPARC_TLS_LE_HIX22 = 72,
+ R_SPARC_TLS_LE_LOX10 = 73,
+ R_SPARC_TLS_DTPMOD32 = 74,
+ R_SPARC_TLS_DTPMOD64 = 75,
+ R_SPARC_TLS_DTPOFF32 = 76,
+ R_SPARC_TLS_DTPOFF64 = 77,
+ R_SPARC_TLS_TPOFF32 = 78,
+ R_SPARC_TLS_TPOFF64 = 79,
+ R_SPARC_GOTDATA_HIX22 = 80,
+ R_SPARC_GOTDATA_LOX22 = 81,
+ R_SPARC_GOTDATA_OP_HIX22 = 82,
+ R_SPARC_GOTDATA_OP_LOX22 = 83,
+ R_SPARC_GOTDATA_OP = 84
+};
+
// Section header.
struct Elf32_Shdr {
Elf32_Word sh_name; // Section name (index into string table)
@@ -1130,7 +1225,7 @@ enum {
};
// Section types.
-enum LLVM_ENUM_INT_TYPE(unsigned) {
+enum : unsigned {
SHT_NULL = 0, // No associated section (inactive entry).
SHT_PROGBITS = 1, // Program-defined contents.
SHT_SYMTAB = 2, // Symbol table.
@@ -1178,7 +1273,7 @@ enum LLVM_ENUM_INT_TYPE(unsigned) {
};
// Section flags.
-enum LLVM_ENUM_INT_TYPE(unsigned) {
+enum : unsigned {
// Section data should be writable during execution.
SHF_WRITE = 0x1,
@@ -1270,7 +1365,7 @@ enum LLVM_ENUM_INT_TYPE(unsigned) {
};
// Section Group Flags
-enum LLVM_ENUM_INT_TYPE(unsigned) {
+enum : unsigned {
GRP_COMDAT = 0x1,
GRP_MASKOS = 0x0ff00000,
GRP_MASKPROC = 0xf0000000
@@ -1492,7 +1587,7 @@ enum {
};
// Segment flag bits.
-enum LLVM_ENUM_INT_TYPE(unsigned) {
+enum : unsigned {
PF_X = 1, // Execute
PF_W = 2, // Write
PF_R = 4, // Read
diff --git a/include/llvm/Support/Endian.h b/include/llvm/Support/Endian.h
index 0d35849..2c5ab74 100644
--- a/include/llvm/Support/Endian.h
+++ b/include/llvm/Support/Endian.h
@@ -17,7 +17,6 @@
#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 {
@@ -35,6 +34,7 @@ namespace detail {
} // end namespace detail
namespace endian {
+/// Swap the bytes of value to match the given endianness.
template<typename value_type, endianness endian>
inline value_type byte_swap(value_type value) {
if (endian != native && sys::IsBigEndianHost != (endian == big))
@@ -42,6 +42,7 @@ inline value_type byte_swap(value_type value) {
return value;
}
+/// Read a value of a particular endianness from memory.
template<typename value_type,
endianness endian,
std::size_t alignment>
@@ -55,6 +56,16 @@ inline value_type read(const void *memory) {
return byte_swap<value_type, endian>(ret);
}
+/// Read a value of a particular endianness from a buffer, and increment the
+/// buffer past that value.
+template<typename value_type, endianness endian, std::size_t alignment>
+inline value_type readNext(const unsigned char *&memory) {
+ value_type ret = read<value_type, endian, alignment>(memory);
+ memory += sizeof(value_type);
+ return ret;
+}
+
+/// Write a value to memory with a particular endianness.
template<typename value_type,
endianness endian,
std::size_t alignment>
diff --git a/include/llvm/Support/EndianStream.h b/include/llvm/Support/EndianStream.h
new file mode 100644
index 0000000..89c66d3
--- /dev/null
+++ b/include/llvm/Support/EndianStream.h
@@ -0,0 +1,39 @@
+//===- EndianStream.h - Stream ops with endian specific data ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines utilities for operating on streams that have endian
+// specific data.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LLVM_SUPPORT_ENDIAN_STREAM_H_
+#define _LLVM_SUPPORT_ENDIAN_STREAM_H_
+
+#include <llvm/Support/Endian.h>
+#include <llvm/Support/raw_ostream.h>
+
+namespace llvm {
+namespace support {
+
+namespace endian {
+/// Adapter to write values to a stream in a particular byte order.
+template <endianness endian> struct Writer {
+ raw_ostream &OS;
+ Writer(raw_ostream &OS) : OS(OS) {}
+ template <typename value_type> void write(value_type Val) {
+ Val = byte_swap<value_type, endian>(Val);
+ OS.write((const char *)&Val, sizeof(value_type));
+ }
+};
+} // end namespace endian
+
+} // end namespace support
+} // end namespace llvm
+
+#endif // _LLVM_SUPPORT_ENDIAN_STREAM_H_
diff --git a/include/llvm/Support/ErrorOr.h b/include/llvm/Support/ErrorOr.h
index d5b11cb..becd957 100644
--- a/include/llvm/Support/ErrorOr.h
+++ b/include/llvm/Support/ErrorOr.h
@@ -19,15 +19,10 @@
#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 {
-#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 &&
@@ -41,12 +36,6 @@ typename std::enable_if< !std::is_constructible<T, V>::value
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>
@@ -71,11 +60,10 @@ public:
/// It is used like the following.
/// \code
/// ErrorOr<Buffer> getBuffer();
-/// void handleError(error_code ec);
///
/// auto buffer = getBuffer();
-/// if (!buffer)
-/// handleError(buffer);
+/// if (error_code ec = buffer.getError())
+/// return ec;
/// buffer->write("adena");
/// \endcode
///
@@ -93,35 +81,32 @@ public:
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;
+ static const bool isRef = std::is_reference<T>::value;
+ typedef ReferenceStorage<typename std::remove_reference<T>::type> wrap;
public:
- typedef typename
- conditional< isRef
- , wrap
- , T
- >::type storage_type;
+ typedef typename std::conditional<isRef, wrap, T>::type storage_type;
private:
- typedef typename remove_reference<T>::type &reference;
- typedef typename remove_reference<T>::type *pointer;
+ typedef typename std::remove_reference<T>::type &reference;
+ typedef const typename std::remove_reference<T>::type &const_reference;
+ typedef typename std::remove_reference<T>::type *pointer;
public:
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)
+ ErrorOr(E ErrorCode, typename std::enable_if<is_error_code_enum<E>::value ||
+ is_error_condition_enum<E>::value,
+ void *>::type = 0)
: HasError(true) {
- new (getError()) error_code(make_error_code(ErrorCode));
+ new (getErrorStorage()) error_code(make_error_code(ErrorCode));
}
ErrorOr(llvm::error_code EC) : HasError(true) {
- new (getError()) error_code(EC);
+ new (getErrorStorage()) error_code(EC);
}
ErrorOr(T Val) : HasError(false) {
- new (get()) storage_type(moveIfMoveConstructible<storage_type>(Val));
+ new (getStorage()) storage_type(moveIfMoveConstructible<storage_type>(Val));
}
ErrorOr(const ErrorOr &Other) {
@@ -144,7 +129,6 @@ public:
return *this;
}
-#if LLVM_HAS_RVALUE_REFERENCES
ErrorOr(ErrorOr &&Other) {
moveConstruct(std::move(Other));
}
@@ -164,31 +148,30 @@ public:
moveAssign(std::move(Other));
return *this;
}
-#endif
~ErrorOr() {
if (!HasError)
- get()->~storage_type();
+ getStorage()->~storage_type();
}
- typedef void (*unspecified_bool_type)();
- static void unspecified_bool_true() {}
-
/// \brief Return false if there is an error.
- operator unspecified_bool_type() const {
- return HasError ? 0 : unspecified_bool_true;
+ LLVM_EXPLICIT operator bool() const {
+ return !HasError;
}
- operator llvm::error_code() const {
- return HasError ? *getError() : llvm::error_code::success();
+ reference get() { return *getStorage(); }
+ const_reference get() const { return const_cast<ErrorOr<T> >(this)->get(); }
+
+ error_code getError() const {
+ return HasError ? *getErrorStorage() : error_code::success();
}
pointer operator ->() {
- return toPointer(get());
+ return toPointer(getStorage());
}
reference operator *() {
- return *get();
+ return *getStorage();
}
private:
@@ -197,11 +180,11 @@ private:
if (!Other.HasError) {
// Get the other value.
HasError = false;
- new (get()) storage_type(*Other.get());
+ new (getStorage()) storage_type(*Other.getStorage());
} else {
// Get other's error.
HasError = true;
- new (getError()) error_code(Other);
+ new (getErrorStorage()) error_code(Other.getError());
}
}
@@ -224,17 +207,16 @@ private:
new (this) ErrorOr(Other);
}
-#if LLVM_HAS_RVALUE_REFERENCES
template <class OtherT>
void moveConstruct(ErrorOr<OtherT> &&Other) {
if (!Other.HasError) {
// Get the other value.
HasError = false;
- new (get()) storage_type(std::move(*Other.get()));
+ new (getStorage()) storage_type(std::move(*Other.getStorage()));
} else {
// Get other's error.
HasError = true;
- new (getError()) error_code(Other);
+ new (getErrorStorage()) error_code(Other.getError());
}
}
@@ -246,7 +228,6 @@ private:
this->~ErrorOr();
new (this) ErrorOr(std::move(Other));
}
-#endif
pointer toPointer(pointer Val) {
return Val;
@@ -256,23 +237,23 @@ private:
return &Val->get();
}
- storage_type *get() {
+ storage_type *getStorage() {
assert(!HasError && "Cannot get value when an error exists!");
return reinterpret_cast<storage_type*>(TStorage.buffer);
}
- const storage_type *get() const {
+ const storage_type *getStorage() const {
assert(!HasError && "Cannot get value when an error exists!");
return reinterpret_cast<const storage_type*>(TStorage.buffer);
}
- error_code *getError() {
+ error_code *getErrorStorage() {
assert(HasError && "Cannot get error when a value exists!");
return reinterpret_cast<error_code*>(ErrorStorage.buffer);
}
- const error_code *getError() const {
- return const_cast<ErrorOr<T> *>(this)->getError();
+ const error_code *getErrorStorage() const {
+ return const_cast<ErrorOr<T> *>(this)->getErrorStorage();
}
@@ -284,8 +265,8 @@ private:
};
template<class T, class E>
-typename enable_if_c<is_error_code_enum<E>::value ||
- is_error_condition_enum<E>::value, bool>::type
+typename std::enable_if<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;
}
diff --git a/include/llvm/Support/FileOutputBuffer.h b/include/llvm/Support/FileOutputBuffer.h
index cbc9c46..1884a24 100644
--- a/include/llvm/Support/FileOutputBuffer.h
+++ b/include/llvm/Support/FileOutputBuffer.h
@@ -43,6 +43,9 @@ public:
static error_code create(StringRef FilePath, size_t Size,
OwningPtr<FileOutputBuffer> &Result,
unsigned Flags = 0);
+ static error_code create(StringRef FilePath, size_t Size,
+ std::unique_ptr<FileOutputBuffer> &Result,
+ unsigned Flags = 0);
/// Returns a pointer to the start of the buffer.
uint8_t *getBufferStart() {
@@ -83,7 +86,7 @@ private:
FileOutputBuffer(llvm::sys::fs::mapped_file_region *R,
StringRef Path, StringRef TempPath);
- OwningPtr<llvm::sys::fs::mapped_file_region> Region;
+ std::unique_ptr<llvm::sys::fs::mapped_file_region> Region;
SmallString<128> FinalPath;
SmallString<128> TempPath;
};
diff --git a/include/llvm/Support/FileSystem.h b/include/llvm/Support/FileSystem.h
index d301f84..b511a8e 100644
--- a/include/llvm/Support/FileSystem.h
+++ b/include/llvm/Support/FileSystem.h
@@ -28,7 +28,6 @@
#define LLVM_SUPPORT_FILESYSTEM_H
#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/DataTypes.h"
@@ -39,6 +38,7 @@
#include <iterator>
#include <stack>
#include <string>
+#include <tuple>
#include <vector>
#ifdef HAVE_SYS_STAT_H
@@ -49,10 +49,9 @@ namespace llvm {
namespace sys {
namespace fs {
-/// file_type - An "enum class" enumeration for the file system's view of the
-/// type.
+/// An "enum class" enumeration for the file system's view of the type.
struct file_type {
- enum _ {
+ enum Impl {
status_error,
file_not_found,
regular_file,
@@ -65,12 +64,11 @@ struct file_type {
type_unknown
};
- file_type(_ v) : v_(v) {}
- explicit file_type(int v) : v_(_(v)) {}
- operator int() const {return v_;}
+ file_type(Impl V) : V(V) {}
+ operator Impl() const { return V; }
private:
- int v_;
+ Impl V;
};
/// space_info - Self explanatory.
@@ -137,8 +135,7 @@ public:
}
bool operator!=(const UniqueID &Other) const { return !(*this == Other); }
bool operator<(const UniqueID &Other) const {
- return Device < Other.Device ||
- (Device == Other.Device && File < Other.File);
+ return std::tie(Device, File) < std::tie(Other.Device, Other.File);
}
uint64_t getDevice() const { return Device; }
uint64_t getFile() const { return File; }
@@ -272,51 +269,42 @@ private:
/// platform specific error_code.
error_code make_absolute(SmallVectorImpl<char> &path);
+/// @brief Normalize path separators in \a Path
+///
+/// If the path contains any '\' separators, they are transformed into '/'.
+/// This is particularly useful when cross-compiling Windows on Linux, but is
+/// safe to invoke on Windows, which accepts both characters as a path
+/// separator.
+error_code normalize_separators(SmallVectorImpl<char> &Path);
+
/// @brief Create all the non-existent directories in path.
///
/// @param path Directories to create.
-/// @param existed Set to true if \a path already existed, false otherwise.
-/// @returns errc::success if is_directory(path) and existed have been set,
-/// otherwise a platform specific error_code.
-error_code create_directories(const Twine &path, bool &existed);
-
-/// @brief Convenience function for clients that don't need to know if the
-/// directory existed or not.
-inline error_code create_directories(const Twine &Path) {
- bool Existed;
- return create_directories(Path, Existed);
-}
+/// @returns errc::success if is_directory(path), otherwise a platform
+/// specific error_code. If IgnoreExisting is false, also returns
+/// error if the directory already existed.
+error_code create_directories(const Twine &path, bool IgnoreExisting = true);
/// @brief Create the directory in path.
///
/// @param path Directory to create.
-/// @param existed Set to true if \a path already existed, false otherwise.
-/// @returns errc::success if is_directory(path) and existed have been set,
-/// otherwise a platform specific error_code.
-error_code create_directory(const Twine &path, bool &existed);
-
-/// @brief Convenience function for clients that don't need to know if the
-/// directory existed or not.
-inline error_code create_directory(const Twine &Path) {
- bool Existed;
- return create_directory(Path, Existed);
-}
+/// @returns errc::success if is_directory(path), otherwise a platform
+/// specific error_code. If IgnoreExisting is false, also returns
+/// error if the directory already existed.
+error_code create_directory(const Twine &path, bool IgnoreExisting = true);
-/// @brief Create a hard link from \a from to \a to.
+/// @brief Create a link from \a from to \a to.
+///
+/// The link may be a soft or a hard link, depending on the platform. The caller
+/// may not assume which one. Currently on windows it creates a hard link since
+/// soft links require extra privileges. On unix, it creates a soft link since
+/// hard links don't work on SMB file systems.
///
/// @param to The path to hard link to.
/// @param from The path to hard link from. This is created.
-/// @returns errc::success if exists(to) && exists(from) && equivalent(to, from)
-/// , otherwise a platform specific error_code.
-error_code create_hard_link(const Twine &to, const Twine &from);
-
-/// @brief Create a symbolic link from \a from to \a to.
-///
-/// @param to The path to symbolically link to.
-/// @param from The path to symbolically link from. This is created.
-/// @returns errc::success if exists(to) && exists(from) && is_symlink(from),
-/// otherwise a platform specific error_code.
-error_code create_symlink(const Twine &to, const Twine &from);
+/// @returns errc::success if the link was created, otherwise a platform
+/// specific error_code.
+error_code create_link(const Twine &to, const Twine &from);
/// @brief Get the current path.
///
@@ -328,34 +316,10 @@ error_code current_path(SmallVectorImpl<char> &result);
/// @brief Remove path. Equivalent to POSIX remove().
///
/// @param path Input path.
-/// @param existed Set to true if \a path existed, false if it did not.
-/// undefined otherwise.
-/// @returns errc::success if path has been removed and existed has been
-/// successfully set, otherwise a platform specific error_code.
-error_code remove(const Twine &path, bool &existed);
-
-/// @brief Convenience function for clients that don't need to know if the file
-/// existed or not.
-inline error_code remove(const Twine &Path) {
- bool Existed;
- return remove(Path, Existed);
-}
-
-/// @brief Recursively remove all files below \a path, then \a path. Files are
-/// removed as if by POSIX remove().
-///
-/// @param path Input path.
-/// @param num_removed Number of files removed.
-/// @returns errc::success if path has been removed and num_removed has been
-/// successfully set, otherwise a platform specific error_code.
-error_code remove_all(const Twine &path, uint32_t &num_removed);
-
-/// @brief Convenience function for clients that don't need to know how many
-/// files were removed.
-inline error_code remove_all(const Twine &Path) {
- uint32_t Removed;
- return remove_all(Path, Removed);
-}
+/// @returns errc::success if path has been removed or didn't exist, otherwise a
+/// platform specific error code. If IgnoreNonExisting is false, also
+/// returns error if the file didn't exist.
+error_code remove(const Twine &path, bool IgnoreNonExisting = true);
/// @brief Rename \a from to \a to. Files are renamed as if by POSIX rename().
///
@@ -490,8 +454,7 @@ inline bool is_regular_file(const Twine &Path) {
/// directory, regular file, or symlink?
///
/// @param status A file_status previously returned from status.
-/// @returns exists(s) && !is_regular_file(s) && !is_directory(s) &&
-/// !is_symlink(s)
+/// @returns exists(s) && !is_regular_file(s) && !is_directory(s)
bool is_other(file_status status);
/// @brief Is path something that exists but is not a directory,
@@ -504,21 +467,6 @@ bool is_other(file_status status);
/// platform specific error_code.
error_code is_other(const Twine &path, bool &result);
-/// @brief Does status represent a symlink?
-///
-/// @param status A file_status previously returned from stat.
-/// @returns status.type() == symlink_file.
-bool is_symlink(file_status status);
-
-/// @brief Is path a symlink?
-///
-/// @param path Input path.
-/// @param result Set to true if \a path is a symlink, false if it is not.
-/// Undefined otherwise.
-/// @returns errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code is_symlink(const Twine &path, bool &result);
-
/// @brief Get file status as if by POSIX stat().
///
/// @param path Input path.
@@ -545,6 +493,11 @@ inline error_code file_size(const Twine &Path, uint64_t &Result) {
return error_code::success();
}
+/// @brief Set the file modification and access time.
+///
+/// @returns errc::success if the file times were successfully set, otherwise a
+/// platform specific error_code or errc::not_supported on platforms
+/// where the functionality isn't available.
error_code setLastModificationAndAccessTime(int FD, TimeValue Time);
/// @brief Is status available?
@@ -621,9 +574,12 @@ enum OpenFlags {
/// with F_Excl.
F_Append = 2,
- /// F_Binary - The file should be opened in binary mode on platforms that
- /// make this distinction.
- F_Binary = 4
+ /// The file should be opened in text mode on platforms that make this
+ /// distinction.
+ F_Text = 4,
+
+ /// Open the file for read and write.
+ F_RW = 8
};
inline OpenFlags operator|(OpenFlags A, OpenFlags B) {
@@ -704,10 +660,8 @@ private:
public:
typedef char char_type;
-#if LLVM_HAS_RVALUE_REFERENCES
mapped_file_region(mapped_file_region&&);
mapped_file_region &operator =(mapped_file_region&&);
-#endif
/// Construct a mapped_file_region at \a path starting at \a offset of length
/// \a length and with access \a mode.
diff --git a/include/llvm/Support/FileUtilities.h b/include/llvm/Support/FileUtilities.h
index 79c59e4..873b8df 100644
--- a/include/llvm/Support/FileUtilities.h
+++ b/include/llvm/Support/FileUtilities.h
@@ -51,8 +51,7 @@ namespace llvm {
~FileRemover() {
if (DeleteIt) {
// Ignore problems deleting the file.
- bool existed;
- sys::fs::remove(Filename.str(), existed);
+ sys::fs::remove(Filename.str());
}
}
@@ -62,8 +61,7 @@ namespace llvm {
void setFile(const Twine& filename, bool deleteIt = true) {
if (DeleteIt) {
// Ignore problems deleting the file.
- bool existed;
- sys::fs::remove(Filename.str(), existed);
+ sys::fs::remove(Filename.str());
}
Filename.clear();
diff --git a/include/llvm/Support/Format.h b/include/llvm/Support/Format.h
index aaa54e1..a62801f 100644
--- a/include/llvm/Support/Format.h
+++ b/include/llvm/Support/Format.h
@@ -84,7 +84,7 @@ public:
: format_object_base(fmt), Val(val) {
}
- virtual int snprint(char *Buffer, unsigned BufferSize) const {
+ int snprint(char *Buffer, unsigned BufferSize) const override {
return snprintf(Buffer, BufferSize, Fmt, Val);
}
};
@@ -102,7 +102,7 @@ public:
: format_object_base(fmt), Val1(val1), Val2(val2) {
}
- virtual int snprint(char *Buffer, unsigned BufferSize) const {
+ int snprint(char *Buffer, unsigned BufferSize) const override {
return snprintf(Buffer, BufferSize, Fmt, Val1, Val2);
}
};
@@ -121,7 +121,7 @@ public:
: format_object_base(fmt), Val1(val1), Val2(val2), Val3(val3) {
}
- virtual int snprint(char *Buffer, unsigned BufferSize) const {
+ int snprint(char *Buffer, unsigned BufferSize) const override {
return snprintf(Buffer, BufferSize, Fmt, Val1, Val2, Val3);
}
};
@@ -142,7 +142,7 @@ public:
: format_object_base(fmt), Val1(val1), Val2(val2), Val3(val3), Val4(val4) {
}
- virtual int snprint(char *Buffer, unsigned BufferSize) const {
+ int snprint(char *Buffer, unsigned BufferSize) const override {
return snprintf(Buffer, BufferSize, Fmt, Val1, Val2, Val3, Val4);
}
};
@@ -165,7 +165,7 @@ public:
Val5(val5) {
}
- virtual int snprint(char *Buffer, unsigned BufferSize) const {
+ int snprint(char *Buffer, unsigned BufferSize) const override {
return snprintf(Buffer, BufferSize, Fmt, Val1, Val2, Val3, Val4, Val5);
}
};
diff --git a/include/llvm/Support/FormattedStream.h b/include/llvm/Support/FormattedStream.h
index df1f218..78c4809 100644
--- a/include/llvm/Support/FormattedStream.h
+++ b/include/llvm/Support/FormattedStream.h
@@ -57,11 +57,11 @@ private:
///
const char *Scanned;
- virtual void write_impl(const char *Ptr, size_t Size) LLVM_OVERRIDE;
+ void write_impl(const char *Ptr, size_t Size) 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 {
+ uint64_t current_pos() const 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).
@@ -129,25 +129,23 @@ public:
/// getLine - Return the line number
unsigned getLine() { return Position.second; }
-
- raw_ostream &resetColor() {
+
+ raw_ostream &resetColor() override {
TheStream->resetColor();
return *this;
}
-
- raw_ostream &reverseColor() {
+
+ raw_ostream &reverseColor() override {
TheStream->reverseColor();
return *this;
}
-
- raw_ostream &changeColor(enum Colors Color,
- bool Bold,
- bool BG) {
+
+ raw_ostream &changeColor(enum Colors Color, bool Bold, bool BG) override {
TheStream->changeColor(Color, Bold, BG);
return *this;
}
-
- bool is_displayed() const {
+
+ bool is_displayed() const override {
return TheStream->is_displayed();
}
diff --git a/include/llvm/Support/GCOV.h b/include/llvm/Support/GCOV.h
index 0aa716a..902f2db 100644
--- a/include/llvm/Support/GCOV.h
+++ b/include/llvm/Support/GCOV.h
@@ -1,4 +1,4 @@
-//===-- llvm/Support/GCOV.h - LLVM coverage tool ----------------*- C++ -*-===//
+//===- GCOV.h - LLVM coverage tool ----------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
//
-// This header provides the interface to read and write coverage files that
+// This header provides the interface to read and write coverage files that
// use 'gcov' format.
//
//===----------------------------------------------------------------------===//
@@ -16,6 +16,7 @@
#define LLVM_SUPPORT_GCOV_H
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Support/MemoryBuffer.h"
@@ -28,36 +29,69 @@ class GCOVBlock;
class FileInfo;
namespace GCOV {
- enum GCOVFormat {
- InvalidGCOV,
- GCNO_402,
- GCNO_404,
- GCDA_402,
- GCDA_404
+ enum GCOVVersion {
+ V402,
+ V404
};
} // end GCOV namespace
+/// GCOVOptions - A struct for passing gcov options between functions.
+struct GCOVOptions {
+ GCOVOptions(bool A, bool B, bool C, bool F, bool P, bool U)
+ : AllBlocks(A), BranchInfo(B), BranchCount(C), FuncCoverage(F),
+ PreservePaths(P), UncondBranch(U) {}
+
+ bool AllBlocks;
+ bool BranchInfo;
+ bool BranchCount;
+ bool FuncCoverage;
+ bool PreservePaths;
+ bool UncondBranch;
+};
+
/// GCOVBuffer - A wrapper around MemoryBuffer to provide GCOV specific
/// read operations.
class GCOVBuffer {
public:
GCOVBuffer(MemoryBuffer *B) : Buffer(B), Cursor(0) {}
- /// readGCOVFormat - Read GCOV signature at the beginning of buffer.
- GCOV::GCOVFormat readGCOVFormat() {
- StringRef Magic = Buffer->getBuffer().slice(0, 12);
- Cursor = 12;
- if (Magic == "oncg*404MVLL")
- return GCOV::GCNO_404;
- else if (Magic == "oncg*204MVLL")
- return GCOV::GCNO_402;
- else if (Magic == "adcg*404MVLL")
- return GCOV::GCDA_404;
- else if (Magic == "adcg*204MVLL")
- return GCOV::GCDA_402;
-
- Cursor = 0;
- return GCOV::InvalidGCOV;
+ /// readGCNOFormat - Check GCNO signature is valid at the beginning of buffer.
+ bool readGCNOFormat() {
+ StringRef File = Buffer->getBuffer().slice(0, 4);
+ if (File != "oncg") {
+ errs() << "Unexpected file type: " << File << ".\n";
+ return false;
+ }
+ Cursor = 4;
+ return true;
+ }
+
+ /// readGCDAFormat - Check GCDA signature is valid at the beginning of buffer.
+ bool readGCDAFormat() {
+ StringRef File = Buffer->getBuffer().slice(0, 4);
+ if (File != "adcg") {
+ errs() << "Unexpected file type: " << File << ".\n";
+ return false;
+ }
+ Cursor = 4;
+ return true;
+ }
+
+ /// readGCOVVersion - Read GCOV version.
+ bool readGCOVVersion(GCOV::GCOVVersion &Version) {
+ StringRef VersionStr = Buffer->getBuffer().slice(Cursor, Cursor+4);
+ if (VersionStr == "*204") {
+ Cursor += 4;
+ Version = GCOV::V402;
+ return true;
+ }
+ if (VersionStr == "*404") {
+ Cursor += 4;
+ Version = GCOV::V404;
+ return true;
+ }
+ errs() << "Unexpected version: " << VersionStr << ".\n";
+ return false;
}
/// readFunctionTag - If cursor points to a function tag then increment the
@@ -170,8 +204,11 @@ public:
}
bool readString(StringRef &Str) {
- uint32_t Len;
- if (!readInt(Len)) return false;
+ uint32_t Len = 0;
+ // Keep reading until we find a non-zero length. This emulates gcov's
+ // behaviour, which appears to do the same.
+ while (Len == 0)
+ if (!readInt(Len)) return false;
Len *= 4;
if (Buffer->getBuffer().size() < Cursor+Len) {
errs() << "Unexpected end of memory buffer: " << Cursor+Len << ".\n";
@@ -193,67 +230,188 @@ private:
/// (.gcno and .gcda).
class GCOVFile {
public:
- GCOVFile() : Functions(), RunCount(0), ProgramCount(0) {}
+ GCOVFile() : GCNOInitialized(false), Checksum(0), Functions(), RunCount(0),
+ ProgramCount(0) {}
~GCOVFile();
- bool read(GCOVBuffer &Buffer);
- void dump();
+ bool readGCNO(GCOVBuffer &Buffer);
+ bool readGCDA(GCOVBuffer &Buffer);
+ uint32_t getChecksum() const { return Checksum; }
+ void dump() const;
void collectLineCounts(FileInfo &FI);
private:
+ bool GCNOInitialized;
+ GCOV::GCOVVersion Version;
+ uint32_t Checksum;
SmallVector<GCOVFunction *, 16> Functions;
uint32_t RunCount;
uint32_t ProgramCount;
};
+/// GCOVEdge - Collects edge information.
+struct GCOVEdge {
+ GCOVEdge(GCOVBlock *S, GCOVBlock *D): Src(S), Dst(D), Count(0) {}
+
+ GCOVBlock *Src;
+ GCOVBlock *Dst;
+ uint64_t Count;
+};
+
/// GCOVFunction - Collects function information.
class GCOVFunction {
public:
- GCOVFunction() : Ident(0), LineNumber(0) {}
+ typedef SmallVectorImpl<GCOVBlock *>::const_iterator BlockIterator;
+
+ GCOVFunction(GCOVFile &P) : Parent(P), Ident(0), LineNumber(0) {}
~GCOVFunction();
- bool read(GCOVBuffer &Buffer, GCOV::GCOVFormat Format);
+ bool readGCNO(GCOVBuffer &Buffer, GCOV::GCOVVersion Version);
+ bool readGCDA(GCOVBuffer &Buffer, GCOV::GCOVVersion Version);
+ StringRef getName() const { return Name; }
StringRef getFilename() const { return Filename; }
- void dump();
+ size_t getNumBlocks() const { return Blocks.size(); }
+ uint64_t getEntryCount() const;
+ uint64_t getExitCount() const;
+
+ BlockIterator block_begin() const { return Blocks.begin(); }
+ BlockIterator block_end() const { return Blocks.end(); }
+
+ void dump() const;
void collectLineCounts(FileInfo &FI);
private:
+ GCOVFile &Parent;
uint32_t Ident;
+ uint32_t Checksum;
uint32_t LineNumber;
StringRef Name;
StringRef Filename;
SmallVector<GCOVBlock *, 16> Blocks;
+ SmallVector<GCOVEdge *, 16> Edges;
};
/// GCOVBlock - Collects block information.
class GCOVBlock {
+ struct EdgeWeight {
+ EdgeWeight(GCOVBlock *D): Dst(D), Count(0) {}
+
+ GCOVBlock *Dst;
+ uint64_t Count;
+ };
+
+ struct SortDstEdgesFunctor {
+ bool operator()(const GCOVEdge *E1, const GCOVEdge *E2) {
+ return E1->Dst->Number < E2->Dst->Number;
+ }
+ };
public:
- GCOVBlock(GCOVFunction &P, uint32_t N) :
- Parent(P), Number(N), Counter(0), Edges(), Lines() {}
+ typedef SmallVectorImpl<GCOVEdge *>::const_iterator EdgeIterator;
+
+ GCOVBlock(GCOVFunction &P, uint32_t N) : Parent(P), Number(N), Counter(0),
+ DstEdgesAreSorted(true), SrcEdges(), DstEdges(), Lines() {}
~GCOVBlock();
- void addEdge(uint32_t N) { Edges.push_back(N); }
+ const GCOVFunction &getParent() const { return Parent; }
void addLine(uint32_t N) { Lines.push_back(N); }
- void addCount(uint64_t N) { Counter += N; }
- size_t getNumEdges() { return Edges.size(); }
- void dump();
+ uint32_t getLastLine() const { return Lines.back(); }
+ void addCount(size_t DstEdgeNo, uint64_t N);
+ uint64_t getCount() const { return Counter; }
+
+ void addSrcEdge(GCOVEdge *Edge) {
+ assert(Edge->Dst == this); // up to caller to ensure edge is valid
+ SrcEdges.push_back(Edge);
+ }
+ void addDstEdge(GCOVEdge *Edge) {
+ assert(Edge->Src == this); // up to caller to ensure edge is valid
+ // Check if adding this edge causes list to become unsorted.
+ if (DstEdges.size() && DstEdges.back()->Dst->Number > Edge->Dst->Number)
+ DstEdgesAreSorted = false;
+ DstEdges.push_back(Edge);
+ }
+ size_t getNumSrcEdges() const { return SrcEdges.size(); }
+ size_t getNumDstEdges() const { return DstEdges.size(); }
+ void sortDstEdges();
+
+ EdgeIterator src_begin() const { return SrcEdges.begin(); }
+ EdgeIterator src_end() const { return SrcEdges.end(); }
+ EdgeIterator dst_begin() const { return DstEdges.begin(); }
+ EdgeIterator dst_end() const { return DstEdges.end(); }
+
+ void dump() const;
void collectLineCounts(FileInfo &FI);
private:
GCOVFunction &Parent;
uint32_t Number;
uint64_t Counter;
- SmallVector<uint32_t, 16> Edges;
+ bool DstEdgesAreSorted;
+ SmallVector<GCOVEdge *, 16> SrcEdges;
+ SmallVector<GCOVEdge *, 16> DstEdges;
SmallVector<uint32_t, 16> Lines;
};
-typedef DenseMap<uint32_t, uint64_t> LineCounts;
class FileInfo {
+ // It is unlikely--but possible--for multiple functions to be on the same line.
+ // Therefore this typedef allows LineData.Functions to store multiple functions
+ // per instance. This is rare, however, so optimize for the common case.
+ typedef SmallVector<const GCOVFunction *, 1> FunctionVector;
+ typedef DenseMap<uint32_t, FunctionVector> FunctionLines;
+ typedef SmallVector<const GCOVBlock *, 4> BlockVector;
+ typedef DenseMap<uint32_t, BlockVector> BlockLines;
+
+ struct LineData {
+ BlockLines Blocks;
+ FunctionLines Functions;
+ };
+
+ struct GCOVCoverage {
+ GCOVCoverage(StringRef Name) :
+ Name(Name), LogicalLines(0), LinesExec(0), Branches(0), BranchesExec(0),
+ BranchesTaken(0) {}
+
+ StringRef Name;
+
+ uint32_t LogicalLines;
+ uint32_t LinesExec;
+
+ uint32_t Branches;
+ uint32_t BranchesExec;
+ uint32_t BranchesTaken;
+ };
public:
- void addLineCount(StringRef Filename, uint32_t Line, uint64_t Count) {
- LineInfo[Filename][Line-1] += Count;
+ FileInfo(const GCOVOptions &Options) :
+ Options(Options), LineInfo(), RunCount(0), ProgramCount(0) {}
+
+ void addBlockLine(StringRef Filename, uint32_t Line, const GCOVBlock *Block) {
+ LineInfo[Filename].Blocks[Line-1].push_back(Block);
+ }
+ void addFunctionLine(StringRef Filename, uint32_t Line,
+ const GCOVFunction *Function) {
+ LineInfo[Filename].Functions[Line-1].push_back(Function);
}
void setRunCount(uint32_t Runs) { RunCount = Runs; }
void setProgramCount(uint32_t Programs) { ProgramCount = Programs; }
- void print(raw_fd_ostream &OS, StringRef gcnoFile, StringRef gcdaFile);
+ void print(StringRef GCNOFile, StringRef GCDAFile);
private:
- StringMap<LineCounts> LineInfo;
+ void printFunctionSummary(raw_fd_ostream &OS,
+ const FunctionVector &Funcs) const;
+ void printBlockInfo(raw_fd_ostream &OS, const GCOVBlock &Block,
+ uint32_t LineIndex, uint32_t &BlockNo) const;
+ void printBranchInfo(raw_fd_ostream &OS, const GCOVBlock &Block,
+ GCOVCoverage &Coverage, uint32_t &EdgeNo);
+ void printUncondBranchInfo(raw_fd_ostream &OS, uint32_t &EdgeNo,
+ uint64_t Count) const;
+
+ void printCoverage(const GCOVCoverage &Coverage) const;
+ void printFuncCoverage() const;
+ void printFileCoverage() const;
+
+ const GCOVOptions &Options;
+ StringMap<LineData> LineInfo;
uint32_t RunCount;
uint32_t ProgramCount;
+
+ typedef SmallVector<std::pair<std::string, GCOVCoverage>, 4>
+ FileCoverageList;
+ typedef MapVector<const GCOVFunction *, GCOVCoverage> FuncCoverageMap;
+
+ FileCoverageList FileCoverages;
+ FuncCoverageMap FuncCoverages;
};
}
diff --git a/include/llvm/Support/GenericDomTree.h b/include/llvm/Support/GenericDomTree.h
new file mode 100644
index 0000000..6878844
--- /dev/null
+++ b/include/llvm/Support/GenericDomTree.h
@@ -0,0 +1,717 @@
+//===- GenericDomTree.h - Generic dominator trees for graphs ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+/// \file
+///
+/// This file defines a set of templates that efficiently compute a dominator
+/// tree over a generic graph. This is used typically in LLVM for fast
+/// dominance queries on the CFG, but is fully generic w.r.t. the underlying
+/// graph types.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_GENERIC_DOM_TREE_H
+#define LLVM_SUPPORT_GENERIC_DOM_TREE_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DepthFirstIterator.h"
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+/// DominatorBase - Base class that other, more interesting dominator analyses
+/// inherit from.
+///
+template <class NodeT>
+class DominatorBase {
+protected:
+ std::vector<NodeT*> Roots;
+ const bool IsPostDominators;
+ inline explicit DominatorBase(bool isPostDom) :
+ Roots(), IsPostDominators(isPostDom) {}
+public:
+
+ /// getRoots - Return the root blocks of the current CFG. This may include
+ /// multiple blocks if we are computing post dominators. For forward
+ /// dominators, this will always be a single block (the entry node).
+ ///
+ inline const std::vector<NodeT*> &getRoots() const { return Roots; }
+
+ /// isPostDominator - Returns true if analysis based of postdoms
+ ///
+ bool isPostDominator() const { return IsPostDominators; }
+};
+
+
+//===----------------------------------------------------------------------===//
+// DomTreeNodeBase - Dominator Tree Node
+template<class NodeT> class DominatorTreeBase;
+struct PostDominatorTree;
+
+template <class NodeT>
+class DomTreeNodeBase {
+ NodeT *TheBB;
+ DomTreeNodeBase<NodeT> *IDom;
+ std::vector<DomTreeNodeBase<NodeT> *> Children;
+ mutable int DFSNumIn, DFSNumOut;
+
+ template<class N> friend class DominatorTreeBase;
+ friend struct PostDominatorTree;
+public:
+ typedef typename std::vector<DomTreeNodeBase<NodeT> *>::iterator iterator;
+ typedef typename std::vector<DomTreeNodeBase<NodeT> *>::const_iterator
+ const_iterator;
+
+ iterator begin() { return Children.begin(); }
+ iterator end() { return Children.end(); }
+ const_iterator begin() const { return Children.begin(); }
+ const_iterator end() const { return Children.end(); }
+
+ NodeT *getBlock() const { return TheBB; }
+ DomTreeNodeBase<NodeT> *getIDom() const { return IDom; }
+ const std::vector<DomTreeNodeBase<NodeT>*> &getChildren() const {
+ return Children;
+ }
+
+ DomTreeNodeBase(NodeT *BB, DomTreeNodeBase<NodeT> *iDom)
+ : TheBB(BB), IDom(iDom), DFSNumIn(-1), DFSNumOut(-1) { }
+
+ DomTreeNodeBase<NodeT> *addChild(DomTreeNodeBase<NodeT> *C) {
+ Children.push_back(C);
+ return C;
+ }
+
+ size_t getNumChildren() const {
+ return Children.size();
+ }
+
+ void clearAllChildren() {
+ Children.clear();
+ }
+
+ bool compare(const DomTreeNodeBase<NodeT> *Other) const {
+ if (getNumChildren() != Other->getNumChildren())
+ return true;
+
+ SmallPtrSet<const NodeT *, 4> OtherChildren;
+ for (const_iterator I = Other->begin(), E = Other->end(); I != E; ++I) {
+ const NodeT *Nd = (*I)->getBlock();
+ OtherChildren.insert(Nd);
+ }
+
+ for (const_iterator I = begin(), E = end(); I != E; ++I) {
+ const NodeT *N = (*I)->getBlock();
+ if (OtherChildren.count(N) == 0)
+ return true;
+ }
+ return false;
+ }
+
+ void setIDom(DomTreeNodeBase<NodeT> *NewIDom) {
+ assert(IDom && "No immediate dominator?");
+ if (IDom != NewIDom) {
+ typename std::vector<DomTreeNodeBase<NodeT>*>::iterator I =
+ std::find(IDom->Children.begin(), IDom->Children.end(), this);
+ assert(I != IDom->Children.end() &&
+ "Not in immediate dominator children set!");
+ // I am no longer your child...
+ IDom->Children.erase(I);
+
+ // Switch to new dominator
+ IDom = NewIDom;
+ IDom->Children.push_back(this);
+ }
+ }
+
+ /// getDFSNumIn/getDFSNumOut - These are an internal implementation detail, do
+ /// not call them.
+ unsigned getDFSNumIn() const { return DFSNumIn; }
+ unsigned getDFSNumOut() const { return DFSNumOut; }
+private:
+ // Return true if this node is dominated by other. Use this only if DFS info
+ // is valid.
+ bool DominatedBy(const DomTreeNodeBase<NodeT> *other) const {
+ return this->DFSNumIn >= other->DFSNumIn &&
+ this->DFSNumOut <= other->DFSNumOut;
+ }
+};
+
+template<class NodeT>
+inline raw_ostream &operator<<(raw_ostream &o,
+ const DomTreeNodeBase<NodeT> *Node) {
+ if (Node->getBlock())
+ Node->getBlock()->printAsOperand(o, false);
+ else
+ o << " <<exit node>>";
+
+ o << " {" << Node->getDFSNumIn() << "," << Node->getDFSNumOut() << "}";
+
+ return o << "\n";
+}
+
+template<class NodeT>
+inline void PrintDomTree(const DomTreeNodeBase<NodeT> *N, raw_ostream &o,
+ unsigned Lev) {
+ o.indent(2*Lev) << "[" << Lev << "] " << N;
+ for (typename DomTreeNodeBase<NodeT>::const_iterator I = N->begin(),
+ E = N->end(); I != E; ++I)
+ PrintDomTree<NodeT>(*I, o, Lev+1);
+}
+
+//===----------------------------------------------------------------------===//
+/// DominatorTree - Calculate the immediate dominator tree for a function.
+///
+
+template<class FuncT, class N>
+void Calculate(DominatorTreeBase<typename GraphTraits<N>::NodeType>& DT,
+ FuncT& F);
+
+template<class NodeT>
+class DominatorTreeBase : public DominatorBase<NodeT> {
+ bool dominatedBySlowTreeWalk(const DomTreeNodeBase<NodeT> *A,
+ const DomTreeNodeBase<NodeT> *B) const {
+ assert(A != B);
+ assert(isReachableFromEntry(B));
+ assert(isReachableFromEntry(A));
+
+ const DomTreeNodeBase<NodeT> *IDom;
+ while ((IDom = B->getIDom()) != 0 && IDom != A && IDom != B)
+ B = IDom; // Walk up the tree
+ return IDom != 0;
+ }
+
+protected:
+ typedef DenseMap<NodeT*, DomTreeNodeBase<NodeT>*> DomTreeNodeMapType;
+ DomTreeNodeMapType DomTreeNodes;
+ DomTreeNodeBase<NodeT> *RootNode;
+
+ mutable bool DFSInfoValid;
+ mutable unsigned int SlowQueries;
+ // Information record used during immediate dominators computation.
+ struct InfoRec {
+ unsigned DFSNum;
+ unsigned Parent;
+ unsigned Semi;
+ NodeT *Label;
+
+ InfoRec() : DFSNum(0), Parent(0), Semi(0), Label(0) {}
+ };
+
+ DenseMap<NodeT*, NodeT*> IDoms;
+
+ // Vertex - Map the DFS number to the NodeT*
+ std::vector<NodeT*> Vertex;
+
+ // Info - Collection of information used during the computation of idoms.
+ DenseMap<NodeT*, InfoRec> Info;
+
+ void reset() {
+ for (typename DomTreeNodeMapType::iterator I = this->DomTreeNodes.begin(),
+ E = DomTreeNodes.end(); I != E; ++I)
+ delete I->second;
+ DomTreeNodes.clear();
+ IDoms.clear();
+ this->Roots.clear();
+ Vertex.clear();
+ RootNode = 0;
+ }
+
+ // NewBB is split and now it has one successor. Update dominator tree to
+ // reflect this change.
+ template<class N, class GraphT>
+ void Split(DominatorTreeBase<typename GraphT::NodeType>& DT,
+ typename GraphT::NodeType* NewBB) {
+ assert(std::distance(GraphT::child_begin(NewBB),
+ GraphT::child_end(NewBB)) == 1 &&
+ "NewBB should have a single successor!");
+ typename GraphT::NodeType* NewBBSucc = *GraphT::child_begin(NewBB);
+
+ std::vector<typename GraphT::NodeType*> PredBlocks;
+ typedef GraphTraits<Inverse<N> > InvTraits;
+ for (typename InvTraits::ChildIteratorType PI =
+ InvTraits::child_begin(NewBB),
+ PE = InvTraits::child_end(NewBB); PI != PE; ++PI)
+ PredBlocks.push_back(*PI);
+
+ assert(!PredBlocks.empty() && "No predblocks?");
+
+ bool NewBBDominatesNewBBSucc = true;
+ for (typename InvTraits::ChildIteratorType PI =
+ InvTraits::child_begin(NewBBSucc),
+ E = InvTraits::child_end(NewBBSucc); PI != E; ++PI) {
+ typename InvTraits::NodeType *ND = *PI;
+ if (ND != NewBB && !DT.dominates(NewBBSucc, ND) &&
+ DT.isReachableFromEntry(ND)) {
+ NewBBDominatesNewBBSucc = false;
+ break;
+ }
+ }
+
+ // Find NewBB's immediate dominator and create new dominator tree node for
+ // NewBB.
+ NodeT *NewBBIDom = 0;
+ unsigned i = 0;
+ for (i = 0; i < PredBlocks.size(); ++i)
+ if (DT.isReachableFromEntry(PredBlocks[i])) {
+ NewBBIDom = PredBlocks[i];
+ break;
+ }
+
+ // It's possible that none of the predecessors of NewBB are reachable;
+ // in that case, NewBB itself is unreachable, so nothing needs to be
+ // changed.
+ if (!NewBBIDom)
+ return;
+
+ for (i = i + 1; i < PredBlocks.size(); ++i) {
+ if (DT.isReachableFromEntry(PredBlocks[i]))
+ NewBBIDom = DT.findNearestCommonDominator(NewBBIDom, PredBlocks[i]);
+ }
+
+ // Create the new dominator tree node... and set the idom of NewBB.
+ DomTreeNodeBase<NodeT> *NewBBNode = DT.addNewBlock(NewBB, NewBBIDom);
+
+ // If NewBB strictly dominates other blocks, then it is now the immediate
+ // dominator of NewBBSucc. Update the dominator tree as appropriate.
+ if (NewBBDominatesNewBBSucc) {
+ DomTreeNodeBase<NodeT> *NewBBSuccNode = DT.getNode(NewBBSucc);
+ DT.changeImmediateDominator(NewBBSuccNode, NewBBNode);
+ }
+ }
+
+public:
+ explicit DominatorTreeBase(bool isPostDom)
+ : DominatorBase<NodeT>(isPostDom), DFSInfoValid(false), SlowQueries(0) {}
+ virtual ~DominatorTreeBase() { reset(); }
+
+ /// compare - Return false if the other dominator tree base matches this
+ /// dominator tree base. Otherwise return true.
+ bool compare(const DominatorTreeBase &Other) const {
+
+ const DomTreeNodeMapType &OtherDomTreeNodes = Other.DomTreeNodes;
+ if (DomTreeNodes.size() != OtherDomTreeNodes.size())
+ return true;
+
+ for (typename DomTreeNodeMapType::const_iterator
+ I = this->DomTreeNodes.begin(),
+ E = this->DomTreeNodes.end(); I != E; ++I) {
+ NodeT *BB = I->first;
+ typename DomTreeNodeMapType::const_iterator OI = OtherDomTreeNodes.find(BB);
+ if (OI == OtherDomTreeNodes.end())
+ return true;
+
+ DomTreeNodeBase<NodeT>* MyNd = I->second;
+ DomTreeNodeBase<NodeT>* OtherNd = OI->second;
+
+ if (MyNd->compare(OtherNd))
+ return true;
+ }
+
+ return false;
+ }
+
+ virtual void releaseMemory() { reset(); }
+
+ /// getNode - return the (Post)DominatorTree node for the specified basic
+ /// block. This is the same as using operator[] on this class.
+ ///
+ inline DomTreeNodeBase<NodeT> *getNode(NodeT *BB) const {
+ return DomTreeNodes.lookup(BB);
+ }
+
+ /// getRootNode - This returns the entry node for the CFG of the function. If
+ /// this tree represents the post-dominance relations for a function, however,
+ /// this root may be a node with the block == NULL. This is the case when
+ /// there are multiple exit nodes from a particular function. Consumers of
+ /// post-dominance information must be capable of dealing with this
+ /// possibility.
+ ///
+ DomTreeNodeBase<NodeT> *getRootNode() { return RootNode; }
+ const DomTreeNodeBase<NodeT> *getRootNode() const { return RootNode; }
+
+ /// Get all nodes dominated by R, including R itself.
+ void getDescendants(NodeT *R, SmallVectorImpl<NodeT *> &Result) const {
+ Result.clear();
+ const DomTreeNodeBase<NodeT> *RN = getNode(R);
+ if (RN == NULL)
+ return; // If R is unreachable, it will not be present in the DOM tree.
+ SmallVector<const DomTreeNodeBase<NodeT> *, 8> WL;
+ WL.push_back(RN);
+
+ while (!WL.empty()) {
+ const DomTreeNodeBase<NodeT> *N = WL.pop_back_val();
+ Result.push_back(N->getBlock());
+ WL.append(N->begin(), N->end());
+ }
+ }
+
+ /// properlyDominates - Returns true iff A dominates B and A != B.
+ /// Note that this is not a constant time operation!
+ ///
+ bool properlyDominates(const DomTreeNodeBase<NodeT> *A,
+ const DomTreeNodeBase<NodeT> *B) const {
+ if (A == 0 || B == 0)
+ return false;
+ if (A == B)
+ return false;
+ return dominates(A, B);
+ }
+
+ bool properlyDominates(const NodeT *A, const NodeT *B) const;
+
+ /// isReachableFromEntry - Return true if A is dominated by the entry
+ /// block of the function containing it.
+ bool isReachableFromEntry(const NodeT* A) const {
+ assert(!this->isPostDominator() &&
+ "This is not implemented for post dominators");
+ return isReachableFromEntry(getNode(const_cast<NodeT *>(A)));
+ }
+
+ inline bool isReachableFromEntry(const DomTreeNodeBase<NodeT> *A) const {
+ return A;
+ }
+
+ /// dominates - Returns true iff A dominates B. Note that this is not a
+ /// constant time operation!
+ ///
+ inline bool dominates(const DomTreeNodeBase<NodeT> *A,
+ const DomTreeNodeBase<NodeT> *B) const {
+ // A node trivially dominates itself.
+ if (B == A)
+ return true;
+
+ // An unreachable node is dominated by anything.
+ if (!isReachableFromEntry(B))
+ return true;
+
+ // And dominates nothing.
+ if (!isReachableFromEntry(A))
+ return false;
+
+ // Compare the result of the tree walk and the dfs numbers, if expensive
+ // checks are enabled.
+#ifdef XDEBUG
+ assert((!DFSInfoValid ||
+ (dominatedBySlowTreeWalk(A, B) == B->DominatedBy(A))) &&
+ "Tree walk disagrees with dfs numbers!");
+#endif
+
+ if (DFSInfoValid)
+ return B->DominatedBy(A);
+
+ // If we end up with too many slow queries, just update the
+ // DFS numbers on the theory that we are going to keep querying.
+ SlowQueries++;
+ if (SlowQueries > 32) {
+ updateDFSNumbers();
+ return B->DominatedBy(A);
+ }
+
+ return dominatedBySlowTreeWalk(A, B);
+ }
+
+ bool dominates(const NodeT *A, const NodeT *B) const;
+
+ NodeT *getRoot() const {
+ assert(this->Roots.size() == 1 && "Should always have entry node!");
+ return this->Roots[0];
+ }
+
+ /// findNearestCommonDominator - Find nearest common dominator basic block
+ /// for basic block A and B. If there is no such block then return NULL.
+ NodeT *findNearestCommonDominator(NodeT *A, NodeT *B) {
+ assert(A->getParent() == B->getParent() &&
+ "Two blocks are not in same function");
+
+ // If either A or B is a entry block then it is nearest common dominator
+ // (for forward-dominators).
+ if (!this->isPostDominator()) {
+ NodeT &Entry = A->getParent()->front();
+ if (A == &Entry || B == &Entry)
+ return &Entry;
+ }
+
+ // If B dominates A then B is nearest common dominator.
+ if (dominates(B, A))
+ return B;
+
+ // If A dominates B then A is nearest common dominator.
+ if (dominates(A, B))
+ return A;
+
+ DomTreeNodeBase<NodeT> *NodeA = getNode(A);
+ DomTreeNodeBase<NodeT> *NodeB = getNode(B);
+
+ // Collect NodeA dominators set.
+ SmallPtrSet<DomTreeNodeBase<NodeT>*, 16> NodeADoms;
+ NodeADoms.insert(NodeA);
+ DomTreeNodeBase<NodeT> *IDomA = NodeA->getIDom();
+ while (IDomA) {
+ NodeADoms.insert(IDomA);
+ IDomA = IDomA->getIDom();
+ }
+
+ // Walk NodeB immediate dominators chain and find common dominator node.
+ DomTreeNodeBase<NodeT> *IDomB = NodeB->getIDom();
+ while (IDomB) {
+ if (NodeADoms.count(IDomB) != 0)
+ return IDomB->getBlock();
+
+ IDomB = IDomB->getIDom();
+ }
+
+ return NULL;
+ }
+
+ const NodeT *findNearestCommonDominator(const NodeT *A, const NodeT *B) {
+ // Cast away the const qualifiers here. This is ok since
+ // const is re-introduced on the return type.
+ return findNearestCommonDominator(const_cast<NodeT *>(A),
+ const_cast<NodeT *>(B));
+ }
+
+ //===--------------------------------------------------------------------===//
+ // API to update (Post)DominatorTree information based on modifications to
+ // the CFG...
+
+ /// addNewBlock - Add a new node to the dominator tree information. This
+ /// creates a new node as a child of DomBB dominator node,linking it into
+ /// the children list of the immediate dominator.
+ DomTreeNodeBase<NodeT> *addNewBlock(NodeT *BB, NodeT *DomBB) {
+ assert(getNode(BB) == 0 && "Block already in dominator tree!");
+ DomTreeNodeBase<NodeT> *IDomNode = getNode(DomBB);
+ assert(IDomNode && "Not immediate dominator specified for block!");
+ DFSInfoValid = false;
+ return DomTreeNodes[BB] =
+ IDomNode->addChild(new DomTreeNodeBase<NodeT>(BB, IDomNode));
+ }
+
+ /// changeImmediateDominator - This method is used to update the dominator
+ /// tree information when a node's immediate dominator changes.
+ ///
+ void changeImmediateDominator(DomTreeNodeBase<NodeT> *N,
+ DomTreeNodeBase<NodeT> *NewIDom) {
+ assert(N && NewIDom && "Cannot change null node pointers!");
+ DFSInfoValid = false;
+ N->setIDom(NewIDom);
+ }
+
+ void changeImmediateDominator(NodeT *BB, NodeT *NewBB) {
+ changeImmediateDominator(getNode(BB), getNode(NewBB));
+ }
+
+ /// eraseNode - Removes a node from the dominator tree. Block must not
+ /// dominate any other blocks. Removes node from its immediate dominator's
+ /// children list. Deletes dominator node associated with basic block BB.
+ void eraseNode(NodeT *BB) {
+ DomTreeNodeBase<NodeT> *Node = getNode(BB);
+ assert(Node && "Removing node that isn't in dominator tree.");
+ assert(Node->getChildren().empty() && "Node is not a leaf node.");
+
+ // Remove node from immediate dominator's children list.
+ DomTreeNodeBase<NodeT> *IDom = Node->getIDom();
+ if (IDom) {
+ typename std::vector<DomTreeNodeBase<NodeT>*>::iterator I =
+ std::find(IDom->Children.begin(), IDom->Children.end(), Node);
+ assert(I != IDom->Children.end() &&
+ "Not in immediate dominator children set!");
+ // I am no longer your child...
+ IDom->Children.erase(I);
+ }
+
+ DomTreeNodes.erase(BB);
+ delete Node;
+ }
+
+ /// removeNode - Removes a node from the dominator tree. Block must not
+ /// dominate any other blocks. Invalidates any node pointing to removed
+ /// block.
+ void removeNode(NodeT *BB) {
+ assert(getNode(BB) && "Removing node that isn't in dominator tree.");
+ DomTreeNodes.erase(BB);
+ }
+
+ /// splitBlock - BB is split and now it has one successor. Update dominator
+ /// tree to reflect this change.
+ void splitBlock(NodeT* NewBB) {
+ if (this->IsPostDominators)
+ this->Split<Inverse<NodeT*>, GraphTraits<Inverse<NodeT*> > >(*this, NewBB);
+ else
+ this->Split<NodeT*, GraphTraits<NodeT*> >(*this, NewBB);
+ }
+
+ /// print - Convert to human readable form
+ ///
+ void print(raw_ostream &o) const {
+ o << "=============================--------------------------------\n";
+ if (this->isPostDominator())
+ o << "Inorder PostDominator Tree: ";
+ else
+ o << "Inorder Dominator Tree: ";
+ if (!this->DFSInfoValid)
+ o << "DFSNumbers invalid: " << SlowQueries << " slow queries.";
+ o << "\n";
+
+ // The postdom tree can have a null root if there are no returns.
+ if (getRootNode())
+ PrintDomTree<NodeT>(getRootNode(), o, 1);
+ }
+
+protected:
+ template<class GraphT>
+ friend typename GraphT::NodeType* Eval(
+ DominatorTreeBase<typename GraphT::NodeType>& DT,
+ typename GraphT::NodeType* V,
+ unsigned LastLinked);
+
+ template<class GraphT>
+ friend unsigned DFSPass(DominatorTreeBase<typename GraphT::NodeType>& DT,
+ typename GraphT::NodeType* V,
+ unsigned N);
+
+ template<class FuncT, class N>
+ friend void Calculate(DominatorTreeBase<typename GraphTraits<N>::NodeType>& DT,
+ FuncT& F);
+
+ /// updateDFSNumbers - Assign In and Out numbers to the nodes while walking
+ /// dominator tree in dfs order.
+ void updateDFSNumbers() const {
+ unsigned DFSNum = 0;
+
+ SmallVector<std::pair<const DomTreeNodeBase<NodeT>*,
+ typename DomTreeNodeBase<NodeT>::const_iterator>, 32> WorkStack;
+
+ const DomTreeNodeBase<NodeT> *ThisRoot = getRootNode();
+
+ if (!ThisRoot)
+ return;
+
+ // Even in the case of multiple exits that form the post dominator root
+ // nodes, do not iterate over all exits, but start from the virtual root
+ // node. Otherwise bbs, that are not post dominated by any exit but by the
+ // virtual root node, will never be assigned a DFS number.
+ WorkStack.push_back(std::make_pair(ThisRoot, ThisRoot->begin()));
+ ThisRoot->DFSNumIn = DFSNum++;
+
+ while (!WorkStack.empty()) {
+ const DomTreeNodeBase<NodeT> *Node = WorkStack.back().first;
+ typename DomTreeNodeBase<NodeT>::const_iterator ChildIt =
+ WorkStack.back().second;
+
+ // If we visited all of the children of this node, "recurse" back up the
+ // stack setting the DFOutNum.
+ if (ChildIt == Node->end()) {
+ Node->DFSNumOut = DFSNum++;
+ WorkStack.pop_back();
+ } else {
+ // Otherwise, recursively visit this child.
+ const DomTreeNodeBase<NodeT> *Child = *ChildIt;
+ ++WorkStack.back().second;
+
+ WorkStack.push_back(std::make_pair(Child, Child->begin()));
+ Child->DFSNumIn = DFSNum++;
+ }
+ }
+
+ SlowQueries = 0;
+ DFSInfoValid = true;
+ }
+
+ DomTreeNodeBase<NodeT> *getNodeForBlock(NodeT *BB) {
+ if (DomTreeNodeBase<NodeT> *Node = getNode(BB))
+ return Node;
+
+ // Haven't calculated this node yet? Get or calculate the node for the
+ // immediate dominator.
+ NodeT *IDom = getIDom(BB);
+
+ assert(IDom || this->DomTreeNodes[NULL]);
+ DomTreeNodeBase<NodeT> *IDomNode = getNodeForBlock(IDom);
+
+ // Add a new tree node for this NodeT, and link it as a child of
+ // IDomNode
+ DomTreeNodeBase<NodeT> *C = new DomTreeNodeBase<NodeT>(BB, IDomNode);
+ return this->DomTreeNodes[BB] = IDomNode->addChild(C);
+ }
+
+ inline NodeT *getIDom(NodeT *BB) const {
+ return IDoms.lookup(BB);
+ }
+
+ inline void addRoot(NodeT* BB) {
+ this->Roots.push_back(BB);
+ }
+
+public:
+ /// recalculate - compute a dominator tree for the given function
+ template<class FT>
+ void recalculate(FT& F) {
+ typedef GraphTraits<FT*> TraitsTy;
+ reset();
+ this->Vertex.push_back(0);
+
+ if (!this->IsPostDominators) {
+ // Initialize root
+ NodeT *entry = TraitsTy::getEntryNode(&F);
+ this->Roots.push_back(entry);
+ this->IDoms[entry] = 0;
+ this->DomTreeNodes[entry] = 0;
+
+ Calculate<FT, NodeT*>(*this, F);
+ } else {
+ // Initialize the roots list
+ for (typename TraitsTy::nodes_iterator I = TraitsTy::nodes_begin(&F),
+ E = TraitsTy::nodes_end(&F); I != E; ++I) {
+ if (TraitsTy::child_begin(I) == TraitsTy::child_end(I))
+ addRoot(I);
+
+ // Prepopulate maps so that we don't get iterator invalidation issues later.
+ this->IDoms[I] = 0;
+ this->DomTreeNodes[I] = 0;
+ }
+
+ Calculate<FT, Inverse<NodeT*> >(*this, F);
+ }
+ }
+};
+
+// These two functions are declared out of line as a workaround for building
+// with old (< r147295) versions of clang because of pr11642.
+template<class NodeT>
+bool DominatorTreeBase<NodeT>::dominates(const NodeT *A, const NodeT *B) const {
+ if (A == B)
+ return true;
+
+ // Cast away the const qualifiers here. This is ok since
+ // this function doesn't actually return the values returned
+ // from getNode.
+ return dominates(getNode(const_cast<NodeT *>(A)),
+ getNode(const_cast<NodeT *>(B)));
+}
+template<class NodeT>
+bool
+DominatorTreeBase<NodeT>::properlyDominates(const NodeT *A, const NodeT *B) const {
+ if (A == B)
+ return false;
+
+ // Cast away the const qualifiers here. This is ok since
+ // this function doesn't actually return the values returned
+ // from getNode.
+ return dominates(getNode(const_cast<NodeT *>(A)),
+ getNode(const_cast<NodeT *>(B)));
+}
+
+}
+
+#endif
diff --git a/include/llvm/Support/GenericDomTreeConstruction.h b/include/llvm/Support/GenericDomTreeConstruction.h
new file mode 100644
index 0000000..f6bb8f4
--- /dev/null
+++ b/include/llvm/Support/GenericDomTreeConstruction.h
@@ -0,0 +1,289 @@
+//===- GenericDomTreeConstruction.h - Dominator Calculation ------*- C++ -*-==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+/// \file
+///
+/// Generic dominator tree construction - This file provides routines to
+/// construct immediate dominator information for a flow-graph based on the
+/// algorithm described in this document:
+///
+/// A Fast Algorithm for Finding Dominators in a Flowgraph
+/// T. Lengauer & R. Tarjan, ACM TOPLAS July 1979, pgs 121-141.
+///
+/// This implements the O(n*log(n)) versions of EVAL and LINK, because it turns
+/// out that the theoretically slower O(n*log(n)) implementation is actually
+/// faster than the almost-linear O(n*alpha(n)) version, even for large CFGs.
+///
+//===----------------------------------------------------------------------===//
+
+
+#ifndef LLVM_SUPPORT_GENERIC_DOM_TREE_CONSTRUCTION_H
+#define LLVM_SUPPORT_GENERIC_DOM_TREE_CONSTRUCTION_H
+
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/Support/GenericDomTree.h"
+
+namespace llvm {
+
+template<class GraphT>
+unsigned DFSPass(DominatorTreeBase<typename GraphT::NodeType>& DT,
+ typename GraphT::NodeType* V, unsigned N) {
+ // This is more understandable as a recursive algorithm, but we can't use the
+ // recursive algorithm due to stack depth issues. Keep it here for
+ // documentation purposes.
+#if 0
+ InfoRec &VInfo = DT.Info[DT.Roots[i]];
+ VInfo.DFSNum = VInfo.Semi = ++N;
+ VInfo.Label = V;
+
+ Vertex.push_back(V); // Vertex[n] = V;
+
+ for (succ_iterator SI = succ_begin(V), E = succ_end(V); SI != E; ++SI) {
+ InfoRec &SuccVInfo = DT.Info[*SI];
+ if (SuccVInfo.Semi == 0) {
+ SuccVInfo.Parent = V;
+ N = DTDFSPass(DT, *SI, N);
+ }
+ }
+#else
+ bool IsChildOfArtificialExit = (N != 0);
+
+ SmallVector<std::pair<typename GraphT::NodeType*,
+ typename GraphT::ChildIteratorType>, 32> Worklist;
+ Worklist.push_back(std::make_pair(V, GraphT::child_begin(V)));
+ while (!Worklist.empty()) {
+ typename GraphT::NodeType* BB = Worklist.back().first;
+ typename GraphT::ChildIteratorType NextSucc = Worklist.back().second;
+
+ typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &BBInfo =
+ DT.Info[BB];
+
+ // First time we visited this BB?
+ if (NextSucc == GraphT::child_begin(BB)) {
+ BBInfo.DFSNum = BBInfo.Semi = ++N;
+ BBInfo.Label = BB;
+
+ DT.Vertex.push_back(BB); // Vertex[n] = V;
+
+ if (IsChildOfArtificialExit)
+ BBInfo.Parent = 1;
+
+ IsChildOfArtificialExit = false;
+ }
+
+ // store the DFS number of the current BB - the reference to BBInfo might
+ // get invalidated when processing the successors.
+ unsigned BBDFSNum = BBInfo.DFSNum;
+
+ // If we are done with this block, remove it from the worklist.
+ if (NextSucc == GraphT::child_end(BB)) {
+ Worklist.pop_back();
+ continue;
+ }
+
+ // Increment the successor number for the next time we get to it.
+ ++Worklist.back().second;
+
+ // Visit the successor next, if it isn't already visited.
+ typename GraphT::NodeType* Succ = *NextSucc;
+
+ typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &SuccVInfo =
+ DT.Info[Succ];
+ if (SuccVInfo.Semi == 0) {
+ SuccVInfo.Parent = BBDFSNum;
+ Worklist.push_back(std::make_pair(Succ, GraphT::child_begin(Succ)));
+ }
+ }
+#endif
+ return N;
+}
+
+template<class GraphT>
+typename GraphT::NodeType*
+Eval(DominatorTreeBase<typename GraphT::NodeType>& DT,
+ typename GraphT::NodeType *VIn, unsigned LastLinked) {
+ typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &VInInfo =
+ DT.Info[VIn];
+ if (VInInfo.DFSNum < LastLinked)
+ return VIn;
+
+ SmallVector<typename GraphT::NodeType*, 32> Work;
+ SmallPtrSet<typename GraphT::NodeType*, 32> Visited;
+
+ if (VInInfo.Parent >= LastLinked)
+ Work.push_back(VIn);
+
+ while (!Work.empty()) {
+ typename GraphT::NodeType* V = Work.back();
+ typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &VInfo =
+ DT.Info[V];
+ typename GraphT::NodeType* VAncestor = DT.Vertex[VInfo.Parent];
+
+ // Process Ancestor first
+ if (Visited.insert(VAncestor) && VInfo.Parent >= LastLinked) {
+ Work.push_back(VAncestor);
+ continue;
+ }
+ Work.pop_back();
+
+ // Update VInfo based on Ancestor info
+ if (VInfo.Parent < LastLinked)
+ continue;
+
+ typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &VAInfo =
+ DT.Info[VAncestor];
+ typename GraphT::NodeType* VAncestorLabel = VAInfo.Label;
+ typename GraphT::NodeType* VLabel = VInfo.Label;
+ if (DT.Info[VAncestorLabel].Semi < DT.Info[VLabel].Semi)
+ VInfo.Label = VAncestorLabel;
+ VInfo.Parent = VAInfo.Parent;
+ }
+
+ return VInInfo.Label;
+}
+
+template<class FuncT, class NodeT>
+void Calculate(DominatorTreeBase<typename GraphTraits<NodeT>::NodeType>& DT,
+ FuncT& F) {
+ typedef GraphTraits<NodeT> GraphT;
+
+ unsigned N = 0;
+ bool MultipleRoots = (DT.Roots.size() > 1);
+ if (MultipleRoots) {
+ typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &BBInfo =
+ DT.Info[NULL];
+ BBInfo.DFSNum = BBInfo.Semi = ++N;
+ BBInfo.Label = NULL;
+
+ DT.Vertex.push_back(NULL); // Vertex[n] = V;
+ }
+
+ // Step #1: Number blocks in depth-first order and initialize variables used
+ // in later stages of the algorithm.
+ for (unsigned i = 0, e = static_cast<unsigned>(DT.Roots.size());
+ i != e; ++i)
+ N = DFSPass<GraphT>(DT, DT.Roots[i], N);
+
+ // it might be that some blocks did not get a DFS number (e.g., blocks of
+ // infinite loops). In these cases an artificial exit node is required.
+ MultipleRoots |= (DT.isPostDominator() && N != GraphTraits<FuncT*>::size(&F));
+
+ // When naively implemented, the Lengauer-Tarjan algorithm requires a separate
+ // bucket for each vertex. However, this is unnecessary, because each vertex
+ // is only placed into a single bucket (that of its semidominator), and each
+ // vertex's bucket is processed before it is added to any bucket itself.
+ //
+ // Instead of using a bucket per vertex, we use a single array Buckets that
+ // has two purposes. Before the vertex V with preorder number i is processed,
+ // Buckets[i] stores the index of the first element in V's bucket. After V's
+ // bucket is processed, Buckets[i] stores the index of the next element in the
+ // bucket containing V, if any.
+ SmallVector<unsigned, 32> Buckets;
+ Buckets.resize(N + 1);
+ for (unsigned i = 1; i <= N; ++i)
+ Buckets[i] = i;
+
+ for (unsigned i = N; i >= 2; --i) {
+ typename GraphT::NodeType* W = DT.Vertex[i];
+ typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &WInfo =
+ DT.Info[W];
+
+ // Step #2: Implicitly define the immediate dominator of vertices
+ for (unsigned j = i; Buckets[j] != i; j = Buckets[j]) {
+ typename GraphT::NodeType* V = DT.Vertex[Buckets[j]];
+ typename GraphT::NodeType* U = Eval<GraphT>(DT, V, i + 1);
+ DT.IDoms[V] = DT.Info[U].Semi < i ? U : W;
+ }
+
+ // Step #3: Calculate the semidominators of all vertices
+
+ // initialize the semi dominator to point to the parent node
+ WInfo.Semi = WInfo.Parent;
+ typedef GraphTraits<Inverse<NodeT> > InvTraits;
+ for (typename InvTraits::ChildIteratorType CI =
+ InvTraits::child_begin(W),
+ E = InvTraits::child_end(W); CI != E; ++CI) {
+ typename InvTraits::NodeType *N = *CI;
+ if (DT.Info.count(N)) { // Only if this predecessor is reachable!
+ unsigned SemiU = DT.Info[Eval<GraphT>(DT, N, i + 1)].Semi;
+ if (SemiU < WInfo.Semi)
+ WInfo.Semi = SemiU;
+ }
+ }
+
+ // If V is a non-root vertex and sdom(V) = parent(V), then idom(V) is
+ // necessarily parent(V). In this case, set idom(V) here and avoid placing
+ // V into a bucket.
+ if (WInfo.Semi == WInfo.Parent) {
+ DT.IDoms[W] = DT.Vertex[WInfo.Parent];
+ } else {
+ Buckets[i] = Buckets[WInfo.Semi];
+ Buckets[WInfo.Semi] = i;
+ }
+ }
+
+ if (N >= 1) {
+ typename GraphT::NodeType* Root = DT.Vertex[1];
+ for (unsigned j = 1; Buckets[j] != 1; j = Buckets[j]) {
+ typename GraphT::NodeType* V = DT.Vertex[Buckets[j]];
+ DT.IDoms[V] = Root;
+ }
+ }
+
+ // Step #4: Explicitly define the immediate dominator of each vertex
+ for (unsigned i = 2; i <= N; ++i) {
+ typename GraphT::NodeType* W = DT.Vertex[i];
+ typename GraphT::NodeType*& WIDom = DT.IDoms[W];
+ if (WIDom != DT.Vertex[DT.Info[W].Semi])
+ WIDom = DT.IDoms[WIDom];
+ }
+
+ if (DT.Roots.empty()) return;
+
+ // Add a node for the root. This node might be the actual root, if there is
+ // one exit block, or it may be the virtual exit (denoted by (BasicBlock *)0)
+ // which postdominates all real exits if there are multiple exit blocks, or
+ // an infinite loop.
+ typename GraphT::NodeType* Root = !MultipleRoots ? DT.Roots[0] : 0;
+
+ DT.DomTreeNodes[Root] = DT.RootNode =
+ new DomTreeNodeBase<typename GraphT::NodeType>(Root, 0);
+
+ // Loop over all of the reachable blocks in the function...
+ for (unsigned i = 2; i <= N; ++i) {
+ typename GraphT::NodeType* W = DT.Vertex[i];
+
+ DomTreeNodeBase<typename GraphT::NodeType> *BBNode = DT.DomTreeNodes[W];
+ if (BBNode) continue; // Haven't calculated this node yet?
+
+ typename GraphT::NodeType* ImmDom = DT.getIDom(W);
+
+ assert(ImmDom || DT.DomTreeNodes[NULL]);
+
+ // Get or calculate the node for the immediate dominator
+ DomTreeNodeBase<typename GraphT::NodeType> *IDomNode =
+ DT.getNodeForBlock(ImmDom);
+
+ // Add a new tree node for this BasicBlock, and link it as a child of
+ // IDomNode
+ DomTreeNodeBase<typename GraphT::NodeType> *C =
+ new DomTreeNodeBase<typename GraphT::NodeType>(W, IDomNode);
+ DT.DomTreeNodes[W] = IDomNode->addChild(C);
+ }
+
+ // Free temporary memory used to construct idom's
+ DT.IDoms.clear();
+ DT.Info.clear();
+ std::vector<typename GraphT::NodeType*>().swap(DT.Vertex);
+
+ DT.updateDFSNumbers();
+}
+
+}
+
+#endif
diff --git a/include/llvm/Support/GetElementPtrTypeIterator.h b/include/llvm/Support/GetElementPtrTypeIterator.h
deleted file mode 100644
index aacb531..0000000
--- a/include/llvm/Support/GetElementPtrTypeIterator.h
+++ /dev/null
@@ -1,113 +0,0 @@
-//===- llvm/Support/GetElementPtrTypeIterator.h -----------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements an iterator for walking through the types indexed by
-// getelementptr instructions.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SUPPORT_GETELEMENTPTRTYPEITERATOR_H
-#define LLVM_SUPPORT_GETELEMENTPTRTYPEITERATOR_H
-
-#include "llvm/IR/DerivedTypes.h"
-#include "llvm/IR/User.h"
-
-namespace llvm {
- template<typename ItTy = User::const_op_iterator>
- class generic_gep_type_iterator
- : public std::iterator<std::forward_iterator_tag, Type *, ptrdiff_t> {
- typedef std::iterator<std::forward_iterator_tag,
- Type *, ptrdiff_t> super;
-
- ItTy OpIt;
- Type *CurTy;
- generic_gep_type_iterator() {}
- public:
-
- static generic_gep_type_iterator begin(Type *Ty, ItTy It) {
- generic_gep_type_iterator I;
- I.CurTy = Ty;
- I.OpIt = It;
- return I;
- }
- static generic_gep_type_iterator end(ItTy It) {
- generic_gep_type_iterator I;
- I.CurTy = 0;
- I.OpIt = It;
- return I;
- }
-
- bool operator==(const generic_gep_type_iterator& x) const {
- return OpIt == x.OpIt;
- }
- bool operator!=(const generic_gep_type_iterator& x) const {
- return !operator==(x);
- }
-
- Type *operator*() const {
- return CurTy;
- }
-
- Type *getIndexedType() const {
- CompositeType *CT = cast<CompositeType>(CurTy);
- return CT->getTypeAtIndex(getOperand());
- }
-
- // This is a non-standard operator->. It allows you to call methods on the
- // current type directly.
- Type *operator->() const { return operator*(); }
-
- Value *getOperand() const { return *OpIt; }
-
- generic_gep_type_iterator& operator++() { // Preincrement
- if (CompositeType *CT = dyn_cast<CompositeType>(CurTy)) {
- CurTy = CT->getTypeAtIndex(getOperand());
- } else {
- CurTy = 0;
- }
- ++OpIt;
- return *this;
- }
-
- generic_gep_type_iterator operator++(int) { // Postincrement
- generic_gep_type_iterator tmp = *this; ++*this; return tmp;
- }
- };
-
- typedef generic_gep_type_iterator<> gep_type_iterator;
-
- inline gep_type_iterator gep_type_begin(const User *GEP) {
- return gep_type_iterator::begin
- (GEP->getOperand(0)->getType()->getScalarType(), GEP->op_begin()+1);
- }
- inline gep_type_iterator gep_type_end(const User *GEP) {
- return gep_type_iterator::end(GEP->op_end());
- }
- inline gep_type_iterator gep_type_begin(const User &GEP) {
- return gep_type_iterator::begin
- (GEP.getOperand(0)->getType()->getScalarType(), GEP.op_begin()+1);
- }
- inline gep_type_iterator gep_type_end(const User &GEP) {
- return gep_type_iterator::end(GEP.op_end());
- }
-
- template<typename T>
- inline generic_gep_type_iterator<const T *>
- gep_type_begin(Type *Op0, ArrayRef<T> A) {
- return generic_gep_type_iterator<const T *>::begin(Op0, A.begin());
- }
-
- template<typename T>
- inline generic_gep_type_iterator<const T *>
- gep_type_end(Type * /*Op0*/, ArrayRef<T> A) {
- return generic_gep_type_iterator<const T *>::end(A.end());
- }
-} // end namespace llvm
-
-#endif
diff --git a/include/llvm/Support/Host.h b/include/llvm/Support/Host.h
index 28c4cc7..8f4bf3c 100644
--- a/include/llvm/Support/Host.h
+++ b/include/llvm/Support/Host.h
@@ -55,7 +55,7 @@ namespace sys {
/// target which matches the host.
///
/// \return - The host CPU name, or empty if the CPU could not be determined.
- std::string getHostCPUName();
+ StringRef getHostCPUName();
/// getHostCPUFeatures - Get the LLVM names for the host CPU features.
/// The particular format of the names are target dependent, and suitable for
diff --git a/include/llvm/Support/InstIterator.h b/include/llvm/Support/InstIterator.h
deleted file mode 100644
index ac936a1..0000000
--- a/include/llvm/Support/InstIterator.h
+++ /dev/null
@@ -1,147 +0,0 @@
-//===- llvm/Support/InstIterator.h - Classes for inst iteration -*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains definitions of two iterators for iterating over the
-// instructions in a function. This is effectively a wrapper around a two level
-// iterator that can probably be genericized later.
-//
-// Note that this iterator gets invalidated any time that basic blocks or
-// instructions are moved around.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SUPPORT_INSTITERATOR_H
-#define LLVM_SUPPORT_INSTITERATOR_H
-
-#include "llvm/IR/BasicBlock.h"
-#include "llvm/IR/Function.h"
-
-namespace llvm {
-
-// This class implements inst_begin() & inst_end() for
-// inst_iterator and const_inst_iterator's.
-//
-template <class _BB_t, class _BB_i_t, class _BI_t, class _II_t>
-class InstIterator {
- typedef _BB_t BBty;
- typedef _BB_i_t BBIty;
- typedef _BI_t BIty;
- typedef _II_t IIty;
- _BB_t *BBs; // BasicBlocksType
- _BB_i_t BB; // BasicBlocksType::iterator
- _BI_t BI; // BasicBlock::iterator
-public:
- typedef std::bidirectional_iterator_tag iterator_category;
- typedef IIty value_type;
- typedef signed difference_type;
- typedef IIty* pointer;
- typedef IIty& reference;
-
- // Default constructor
- InstIterator() {}
-
- // Copy constructor...
- template<typename A, typename B, typename C, typename D>
- InstIterator(const InstIterator<A,B,C,D> &II)
- : BBs(II.BBs), BB(II.BB), BI(II.BI) {}
-
- template<typename A, typename B, typename C, typename D>
- InstIterator(InstIterator<A,B,C,D> &II)
- : BBs(II.BBs), BB(II.BB), BI(II.BI) {}
-
- template<class M> InstIterator(M &m)
- : BBs(&m.getBasicBlockList()), BB(BBs->begin()) { // begin ctor
- if (BB != BBs->end()) {
- BI = BB->begin();
- advanceToNextBB();
- }
- }
-
- template<class M> InstIterator(M &m, bool)
- : BBs(&m.getBasicBlockList()), BB(BBs->end()) { // end ctor
- }
-
- // Accessors to get at the underlying iterators...
- inline BBIty &getBasicBlockIterator() { return BB; }
- inline BIty &getInstructionIterator() { return BI; }
-
- inline reference operator*() const { return *BI; }
- inline pointer operator->() const { return &operator*(); }
-
- inline bool operator==(const InstIterator &y) const {
- return BB == y.BB && (BB == BBs->end() || BI == y.BI);
- }
- inline bool operator!=(const InstIterator& y) const {
- return !operator==(y);
- }
-
- InstIterator& operator++() {
- ++BI;
- advanceToNextBB();
- return *this;
- }
- inline InstIterator operator++(int) {
- InstIterator tmp = *this; ++*this; return tmp;
- }
-
- InstIterator& operator--() {
- while (BB == BBs->end() || BI == BB->begin()) {
- --BB;
- BI = BB->end();
- }
- --BI;
- return *this;
- }
- inline InstIterator operator--(int) {
- InstIterator tmp = *this; --*this; return tmp;
- }
-
- inline bool atEnd() const { return BB == BBs->end(); }
-
-private:
- inline void advanceToNextBB() {
- // The only way that the II could be broken is if it is now pointing to
- // the end() of the current BasicBlock and there are successor BBs.
- while (BI == BB->end()) {
- ++BB;
- if (BB == BBs->end()) break;
- BI = BB->begin();
- }
- }
-};
-
-
-typedef InstIterator<iplist<BasicBlock>,
- Function::iterator, BasicBlock::iterator,
- Instruction> inst_iterator;
-typedef InstIterator<const iplist<BasicBlock>,
- Function::const_iterator,
- BasicBlock::const_iterator,
- const Instruction> const_inst_iterator;
-
-inline inst_iterator inst_begin(Function *F) { return inst_iterator(*F); }
-inline inst_iterator inst_end(Function *F) { return inst_iterator(*F, true); }
-inline const_inst_iterator inst_begin(const Function *F) {
- return const_inst_iterator(*F);
-}
-inline const_inst_iterator inst_end(const Function *F) {
- return const_inst_iterator(*F, true);
-}
-inline inst_iterator inst_begin(Function &F) { return inst_iterator(F); }
-inline inst_iterator inst_end(Function &F) { return inst_iterator(F, true); }
-inline const_inst_iterator inst_begin(const Function &F) {
- return const_inst_iterator(F);
-}
-inline const_inst_iterator inst_end(const Function &F) {
- return const_inst_iterator(F, true);
-}
-
-} // End llvm namespace
-
-#endif
diff --git a/include/llvm/Support/LEB128.h b/include/llvm/Support/LEB128.h
index 3d73792..9ef5fe6 100644
--- a/include/llvm/Support/LEB128.h
+++ b/include/llvm/Support/LEB128.h
@@ -90,6 +90,12 @@ inline uint64_t decodeULEB128(const uint8_t *p, unsigned *n = 0) {
return Value;
}
+/// Utility function to get the size of the ULEB128-encoded value.
+extern unsigned getULEB128Size(uint64_t Value);
+
+/// Utility function to get the size of the SLEB128-encoded value.
+extern unsigned getSLEB128Size(int64_t Value);
+
} // namespace llvm
#endif // LLVM_SYSTEM_LEB128_H
diff --git a/include/llvm/Support/LeakDetector.h b/include/llvm/Support/LeakDetector.h
deleted file mode 100644
index 501a9db..0000000
--- a/include/llvm/Support/LeakDetector.h
+++ /dev/null
@@ -1,92 +0,0 @@
-//===-- llvm/Support/LeakDetector.h - Provide leak detection ----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines a class that can be used to provide very simple memory leak
-// checks for an API. Basically LLVM uses this to make sure that Instructions,
-// for example, are deleted when they are supposed to be, and not leaked away.
-//
-// When compiling with NDEBUG (Release build), this class does nothing, thus
-// adding no checking overhead to release builds. Note that this class is
-// implemented in a very simple way, requiring completely manual manipulation
-// and checking for garbage, but this is intentional: users should not be using
-// this API, only other APIs should.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SUPPORT_LEAKDETECTOR_H
-#define LLVM_SUPPORT_LEAKDETECTOR_H
-
-#include <string>
-
-namespace llvm {
-
-class LLVMContext;
-class Value;
-
-struct LeakDetector {
- /// addGarbageObject - Add a pointer to the internal set of "garbage" object
- /// pointers. This should be called when objects are created, or if they are
- /// taken out of an owning collection.
- ///
- static void addGarbageObject(void *Object) {
-#ifndef NDEBUG
- addGarbageObjectImpl(Object);
-#endif
- }
-
- /// removeGarbageObject - Remove a pointer from our internal representation of
- /// our "garbage" objects. This should be called when an object is added to
- /// an "owning" collection.
- ///
- static void removeGarbageObject(void *Object) {
-#ifndef NDEBUG
- removeGarbageObjectImpl(Object);
-#endif
- }
-
- /// checkForGarbage - Traverse the internal representation of garbage
- /// pointers. If there are any pointers that have been add'ed, but not
- /// remove'd, big obnoxious warnings about memory leaks are issued.
- ///
- /// The specified message will be printed indicating when the check was
- /// performed.
- ///
- static void checkForGarbage(LLVMContext &C, const std::string &Message) {
-#ifndef NDEBUG
- checkForGarbageImpl(C, Message);
-#endif
- }
-
- /// Overload the normal methods to work better with Value*'s because they are
- /// by far the most common in LLVM. This does not affect the actual
- /// functioning of this class, it just makes the warning messages nicer.
- ///
- static void addGarbageObject(const Value *Object) {
-#ifndef NDEBUG
- addGarbageObjectImpl(Object);
-#endif
- }
- static void removeGarbageObject(const Value *Object) {
-#ifndef NDEBUG
- removeGarbageObjectImpl(Object);
-#endif
- }
-
-private:
- // If we are debugging, the actual implementations will be called...
- static void addGarbageObjectImpl(const Value *Object);
- static void removeGarbageObjectImpl(const Value *Object);
- static void addGarbageObjectImpl(void *Object);
- static void removeGarbageObjectImpl(void *Object);
- static void checkForGarbageImpl(LLVMContext &C, const std::string &Message);
-};
-
-} // End llvm namespace
-
-#endif
diff --git a/include/llvm/Support/LineIterator.h b/include/llvm/Support/LineIterator.h
new file mode 100644
index 0000000..7077656
--- /dev/null
+++ b/include/llvm/Support/LineIterator.h
@@ -0,0 +1,84 @@
+//===- LineIterator.h - Iterator to read a text buffer's lines --*- 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_LINEITERATOR_H__
+#define LLVM_SUPPORT_LINEITERATOR_H__
+
+#include "llvm/ADT/StringRef.h"
+#include <iterator>
+
+namespace llvm {
+
+class MemoryBuffer;
+
+/// \brief A forward iterator which reads non-blank text lines from a buffer.
+///
+/// This class provides a forward iterator interface for reading one line at
+/// a time from a buffer. When default constructed the iterator will be the
+/// "end" iterator.
+///
+/// The iterator also is aware of what line number it is currently processing
+/// and can strip comment lines given the comment-starting character.
+///
+/// Note that this iterator requires the buffer to be nul terminated.
+class line_iterator
+ : public std::iterator<std::forward_iterator_tag, StringRef, ptrdiff_t> {
+ const MemoryBuffer *Buffer;
+ char CommentMarker;
+
+ unsigned LineNumber;
+ StringRef CurrentLine;
+
+public:
+ /// \brief Default construct an "end" iterator.
+ line_iterator() : Buffer(0) {}
+
+ /// \brief Construct a new iterator around some memory buffer.
+ explicit line_iterator(const MemoryBuffer &Buffer, char CommentMarker = '\0');
+
+ /// \brief Return true if we've reached EOF or are an "end" iterator.
+ bool is_at_eof() const { return !Buffer; }
+
+ /// \brief Return true if we're an "end" iterator or have reached EOF.
+ bool is_at_end() const { return is_at_eof(); }
+
+ /// \brief Return the current line number. May return any number at EOF.
+ int64_t line_number() const { return LineNumber; }
+
+ /// \brief Advance to the next (non-empty, non-comment) line.
+ line_iterator &operator++() {
+ advance();
+ return *this;
+ }
+ line_iterator operator++(int) {
+ line_iterator tmp(*this);
+ advance();
+ return tmp;
+ }
+
+ /// \brief Get the current line as a \c StringRef.
+ StringRef operator*() const { return CurrentLine; }
+ const StringRef *operator->() const { return &CurrentLine; }
+
+ friend bool operator==(const line_iterator &LHS, const line_iterator &RHS) {
+ return LHS.Buffer == RHS.Buffer &&
+ LHS.CurrentLine.begin() == RHS.CurrentLine.begin();
+ }
+
+ friend bool operator!=(const line_iterator &LHS, const line_iterator &RHS) {
+ return !(LHS == RHS);
+ }
+
+private:
+ /// \brief Advance the iterator to the next line.
+ void advance();
+};
+}
+
+#endif // LLVM_SUPPORT_LINEITERATOR_H__
diff --git a/include/llvm/Support/MD5.h b/include/llvm/Support/MD5.h
index b2b8c2d..4eb8507 100644
--- a/include/llvm/Support/MD5.h
+++ b/include/llvm/Support/MD5.h
@@ -28,13 +28,12 @@
#ifndef LLVM_SYSTEM_MD5_H
#define LLVM_SYSTEM_MD5_H
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/DataTypes.h"
namespace llvm {
-template <typename T> class ArrayRef;
-
class MD5 {
// Any 32-bit or wider unsigned integer data type will do.
typedef uint32_t MD5_u32plus;
diff --git a/include/llvm/Support/MachO.h b/include/llvm/Support/MachO.h
index 897a611..ef06a41 100644
--- a/include/llvm/Support/MachO.h
+++ b/include/llvm/Support/MachO.h
@@ -21,7 +21,7 @@
namespace llvm {
namespace MachO {
// Enums from <mach-o/loader.h>
- enum LLVM_ENUM_INT_TYPE(uint32_t) {
+ enum : uint32_t {
// Constants for the "magic" field in llvm::MachO::mach_header and
// llvm::MachO::mach_header_64
MH_MAGIC = 0xFEEDFACEu,
@@ -76,12 +76,12 @@ namespace llvm {
MH_DEAD_STRIPPABLE_DYLIB = 0x00400000u
};
- enum LLVM_ENUM_INT_TYPE(uint32_t) {
+ enum : uint32_t {
// Flags for the "cmd" field in llvm::MachO::load_command
LC_REQ_DYLD = 0x80000000u
};
- enum LoadCommandType LLVM_ENUM_INT_TYPE(uint32_t) {
+ enum LoadCommandType : uint32_t {
// Constants for the "cmd" field in llvm::MachO::load_command
LC_SEGMENT = 0x00000001u,
LC_SYMTAB = 0x00000002u,
@@ -128,10 +128,11 @@ namespace llvm {
LC_SOURCE_VERSION = 0x0000002Au,
LC_DYLIB_CODE_SIGN_DRS = 0x0000002Bu,
// 0x0000002Cu,
- LC_LINKER_OPTIONS = 0x0000002Du
+ LC_LINKER_OPTIONS = 0x0000002Du,
+ LC_LINKER_OPTIMIZATION_HINT = 0x0000002Eu
};
- enum LLVM_ENUM_INT_TYPE(uint32_t) {
+ enum : uint32_t {
// Constant bits for the "flags" field in llvm::MachO::segment_command
SG_HIGHVM = 0x1u,
SG_FVMLIB = 0x2u,
@@ -147,7 +148,9 @@ namespace llvm {
SECTION_ATTRIBUTES_SYS = 0x00ffff00u // SECTION_ATTRIBUTES_SYS
};
- enum SectionType {
+ /// These are the section type and attributes fields. A MachO section can
+ /// have only one Type, but can have any of the attributes specified.
+ enum SectionType : uint32_t {
// Constant masks for the "flags[7:0]" field in llvm::MachO::section and
// llvm::MachO::section_64 (mask "flags" with SECTION_TYPE)
S_REGULAR = 0x00u,
@@ -171,10 +174,12 @@ namespace llvm {
S_THREAD_LOCAL_ZEROFILL = 0x12u,
S_THREAD_LOCAL_VARIABLES = 0x13u,
S_THREAD_LOCAL_VARIABLE_POINTERS = 0x14u,
- S_THREAD_LOCAL_INIT_FUNCTION_POINTERS = 0x15u
+ S_THREAD_LOCAL_INIT_FUNCTION_POINTERS = 0x15u,
+
+ LAST_KNOWN_SECTION_TYPE = S_THREAD_LOCAL_INIT_FUNCTION_POINTERS
};
- enum LLVM_ENUM_INT_TYPE(uint32_t) {
+ enum : uint32_t {
// Constant masks for the "flags[31:24]" field in llvm::MachO::section and
// llvm::MachO::section_64 (mask "flags" with SECTION_ATTRIBUTES_USR)
S_ATTR_PURE_INSTRUCTIONS = 0x80000000u,
@@ -348,7 +353,7 @@ namespace llvm {
N_LENG = 0xFEu
};
- enum LLVM_ENUM_INT_TYPE(uint32_t) {
+ enum : uint32_t {
// Constant values for the r_symbolnum field in an
// llvm::MachO::relocation_info structure when r_extern is 0.
R_ABS = 0,
@@ -403,6 +408,34 @@ namespace llvm {
ARM_RELOC_HALF = 8,
ARM_RELOC_HALF_SECTDIFF = 9,
+ // Constant values for the r_type field in an ARM64 architecture
+ // llvm::MachO::relocation_info or llvm::MachO::scattered_relocation_info
+ // structure.
+
+ // For pointers.
+ ARM64_RELOC_UNSIGNED = 0,
+ // Must be followed by an ARM64_RELOC_UNSIGNED
+ ARM64_RELOC_SUBTRACTOR = 1,
+ // A B/BL instruction with 26-bit displacement.
+ ARM64_RELOC_BRANCH26 = 2,
+ // PC-rel distance to page of target.
+ ARM64_RELOC_PAGE21 = 3,
+ // Offset within page, scaled by r_length.
+ ARM64_RELOC_PAGEOFF12 = 4,
+ // PC-rel distance to page of GOT slot.
+ ARM64_RELOC_GOT_LOAD_PAGE21 = 5,
+ // Offset within page of GOT slot, scaled by r_length.
+ ARM64_RELOC_GOT_LOAD_PAGEOFF12 = 6,
+ // For pointers to GOT slots.
+ ARM64_RELOC_POINTER_TO_GOT = 7,
+ // PC-rel distance to page of TLVP slot.
+ ARM64_RELOC_TLVP_LOAD_PAGE21 = 8,
+ // Offset within page of TLVP slot, scaled by r_length.
+ ARM64_RELOC_TLVP_LOAD_PAGEOFF12 = 9,
+ // Must be followed by ARM64_RELOC_PAGE21 or ARM64_RELOC_PAGEOFF12.
+ ARM64_RELOC_ADDEND = 10,
+
+
// Constant values for the r_type field in an x86_64 architecture
// llvm::MachO::relocation_info or llvm::MachO::scattered_relocation_info
// structure
@@ -739,9 +772,10 @@ namespace llvm {
};
struct version_min_command {
- uint32_t cmd;
- uint32_t cmdsize;
- uint32_t version;
+ uint32_t cmd; // LC_VERSION_MIN_MACOSX or
+ // LC_VERSION_MIN_IPHONEOS
+ uint32_t cmdsize; // sizeof(struct version_min_command)
+ uint32_t version; // X.Y.Z is encoded in nibbles xxxx.yy.zz
uint32_t reserved;
};
@@ -893,7 +927,7 @@ namespace llvm {
}
// Enums from <mach/machine.h>
- enum LLVM_ENUM_INT_TYPE(uint32_t) {
+ enum : uint32_t {
// Capability bits used in the definition of cpu_type.
CPU_ARCH_MASK = 0xff000000, // Mask for architecture bits
CPU_ARCH_ABI64 = 0x01000000 // 64 bit ABI
@@ -908,12 +942,13 @@ namespace llvm {
/* CPU_TYPE_MIPS = 8, */
CPU_TYPE_MC98000 = 10, // Old Motorola PowerPC
CPU_TYPE_ARM = 12,
+ CPU_TYPE_ARM64 = CPU_TYPE_ARM | CPU_ARCH_ABI64,
CPU_TYPE_SPARC = 14,
CPU_TYPE_POWERPC = 18,
CPU_TYPE_POWERPC64 = CPU_TYPE_POWERPC | CPU_ARCH_ABI64
};
- enum LLVM_ENUM_INT_TYPE(uint32_t) {
+ enum : uint32_t {
// Capability bits used in the definition of cpusubtype.
CPU_SUB_TYPE_MASK = 0xff000000, // Mask for architecture bits
CPU_SUB_TYPE_LIB64 = 0x80000000, // 64 bit libraries
@@ -973,7 +1008,7 @@ namespace llvm {
CPU_SUBTYPE_ARM_V5TEJ = 7,
CPU_SUBTYPE_ARM_XSCALE = 8,
CPU_SUBTYPE_ARM_V7 = 9,
- CPU_SUBTYPE_ARM_V7F = 10,
+ // unused ARM_V7F = 10,
CPU_SUBTYPE_ARM_V7S = 11,
CPU_SUBTYPE_ARM_V7K = 12,
CPU_SUBTYPE_ARM_V6M = 14,
@@ -981,6 +1016,10 @@ namespace llvm {
CPU_SUBTYPE_ARM_V7EM = 16
};
+ enum CPUSubTypeARM64 {
+ CPU_SUBTYPE_ARM64_ALL = 0
+ };
+
enum CPUSubTypeSPARC {
CPU_SUBTYPE_SPARC_ALL = 0
};
diff --git a/include/llvm/Support/MathExtras.h b/include/llvm/Support/MathExtras.h
index ff41608..f1f7b4f 100644
--- a/include/llvm/Support/MathExtras.h
+++ b/include/llvm/Support/MathExtras.h
@@ -16,9 +16,9 @@
#include "llvm/Support/Compiler.h"
#include "llvm/Support/SwapByteOrder.h"
-#include "llvm/Support/type_traits.h"
-
+#include <cassert>
#include <cstring>
+#include <type_traits>
#ifdef _MSC_VER
#include <intrin.h>
@@ -44,8 +44,8 @@ enum ZeroBehavior {
/// \param ZB the behavior on an input of 0. Only ZB_Width and ZB_Undefined are
/// valid arguments.
template <typename T>
-typename enable_if_c<std::numeric_limits<T>::is_integer &&
- !std::numeric_limits<T>::is_signed, std::size_t>::type
+typename std::enable_if<std::numeric_limits<T>::is_integer &&
+ !std::numeric_limits<T>::is_signed, std::size_t>::type
countTrailingZeros(T Val, ZeroBehavior ZB = ZB_Width) {
(void)ZB;
@@ -71,8 +71,8 @@ countTrailingZeros(T Val, ZeroBehavior ZB = ZB_Width) {
// Disable signed.
template <typename T>
-typename enable_if_c<std::numeric_limits<T>::is_integer &&
- std::numeric_limits<T>::is_signed, std::size_t>::type
+typename std::enable_if<std::numeric_limits<T>::is_integer &&
+ std::numeric_limits<T>::is_signed, std::size_t>::type
countTrailingZeros(T Val, ZeroBehavior ZB = ZB_Width) LLVM_DELETED_FUNCTION;
#if __GNUC__ >= 4 || _MSC_VER
@@ -115,8 +115,8 @@ inline std::size_t countTrailingZeros<uint64_t>(uint64_t Val, ZeroBehavior ZB) {
/// \param ZB the behavior on an input of 0. Only ZB_Width and ZB_Undefined are
/// valid arguments.
template <typename T>
-typename enable_if_c<std::numeric_limits<T>::is_integer &&
- !std::numeric_limits<T>::is_signed, std::size_t>::type
+typename std::enable_if<std::numeric_limits<T>::is_integer &&
+ !std::numeric_limits<T>::is_signed, std::size_t>::type
countLeadingZeros(T Val, ZeroBehavior ZB = ZB_Width) {
(void)ZB;
@@ -137,8 +137,8 @@ countLeadingZeros(T Val, ZeroBehavior ZB = ZB_Width) {
// Disable signed.
template <typename T>
-typename enable_if_c<std::numeric_limits<T>::is_integer &&
- std::numeric_limits<T>::is_signed, std::size_t>::type
+typename std::enable_if<std::numeric_limits<T>::is_integer &&
+ std::numeric_limits<T>::is_signed, std::size_t>::type
countLeadingZeros(T Val, ZeroBehavior ZB = ZB_Width) LLVM_DELETED_FUNCTION;
#if __GNUC__ >= 4 || _MSC_VER
@@ -181,8 +181,8 @@ inline std::size_t countLeadingZeros<uint64_t>(uint64_t Val, ZeroBehavior ZB) {
/// \param ZB the behavior on an input of 0. Only ZB_Max and ZB_Undefined are
/// valid arguments.
template <typename T>
-typename enable_if_c<std::numeric_limits<T>::is_integer &&
- !std::numeric_limits<T>::is_signed, T>::type
+typename std::enable_if<std::numeric_limits<T>::is_integer &&
+ !std::numeric_limits<T>::is_signed, T>::type
findFirstSet(T Val, ZeroBehavior ZB = ZB_Max) {
if (ZB == ZB_Max && Val == 0)
return std::numeric_limits<T>::max();
@@ -192,8 +192,8 @@ findFirstSet(T Val, ZeroBehavior ZB = ZB_Max) {
// Disable signed.
template <typename T>
-typename enable_if_c<std::numeric_limits<T>::is_integer &&
- std::numeric_limits<T>::is_signed, T>::type
+typename std::enable_if<std::numeric_limits<T>::is_integer &&
+ std::numeric_limits<T>::is_signed, T>::type
findFirstSet(T Val, ZeroBehavior ZB = ZB_Max) LLVM_DELETED_FUNCTION;
/// \brief Get the index of the last set bit starting from the least
@@ -204,8 +204,8 @@ findFirstSet(T Val, ZeroBehavior ZB = ZB_Max) LLVM_DELETED_FUNCTION;
/// \param ZB the behavior on an input of 0. Only ZB_Max and ZB_Undefined are
/// valid arguments.
template <typename T>
-typename enable_if_c<std::numeric_limits<T>::is_integer &&
- !std::numeric_limits<T>::is_signed, T>::type
+typename std::enable_if<std::numeric_limits<T>::is_integer &&
+ !std::numeric_limits<T>::is_signed, T>::type
findLastSet(T Val, ZeroBehavior ZB = ZB_Max) {
if (ZB == ZB_Max && Val == 0)
return std::numeric_limits<T>::max();
@@ -218,8 +218,8 @@ findLastSet(T Val, ZeroBehavior ZB = ZB_Max) {
// Disable signed.
template <typename T>
-typename enable_if_c<std::numeric_limits<T>::is_integer &&
- std::numeric_limits<T>::is_signed, T>::type
+typename std::enable_if<std::numeric_limits<T>::is_integer &&
+ std::numeric_limits<T>::is_signed, T>::type
findLastSet(T Val, ZeroBehavior ZB = ZB_Max) LLVM_DELETED_FUNCTION;
/// \brief Macro compressed bit reversal table for 256 bits.
@@ -541,6 +541,18 @@ inline uint64_t MinAlign(uint64_t A, uint64_t B) {
return (A | B) & (1 + ~(A | B));
}
+/// \brief Aligns \c Ptr to \c Alignment bytes, rounding up.
+///
+/// Alignment should be a power of two. This method rounds up, so
+/// AlignPtr(7, 4) == 8 and AlignPtr(8, 4) == 8.
+inline char *alignPtr(char *Ptr, size_t Alignment) {
+ assert(Alignment && isPowerOf2_64((uint64_t)Alignment) &&
+ "Alignment is not a power of two!");
+
+ return (char *)(((uintptr_t)Ptr + Alignment - 1) &
+ ~(uintptr_t)(Alignment - 1));
+}
+
/// NextPowerOf2 - Returns the next power of two (in 64-bits)
/// that is strictly greater than A. Returns zero on overflow.
inline uint64_t NextPowerOf2(uint64_t A) {
@@ -553,6 +565,13 @@ inline uint64_t NextPowerOf2(uint64_t A) {
return A + 1;
}
+/// Returns the power of two which is less than or equal to the given value.
+/// Essentially, it is a floor operation across the domain of powers of two.
+inline uint64_t PowerOf2Floor(uint64_t A) {
+ if (!A) return 0;
+ return 1ull << (63 - countLeadingZeros(A, ZB_Undefined));
+}
+
/// Returns the next integer (mod 2**64) that is greater than or equal to
/// \p Value and is a multiple of \p Align. \p Align must be non-zero.
///
diff --git a/include/llvm/Support/Memory.h b/include/llvm/Support/Memory.h
index a08c796..8251fcd 100644
--- a/include/llvm/Support/Memory.h
+++ b/include/llvm/Support/Memory.h
@@ -95,7 +95,7 @@ namespace sys {
/// memory was not allocated using the allocateMappedMemory method.
/// \p Block describes the memory block to be protected.
/// \p Flags specifies the new protection state to be assigned to the block.
- /// \p ErrMsg [out] returns a string describing any error that occured.
+ /// \p ErrMsg [out] returns a string describing any error that occurred.
///
/// If \p Flags is MF_WRITE, the actual behavior varies
/// with the operating system (i.e. MF_READ | MF_WRITE on Windows) and the
diff --git a/include/llvm/Support/MemoryBuffer.h b/include/llvm/Support/MemoryBuffer.h
index ff22fb6..578c7e8 100644
--- a/include/llvm/Support/MemoryBuffer.h
+++ b/include/llvm/Support/MemoryBuffer.h
@@ -14,11 +14,12 @@
#ifndef LLVM_SUPPORT_MEMORYBUFFER_H
#define LLVM_SUPPORT_MEMORYBUFFER_H
+#include "llvm-c/Support.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/CBindingWrapping.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataTypes.h"
-#include "llvm-c/Core.h"
+#include <memory>
namespace llvm {
@@ -66,7 +67,11 @@ public:
/// MemoryBuffer if successful, otherwise returning null. If FileSize is
/// specified, this means that the client knows that the file exists and that
/// it has the specified size.
- static error_code getFile(Twine Filename, OwningPtr<MemoryBuffer> &result,
+ static error_code getFile(Twine Filename, OwningPtr<MemoryBuffer> &Result,
+ int64_t FileSize = -1,
+ bool RequiresNullTerminator = true);
+ static error_code getFile(Twine Filename,
+ std::unique_ptr<MemoryBuffer> &Result,
int64_t FileSize = -1,
bool RequiresNullTerminator = true);
@@ -76,6 +81,9 @@ public:
static error_code getOpenFileSlice(int FD, const char *Filename,
OwningPtr<MemoryBuffer> &Result,
uint64_t MapSize, int64_t Offset);
+ static error_code getOpenFileSlice(int FD, const char *Filename,
+ std::unique_ptr<MemoryBuffer> &Result,
+ uint64_t MapSize, int64_t Offset);
/// Given an already-open file descriptor, read the file and return a
/// MemoryBuffer.
@@ -83,6 +91,10 @@ public:
OwningPtr<MemoryBuffer> &Result,
uint64_t FileSize,
bool RequiresNullTerminator = true);
+ static error_code getOpenFile(int FD, const char *Filename,
+ std::unique_ptr<MemoryBuffer> &Result,
+ uint64_t FileSize,
+ bool RequiresNullTerminator = true);
/// getMemBuffer - Open the specified memory range as a MemoryBuffer. Note
/// that InputData must be null terminated if RequiresNullTerminator is true.
@@ -111,14 +123,18 @@ public:
/// getSTDIN - Read all of stdin into a file buffer, and return it.
/// If an error occurs, this returns null and sets ec.
- static error_code getSTDIN(OwningPtr<MemoryBuffer> &result);
+ static error_code getSTDIN(OwningPtr<MemoryBuffer> &Result);
+ static error_code getSTDIN(std::unique_ptr<MemoryBuffer> &Result);
/// getFileOrSTDIN - Open the specified file as a MemoryBuffer, or open stdin
/// if the Filename is "-". If an error occurs, this returns null and sets
/// ec.
static error_code getFileOrSTDIN(StringRef Filename,
- OwningPtr<MemoryBuffer> &result,
+ OwningPtr<MemoryBuffer> &Result,
+ int64_t FileSize = -1);
+ static error_code getFileOrSTDIN(StringRef Filename,
+ std::unique_ptr<MemoryBuffer> &Result,
int64_t FileSize = -1);
//===--------------------------------------------------------------------===//
diff --git a/include/llvm/Support/NoFolder.h b/include/llvm/Support/NoFolder.h
deleted file mode 100644
index ecfbbaa..0000000
--- a/include/llvm/Support/NoFolder.h
+++ /dev/null
@@ -1,298 +0,0 @@
-//======-- llvm/Support/NoFolder.h - Constant folding helper -*- C++ -*-======//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the NoFolder class, a helper for IRBuilder. It provides
-// IRBuilder with a set of methods for creating unfolded constants. This is
-// useful for learners trying to understand how LLVM IR works, and who don't
-// want details to be hidden by the constant folder. For general constant
-// creation and folding, use ConstantExpr and the routines in
-// llvm/Analysis/ConstantFolding.h.
-//
-// Note: since it is not actually possible to create unfolded constants, this
-// class returns instructions rather than constants.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SUPPORT_NOFOLDER_H
-#define LLVM_SUPPORT_NOFOLDER_H
-
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/IR/Constants.h"
-#include "llvm/IR/Instructions.h"
-
-namespace llvm {
-
-/// NoFolder - Create "constants" (actually, instructions) with no folding.
-class NoFolder {
-public:
- explicit NoFolder() {}
-
- //===--------------------------------------------------------------------===//
- // Binary Operators
- //===--------------------------------------------------------------------===//
-
- Instruction *CreateAdd(Constant *LHS, Constant *RHS,
- bool HasNUW = false, bool HasNSW = false) const {
- BinaryOperator *BO = BinaryOperator::CreateAdd(LHS, RHS);
- if (HasNUW) BO->setHasNoUnsignedWrap();
- if (HasNSW) BO->setHasNoSignedWrap();
- return BO;
- }
- Instruction *CreateNSWAdd(Constant *LHS, Constant *RHS) const {
- return BinaryOperator::CreateNSWAdd(LHS, RHS);
- }
- Instruction *CreateNUWAdd(Constant *LHS, Constant *RHS) const {
- return BinaryOperator::CreateNUWAdd(LHS, RHS);
- }
- Instruction *CreateFAdd(Constant *LHS, Constant *RHS) const {
- return BinaryOperator::CreateFAdd(LHS, RHS);
- }
- Instruction *CreateSub(Constant *LHS, Constant *RHS,
- bool HasNUW = false, bool HasNSW = false) const {
- BinaryOperator *BO = BinaryOperator::CreateSub(LHS, RHS);
- if (HasNUW) BO->setHasNoUnsignedWrap();
- if (HasNSW) BO->setHasNoSignedWrap();
- return BO;
- }
- Instruction *CreateNSWSub(Constant *LHS, Constant *RHS) const {
- return BinaryOperator::CreateNSWSub(LHS, RHS);
- }
- Instruction *CreateNUWSub(Constant *LHS, Constant *RHS) const {
- return BinaryOperator::CreateNUWSub(LHS, RHS);
- }
- Instruction *CreateFSub(Constant *LHS, Constant *RHS) const {
- return BinaryOperator::CreateFSub(LHS, RHS);
- }
- Instruction *CreateMul(Constant *LHS, Constant *RHS,
- bool HasNUW = false, bool HasNSW = false) const {
- BinaryOperator *BO = BinaryOperator::CreateMul(LHS, RHS);
- if (HasNUW) BO->setHasNoUnsignedWrap();
- if (HasNSW) BO->setHasNoSignedWrap();
- return BO;
- }
- Instruction *CreateNSWMul(Constant *LHS, Constant *RHS) const {
- return BinaryOperator::CreateNSWMul(LHS, RHS);
- }
- Instruction *CreateNUWMul(Constant *LHS, Constant *RHS) const {
- return BinaryOperator::CreateNUWMul(LHS, RHS);
- }
- Instruction *CreateFMul(Constant *LHS, Constant *RHS) const {
- return BinaryOperator::CreateFMul(LHS, RHS);
- }
- Instruction *CreateUDiv(Constant *LHS, Constant *RHS,
- bool isExact = false) const {
- if (!isExact)
- return BinaryOperator::CreateUDiv(LHS, RHS);
- return BinaryOperator::CreateExactUDiv(LHS, RHS);
- }
- Instruction *CreateExactUDiv(Constant *LHS, Constant *RHS) const {
- return BinaryOperator::CreateExactUDiv(LHS, RHS);
- }
- Instruction *CreateSDiv(Constant *LHS, Constant *RHS,
- bool isExact = false) const {
- if (!isExact)
- return BinaryOperator::CreateSDiv(LHS, RHS);
- return BinaryOperator::CreateExactSDiv(LHS, RHS);
- }
- Instruction *CreateExactSDiv(Constant *LHS, Constant *RHS) const {
- return BinaryOperator::CreateExactSDiv(LHS, RHS);
- }
- Instruction *CreateFDiv(Constant *LHS, Constant *RHS) const {
- return BinaryOperator::CreateFDiv(LHS, RHS);
- }
- Instruction *CreateURem(Constant *LHS, Constant *RHS) const {
- return BinaryOperator::CreateURem(LHS, RHS);
- }
- Instruction *CreateSRem(Constant *LHS, Constant *RHS) const {
- return BinaryOperator::CreateSRem(LHS, RHS);
- }
- Instruction *CreateFRem(Constant *LHS, Constant *RHS) const {
- return BinaryOperator::CreateFRem(LHS, RHS);
- }
- Instruction *CreateShl(Constant *LHS, Constant *RHS, bool HasNUW = false,
- bool HasNSW = false) const {
- BinaryOperator *BO = BinaryOperator::CreateShl(LHS, RHS);
- if (HasNUW) BO->setHasNoUnsignedWrap();
- if (HasNSW) BO->setHasNoSignedWrap();
- return BO;
- }
- Instruction *CreateLShr(Constant *LHS, Constant *RHS,
- bool isExact = false) const {
- if (!isExact)
- return BinaryOperator::CreateLShr(LHS, RHS);
- return BinaryOperator::CreateExactLShr(LHS, RHS);
- }
- Instruction *CreateAShr(Constant *LHS, Constant *RHS,
- bool isExact = false) const {
- if (!isExact)
- return BinaryOperator::CreateAShr(LHS, RHS);
- return BinaryOperator::CreateExactAShr(LHS, RHS);
- }
- Instruction *CreateAnd(Constant *LHS, Constant *RHS) const {
- return BinaryOperator::CreateAnd(LHS, RHS);
- }
- Instruction *CreateOr(Constant *LHS, Constant *RHS) const {
- return BinaryOperator::CreateOr(LHS, RHS);
- }
- Instruction *CreateXor(Constant *LHS, Constant *RHS) const {
- return BinaryOperator::CreateXor(LHS, RHS);
- }
-
- Instruction *CreateBinOp(Instruction::BinaryOps Opc,
- Constant *LHS, Constant *RHS) const {
- return BinaryOperator::Create(Opc, LHS, RHS);
- }
-
- //===--------------------------------------------------------------------===//
- // Unary Operators
- //===--------------------------------------------------------------------===//
-
- Instruction *CreateNeg(Constant *C,
- bool HasNUW = false, bool HasNSW = false) const {
- BinaryOperator *BO = BinaryOperator::CreateNeg(C);
- if (HasNUW) BO->setHasNoUnsignedWrap();
- if (HasNSW) BO->setHasNoSignedWrap();
- return BO;
- }
- Instruction *CreateNSWNeg(Constant *C) const {
- return BinaryOperator::CreateNSWNeg(C);
- }
- Instruction *CreateNUWNeg(Constant *C) const {
- return BinaryOperator::CreateNUWNeg(C);
- }
- Instruction *CreateFNeg(Constant *C) const {
- return BinaryOperator::CreateFNeg(C);
- }
- Instruction *CreateNot(Constant *C) const {
- return BinaryOperator::CreateNot(C);
- }
-
- //===--------------------------------------------------------------------===//
- // Memory Instructions
- //===--------------------------------------------------------------------===//
-
- Constant *CreateGetElementPtr(Constant *C,
- ArrayRef<Constant *> IdxList) const {
- return ConstantExpr::getGetElementPtr(C, IdxList);
- }
- Constant *CreateGetElementPtr(Constant *C, Constant *Idx) const {
- // This form of the function only exists to avoid ambiguous overload
- // warnings about whether to convert Idx to ArrayRef<Constant *> or
- // ArrayRef<Value *>.
- return ConstantExpr::getGetElementPtr(C, Idx);
- }
- Instruction *CreateGetElementPtr(Constant *C,
- ArrayRef<Value *> IdxList) const {
- return GetElementPtrInst::Create(C, IdxList);
- }
-
- Constant *CreateInBoundsGetElementPtr(Constant *C,
- ArrayRef<Constant *> IdxList) const {
- return ConstantExpr::getInBoundsGetElementPtr(C, IdxList);
- }
- Constant *CreateInBoundsGetElementPtr(Constant *C, Constant *Idx) const {
- // This form of the function only exists to avoid ambiguous overload
- // warnings about whether to convert Idx to ArrayRef<Constant *> or
- // ArrayRef<Value *>.
- return ConstantExpr::getInBoundsGetElementPtr(C, Idx);
- }
- Instruction *CreateInBoundsGetElementPtr(Constant *C,
- ArrayRef<Value *> IdxList) const {
- return GetElementPtrInst::CreateInBounds(C, IdxList);
- }
-
- //===--------------------------------------------------------------------===//
- // Cast/Conversion Operators
- //===--------------------------------------------------------------------===//
-
- Instruction *CreateCast(Instruction::CastOps Op, Constant *C,
- Type *DestTy) const {
- return CastInst::Create(Op, C, DestTy);
- }
- Instruction *CreatePointerCast(Constant *C, Type *DestTy) const {
- return CastInst::CreatePointerCast(C, DestTy);
- }
- Instruction *CreateIntCast(Constant *C, Type *DestTy,
- bool isSigned) const {
- return CastInst::CreateIntegerCast(C, DestTy, isSigned);
- }
- Instruction *CreateFPCast(Constant *C, Type *DestTy) const {
- return CastInst::CreateFPCast(C, DestTy);
- }
-
- Instruction *CreateBitCast(Constant *C, Type *DestTy) const {
- return CreateCast(Instruction::BitCast, C, DestTy);
- }
- Instruction *CreateIntToPtr(Constant *C, Type *DestTy) const {
- return CreateCast(Instruction::IntToPtr, C, DestTy);
- }
- Instruction *CreatePtrToInt(Constant *C, Type *DestTy) const {
- return CreateCast(Instruction::PtrToInt, C, DestTy);
- }
- Instruction *CreateZExtOrBitCast(Constant *C, Type *DestTy) const {
- return CastInst::CreateZExtOrBitCast(C, DestTy);
- }
- Instruction *CreateSExtOrBitCast(Constant *C, Type *DestTy) const {
- return CastInst::CreateSExtOrBitCast(C, DestTy);
- }
-
- Instruction *CreateTruncOrBitCast(Constant *C, Type *DestTy) const {
- return CastInst::CreateTruncOrBitCast(C, DestTy);
- }
-
- //===--------------------------------------------------------------------===//
- // Compare Instructions
- //===--------------------------------------------------------------------===//
-
- Instruction *CreateICmp(CmpInst::Predicate P,
- Constant *LHS, Constant *RHS) const {
- return new ICmpInst(P, LHS, RHS);
- }
- Instruction *CreateFCmp(CmpInst::Predicate P,
- Constant *LHS, Constant *RHS) const {
- return new FCmpInst(P, LHS, RHS);
- }
-
- //===--------------------------------------------------------------------===//
- // Other Instructions
- //===--------------------------------------------------------------------===//
-
- Instruction *CreateSelect(Constant *C,
- Constant *True, Constant *False) const {
- return SelectInst::Create(C, True, False);
- }
-
- Instruction *CreateExtractElement(Constant *Vec, Constant *Idx) const {
- return ExtractElementInst::Create(Vec, Idx);
- }
-
- Instruction *CreateInsertElement(Constant *Vec, Constant *NewElt,
- Constant *Idx) const {
- return InsertElementInst::Create(Vec, NewElt, Idx);
- }
-
- Instruction *CreateShuffleVector(Constant *V1, Constant *V2,
- Constant *Mask) const {
- return new ShuffleVectorInst(V1, V2, Mask);
- }
-
- Instruction *CreateExtractValue(Constant *Agg,
- ArrayRef<unsigned> IdxList) const {
- return ExtractValueInst::Create(Agg, IdxList);
- }
-
- Instruction *CreateInsertValue(Constant *Agg, Constant *Val,
- ArrayRef<unsigned> IdxList) const {
- return InsertValueInst::Create(Agg, Val, IdxList);
- }
-};
-
-}
-
-#endif
diff --git a/include/llvm/Support/PassNameParser.h b/include/llvm/Support/PassNameParser.h
deleted file mode 100644
index c0914b1..0000000
--- a/include/llvm/Support/PassNameParser.h
+++ /dev/null
@@ -1,136 +0,0 @@
-//===- llvm/Support/PassNameParser.h ----------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains the PassNameParser and FilteredPassNameParser<> classes,
-// which are used to add command line arguments to a utility for all of the
-// passes that have been registered into the system.
-//
-// The PassNameParser class adds ALL passes linked into the system (that are
-// creatable) as command line arguments to the tool (when instantiated with the
-// appropriate command line option template). The FilteredPassNameParser<>
-// template is used for the same purposes as PassNameParser, except that it only
-// includes passes that have a PassType that are compatible with the filter
-// (which is the template argument).
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SUPPORT_PASSNAMEPARSER_H
-#define LLVM_SUPPORT_PASSNAMEPARSER_H
-
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/Pass.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/raw_ostream.h"
-#include <cstring>
-
-namespace llvm {
-
-//===----------------------------------------------------------------------===//
-// PassNameParser class - Make use of the pass registration mechanism to
-// automatically add a command line argument to opt for each pass.
-//
-class PassNameParser : public PassRegistrationListener,
- public cl::parser<const PassInfo*> {
- cl::Option *Opt;
-public:
- PassNameParser() : Opt(0) {}
- virtual ~PassNameParser();
-
- void initialize(cl::Option &O) {
- Opt = &O;
- cl::parser<const PassInfo*>::initialize(O);
-
- // Add all of the passes to the map that got initialized before 'this' did.
- enumeratePasses();
- }
-
- // ignorablePassImpl - Can be overriden in subclasses to refine the list of
- // which passes we want to include.
- //
- virtual bool ignorablePassImpl(const PassInfo *P) const { return false; }
-
- inline bool ignorablePass(const PassInfo *P) const {
- // Ignore non-selectable and non-constructible passes! Ignore
- // non-optimizations.
- return P->getPassArgument() == 0 || *P->getPassArgument() == 0 ||
- P->getNormalCtor() == 0 || ignorablePassImpl(P);
- }
-
- // Implement the PassRegistrationListener callbacks used to populate our map
- //
- virtual void passRegistered(const PassInfo *P) {
- if (ignorablePass(P) || !Opt) return;
- if (findOption(P->getPassArgument()) != getNumOptions()) {
- errs() << "Two passes with the same argument (-"
- << P->getPassArgument() << ") attempted to be registered!\n";
- llvm_unreachable(0);
- }
- addLiteralOption(P->getPassArgument(), P, P->getPassName());
- }
- virtual void passEnumerate(const PassInfo *P) { passRegistered(P); }
-
- // printOptionInfo - Print out information about this option. Override the
- // default implementation to sort the table before we print...
- virtual void printOptionInfo(const cl::Option &O, size_t GlobalWidth) const {
- PassNameParser *PNP = const_cast<PassNameParser*>(this);
- array_pod_sort(PNP->Values.begin(), PNP->Values.end(), ValLessThan);
- cl::parser<const PassInfo*>::printOptionInfo(O, GlobalWidth);
- }
-
-private:
- // ValLessThan - Provide a sorting comparator for Values elements...
- static int ValLessThan(const PassNameParser::OptionInfo *VT1,
- const PassNameParser::OptionInfo *VT2) {
- return std::strcmp(VT1->Name, VT2->Name);
- }
-};
-
-///===----------------------------------------------------------------------===//
-/// FilteredPassNameParser class - Make use of the pass registration
-/// mechanism to automatically add a command line argument to opt for
-/// each pass that satisfies a filter criteria. Filter should return
-/// true for passes to be registered as command-line options.
-///
-template<typename Filter>
-class FilteredPassNameParser : public PassNameParser {
-private:
- Filter filter;
-
-public:
- bool ignorablePassImpl(const PassInfo *P) const { return !filter(*P); }
-};
-
-///===----------------------------------------------------------------------===//
-/// PassArgFilter - A filter for use with PassNameFilterParser that only
-/// accepts a Pass whose Arg matches certain strings.
-///
-/// Use like this:
-///
-/// extern const char AllowedPassArgs[] = "-anders_aa -dse";
-///
-/// static cl::list<
-/// const PassInfo*,
-/// bool,
-/// FilteredPassNameParser<PassArgFilter<AllowedPassArgs> > >
-/// PassList(cl::desc("Passes available:"));
-///
-/// Only the -anders_aa and -dse options will be available to the user.
-///
-template<const char *Args>
-class PassArgFilter {
-public:
- bool operator()(const PassInfo &P) const {
- return(std::strstr(Args, P.getPassArgument()));
- }
-};
-
-} // End llvm namespace
-
-#endif
diff --git a/include/llvm/Support/Path.h b/include/llvm/Support/Path.h
index b2afe1b..ba18529 100644
--- a/include/llvm/Support/Path.h
+++ b/include/llvm/Support/Path.h
@@ -306,6 +306,12 @@ bool is_separator(char value);
/// @param result Holds the resulting path name.
void system_temp_directory(bool erasedOnReboot, SmallVectorImpl<char> &result);
+/// @brief Get the user's home directory.
+///
+/// @param result Holds the resulting path name.
+/// @result True if a home directory is set, false otherwise.
+bool home_directory(SmallVectorImpl<char> &result);
+
/// @brief Has root name?
///
/// root_name != ""
diff --git a/include/llvm/Support/PatternMatch.h b/include/llvm/Support/PatternMatch.h
deleted file mode 100644
index 240bb81..0000000
--- a/include/llvm/Support/PatternMatch.h
+++ /dev/null
@@ -1,1121 +0,0 @@
-//===-- llvm/Support/PatternMatch.h - Match on the LLVM IR ------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file provides a simple and efficient mechanism for performing general
-// tree-based pattern matches on the LLVM IR. The power of these routines is
-// that it allows you to write concise patterns that are expressive and easy to
-// understand. The other major advantage of this is that it allows you to
-// trivially capture/bind elements in the pattern to variables. For example,
-// you can do something like this:
-//
-// Value *Exp = ...
-// Value *X, *Y; ConstantInt *C1, *C2; // (X & C1) | (Y & C2)
-// if (match(Exp, m_Or(m_And(m_Value(X), m_ConstantInt(C1)),
-// m_And(m_Value(Y), m_ConstantInt(C2))))) {
-// ... Pattern is matched and variables are bound ...
-// }
-//
-// This is primarily useful to things like the instruction combiner, but can
-// also be useful for static analysis tools or code generators.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SUPPORT_PATTERNMATCH_H
-#define LLVM_SUPPORT_PATTERNMATCH_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 {
-
-template<typename Val, typename Pattern>
-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);
- }
-};
-
-template<typename T>
-inline OneUse_match<T> m_OneUse(const T &SubPattern) { return SubPattern; }
-
-
-template<typename Class>
-struct class_match {
- template<typename ITy>
- bool match(ITy *V) { return isa<Class>(V); }
-};
-
-/// m_Value() - Match an arbitrary value and ignore it.
-inline class_match<Value> m_Value() { return class_match<Value>(); }
-/// m_ConstantInt() - Match an arbitrary ConstantInt and ignore it.
-inline class_match<ConstantInt> m_ConstantInt() {
- return class_match<ConstantInt>();
-}
-/// m_Undef() - Match an arbitrary undef constant.
-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) {
- if (const Constant *C = dyn_cast<Constant>(V))
- return C->isNullValue();
- 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) {}
- template<typename ITy>
- bool match(ITy *V) {
- if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
- 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>
- bool match(ITy *V) {
- if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
- const APInt &CIV = CI->getValue();
- if (Val >= 0)
- return CIV == static_cast<uint64_t>(Val);
- // If Val is negative, and CI is shorter than it, truncate to the right
- // number of bits. If it is larger, then we have to sign extend. Just
- // compare their negated values.
- return -CIV == -Val;
- }
- return false;
- }
-};
-
-/// m_ConstantInt<int64_t> - Match a ConstantInt with a specific value.
-template<int64_t Val>
-inline constantint_match<Val> m_ConstantInt() {
- return constantint_match<Val>();
-}
-
-/// cst_pred_ty - This helper class is used to match scalar and vector constants
-/// that satisfy a specified predicate.
-template<typename Predicate>
-struct cst_pred_ty : public Predicate {
- template<typename ITy>
- bool match(ITy *V) {
- if (const ConstantInt *CI = dyn_cast<ConstantInt>(V))
- 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>
-struct api_pred_ty : public Predicate {
- const APInt *&Res;
- api_pred_ty(const APInt *&R) : Res(R) {}
- template<typename ITy>
- bool match(ITy *V) {
- if (const ConstantInt *CI = dyn_cast<ConstantInt>(V))
- 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; }
-};
-
-/// 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; }
-
-struct is_sign_bit {
- bool isValue(const APInt &C) { return C.isSignBit(); }
-};
-
-/// m_SignBit() - Match an integer or vector with only the sign bit(s) set.
-inline cst_pred_ty<is_sign_bit> m_SignBit() {return cst_pred_ty<is_sign_bit>();}
-inline api_pred_ty<is_sign_bit> m_SignBit(const APInt *&V) { return V; }
-
-struct is_power2 {
- bool isValue(const APInt &C) { return C.isPowerOf2(); }
-};
-
-/// m_Power2() - Match an integer or vector power of 2.
-inline cst_pred_ty<is_power2> m_Power2() { return cst_pred_ty<is_power2>(); }
-inline api_pred_ty<is_power2> m_Power2(const APInt *&V) { return V; }
-
-template<typename Class>
-struct bind_ty {
- Class *&VR;
- bind_ty(Class *&V) : VR(V) {}
-
- template<typename ITy>
- bool match(ITy *V) {
- if (Class *CV = dyn_cast<Class>(V)) {
- VR = CV;
- return true;
- }
- return false;
- }
-};
-
-/// m_Value - Match a value, capturing it if we match.
-inline bind_ty<Value> m_Value(Value *&V) { return V; }
-
-/// m_ConstantInt - Match a ConstantInt, capturing the value if we match.
-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;
- specificval_ty(const Value *V) : Val(V) {}
-
- template<typename ITy>
- bool match(ITy *V) {
- return V == Val;
- }
-};
-
-/// 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))
- if (CV->getBitWidth() <= 64) {
- VR = CV->getZExtValue();
- return true;
- }
- return false;
- }
-};
-
-/// 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.
-//
-
-template<typename LHS_t, typename RHS_t, unsigned Opcode>
-struct BinaryOp_match {
- LHS_t L;
- RHS_t R;
-
- BinaryOp_match(const LHS_t &LHS, const RHS_t &RHS) : L(LHS), R(RHS) {}
-
- template<typename OpTy>
- bool match(OpTy *V) {
- if (V->getValueID() == Value::InstructionVal + Opcode) {
- BinaryOperator *I = cast<BinaryOperator>(V);
- return L.match(I->getOperand(0)) && R.match(I->getOperand(1));
- }
- if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
- return CE->getOpcode() == Opcode && L.match(CE->getOperand(0)) &&
- R.match(CE->getOperand(1));
- return false;
- }
-};
-
-template<typename LHS, typename RHS>
-inline BinaryOp_match<LHS, RHS, Instruction::Add>
-m_Add(const LHS &L, const RHS &R) {
- return BinaryOp_match<LHS, RHS, Instruction::Add>(L, R);
-}
-
-template<typename LHS, typename RHS>
-inline BinaryOp_match<LHS, RHS, Instruction::FAdd>
-m_FAdd(const LHS &L, const RHS &R) {
- return BinaryOp_match<LHS, RHS, Instruction::FAdd>(L, R);
-}
-
-template<typename LHS, typename RHS>
-inline BinaryOp_match<LHS, RHS, Instruction::Sub>
-m_Sub(const LHS &L, const RHS &R) {
- return BinaryOp_match<LHS, RHS, Instruction::Sub>(L, R);
-}
-
-template<typename LHS, typename RHS>
-inline BinaryOp_match<LHS, RHS, Instruction::FSub>
-m_FSub(const LHS &L, const RHS &R) {
- return BinaryOp_match<LHS, RHS, Instruction::FSub>(L, R);
-}
-
-template<typename LHS, typename RHS>
-inline BinaryOp_match<LHS, RHS, Instruction::Mul>
-m_Mul(const LHS &L, const RHS &R) {
- return BinaryOp_match<LHS, RHS, Instruction::Mul>(L, R);
-}
-
-template<typename LHS, typename RHS>
-inline BinaryOp_match<LHS, RHS, Instruction::FMul>
-m_FMul(const LHS &L, const RHS &R) {
- return BinaryOp_match<LHS, RHS, Instruction::FMul>(L, R);
-}
-
-template<typename LHS, typename RHS>
-inline BinaryOp_match<LHS, RHS, Instruction::UDiv>
-m_UDiv(const LHS &L, const RHS &R) {
- return BinaryOp_match<LHS, RHS, Instruction::UDiv>(L, R);
-}
-
-template<typename LHS, typename RHS>
-inline BinaryOp_match<LHS, RHS, Instruction::SDiv>
-m_SDiv(const LHS &L, const RHS &R) {
- return BinaryOp_match<LHS, RHS, Instruction::SDiv>(L, R);
-}
-
-template<typename LHS, typename RHS>
-inline BinaryOp_match<LHS, RHS, Instruction::FDiv>
-m_FDiv(const LHS &L, const RHS &R) {
- return BinaryOp_match<LHS, RHS, Instruction::FDiv>(L, R);
-}
-
-template<typename LHS, typename RHS>
-inline BinaryOp_match<LHS, RHS, Instruction::URem>
-m_URem(const LHS &L, const RHS &R) {
- return BinaryOp_match<LHS, RHS, Instruction::URem>(L, R);
-}
-
-template<typename LHS, typename RHS>
-inline BinaryOp_match<LHS, RHS, Instruction::SRem>
-m_SRem(const LHS &L, const RHS &R) {
- return BinaryOp_match<LHS, RHS, Instruction::SRem>(L, R);
-}
-
-template<typename LHS, typename RHS>
-inline BinaryOp_match<LHS, RHS, Instruction::FRem>
-m_FRem(const LHS &L, const RHS &R) {
- return BinaryOp_match<LHS, RHS, Instruction::FRem>(L, R);
-}
-
-template<typename LHS, typename RHS>
-inline BinaryOp_match<LHS, RHS, Instruction::And>
-m_And(const LHS &L, const RHS &R) {
- return BinaryOp_match<LHS, RHS, Instruction::And>(L, R);
-}
-
-template<typename LHS, typename RHS>
-inline BinaryOp_match<LHS, RHS, Instruction::Or>
-m_Or(const LHS &L, const RHS &R) {
- return BinaryOp_match<LHS, RHS, Instruction::Or>(L, R);
-}
-
-template<typename LHS, typename RHS>
-inline BinaryOp_match<LHS, RHS, Instruction::Xor>
-m_Xor(const LHS &L, const RHS &R) {
- return BinaryOp_match<LHS, RHS, Instruction::Xor>(L, R);
-}
-
-template<typename LHS, typename RHS>
-inline BinaryOp_match<LHS, RHS, Instruction::Shl>
-m_Shl(const LHS &L, const RHS &R) {
- return BinaryOp_match<LHS, RHS, Instruction::Shl>(L, R);
-}
-
-template<typename LHS, typename RHS>
-inline BinaryOp_match<LHS, RHS, Instruction::LShr>
-m_LShr(const LHS &L, const RHS &R) {
- return BinaryOp_match<LHS, RHS, Instruction::LShr>(L, R);
-}
-
-template<typename LHS, typename RHS>
-inline BinaryOp_match<LHS, RHS, Instruction::AShr>
-m_AShr(const LHS &L, const RHS &R) {
- return BinaryOp_match<LHS, RHS, Instruction::AShr>(L, R);
-}
-
-//===----------------------------------------------------------------------===//
-// Class that matches two different binary ops.
-//
-template<typename LHS_t, typename RHS_t, unsigned Opc1, unsigned Opc2>
-struct BinOp2_match {
- LHS_t L;
- RHS_t R;
-
- BinOp2_match(const LHS_t &LHS, const RHS_t &RHS) : L(LHS), R(RHS) {}
-
- template<typename OpTy>
- bool match(OpTy *V) {
- if (V->getValueID() == Value::InstructionVal + Opc1 ||
- V->getValueID() == Value::InstructionVal + Opc2) {
- BinaryOperator *I = cast<BinaryOperator>(V);
- return L.match(I->getOperand(0)) && R.match(I->getOperand(1));
- }
- if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
- return (CE->getOpcode() == Opc1 || CE->getOpcode() == Opc2) &&
- L.match(CE->getOperand(0)) && R.match(CE->getOperand(1));
- return false;
- }
-};
-
-/// m_Shr - Matches LShr or AShr.
-template<typename LHS, typename RHS>
-inline BinOp2_match<LHS, RHS, Instruction::LShr, Instruction::AShr>
-m_Shr(const LHS &L, const RHS &R) {
- return BinOp2_match<LHS, RHS, Instruction::LShr, Instruction::AShr>(L, R);
-}
-
-/// m_LogicalShift - Matches LShr or Shl.
-template<typename LHS, typename RHS>
-inline BinOp2_match<LHS, RHS, Instruction::LShr, Instruction::Shl>
-m_LogicalShift(const LHS &L, const RHS &R) {
- return BinOp2_match<LHS, RHS, Instruction::LShr, Instruction::Shl>(L, R);
-}
-
-/// m_IDiv - Matches UDiv and SDiv.
-template<typename LHS, typename RHS>
-inline BinOp2_match<LHS, RHS, Instruction::SDiv, Instruction::UDiv>
-m_IDiv(const LHS &L, const RHS &R) {
- return BinOp2_match<LHS, RHS, Instruction::SDiv, Instruction::UDiv>(L, R);
-}
-
-//===----------------------------------------------------------------------===//
-// Class that matches exact binary ops.
-//
-template<typename SubPattern_t>
-struct Exact_match {
- SubPattern_t SubPattern;
-
- Exact_match(const SubPattern_t &SP) : SubPattern(SP) {}
-
- template<typename OpTy>
- bool match(OpTy *V) {
- if (PossiblyExactOperator *PEO = dyn_cast<PossiblyExactOperator>(V))
- return PEO->isExact() && SubPattern.match(V);
- return false;
- }
-};
-
-template<typename T>
-inline Exact_match<T> m_Exact(const T &SubPattern) { return SubPattern; }
-
-//===----------------------------------------------------------------------===//
-// Matchers for CmpInst classes
-//
-
-template<typename LHS_t, typename RHS_t, typename Class, typename PredicateTy>
-struct CmpClass_match {
- PredicateTy &Predicate;
- LHS_t L;
- RHS_t R;
-
- CmpClass_match(PredicateTy &Pred, const LHS_t &LHS, const RHS_t &RHS)
- : Predicate(Pred), L(LHS), R(RHS) {}
-
- template<typename OpTy>
- bool match(OpTy *V) {
- if (Class *I = dyn_cast<Class>(V))
- if (L.match(I->getOperand(0)) && R.match(I->getOperand(1))) {
- Predicate = I->getPredicate();
- return true;
- }
- return false;
- }
-};
-
-template<typename LHS, typename RHS>
-inline CmpClass_match<LHS, RHS, ICmpInst, ICmpInst::Predicate>
-m_ICmp(ICmpInst::Predicate &Pred, const LHS &L, const RHS &R) {
- return CmpClass_match<LHS, RHS,
- ICmpInst, ICmpInst::Predicate>(Pred, L, R);
-}
-
-template<typename LHS, typename RHS>
-inline CmpClass_match<LHS, RHS, FCmpInst, FCmpInst::Predicate>
-m_FCmp(FCmpInst::Predicate &Pred, const LHS &L, const RHS &R) {
- return CmpClass_match<LHS, RHS,
- FCmpInst, FCmpInst::Predicate>(Pred, L, R);
-}
-
-//===----------------------------------------------------------------------===//
-// Matchers for SelectInst classes
-//
-
-template<typename Cond_t, typename LHS_t, typename RHS_t>
-struct SelectClass_match {
- Cond_t C;
- LHS_t L;
- RHS_t R;
-
- SelectClass_match(const Cond_t &Cond, const LHS_t &LHS,
- const RHS_t &RHS)
- : C(Cond), L(LHS), R(RHS) {}
-
- template<typename OpTy>
- bool match(OpTy *V) {
- if (SelectInst *I = dyn_cast<SelectInst>(V))
- return C.match(I->getOperand(0)) &&
- L.match(I->getOperand(1)) &&
- R.match(I->getOperand(2));
- return false;
- }
-};
-
-template<typename Cond, typename LHS, typename RHS>
-inline SelectClass_match<Cond, LHS, RHS>
-m_Select(const Cond &C, const LHS &L, const RHS &R) {
- return SelectClass_match<Cond, LHS, RHS>(C, L, R);
-}
-
-/// m_SelectCst - This matches a select of two constants, e.g.:
-/// m_SelectCst<-1, 0>(m_Value(V))
-template<int64_t L, int64_t R, typename Cond>
-inline SelectClass_match<Cond, constantint_match<L>, constantint_match<R> >
-m_SelectCst(const Cond &C) {
- return m_Select(C, m_ConstantInt<L>(), m_ConstantInt<R>());
-}
-
-
-//===----------------------------------------------------------------------===//
-// Matchers for CastInst classes
-//
-
-template<typename Op_t, unsigned Opcode>
-struct CastClass_match {
- Op_t Op;
-
- CastClass_match(const Op_t &OpMatch) : Op(OpMatch) {}
-
- template<typename OpTy>
- bool match(OpTy *V) {
- if (Operator *O = dyn_cast<Operator>(V))
- return O->getOpcode() == Opcode && Op.match(O->getOperand(0));
- return false;
- }
-};
-
-/// m_BitCast
-template<typename OpTy>
-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>
-m_PtrToInt(const OpTy &Op) {
- return CastClass_match<OpTy, Instruction::PtrToInt>(Op);
-}
-
-/// m_Trunc
-template<typename OpTy>
-inline CastClass_match<OpTy, Instruction::Trunc>
-m_Trunc(const OpTy &Op) {
- return CastClass_match<OpTy, Instruction::Trunc>(Op);
-}
-
-/// m_SExt
-template<typename OpTy>
-inline CastClass_match<OpTy, Instruction::SExt>
-m_SExt(const OpTy &Op) {
- return CastClass_match<OpTy, Instruction::SExt>(Op);
-}
-
-/// m_ZExt
-template<typename OpTy>
-inline CastClass_match<OpTy, Instruction::ZExt>
-m_ZExt(const OpTy &Op) {
- return CastClass_match<OpTy, Instruction::ZExt>(Op);
-}
-
-/// m_UIToFP
-template<typename OpTy>
-inline CastClass_match<OpTy, Instruction::UIToFP>
-m_UIToFP(const OpTy &Op) {
- return CastClass_match<OpTy, Instruction::UIToFP>(Op);
-}
-
-/// m_SIToFP
-template<typename OpTy>
-inline CastClass_match<OpTy, Instruction::SIToFP>
-m_SIToFP(const OpTy &Op) {
- return CastClass_match<OpTy, Instruction::SIToFP>(Op);
-}
-
-//===----------------------------------------------------------------------===//
-// Matchers for unary operators
-//
-
-template<typename LHS_t>
-struct not_match {
- LHS_t L;
-
- not_match(const LHS_t &LHS) : L(LHS) {}
-
- template<typename OpTy>
- bool match(OpTy *V) {
- if (Operator *O = dyn_cast<Operator>(V))
- if (O->getOpcode() == Instruction::Xor)
- return matchIfNot(O->getOperand(0), O->getOperand(1));
- return false;
- }
-private:
- bool matchIfNot(Value *LHS, Value *RHS) {
- return (isa<ConstantInt>(RHS) || isa<ConstantDataVector>(RHS) ||
- // FIXME: Remove CV.
- isa<ConstantVector>(RHS)) &&
- cast<Constant>(RHS)->isAllOnesValue() &&
- L.match(LHS);
- }
-};
-
-template<typename LHS>
-inline not_match<LHS> m_Not(const LHS &L) { return L; }
-
-
-template<typename LHS_t>
-struct neg_match {
- LHS_t L;
-
- neg_match(const LHS_t &LHS) : L(LHS) {}
-
- template<typename OpTy>
- bool match(OpTy *V) {
- if (Operator *O = dyn_cast<Operator>(V))
- if (O->getOpcode() == Instruction::Sub)
- return matchIfNeg(O->getOperand(0), O->getOperand(1));
- return false;
- }
-private:
- bool matchIfNeg(Value *LHS, Value *RHS) {
- return ((isa<ConstantInt>(LHS) && cast<ConstantInt>(LHS)->isZero()) ||
- isa<ConstantAggregateZero>(LHS)) &&
- L.match(RHS);
- }
-};
-
-/// m_Neg - Match an integer negate.
-template<typename LHS>
-inline neg_match<LHS> m_Neg(const LHS &L) { return L; }
-
-
-template<typename LHS_t>
-struct fneg_match {
- LHS_t L;
-
- fneg_match(const LHS_t &LHS) : L(LHS) {}
-
- template<typename OpTy>
- bool match(OpTy *V) {
- if (Operator *O = dyn_cast<Operator>(V))
- if (O->getOpcode() == Instruction::FSub)
- return matchIfFNeg(O->getOperand(0), O->getOperand(1));
- return false;
- }
-private:
- bool matchIfFNeg(Value *LHS, Value *RHS) {
- if (ConstantFP *C = dyn_cast<ConstantFP>(LHS))
- return C->isNegativeZeroValue() && L.match(RHS);
- return false;
- }
-};
-
-/// m_FNeg - Match a floating point negate.
-template<typename LHS>
-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;
- BasicBlock *&T, *&F;
- brc_match(const Cond_t &C, BasicBlock *&t, BasicBlock *&f)
- : Cond(C), T(t), F(f) {
- }
-
- template<typename OpTy>
- bool match(OpTy *V) {
- if (BranchInst *BI = dyn_cast<BranchInst>(V))
- if (BI->isConditional() && Cond.match(BI->getCondition())) {
- T = BI->getSuccessor(0);
- F = BI->getSuccessor(1);
- return true;
- }
- return false;
- }
-};
-
-template<typename Cond_t>
-inline brc_match<Cond_t> m_Br(const Cond_t &C, BasicBlock *&T, BasicBlock *&F) {
- return brc_match<Cond_t>(C, T, F);
-}
-
-
-//===----------------------------------------------------------------------===//
-// Matchers for max/min idioms, eg: "select (sgt x, y), x, y" -> smax(x,y).
-//
-
-template<typename CmpInst_t, typename LHS_t, typename RHS_t, typename Pred_t>
-struct MaxMin_match {
- LHS_t L;
- RHS_t R;
-
- MaxMin_match(const LHS_t &LHS, const RHS_t &RHS)
- : L(LHS), R(RHS) {}
-
- template<typename OpTy>
- bool match(OpTy *V) {
- // Look for "(x pred y) ? x : y" or "(x pred y) ? y : x".
- SelectInst *SI = dyn_cast<SelectInst>(V);
- if (!SI)
- return false;
- CmpInst_t *Cmp = dyn_cast<CmpInst_t>(SI->getCondition());
- if (!Cmp)
- return false;
- // At this point we have a select conditioned on a comparison. Check that
- // it is the values returned by the select that are being compared.
- Value *TrueVal = SI->getTrueValue();
- Value *FalseVal = SI->getFalseValue();
- Value *LHS = Cmp->getOperand(0);
- Value *RHS = Cmp->getOperand(1);
- if ((TrueVal != LHS || FalseVal != RHS) &&
- (TrueVal != RHS || FalseVal != LHS))
- return false;
- typename CmpInst_t::Predicate Pred = LHS == TrueVal ?
- Cmp->getPredicate() : Cmp->getSwappedPredicate();
- // Does "(x pred y) ? x : y" represent the desired max/min operation?
- if (!Pred_t::match(Pred))
- return false;
- // It does! Bind the operands.
- return L.match(LHS) && R.match(RHS);
- }
-};
-
-/// smax_pred_ty - Helper class for identifying signed max predicates.
-struct smax_pred_ty {
- static bool match(ICmpInst::Predicate Pred) {
- return Pred == CmpInst::ICMP_SGT || Pred == CmpInst::ICMP_SGE;
- }
-};
-
-/// smin_pred_ty - Helper class for identifying signed min predicates.
-struct smin_pred_ty {
- static bool match(ICmpInst::Predicate Pred) {
- return Pred == CmpInst::ICMP_SLT || Pred == CmpInst::ICMP_SLE;
- }
-};
-
-/// umax_pred_ty - Helper class for identifying unsigned max predicates.
-struct umax_pred_ty {
- static bool match(ICmpInst::Predicate Pred) {
- return Pred == CmpInst::ICMP_UGT || Pred == CmpInst::ICMP_UGE;
- }
-};
-
-/// umin_pred_ty - Helper class for identifying unsigned min predicates.
-struct umin_pred_ty {
- static bool match(ICmpInst::Predicate Pred) {
- return Pred == CmpInst::ICMP_ULT || Pred == CmpInst::ICMP_ULE;
- }
-};
-
-/// ofmax_pred_ty - Helper class for identifying ordered max predicates.
-struct ofmax_pred_ty {
- static bool match(FCmpInst::Predicate Pred) {
- return Pred == CmpInst::FCMP_OGT || Pred == CmpInst::FCMP_OGE;
- }
-};
-
-/// ofmin_pred_ty - Helper class for identifying ordered min predicates.
-struct ofmin_pred_ty {
- static bool match(FCmpInst::Predicate Pred) {
- return Pred == CmpInst::FCMP_OLT || Pred == CmpInst::FCMP_OLE;
- }
-};
-
-/// ufmax_pred_ty - Helper class for identifying unordered max predicates.
-struct ufmax_pred_ty {
- static bool match(FCmpInst::Predicate Pred) {
- return Pred == CmpInst::FCMP_UGT || Pred == CmpInst::FCMP_UGE;
- }
-};
-
-/// ufmin_pred_ty - Helper class for identifying unordered min predicates.
-struct ufmin_pred_ty {
- static bool match(FCmpInst::Predicate Pred) {
- return Pred == CmpInst::FCMP_ULT || Pred == CmpInst::FCMP_ULE;
- }
-};
-
-template<typename LHS, typename RHS>
-inline MaxMin_match<ICmpInst, LHS, RHS, smax_pred_ty>
-m_SMax(const LHS &L, const RHS &R) {
- return MaxMin_match<ICmpInst, LHS, RHS, smax_pred_ty>(L, R);
-}
-
-template<typename LHS, typename RHS>
-inline MaxMin_match<ICmpInst, LHS, RHS, smin_pred_ty>
-m_SMin(const LHS &L, const RHS &R) {
- return MaxMin_match<ICmpInst, LHS, RHS, smin_pred_ty>(L, R);
-}
-
-template<typename LHS, typename RHS>
-inline MaxMin_match<ICmpInst, LHS, RHS, umax_pred_ty>
-m_UMax(const LHS &L, const RHS &R) {
- return MaxMin_match<ICmpInst, LHS, RHS, umax_pred_ty>(L, R);
-}
-
-template<typename LHS, typename RHS>
-inline MaxMin_match<ICmpInst, LHS, RHS, umin_pred_ty>
-m_UMin(const LHS &L, const RHS &R) {
- return MaxMin_match<ICmpInst, LHS, RHS, umin_pred_ty>(L, R);
-}
-
-/// \brief Match an 'ordered' floating point maximum function.
-/// Floating point has one special value 'NaN'. Therefore, there is no total
-/// order. However, if we can ignore the 'NaN' value (for example, because of a
-/// 'no-nans-float-math' flag) a combination of a fcmp and select has 'maximum'
-/// semantics. In the presence of 'NaN' we have to preserve the original
-/// select(fcmp(ogt/ge, L, R), L, R) semantics matched by this predicate.
-///
-/// max(L, R) iff L and R are not NaN
-/// m_OrdFMax(L, R) = R iff L or R are NaN
-template<typename LHS, typename RHS>
-inline MaxMin_match<FCmpInst, LHS, RHS, ofmax_pred_ty>
-m_OrdFMax(const LHS &L, const RHS &R) {
- return MaxMin_match<FCmpInst, LHS, RHS, ofmax_pred_ty>(L, R);
-}
-
-/// \brief Match an 'ordered' floating point minimum function.
-/// Floating point has one special value 'NaN'. Therefore, there is no total
-/// order. However, if we can ignore the 'NaN' value (for example, because of a
-/// 'no-nans-float-math' flag) a combination of a fcmp and select has 'minimum'
-/// semantics. In the presence of 'NaN' we have to preserve the original
-/// select(fcmp(olt/le, L, R), L, R) semantics matched by this predicate.
-///
-/// max(L, R) iff L and R are not NaN
-/// m_OrdFMin(L, R) = R iff L or R are NaN
-template<typename LHS, typename RHS>
-inline MaxMin_match<FCmpInst, LHS, RHS, ofmin_pred_ty>
-m_OrdFMin(const LHS &L, const RHS &R) {
- return MaxMin_match<FCmpInst, LHS, RHS, ofmin_pred_ty>(L, R);
-}
-
-/// \brief Match an 'unordered' floating point maximum function.
-/// Floating point has one special value 'NaN'. Therefore, there is no total
-/// order. However, if we can ignore the 'NaN' value (for example, because of a
-/// 'no-nans-float-math' flag) a combination of a fcmp and select has 'maximum'
-/// semantics. In the presence of 'NaN' we have to preserve the original
-/// select(fcmp(ugt/ge, L, R), L, R) semantics matched by this predicate.
-///
-/// max(L, R) iff L and R are not NaN
-/// m_UnordFMin(L, R) = L iff L or R are NaN
-template<typename LHS, typename RHS>
-inline MaxMin_match<FCmpInst, LHS, RHS, ufmax_pred_ty>
-m_UnordFMax(const LHS &L, const RHS &R) {
- return MaxMin_match<FCmpInst, LHS, RHS, ufmax_pred_ty>(L, R);
-}
-
-/// \brief Match an 'unordered' floating point minimum function.
-/// Floating point has one special value 'NaN'. Therefore, there is no total
-/// order. However, if we can ignore the 'NaN' value (for example, because of a
-/// 'no-nans-float-math' flag) a combination of a fcmp and select has 'minimum'
-/// semantics. In the presence of 'NaN' we have to preserve the original
-/// select(fcmp(ult/le, L, R), L, R) semantics matched by this predicate.
-///
-/// max(L, R) iff L and R are not NaN
-/// m_UnordFMin(L, R) = L iff L or R are NaN
-template<typename LHS, typename RHS>
-inline MaxMin_match<FCmpInst, LHS, RHS, ufmin_pred_ty>
-m_UnordFMin(const LHS &L, const RHS &R) {
- return MaxMin_match<FCmpInst, LHS, RHS, ufmin_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(Intrinsic::ID 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 <Intrinsic::ID IntrID>
-inline IntrinsicID_match
-m_Intrinsic() { return IntrinsicID_match(IntrID); }
-
-template<Intrinsic::ID 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<Intrinsic::ID 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<Intrinsic::ID 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<Intrinsic::ID 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
-
-#endif
diff --git a/include/llvm/Support/PredIteratorCache.h b/include/llvm/Support/PredIteratorCache.h
deleted file mode 100644
index c5fb780..0000000
--- a/include/llvm/Support/PredIteratorCache.h
+++ /dev/null
@@ -1,70 +0,0 @@
-//===- llvm/Support/PredIteratorCache.h - pred_iterator Cache ---*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the PredIteratorCache class.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/Support/Allocator.h"
-#include "llvm/Support/CFG.h"
-
-#ifndef LLVM_SUPPORT_PREDITERATORCACHE_H
-#define LLVM_SUPPORT_PREDITERATORCACHE_H
-
-namespace llvm {
-
- /// PredIteratorCache - This class is an extremely trivial cache for
- /// predecessor iterator queries. This is useful for code that repeatedly
- /// wants the predecessor list for the same blocks.
- class PredIteratorCache {
- /// BlockToPredsMap - Pointer to null-terminated list.
- DenseMap<BasicBlock*, BasicBlock**> BlockToPredsMap;
- DenseMap<BasicBlock*, unsigned> BlockToPredCountMap;
-
- /// Memory - This is the space that holds cached preds.
- BumpPtrAllocator Memory;
- public:
-
- /// GetPreds - Get a cached list for the null-terminated predecessor list of
- /// the specified block. This can be used in a loop like this:
- /// for (BasicBlock **PI = PredCache->GetPreds(BB); *PI; ++PI)
- /// use(*PI);
- /// instead of:
- /// for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI)
- BasicBlock **GetPreds(BasicBlock *BB) {
- BasicBlock **&Entry = BlockToPredsMap[BB];
- if (Entry) return Entry;
-
- SmallVector<BasicBlock*, 32> PredCache(pred_begin(BB), pred_end(BB));
- PredCache.push_back(0); // null terminator.
-
- BlockToPredCountMap[BB] = PredCache.size()-1;
-
- Entry = Memory.Allocate<BasicBlock*>(PredCache.size());
- std::copy(PredCache.begin(), PredCache.end(), Entry);
- return Entry;
- }
-
- unsigned GetNumPreds(BasicBlock *BB) {
- GetPreds(BB);
- return BlockToPredCountMap[BB];
- }
-
- /// clear - Remove all information.
- void clear() {
- BlockToPredsMap.clear();
- BlockToPredCountMap.clear();
- Memory.Reset();
- }
- };
-} // end namespace llvm
-
-#endif
diff --git a/include/llvm/Support/PrettyStackTrace.h b/include/llvm/Support/PrettyStackTrace.h
index 4f68fca..914141a 100644
--- a/include/llvm/Support/PrettyStackTrace.h
+++ b/include/llvm/Support/PrettyStackTrace.h
@@ -50,7 +50,7 @@ namespace llvm {
const char *Str;
public:
PrettyStackTraceString(const char *str) : Str(str) {}
- virtual void print(raw_ostream &OS) const LLVM_OVERRIDE;
+ void print(raw_ostream &OS) const override;
};
/// PrettyStackTraceProgram - This object prints a specified program arguments
@@ -63,7 +63,7 @@ namespace llvm {
: ArgC(argc), ArgV(argv) {
EnablePrettyStackTrace();
}
- virtual void print(raw_ostream &OS) const LLVM_OVERRIDE;
+ void print(raw_ostream &OS) const override;
};
} // end namespace llvm
diff --git a/include/llvm/Support/Process.h b/include/llvm/Support/Process.h
index 2172036..7f6441e 100644
--- a/include/llvm/Support/Process.h
+++ b/include/llvm/Support/Process.h
@@ -29,9 +29,9 @@
#include "llvm/ADT/Optional.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/Support/Allocator.h"
-#include "llvm/Support/system_error.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/TimeValue.h"
+#include "llvm/Support/system_error.h"
namespace llvm {
class StringRef;
@@ -110,10 +110,10 @@ class self_process : public process {
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;
+ id_type get_id() override;
+ TimeValue get_user_time() const override;
+ TimeValue get_system_time() const override;
+ TimeValue get_wall_time() const override;
/// \name Process configuration (sysconf on POSIX)
/// @{
diff --git a/include/llvm/Support/Program.h b/include/llvm/Support/Program.h
index 00571a4..a1067a6 100644
--- a/include/llvm/Support/Program.h
+++ b/include/llvm/Support/Program.h
@@ -52,27 +52,31 @@ struct ProcessInfo {
ProcessInfo();
};
- /// This static constructor (factory) will attempt to locate a program in
- /// the operating system's file system using some pre-determined set of
- /// locations to search (e.g. the PATH on Unix). Paths with slashes are
- /// returned unmodified.
- /// @returns A Path object initialized to the path of the program or a
- /// Path object that is empty (invalid) if the program could not be found.
- /// @brief Construct a Program by finding it by name.
+ /// This function attempts to locate a program in the operating
+ /// system's file system using some pre-determined set of locations to search
+ /// (e.g. the PATH on Unix). Paths with slashes are returned unmodified.
+ ///
+ /// It does not perform hashing as a shell would but instead stats each PATH
+ /// entry individually so should generally be avoided. Core LLVM library
+ /// functions and options should instead require fully specified paths.
+ ///
+ /// @returns A string containing the path of the program or an empty string if
+ /// the program could not be found.
std::string FindProgramByName(const std::string& name);
- // These functions change the specified standard stream (stdin, stdout, or
- // stderr) to binary mode. They return errc::success if the specified stream
+ // These functions change the specified standard stream (stdin or stdout) to
+ // binary mode. They return errc::success if the specified stream
// was changed. Otherwise a platform dependent error is returned.
error_code ChangeStdinToBinary();
error_code ChangeStdoutToBinary();
- error_code ChangeStderrToBinary();
/// This function executes the program using the arguments provided. The
/// invoked program will inherit the stdin, stdout, and stderr file
/// descriptors, the environment and other configuration settings of the
/// invoking program.
- /// This function waits the program to finish.
+ /// This function waits for the program to finish, so should be avoided in
+ /// library functions that aren't expected to block. Consider using
+ /// ExecuteNoWait() instead.
/// @returns an integer result code indicating the status of the program.
/// A zero or positive value indicates the result code of the program.
/// -1 indicates failure to execute
diff --git a/include/llvm/Support/Recycler.h b/include/llvm/Support/Recycler.h
index bcc561d..e97f36a 100644
--- a/include/llvm/Support/Recycler.h
+++ b/include/llvm/Support/Recycler.h
@@ -17,13 +17,12 @@
#include "llvm/ADT/ilist.h"
#include "llvm/Support/AlignOf.h"
+#include "llvm/Support/Allocator.h"
#include "llvm/Support/ErrorHandling.h"
#include <cassert>
namespace llvm {
-class BumpPtrAllocator;
-
/// PrintRecyclingAllocatorStats - Helper for RecyclingAllocator for
/// printing statistics.
///
@@ -100,10 +99,10 @@ public:
template<class SubClass, class AllocatorType>
SubClass *Allocate(AllocatorType &Allocator) {
- assert(sizeof(SubClass) <= Size &&
- "Recycler allocation size is less than object size!");
- assert(AlignOf<SubClass>::Alignment <= Align &&
- "Recycler allocation alignment is less than object alignment!");
+ static_assert(AlignOf<SubClass>::Alignment <= Align,
+ "Recycler allocation alignment is less than object align!");
+ static_assert(sizeof(SubClass) <= Size,
+ "Recycler allocation size is less than object size!");
return !FreeList.empty() ?
reinterpret_cast<SubClass *>(FreeList.remove(FreeList.begin())) :
static_cast<SubClass *>(Allocator.Allocate(Size, Align));
diff --git a/include/llvm/Support/Regex.h b/include/llvm/Support/Regex.h
index 3d071be..2eea369 100644
--- a/include/llvm/Support/Regex.h
+++ b/include/llvm/Support/Regex.h
@@ -17,6 +17,7 @@
#ifndef LLVM_SUPPORT_REGEX_H
#define LLVM_SUPPORT_REGEX_H
+#include "llvm/Support/Compiler.h"
#include <string>
struct llvm_regex;
@@ -45,6 +46,17 @@ namespace llvm {
/// Compiles the given regular expression \p Regex.
Regex(StringRef Regex, unsigned Flags = NoFlags);
+ Regex(const Regex &) LLVM_DELETED_FUNCTION;
+ Regex &operator=(Regex regex) {
+ std::swap(preg, regex.preg);
+ std::swap(error, regex.error);
+ return *this;
+ }
+ Regex(Regex &&regex) {
+ preg = regex.preg;
+ error = regex.error;
+ regex.preg = NULL;
+ }
~Regex();
/// isValid - returns the error encountered during regex compilation, or
@@ -81,6 +93,9 @@ namespace llvm {
/// expression that matches Str and only Str.
static bool isLiteralERE(StringRef Str);
+ /// \brief Turn String into a regex by escaping its special characters.
+ static std::string escape(StringRef String);
+
private:
struct llvm_regex *preg;
int error;
diff --git a/include/llvm/Support/StreamableMemoryObject.h b/include/llvm/Support/StreamableMemoryObject.h
index e823d48..0259630 100644
--- a/include/llvm/Support/StreamableMemoryObject.h
+++ b/include/llvm/Support/StreamableMemoryObject.h
@@ -11,10 +11,11 @@
#ifndef LLVM_SUPPORT_STREAMABLEMEMORYOBJECT_H
#define LLVM_SUPPORT_STREAMABLEMEMORYOBJECT_H
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataStream.h"
#include "llvm/Support/MemoryObject.h"
+#include <cassert>
+#include <memory>
#include <vector>
namespace llvm {
@@ -38,7 +39,7 @@ class StreamableMemoryObject : public MemoryObject {
/// getBase - Returns the lowest valid address in the region.
///
/// @result - The lowest valid address.
- virtual uint64_t getBase() const LLVM_OVERRIDE = 0;
+ uint64_t getBase() const override = 0;
/// getExtent - Returns the size of the region in bytes. (The region is
/// contiguous, so the highest valid address of the region
@@ -46,7 +47,7 @@ class StreamableMemoryObject : public MemoryObject {
/// May block until all bytes in the stream have been read
///
/// @result - The size of the region.
- virtual uint64_t getExtent() const LLVM_OVERRIDE = 0;
+ uint64_t getExtent() const override = 0;
/// readByte - Tries to read a single byte from the region.
/// May block until (address - base) bytes have been read
@@ -54,7 +55,7 @@ class StreamableMemoryObject : public MemoryObject {
/// @param ptr - A pointer to a byte to be filled in. Must be non-NULL.
/// @result - 0 if successful; -1 if not. Failure may be due to a
/// bounds violation or an implementation-specific error.
- virtual int readByte(uint64_t address, uint8_t *ptr) const LLVM_OVERRIDE = 0;
+ int readByte(uint64_t address, uint8_t *ptr) const override = 0;
/// readBytes - Tries to read a contiguous range of bytes from the
/// region, up to the end of the region.
@@ -70,9 +71,8 @@ class StreamableMemoryObject : public MemoryObject {
/// and large enough to hold size bytes.
/// @result - 0 if successful; -1 if not. Failure may be due to a
/// bounds violation or an implementation-specific error.
- virtual int readBytes(uint64_t address,
- uint64_t size,
- uint8_t *buf) const LLVM_OVERRIDE = 0;
+ int readBytes(uint64_t address, uint64_t size,
+ uint8_t *buf) const override = 0;
/// getPointer - Ensures that the requested data is in memory, and returns
/// A pointer to it. More efficient than using readBytes if the
@@ -105,14 +105,12 @@ class StreamableMemoryObject : public MemoryObject {
class StreamingMemoryObject : public StreamableMemoryObject {
public:
StreamingMemoryObject(DataStreamer *streamer);
- virtual uint64_t getBase() const LLVM_OVERRIDE { return 0; }
- virtual uint64_t getExtent() const LLVM_OVERRIDE;
- virtual int readByte(uint64_t address, uint8_t *ptr) const LLVM_OVERRIDE;
- virtual int readBytes(uint64_t address,
- uint64_t size,
- uint8_t *buf) const LLVM_OVERRIDE;
- virtual const uint8_t *getPointer(uint64_t address,
- uint64_t size) const LLVM_OVERRIDE {
+ uint64_t getBase() const override { return 0; }
+ uint64_t getExtent() const override;
+ int readByte(uint64_t address, uint8_t *ptr) const override;
+ int readBytes(uint64_t address, uint64_t size,
+ uint8_t *buf) const override;
+ const uint8_t *getPointer(uint64_t address, uint64_t size) const override {
// This could be fixed by ensuring the bytes are fetched and making a copy,
// requiring that the bitcode size be known, or otherwise ensuring that
// the memory doesn't go away/get reallocated, but it's
@@ -120,8 +118,8 @@ public:
assert(0 && "getPointer in streaming memory objects not allowed");
return NULL;
}
- virtual bool isValidAddress(uint64_t address) const LLVM_OVERRIDE;
- virtual bool isObjectEnd(uint64_t address) const LLVM_OVERRIDE;
+ bool isValidAddress(uint64_t address) const override;
+ bool isObjectEnd(uint64_t address) const override;
/// Drop s bytes from the front of the stream, pushing the positions of the
/// remaining bytes down by s. This is used to skip past the bitcode header,
@@ -137,7 +135,7 @@ public:
private:
const static uint32_t kChunkSize = 4096 * 4;
mutable std::vector<unsigned char> Bytes;
- OwningPtr<DataStreamer> Streamer;
+ std::unique_ptr<DataStreamer> Streamer;
mutable size_t BytesRead; // Bytes read from stream
size_t BytesSkipped;// Bytes skipped at start of stream (e.g. wrapper/header)
mutable size_t ObjectSize; // 0 if unknown, set if wrapper seen or EOF reached
diff --git a/include/llvm/Support/StringRefMemoryObject.h b/include/llvm/Support/StringRefMemoryObject.h
index 994fa34..8a349ea 100644
--- a/include/llvm/Support/StringRefMemoryObject.h
+++ b/include/llvm/Support/StringRefMemoryObject.h
@@ -29,11 +29,11 @@ public:
StringRefMemoryObject(StringRef Bytes, uint64_t Base = 0)
: Bytes(Bytes), Base(Base) {}
- uint64_t getBase() const LLVM_OVERRIDE { return Base; }
- uint64_t getExtent() const LLVM_OVERRIDE { return Bytes.size(); }
+ uint64_t getBase() const override { return Base; }
+ uint64_t getExtent() const override { return Bytes.size(); }
- int readByte(uint64_t Addr, uint8_t *Byte) const LLVM_OVERRIDE;
- int readBytes(uint64_t Addr, uint64_t Size, uint8_t *Buf) const LLVM_OVERRIDE;
+ int readByte(uint64_t Addr, uint8_t *Byte) const override;
+ int readBytes(uint64_t Addr, uint64_t Size, uint8_t *Buf) const override;
};
}
diff --git a/include/llvm/Support/TargetFolder.h b/include/llvm/Support/TargetFolder.h
deleted file mode 100644
index 5c1978d..0000000
--- a/include/llvm/Support/TargetFolder.h
+++ /dev/null
@@ -1,262 +0,0 @@
-//====-- llvm/Support/TargetFolder.h - Constant folding helper -*- C++ -*-====//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the TargetFolder class, a helper for IRBuilder.
-// It provides IRBuilder with a set of methods for creating constants with
-// target dependent folding, in addition to the same target-independent
-// folding that the ConstantFolder class provides. For general constant
-// creation and folding, use ConstantExpr and the routines in
-// llvm/Analysis/ConstantFolding.h.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SUPPORT_TARGETFOLDER_H
-#define LLVM_SUPPORT_TARGETFOLDER_H
-
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/Analysis/ConstantFolding.h"
-#include "llvm/IR/Constants.h"
-#include "llvm/IR/InstrTypes.h"
-
-namespace llvm {
-
-class DataLayout;
-
-/// TargetFolder - Create constants with target dependent folding.
-class TargetFolder {
- const DataLayout *TD;
-
- /// Fold - Fold the constant using target specific information.
- Constant *Fold(Constant *C) const {
- if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C))
- if (Constant *CF = ConstantFoldConstantExpression(CE, TD))
- return CF;
- return C;
- }
-
-public:
- explicit TargetFolder(const DataLayout *TheTD) : TD(TheTD) {}
-
- //===--------------------------------------------------------------------===//
- // Binary Operators
- //===--------------------------------------------------------------------===//
-
- Constant *CreateAdd(Constant *LHS, Constant *RHS,
- bool HasNUW = false, bool HasNSW = false) const {
- return Fold(ConstantExpr::getAdd(LHS, RHS, HasNUW, HasNSW));
- }
- Constant *CreateFAdd(Constant *LHS, Constant *RHS) const {
- return Fold(ConstantExpr::getFAdd(LHS, RHS));
- }
- Constant *CreateSub(Constant *LHS, Constant *RHS,
- bool HasNUW = false, bool HasNSW = false) const {
- return Fold(ConstantExpr::getSub(LHS, RHS, HasNUW, HasNSW));
- }
- Constant *CreateFSub(Constant *LHS, Constant *RHS) const {
- return Fold(ConstantExpr::getFSub(LHS, RHS));
- }
- Constant *CreateMul(Constant *LHS, Constant *RHS,
- bool HasNUW = false, bool HasNSW = false) const {
- return Fold(ConstantExpr::getMul(LHS, RHS, HasNUW, HasNSW));
- }
- Constant *CreateFMul(Constant *LHS, Constant *RHS) const {
- return Fold(ConstantExpr::getFMul(LHS, RHS));
- }
- Constant *CreateUDiv(Constant *LHS, Constant *RHS, bool isExact = false)const{
- return Fold(ConstantExpr::getUDiv(LHS, RHS, isExact));
- }
- Constant *CreateSDiv(Constant *LHS, Constant *RHS, bool isExact = false)const{
- return Fold(ConstantExpr::getSDiv(LHS, RHS, isExact));
- }
- Constant *CreateFDiv(Constant *LHS, Constant *RHS) const {
- return Fold(ConstantExpr::getFDiv(LHS, RHS));
- }
- Constant *CreateURem(Constant *LHS, Constant *RHS) const {
- return Fold(ConstantExpr::getURem(LHS, RHS));
- }
- Constant *CreateSRem(Constant *LHS, Constant *RHS) const {
- return Fold(ConstantExpr::getSRem(LHS, RHS));
- }
- Constant *CreateFRem(Constant *LHS, Constant *RHS) const {
- return Fold(ConstantExpr::getFRem(LHS, RHS));
- }
- Constant *CreateShl(Constant *LHS, Constant *RHS,
- bool HasNUW = false, bool HasNSW = false) const {
- return Fold(ConstantExpr::getShl(LHS, RHS, HasNUW, HasNSW));
- }
- Constant *CreateLShr(Constant *LHS, Constant *RHS, bool isExact = false)const{
- return Fold(ConstantExpr::getLShr(LHS, RHS, isExact));
- }
- Constant *CreateAShr(Constant *LHS, Constant *RHS, bool isExact = false)const{
- return Fold(ConstantExpr::getAShr(LHS, RHS, isExact));
- }
- Constant *CreateAnd(Constant *LHS, Constant *RHS) const {
- return Fold(ConstantExpr::getAnd(LHS, RHS));
- }
- Constant *CreateOr(Constant *LHS, Constant *RHS) const {
- return Fold(ConstantExpr::getOr(LHS, RHS));
- }
- Constant *CreateXor(Constant *LHS, Constant *RHS) const {
- return Fold(ConstantExpr::getXor(LHS, RHS));
- }
-
- Constant *CreateBinOp(Instruction::BinaryOps Opc,
- Constant *LHS, Constant *RHS) const {
- return Fold(ConstantExpr::get(Opc, LHS, RHS));
- }
-
- //===--------------------------------------------------------------------===//
- // Unary Operators
- //===--------------------------------------------------------------------===//
-
- Constant *CreateNeg(Constant *C,
- bool HasNUW = false, bool HasNSW = false) const {
- return Fold(ConstantExpr::getNeg(C, HasNUW, HasNSW));
- }
- Constant *CreateFNeg(Constant *C) const {
- return Fold(ConstantExpr::getFNeg(C));
- }
- Constant *CreateNot(Constant *C) const {
- return Fold(ConstantExpr::getNot(C));
- }
-
- //===--------------------------------------------------------------------===//
- // Memory Instructions
- //===--------------------------------------------------------------------===//
-
- Constant *CreateGetElementPtr(Constant *C,
- ArrayRef<Constant *> IdxList) const {
- return Fold(ConstantExpr::getGetElementPtr(C, IdxList));
- }
- Constant *CreateGetElementPtr(Constant *C, Constant *Idx) const {
- // This form of the function only exists to avoid ambiguous overload
- // warnings about whether to convert Idx to ArrayRef<Constant *> or
- // ArrayRef<Value *>.
- return Fold(ConstantExpr::getGetElementPtr(C, Idx));
- }
- Constant *CreateGetElementPtr(Constant *C,
- ArrayRef<Value *> IdxList) const {
- return Fold(ConstantExpr::getGetElementPtr(C, IdxList));
- }
-
- Constant *CreateInBoundsGetElementPtr(Constant *C,
- ArrayRef<Constant *> IdxList) const {
- return Fold(ConstantExpr::getInBoundsGetElementPtr(C, IdxList));
- }
- Constant *CreateInBoundsGetElementPtr(Constant *C, Constant *Idx) const {
- // This form of the function only exists to avoid ambiguous overload
- // warnings about whether to convert Idx to ArrayRef<Constant *> or
- // ArrayRef<Value *>.
- return Fold(ConstantExpr::getInBoundsGetElementPtr(C, Idx));
- }
- Constant *CreateInBoundsGetElementPtr(Constant *C,
- ArrayRef<Value *> IdxList) const {
- return Fold(ConstantExpr::getInBoundsGetElementPtr(C, IdxList));
- }
-
- //===--------------------------------------------------------------------===//
- // Cast/Conversion Operators
- //===--------------------------------------------------------------------===//
-
- Constant *CreateCast(Instruction::CastOps Op, Constant *C,
- Type *DestTy) const {
- if (C->getType() == DestTy)
- return C; // avoid calling Fold
- return Fold(ConstantExpr::getCast(Op, C, DestTy));
- }
- Constant *CreateIntCast(Constant *C, Type *DestTy,
- bool isSigned) const {
- if (C->getType() == DestTy)
- return C; // avoid calling Fold
- return Fold(ConstantExpr::getIntegerCast(C, DestTy, isSigned));
- }
- Constant *CreatePointerCast(Constant *C, Type *DestTy) const {
- if (C->getType() == DestTy)
- return C; // avoid calling Fold
- return Fold(ConstantExpr::getPointerCast(C, DestTy));
- }
- Constant *CreateFPCast(Constant *C, Type *DestTy) const {
- if (C->getType() == DestTy)
- return C; // avoid calling Fold
- return Fold(ConstantExpr::getFPCast(C, DestTy));
- }
- Constant *CreateBitCast(Constant *C, Type *DestTy) const {
- return CreateCast(Instruction::BitCast, C, DestTy);
- }
- Constant *CreateIntToPtr(Constant *C, Type *DestTy) const {
- return CreateCast(Instruction::IntToPtr, C, DestTy);
- }
- Constant *CreatePtrToInt(Constant *C, Type *DestTy) const {
- return CreateCast(Instruction::PtrToInt, C, DestTy);
- }
- Constant *CreateZExtOrBitCast(Constant *C, Type *DestTy) const {
- if (C->getType() == DestTy)
- return C; // avoid calling Fold
- return Fold(ConstantExpr::getZExtOrBitCast(C, DestTy));
- }
- Constant *CreateSExtOrBitCast(Constant *C, Type *DestTy) const {
- if (C->getType() == DestTy)
- return C; // avoid calling Fold
- return Fold(ConstantExpr::getSExtOrBitCast(C, DestTy));
- }
- Constant *CreateTruncOrBitCast(Constant *C, Type *DestTy) const {
- if (C->getType() == DestTy)
- return C; // avoid calling Fold
- return Fold(ConstantExpr::getTruncOrBitCast(C, DestTy));
- }
-
- //===--------------------------------------------------------------------===//
- // Compare Instructions
- //===--------------------------------------------------------------------===//
-
- Constant *CreateICmp(CmpInst::Predicate P, Constant *LHS,
- Constant *RHS) const {
- return Fold(ConstantExpr::getCompare(P, LHS, RHS));
- }
- Constant *CreateFCmp(CmpInst::Predicate P, Constant *LHS,
- Constant *RHS) const {
- return Fold(ConstantExpr::getCompare(P, LHS, RHS));
- }
-
- //===--------------------------------------------------------------------===//
- // Other Instructions
- //===--------------------------------------------------------------------===//
-
- Constant *CreateSelect(Constant *C, Constant *True, Constant *False) const {
- return Fold(ConstantExpr::getSelect(C, True, False));
- }
-
- Constant *CreateExtractElement(Constant *Vec, Constant *Idx) const {
- return Fold(ConstantExpr::getExtractElement(Vec, Idx));
- }
-
- Constant *CreateInsertElement(Constant *Vec, Constant *NewElt,
- Constant *Idx) const {
- return Fold(ConstantExpr::getInsertElement(Vec, NewElt, Idx));
- }
-
- Constant *CreateShuffleVector(Constant *V1, Constant *V2,
- Constant *Mask) const {
- return Fold(ConstantExpr::getShuffleVector(V1, V2, Mask));
- }
-
- Constant *CreateExtractValue(Constant *Agg,
- ArrayRef<unsigned> IdxList) const {
- return Fold(ConstantExpr::getExtractValue(Agg, IdxList));
- }
-
- Constant *CreateInsertValue(Constant *Agg, Constant *Val,
- ArrayRef<unsigned> IdxList) const {
- return Fold(ConstantExpr::getInsertValue(Agg, Val, IdxList));
- }
-};
-
-}
-
-#endif
diff --git a/include/llvm/Support/TargetRegistry.h b/include/llvm/Support/TargetRegistry.h
index 9ecee3b..8e7478c 100644
--- a/include/llvm/Support/TargetRegistry.h
+++ b/include/llvm/Support/TargetRegistry.h
@@ -19,9 +19,9 @@
#ifndef LLVM_SUPPORT_TARGETREGISTRY_H
#define LLVM_SUPPORT_TARGETREGISTRY_H
+#include "llvm-c/Disassembler.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Support/CodeGen.h"
-#include "llvm-c/Disassembler.h"
#include <cassert>
#include <string>
@@ -46,15 +46,12 @@ namespace llvm {
class MCRelocationInfo;
class MCTargetAsmParser;
class TargetMachine;
- class MCTargetStreamer;
class TargetOptions;
class raw_ostream;
class formatted_raw_ostream;
- MCStreamer *createAsmStreamer(MCContext &Ctx,
- MCTargetStreamer *TargetStreamer,
- formatted_raw_ostream &OS, bool isVerboseAsm,
- bool useLoc, bool useCFI,
+ MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
+ bool isVerboseAsm, bool useCFI,
bool useDwarfDirectory,
MCInstPrinter *InstPrint, MCCodeEmitter *CE,
MCAsmBackend *TAB, bool ShowInst);
@@ -79,7 +76,7 @@ namespace llvm {
public:
friend struct TargetRegistry;
- typedef unsigned (*TripleMatchQualityFnTy)(const std::string &TT);
+ typedef bool (*ArchMatchFnTy)(Triple::ArchType Arch);
typedef MCAsmInfo *(*MCAsmInfoCtorFnTy)(const MCRegisterInfo &MRI,
StringRef TT);
@@ -128,12 +125,12 @@ namespace llvm {
MCAsmBackend &TAB,
raw_ostream &_OS,
MCCodeEmitter *_Emitter,
+ const MCSubtargetInfo &STI,
bool RelaxAll,
bool NoExecStack);
typedef MCStreamer *(*AsmStreamerCtorTy)(MCContext &Ctx,
formatted_raw_ostream &OS,
bool isVerboseAsm,
- bool useLoc,
bool useCFI,
bool useDwarfDirectory,
MCInstPrinter *InstPrint,
@@ -154,9 +151,8 @@ namespace llvm {
/// TargetRegistry.
Target *Next;
- /// TripleMatchQualityFn - The target function for rating the match quality
- /// of a triple.
- TripleMatchQualityFnTy TripleMatchQualityFn;
+ /// The target function for checking if an architecture is supported.
+ ArchMatchFnTy ArchMatchFn;
/// Name - The target name.
const char *Name;
@@ -421,11 +417,12 @@ namespace llvm {
MCAsmBackend &TAB,
raw_ostream &_OS,
MCCodeEmitter *_Emitter,
+ const MCSubtargetInfo &STI,
bool RelaxAll,
bool NoExecStack) const {
if (!MCObjectStreamerCtorFn)
return 0;
- return MCObjectStreamerCtorFn(*this, TT, Ctx, TAB, _OS, _Emitter,
+ return MCObjectStreamerCtorFn(*this, TT, Ctx, TAB, _OS, _Emitter, STI,
RelaxAll, NoExecStack);
}
@@ -433,7 +430,6 @@ namespace llvm {
MCStreamer *createAsmStreamer(MCContext &Ctx,
formatted_raw_ostream &OS,
bool isVerboseAsm,
- bool useLoc,
bool useCFI,
bool useDwarfDirectory,
MCInstPrinter *InstPrint,
@@ -441,10 +437,10 @@ namespace llvm {
MCAsmBackend *TAB,
bool ShowInst) const {
if (AsmStreamerCtorFn)
- return AsmStreamerCtorFn(Ctx, OS, isVerboseAsm, useLoc, useCFI,
+ return AsmStreamerCtorFn(Ctx, OS, isVerboseAsm, useCFI,
useDwarfDirectory, InstPrint, CE, TAB,
ShowInst);
- return llvm::createAsmStreamer(Ctx, 0, OS, isVerboseAsm, useLoc, useCFI,
+ return llvm::createAsmStreamer(Ctx, OS, isVerboseAsm, useCFI,
useDwarfDirectory, InstPrint, CE, TAB,
ShowInst);
}
@@ -490,7 +486,6 @@ namespace llvm {
explicit iterator(Target *T) : Current(T) {}
friend struct TargetRegistry;
public:
- iterator(const iterator &I) : Current(I.Current) {}
iterator() : Current(0) {}
bool operator==(const iterator &x) const {
@@ -578,14 +573,13 @@ namespace llvm {
/// @param Name - The target name. This should be a static string.
/// @param ShortDesc - A short target description. This should be a static
/// string.
- /// @param TQualityFn - The triple match quality computation function for
- /// this target.
+ /// @param ArchMatchFn - The arch match checking function for this target.
/// @param HasJIT - Whether the target supports JIT code
/// generation.
static void RegisterTarget(Target &T,
const char *Name,
const char *ShortDesc,
- Target::TripleMatchQualityFnTy TQualityFn,
+ Target::ArchMatchFnTy ArchMatchFn,
bool HasJIT = false);
/// RegisterMCAsmInfo - Register a MCAsmInfo implementation for the
@@ -831,15 +825,11 @@ namespace llvm {
bool HasJIT = false>
struct RegisterTarget {
RegisterTarget(Target &T, const char *Name, const char *Desc) {
- TargetRegistry::RegisterTarget(T, Name, Desc,
- &getTripleMatchQuality,
- HasJIT);
+ TargetRegistry::RegisterTarget(T, Name, Desc, &getArchMatch, HasJIT);
}
- static unsigned getTripleMatchQuality(const std::string &TT) {
- if (Triple(TT).getArch() == TargetArchType)
- return 20;
- return 0;
+ static bool getArchMatch(Triple::ArchType Arch) {
+ return Arch == TargetArchType;
}
};
diff --git a/include/llvm/Support/TimeValue.h b/include/llvm/Support/TimeValue.h
index 2785408..ee0e286 100644
--- a/include/llvm/Support/TimeValue.h
+++ b/include/llvm/Support/TimeValue.h
@@ -74,8 +74,7 @@ namespace sys {
MILLISECONDS_PER_SECOND = 1000, ///< One Thousand
NANOSECONDS_PER_MICROSECOND = 1000, ///< One Thousand
NANOSECONDS_PER_MILLISECOND = 1000000,///< One Million
- NANOSECONDS_PER_POSIX_TICK = 100, ///< Posix tick is 100 Hz (10ms)
- NANOSECONDS_PER_WIN32_TICK = 100 ///< Win32 tick is 100 Hz (10ms)
+ NANOSECONDS_PER_WIN32_TICK = 100 ///< Win32 tick is 10^7 Hz (10ns)
};
/// @}
@@ -236,15 +235,6 @@ namespace sys {
( nanos_ / NANOSECONDS_PER_MILLISECOND );
}
- /// Converts the TimeValue into the corresponding number of "ticks" for
- /// Posix, correcting for the difference in Posix zero time.
- /// @brief Convert to unix time (100 nanoseconds since 12:00:00a Jan 1,1970)
- uint64_t toPosixTime() const {
- uint64_t result = seconds_ - PosixZeroTimeSeconds;
- result += nanos_ / NANOSECONDS_PER_POSIX_TICK;
- return result;
- }
-
/// Converts the TimeValue into the corresponding number of seconds
/// since the epoch (00:00:00 Jan 1,1970).
uint64_t toEpochTime() const {
diff --git a/include/llvm/Support/ToolOutputFile.h b/include/llvm/Support/ToolOutputFile.h
index a2191ad..88f8ccc 100644
--- a/include/llvm/Support/ToolOutputFile.h
+++ b/include/llvm/Support/ToolOutputFile.h
@@ -47,7 +47,7 @@ public:
/// tool_output_file - This constructor's arguments are passed to
/// to raw_fd_ostream's constructor.
tool_output_file(const char *filename, std::string &ErrorInfo,
- sys::fs::OpenFlags Flags = sys::fs::F_None);
+ sys::fs::OpenFlags Flags);
tool_output_file(const char *Filename, int FD);
diff --git a/include/llvm/Support/UnicodeCharRanges.h b/include/llvm/Support/UnicodeCharRanges.h
index 86faa38..734d323 100644
--- a/include/llvm/Support/UnicodeCharRanges.h
+++ b/include/llvm/Support/UnicodeCharRanges.h
@@ -16,7 +16,6 @@
#include "llvm/Support/Mutex.h"
#include "llvm/Support/MutexGuard.h"
#include "llvm/Support/raw_ostream.h"
-
#include <algorithm>
namespace llvm {
@@ -40,7 +39,7 @@ inline bool operator<(UnicodeCharRange Range, uint32_t Value) {
/// array.
class UnicodeCharSet {
public:
- typedef llvm::ArrayRef<UnicodeCharRange> CharRanges;
+ typedef ArrayRef<UnicodeCharRange> CharRanges;
/// \brief Constructs a UnicodeCharSet instance from an array of
/// UnicodeCharRanges.
@@ -67,17 +66,17 @@ private:
for (CharRanges::const_iterator I = Ranges.begin(), E = Ranges.end();
I != E; ++I) {
if (I != Ranges.begin() && Prev >= I->Lower) {
- DEBUG(llvm::dbgs() << "Upper bound 0x");
- DEBUG(llvm::dbgs().write_hex(Prev));
- DEBUG(llvm::dbgs() << " should be less than succeeding lower bound 0x");
- DEBUG(llvm::dbgs().write_hex(I->Lower) << "\n");
+ DEBUG(dbgs() << "Upper bound 0x");
+ DEBUG(dbgs().write_hex(Prev));
+ DEBUG(dbgs() << " should be less than succeeding lower bound 0x");
+ DEBUG(dbgs().write_hex(I->Lower) << "\n");
return false;
}
if (I->Upper < I->Lower) {
- DEBUG(llvm::dbgs() << "Upper bound 0x");
- DEBUG(llvm::dbgs().write_hex(I->Lower));
- DEBUG(llvm::dbgs() << " should not be less than lower bound 0x");
- DEBUG(llvm::dbgs().write_hex(I->Upper) << "\n");
+ DEBUG(dbgs() << "Upper bound 0x");
+ DEBUG(dbgs().write_hex(I->Lower));
+ DEBUG(dbgs() << " should not be less than lower bound 0x");
+ DEBUG(dbgs().write_hex(I->Upper) << "\n");
return false;
}
Prev = I->Upper;
diff --git a/include/llvm/Support/Valgrind.h b/include/llvm/Support/Valgrind.h
index 7ae40af..cebf75c 100644
--- a/include/llvm/Support/Valgrind.h
+++ b/include/llvm/Support/Valgrind.h
@@ -24,12 +24,10 @@
// tsan (Thread Sanitizer) is a valgrind-based tool that detects these exact
// functions by name.
extern "C" {
-LLVM_ATTRIBUTE_WEAK void AnnotateHappensAfter(const char *file, int line,
- const volatile void *cv);
-LLVM_ATTRIBUTE_WEAK void AnnotateHappensBefore(const char *file, int line,
- const volatile void *cv);
-LLVM_ATTRIBUTE_WEAK void AnnotateIgnoreWritesBegin(const char *file, int line);
-LLVM_ATTRIBUTE_WEAK void AnnotateIgnoreWritesEnd(const char *file, int line);
+void AnnotateHappensAfter(const char *file, int line, const volatile void *cv);
+void AnnotateHappensBefore(const char *file, int line, const volatile void *cv);
+void AnnotateIgnoreWritesBegin(const char *file, int line);
+void AnnotateIgnoreWritesEnd(const char *file, int line);
}
#endif
diff --git a/include/llvm/Support/ValueHandle.h b/include/llvm/Support/ValueHandle.h
deleted file mode 100644
index bc02ba3..0000000
--- a/include/llvm/Support/ValueHandle.h
+++ /dev/null
@@ -1,380 +0,0 @@
-//===- llvm/Support/ValueHandle.h - Value Smart Pointer classes -*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file declares the ValueHandle class and its sub-classes.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SUPPORT_VALUEHANDLE_H
-#define LLVM_SUPPORT_VALUEHANDLE_H
-
-#include "llvm/ADT/DenseMapInfo.h"
-#include "llvm/ADT/PointerIntPair.h"
-#include "llvm/IR/Value.h"
-
-namespace llvm {
-class ValueHandleBase;
-template<typename From> struct simplify_type;
-
-// ValueHandleBase** is only 4-byte aligned.
-template<>
-class PointerLikeTypeTraits<ValueHandleBase**> {
-public:
- static inline void *getAsVoidPointer(ValueHandleBase** P) { return P; }
- static inline ValueHandleBase **getFromVoidPointer(void *P) {
- return static_cast<ValueHandleBase**>(P);
- }
- enum { NumLowBitsAvailable = 2 };
-};
-
-/// ValueHandleBase - This is the common base class of value handles.
-/// ValueHandle's are smart pointers to Value's that have special behavior when
-/// the value is deleted or ReplaceAllUsesWith'd. See the specific handles
-/// below for details.
-///
-class ValueHandleBase {
- friend class Value;
-protected:
- /// HandleBaseKind - This indicates what sub class the handle actually is.
- /// This is to avoid having a vtable for the light-weight handle pointers. The
- /// fully general Callback version does have a vtable.
- enum HandleBaseKind {
- Assert,
- Callback,
- Tracking,
- Weak
- };
-
-private:
- PointerIntPair<ValueHandleBase**, 2, HandleBaseKind> PrevPair;
- ValueHandleBase *Next;
-
- // A subclass may want to store some information along with the value
- // pointer. Allow them to do this by making the value pointer a pointer-int
- // pair. The 'setValPtrInt' and 'getValPtrInt' methods below give them this
- // access.
- PointerIntPair<Value*, 2> VP;
-
- ValueHandleBase(const ValueHandleBase&) LLVM_DELETED_FUNCTION;
-public:
- explicit ValueHandleBase(HandleBaseKind Kind)
- : PrevPair(0, Kind), Next(0), VP(0, 0) {}
- ValueHandleBase(HandleBaseKind Kind, Value *V)
- : PrevPair(0, Kind), Next(0), VP(V, 0) {
- if (isValid(VP.getPointer()))
- AddToUseList();
- }
- ValueHandleBase(HandleBaseKind Kind, const ValueHandleBase &RHS)
- : PrevPair(0, Kind), Next(0), VP(RHS.VP) {
- if (isValid(VP.getPointer()))
- AddToExistingUseList(RHS.getPrevPtr());
- }
- ~ValueHandleBase() {
- if (isValid(VP.getPointer()))
- RemoveFromUseList();
- }
-
- Value *operator=(Value *RHS) {
- if (VP.getPointer() == RHS) return RHS;
- if (isValid(VP.getPointer())) RemoveFromUseList();
- VP.setPointer(RHS);
- if (isValid(VP.getPointer())) AddToUseList();
- return RHS;
- }
-
- Value *operator=(const ValueHandleBase &RHS) {
- if (VP.getPointer() == RHS.VP.getPointer()) return RHS.VP.getPointer();
- if (isValid(VP.getPointer())) RemoveFromUseList();
- VP.setPointer(RHS.VP.getPointer());
- if (isValid(VP.getPointer())) AddToExistingUseList(RHS.getPrevPtr());
- return VP.getPointer();
- }
-
- Value *operator->() const { return getValPtr(); }
- Value &operator*() const { return *getValPtr(); }
-
-protected:
- Value *getValPtr() const { return VP.getPointer(); }
-
- void setValPtrInt(unsigned K) { VP.setInt(K); }
- unsigned getValPtrInt() const { return VP.getInt(); }
-
- static bool isValid(Value *V) {
- return V &&
- V != DenseMapInfo<Value *>::getEmptyKey() &&
- V != DenseMapInfo<Value *>::getTombstoneKey();
- }
-
-public:
- // Callbacks made from Value.
- static void ValueIsDeleted(Value *V);
- static void ValueIsRAUWd(Value *Old, Value *New);
-
-private:
- // Internal implementation details.
- ValueHandleBase **getPrevPtr() const { return PrevPair.getPointer(); }
- HandleBaseKind getKind() const { return PrevPair.getInt(); }
- void setPrevPtr(ValueHandleBase **Ptr) { PrevPair.setPointer(Ptr); }
-
- /// AddToExistingUseList - Add this ValueHandle to the use list for VP, where
- /// List is the address of either the head of the list or a Next node within
- /// the existing use list.
- void AddToExistingUseList(ValueHandleBase **List);
-
- /// AddToExistingUseListAfter - Add this ValueHandle to the use list after
- /// Node.
- void AddToExistingUseListAfter(ValueHandleBase *Node);
-
- /// AddToUseList - Add this ValueHandle to the use list for VP.
- void AddToUseList();
- /// RemoveFromUseList - Remove this ValueHandle from its current use list.
- void RemoveFromUseList();
-};
-
-/// WeakVH - This is a value handle that tries hard to point to a Value, even
-/// across RAUW operations, but will null itself out if the value is destroyed.
-/// this is useful for advisory sorts of information, but should not be used as
-/// the key of a map (since the map would have to rearrange itself when the
-/// pointer changes).
-class WeakVH : public ValueHandleBase {
-public:
- WeakVH() : ValueHandleBase(Weak) {}
- WeakVH(Value *P) : ValueHandleBase(Weak, P) {}
- WeakVH(const WeakVH &RHS)
- : ValueHandleBase(Weak, RHS) {}
-
- Value *operator=(Value *RHS) {
- return ValueHandleBase::operator=(RHS);
- }
- Value *operator=(const ValueHandleBase &RHS) {
- return ValueHandleBase::operator=(RHS);
- }
-
- operator Value*() const {
- return getValPtr();
- }
-};
-
-// Specialize simplify_type to allow WeakVH to participate in
-// dyn_cast, isa, etc.
-template<> struct simplify_type<WeakVH> {
- typedef Value* SimpleType;
- static SimpleType getSimplifiedValue(WeakVH &WVH) {
- return WVH;
- }
-};
-
-/// AssertingVH - This is a Value Handle that points to a value and asserts out
-/// if the value is destroyed while the handle is still live. This is very
-/// useful for catching dangling pointer bugs and other things which can be
-/// non-obvious. One particularly useful place to use this is as the Key of a
-/// map. Dangling pointer bugs often lead to really subtle bugs that only occur
-/// if another object happens to get allocated to the same address as the old
-/// one. Using an AssertingVH ensures that an assert is triggered as soon as
-/// the bad delete occurs.
-///
-/// Note that an AssertingVH handle does *not* follow values across RAUW
-/// operations. This means that RAUW's need to explicitly update the
-/// AssertingVH's as it moves. This is required because in non-assert mode this
-/// class turns into a trivial wrapper around a pointer.
-template <typename ValueTy>
-class AssertingVH
-#ifndef NDEBUG
- : public ValueHandleBase
-#endif
- {
-
-#ifndef NDEBUG
- ValueTy *getValPtr() const {
- return static_cast<ValueTy*>(ValueHandleBase::getValPtr());
- }
- void setValPtr(ValueTy *P) {
- ValueHandleBase::operator=(GetAsValue(P));
- }
-#else
- ValueTy *ThePtr;
- ValueTy *getValPtr() const { return ThePtr; }
- void setValPtr(ValueTy *P) { ThePtr = P; }
-#endif
-
- // Convert a ValueTy*, which may be const, to the type the base
- // class expects.
- static Value *GetAsValue(Value *V) { return V; }
- static Value *GetAsValue(const Value *V) { return const_cast<Value*>(V); }
-
-public:
-#ifndef NDEBUG
- AssertingVH() : ValueHandleBase(Assert) {}
- AssertingVH(ValueTy *P) : ValueHandleBase(Assert, GetAsValue(P)) {}
- AssertingVH(const AssertingVH &RHS) : ValueHandleBase(Assert, RHS) {}
-#else
- AssertingVH() : ThePtr(0) {}
- AssertingVH(ValueTy *P) : ThePtr(P) {}
-#endif
-
- operator ValueTy*() const {
- return getValPtr();
- }
-
- ValueTy *operator=(ValueTy *RHS) {
- setValPtr(RHS);
- return getValPtr();
- }
- ValueTy *operator=(const AssertingVH<ValueTy> &RHS) {
- setValPtr(RHS.getValPtr());
- return getValPtr();
- }
-
- ValueTy *operator->() const { return getValPtr(); }
- ValueTy &operator*() const { return *getValPtr(); }
-};
-
-// Specialize DenseMapInfo to allow AssertingVH to participate in DenseMap.
-template<typename T>
-struct DenseMapInfo<AssertingVH<T> > {
- typedef DenseMapInfo<T*> PointerInfo;
- static inline AssertingVH<T> getEmptyKey() {
- return AssertingVH<T>(PointerInfo::getEmptyKey());
- }
- static inline T* getTombstoneKey() {
- return AssertingVH<T>(PointerInfo::getTombstoneKey());
- }
- static unsigned getHashValue(const AssertingVH<T> &Val) {
- return PointerInfo::getHashValue(Val);
- }
- static bool isEqual(const AssertingVH<T> &LHS, const AssertingVH<T> &RHS) {
- return LHS == RHS;
- }
-};
-
-template <typename T>
-struct isPodLike<AssertingVH<T> > {
-#ifdef NDEBUG
- static const bool value = true;
-#else
- static const bool value = false;
-#endif
-};
-
-
-/// TrackingVH - This is a value handle that tracks a Value (or Value subclass),
-/// even across RAUW operations.
-///
-/// TrackingVH is designed for situations where a client needs to hold a handle
-/// to a Value (or subclass) across some operations which may move that value,
-/// but should never destroy it or replace it with some unacceptable type.
-///
-/// It is an error to do anything with a TrackingVH whose value has been
-/// destroyed, except to destruct it.
-///
-/// It is an error to attempt to replace a value with one of a type which is
-/// incompatible with any of its outstanding TrackingVHs.
-template<typename ValueTy>
-class TrackingVH : public ValueHandleBase {
- void CheckValidity() const {
- Value *VP = ValueHandleBase::getValPtr();
-
- // Null is always ok.
- if (!VP) return;
-
- // Check that this value is valid (i.e., it hasn't been deleted). We
- // explicitly delay this check until access to avoid requiring clients to be
- // unnecessarily careful w.r.t. destruction.
- assert(ValueHandleBase::isValid(VP) && "Tracked Value was deleted!");
-
- // Check that the value is a member of the correct subclass. We would like
- // to check this property on assignment for better debugging, but we don't
- // want to require a virtual interface on this VH. Instead we allow RAUW to
- // replace this value with a value of an invalid type, and check it here.
- assert(isa<ValueTy>(VP) &&
- "Tracked Value was replaced by one with an invalid type!");
- }
-
- ValueTy *getValPtr() const {
- CheckValidity();
- return (ValueTy*)ValueHandleBase::getValPtr();
- }
- void setValPtr(ValueTy *P) {
- CheckValidity();
- ValueHandleBase::operator=(GetAsValue(P));
- }
-
- // Convert a ValueTy*, which may be const, to the type the base
- // class expects.
- static Value *GetAsValue(Value *V) { return V; }
- static Value *GetAsValue(const Value *V) { return const_cast<Value*>(V); }
-
-public:
- TrackingVH() : ValueHandleBase(Tracking) {}
- TrackingVH(ValueTy *P) : ValueHandleBase(Tracking, GetAsValue(P)) {}
- TrackingVH(const TrackingVH &RHS) : ValueHandleBase(Tracking, RHS) {}
-
- operator ValueTy*() const {
- return getValPtr();
- }
-
- ValueTy *operator=(ValueTy *RHS) {
- setValPtr(RHS);
- return getValPtr();
- }
- ValueTy *operator=(const TrackingVH<ValueTy> &RHS) {
- setValPtr(RHS.getValPtr());
- return getValPtr();
- }
-
- ValueTy *operator->() const { return getValPtr(); }
- ValueTy &operator*() const { return *getValPtr(); }
-};
-
-/// CallbackVH - This is a value handle that allows subclasses to define
-/// callbacks that run when the underlying Value has RAUW called on it or is
-/// destroyed. This class can be used as the key of a map, as long as the user
-/// takes it out of the map before calling setValPtr() (since the map has to
-/// rearrange itself when the pointer changes). Unlike ValueHandleBase, this
-/// class has a vtable and a virtual destructor.
-class CallbackVH : public ValueHandleBase {
- virtual void anchor();
-protected:
- CallbackVH(const CallbackVH &RHS)
- : ValueHandleBase(Callback, RHS) {}
-
- virtual ~CallbackVH() {}
-
- void setValPtr(Value *P) {
- ValueHandleBase::operator=(P);
- }
-
-public:
- CallbackVH() : ValueHandleBase(Callback) {}
- CallbackVH(Value *P) : ValueHandleBase(Callback, P) {}
-
- operator Value*() const {
- return getValPtr();
- }
-
- /// Called when this->getValPtr() is destroyed, inside ~Value(), so you may
- /// call any non-virtual Value method on getValPtr(), but no subclass methods.
- /// If WeakVH were implemented as a CallbackVH, it would use this method to
- /// call setValPtr(NULL). AssertingVH would use this method to cause an
- /// assertion failure.
- ///
- /// All implementations must remove the reference from this object to the
- /// Value that's being destroyed.
- virtual void deleted() { setValPtr(NULL); }
-
- /// Called when this->getValPtr()->replaceAllUsesWith(new_value) is called,
- /// _before_ any of the uses have actually been replaced. If WeakVH were
- /// implemented as a CallbackVH, it would use this method to call
- /// setValPtr(new_value). AssertingVH would do nothing in this method.
- virtual void allUsesReplacedWith(Value *) {}
-};
-
-} // End llvm namespace
-
-#endif
diff --git a/include/llvm/Support/Win64EH.h b/include/llvm/Support/Win64EH.h
index ecce713..7ca218e 100644
--- a/include/llvm/Support/Win64EH.h
+++ b/include/llvm/Support/Win64EH.h
@@ -108,17 +108,19 @@ struct UnwindInfo {
/// \brief Return pointer to language specific data part of UnwindInfo.
const void *getLanguageSpecificData() const {
- return reinterpret_cast<const void *>(&UnwindCodes[(NumCodes+1) & ~1]);
+ return reinterpret_cast<const void *>(&UnwindCodes[(NumCodes + 1) & ~1]);
}
/// \brief Return image-relative offset of language-specific exception handler.
uint32_t getLanguageSpecificHandlerOffset() const {
- return *reinterpret_cast<const uint32_t *>(getLanguageSpecificData());
+ return *reinterpret_cast<const support::ulittle32_t *>(
+ getLanguageSpecificData());
}
/// \brief Set image-relative offset of language-specific exception handler.
void setLanguageSpecificHandlerOffset(uint32_t offset) {
- *reinterpret_cast<uint32_t *>(getLanguageSpecificData()) = offset;
+ *reinterpret_cast<support::ulittle32_t *>(getLanguageSpecificData()) =
+ offset;
}
/// \brief Return pointer to exception-specific data.
diff --git a/include/llvm/Support/YAMLParser.h b/include/llvm/Support/YAMLParser.h
index 7020449..5194b52 100644
--- a/include/llvm/Support/YAMLParser.h
+++ b/include/llvm/Support/YAMLParser.h
@@ -38,14 +38,12 @@
#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 <map>
#include <limits>
+#include <map>
#include <utility>
namespace llvm {
@@ -97,8 +95,8 @@ public:
void printError(Node *N, const Twine &Msg);
private:
- OwningPtr<Scanner> scanner;
- OwningPtr<Document> CurrentDoc;
+ std::unique_ptr<Scanner> scanner;
+ std::unique_ptr<Document> CurrentDoc;
friend class Document;
};
@@ -116,7 +114,7 @@ public:
NK_Alias
};
- Node(unsigned int Type, OwningPtr<Document> &, StringRef Anchor,
+ Node(unsigned int Type, std::unique_ptr<Document> &, StringRef Anchor,
StringRef Tag);
/// @brief Get the value of the anchor attached to this node. If it does not
@@ -157,7 +155,7 @@ public:
}
protected:
- OwningPtr<Document> &Doc;
+ std::unique_ptr<Document> &Doc;
SMRange SourceRange;
void operator delete(void *) throw() {}
@@ -176,9 +174,9 @@ private:
/// Example:
/// !!null null
class NullNode : public Node {
- virtual void anchor();
+ void anchor() override;
public:
- NullNode(OwningPtr<Document> &D)
+ NullNode(std::unique_ptr<Document> &D)
: Node(NK_Null, D, StringRef(), StringRef()) {}
static inline bool classof(const Node *N) {
@@ -192,9 +190,9 @@ public:
/// Example:
/// Adena
class ScalarNode : public Node {
- virtual void anchor();
+ void anchor() override;
public:
- ScalarNode(OwningPtr<Document> &D, StringRef Anchor, StringRef Tag,
+ ScalarNode(std::unique_ptr<Document> &D, StringRef Anchor, StringRef Tag,
StringRef Val)
: Node(NK_Scalar, D, Anchor, Tag), Value(Val) {
SMLoc Start = SMLoc::getFromPointer(Val.begin());
@@ -234,13 +232,10 @@ private:
/// Example:
/// Section: .text
class KeyValueNode : public Node {
- virtual void anchor();
+ void anchor() override;
public:
- KeyValueNode(OwningPtr<Document> &D)
- : Node(NK_KeyValue, D, StringRef(), StringRef())
- , Key(0)
- , Value(0)
- {}
+ KeyValueNode(std::unique_ptr<Document> &D)
+ : Node(NK_KeyValue, D, StringRef(), StringRef()), Key(0), Value(0) {}
/// @brief Parse and return the key.
///
@@ -256,7 +251,7 @@ public:
/// @returns The value, or nullptr if failed() == true.
Node *getValue();
- virtual void skip() LLVM_OVERRIDE {
+ void skip() override {
getKey()->skip();
getValue()->skip();
}
@@ -346,7 +341,7 @@ void skip(CollectionType &C) {
/// Name: _main
/// Scope: Global
class MappingNode : public Node {
- virtual void anchor();
+ void anchor() override;
public:
enum MappingType {
MT_Block,
@@ -354,7 +349,7 @@ public:
MT_Inline ///< An inline mapping node is used for "[key: value]".
};
- MappingNode(OwningPtr<Document> &D, StringRef Anchor, StringRef Tag,
+ MappingNode(std::unique_ptr<Document> &D, StringRef Anchor, StringRef Tag,
MappingType MT)
: Node(NK_Mapping, D, Anchor, Tag), Type(MT), IsAtBeginning(true),
IsAtEnd(false), CurrentEntry(0) {}
@@ -370,7 +365,7 @@ public:
iterator end() { return iterator(); }
- virtual void skip() LLVM_OVERRIDE {
+ void skip() override {
yaml::skip(*this);
}
@@ -396,7 +391,7 @@ private:
/// - Hello
/// - World
class SequenceNode : public Node {
- virtual void anchor();
+ void anchor() override;
public:
enum SequenceType {
ST_Block,
@@ -411,7 +406,7 @@ public:
ST_Indentless
};
- SequenceNode(OwningPtr<Document> &D, StringRef Anchor, StringRef Tag,
+ SequenceNode(std::unique_ptr<Document> &D, StringRef Anchor, StringRef Tag,
SequenceType ST)
: Node(NK_Sequence, D, Anchor, Tag), SeqType(ST), IsAtBeginning(true),
IsAtEnd(false),
@@ -431,7 +426,7 @@ public:
iterator end() { return iterator(); }
- virtual void skip() LLVM_OVERRIDE {
+ void skip() override {
yaml::skip(*this);
}
@@ -452,10 +447,10 @@ private:
/// Example:
/// *AnchorName
class AliasNode : public Node {
- virtual void anchor();
+ void anchor() override;
public:
- AliasNode(OwningPtr<Document> &D, StringRef Val)
- : Node(NK_Alias, D, StringRef(), StringRef()), Name(Val) {}
+ AliasNode(std::unique_ptr<Document> &D, StringRef Val)
+ : Node(NK_Alias, D, StringRef(), StringRef()), Name(Val) {}
StringRef getName() const { return Name; }
Node *getTarget();
@@ -532,7 +527,7 @@ private:
class document_iterator {
public:
document_iterator() : Doc(0) {}
- document_iterator(OwningPtr<Document> &D) : Doc(&D) {}
+ document_iterator(std::unique_ptr<Document> &D) : Doc(&D) {}
bool operator ==(const document_iterator &Other) {
if (isAtEnd() || Other.isAtEnd())
@@ -559,16 +554,14 @@ public:
return *Doc->get();
}
- OwningPtr<Document> &operator ->() {
- return *Doc;
- }
+ std::unique_ptr<Document> &operator->() { return *Doc; }
private:
bool isAtEnd() const {
return !Doc || !*Doc;
}
- OwningPtr<Document> *Doc;
+ std::unique_ptr<Document> *Doc;
};
}
diff --git a/include/llvm/Support/YAMLTraits.h b/include/llvm/Support/YAMLTraits.h
index c19eb23..ea217c3 100644
--- a/include/llvm/Support/YAMLTraits.h
+++ b/include/llvm/Support/YAMLTraits.h
@@ -1,4 +1,4 @@
-//===- llvm/Supporrt/YAMLTraits.h -------------------------------*- C++ -*-===//
+//===- llvm/Support/YAMLTraits.h --------------------------------*- C++ -*-===//
//
// The LLVM Linker
//
@@ -13,19 +13,17 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseMapInfo.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Twine.h"
-#include "llvm/Support/Casting.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 {
@@ -45,6 +43,8 @@ template<class T>
struct MappingTraits {
// Must provide:
// static void mapping(IO &io, T &fields);
+ // Optionally may provide:
+ // static StringRef validate(IO &io, T &fields);
};
@@ -227,6 +227,23 @@ public:
static bool const value = (sizeof(test<MappingTraits<T> >(0)) == 1);
};
+// Test if MappingTraits<T>::validate() is defined on type T.
+template <class T>
+struct has_MappingValidateTraits
+{
+ typedef StringRef (*Signature_validate)(class IO&, T&);
+
+ template <typename U>
+ static char test(SameType<Signature_validate, &U::validate>*);
+
+ 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>
@@ -248,7 +265,7 @@ public:
// 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>
+template <typename T, bool Enabled = std::is_class<T>::value>
class has_FlowTraits
{
public:
@@ -278,7 +295,7 @@ public:
// Test if SequenceTraits<T> is defined on type T
template<typename T>
-struct has_SequenceTraits : public llvm::integral_constant<bool,
+struct has_SequenceTraits : public std::integral_constant<bool,
has_SequenceMethodTraits<T>::value > { };
@@ -302,7 +319,7 @@ public:
template<typename T>
-struct missingTraits : public llvm::integral_constant<bool,
+struct missingTraits : public std::integral_constant<bool,
!has_ScalarEnumerationTraits<T>::value
&& !has_ScalarBitSetTraits<T>::value
&& !has_ScalarTraits<T>::value
@@ -310,7 +327,15 @@ struct missingTraits : public llvm::integral_constant<bool,
&& !has_SequenceTraits<T>::value
&& !has_DocumentListTraits<T>::value > {};
+template<typename T>
+struct validatedMappingTraits : public std::integral_constant<bool,
+ has_MappingTraits<T>::value
+ && has_MappingValidateTraits<T>::value> {};
+template<typename T>
+struct unvalidatedMappingTraits : public std::integral_constant<bool,
+ has_MappingTraits<T>::value
+ && !has_MappingValidateTraits<T>::value> {};
// Base class for Input and Output.
class IO {
public:
@@ -318,7 +343,7 @@ public:
IO(void *Ctxt=NULL);
virtual ~IO();
- virtual bool outputting() const = 0;
+ virtual bool outputting() = 0;
virtual unsigned beginSequence() = 0;
virtual bool preflightElement(unsigned, void *&) = 0;
@@ -388,7 +413,7 @@ public:
}
template <typename T>
- typename llvm::enable_if_c<has_SequenceTraits<T>::value,void>::type
+ typename std::enable_if<has_SequenceTraits<T>::value,void>::type
mapOptional(const char* Key, T& Val) {
// omit key/value instead of outputting empty sequence
if ( this->canElideEmptySequence() && !(Val.begin() != Val.end()) )
@@ -397,7 +422,12 @@ public:
}
template <typename T>
- typename llvm::enable_if_c<!has_SequenceTraits<T>::value,void>::type
+ void mapOptional(const char* Key, Optional<T> &Val) {
+ processKeyWithDefault(Key, Val, Optional<T>(), /*Required=*/false);
+ }
+
+ template <typename T>
+ typename std::enable_if<!has_SequenceTraits<T>::value,void>::type
mapOptional(const char* Key, T& Val) {
this->processKey(Key, Val, false);
}
@@ -409,6 +439,26 @@ public:
private:
template <typename T>
+ void processKeyWithDefault(const char *Key, Optional<T> &Val,
+ const Optional<T> &DefaultValue, bool Required) {
+ assert(DefaultValue.hasValue() == false &&
+ "Optional<T> shouldn't have a value!");
+ void *SaveInfo;
+ bool UseDefault;
+ const bool sameAsDefault = outputting() && !Val.hasValue();
+ if (!outputting() && !Val.hasValue())
+ Val = T();
+ if (this->preflightKey(Key, Required, sameAsDefault, UseDefault,
+ SaveInfo)) {
+ yamlize(*this, Val.getValue(), Required);
+ this->postflightKey(SaveInfo);
+ } else {
+ if (UseDefault)
+ Val = DefaultValue;
+ }
+ }
+
+ template <typename T>
void processKeyWithDefault(const char *Key, T &Val, const T& DefaultValue,
bool Required) {
void *SaveInfo;
@@ -442,7 +492,7 @@ private:
template<typename T>
-typename llvm::enable_if_c<has_ScalarEnumerationTraits<T>::value,void>::type
+typename std::enable_if<has_ScalarEnumerationTraits<T>::value,void>::type
yamlize(IO &io, T &Val, bool) {
io.beginEnumScalar();
ScalarEnumerationTraits<T>::enumeration(io, Val);
@@ -450,7 +500,7 @@ yamlize(IO &io, T &Val, bool) {
}
template<typename T>
-typename llvm::enable_if_c<has_ScalarBitSetTraits<T>::value,void>::type
+typename std::enable_if<has_ScalarBitSetTraits<T>::value,void>::type
yamlize(IO &io, T &Val, bool) {
bool DoClear;
if ( io.beginBitSetScalar(DoClear) ) {
@@ -463,7 +513,7 @@ yamlize(IO &io, T &Val, bool) {
template<typename T>
-typename llvm::enable_if_c<has_ScalarTraits<T>::value,void>::type
+typename std::enable_if<has_ScalarTraits<T>::value,void>::type
yamlize(IO &io, T &Val, bool) {
if ( io.outputting() ) {
std::string Storage;
@@ -484,21 +534,41 @@ yamlize(IO &io, T &Val, bool) {
template<typename T>
-typename llvm::enable_if_c<has_MappingTraits<T>::value, void>::type
+typename std::enable_if<validatedMappingTraits<T>::value, void>::type
yamlize(IO &io, T &Val, bool) {
io.beginMapping();
+ if (io.outputting()) {
+ StringRef Err = MappingTraits<T>::validate(io, Val);
+ if (!Err.empty()) {
+ llvm::errs() << Err << "\n";
+ assert(Err.empty() && "invalid struct trying to be written as yaml");
+ }
+ }
MappingTraits<T>::mapping(io, Val);
+ if (!io.outputting()) {
+ StringRef Err = MappingTraits<T>::validate(io, Val);
+ if (!Err.empty())
+ io.setError(Err);
+ }
io.endMapping();
}
template<typename T>
-typename llvm::enable_if_c<missingTraits<T>::value, void>::type
+typename std::enable_if<unvalidatedMappingTraits<T>::value, void>::type
+yamlize(IO &io, T &Val, bool) {
+ io.beginMapping();
+ MappingTraits<T>::mapping(io, Val);
+ io.endMapping();
+}
+
+template<typename T>
+typename std::enable_if<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
+typename std::enable_if<has_SequenceTraits<T>::value,void>::type
yamlize(IO &io, T &Seq, bool) {
if ( has_FlowTraits< SequenceTraits<T> >::value ) {
unsigned incnt = io.beginFlowSequence();
@@ -538,6 +608,12 @@ struct ScalarTraits<StringRef> {
static void output(const StringRef &, void*, llvm::raw_ostream &);
static StringRef input(StringRef, void*, StringRef &);
};
+
+template<>
+struct ScalarTraits<std::string> {
+ static void output(const std::string &, void*, llvm::raw_ostream &);
+ static StringRef input(StringRef, void*, std::string &);
+};
template<>
struct ScalarTraits<uint8_t> {
@@ -697,32 +773,30 @@ public:
// Check if there was an syntax or semantic error during parsing.
llvm::error_code error();
- static bool classof(const IO *io) { return !io->outputting(); }
-
private:
- virtual bool outputting() const;
- virtual bool mapTag(StringRef, bool);
- 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);
- virtual bool canElideEmptySequence();
+ bool outputting() override;
+ bool mapTag(StringRef, bool) override;
+ void beginMapping() override;
+ void endMapping() override;
+ bool preflightKey(const char *, bool, bool, bool &, void *&) override;
+ void postflightKey(void *) override;
+ unsigned beginSequence() override;
+ void endSequence() override;
+ bool preflightElement(unsigned index, void *&) override;
+ void postflightElement(void *) override;
+ unsigned beginFlowSequence() override;
+ bool preflightFlowElement(unsigned , void *&) override;
+ void postflightFlowElement(void *) override;
+ void endFlowSequence() override;
+ void beginEnumScalar() override;
+ bool matchEnumScalar(const char*, bool) override;
+ void endEnumScalar() override;
+ bool beginBitSetScalar(bool &) override;
+ bool bitSetMatch(const char *, bool ) override;
+ void endBitSetScalar() override;
+ void scalarString(StringRef &) override;
+ void setError(const Twine &message) override;
+ bool canElideEmptySequence() override;
class HNode {
virtual void anchor();
@@ -735,7 +809,7 @@ private:
};
class EmptyHNode : public HNode {
- virtual void anchor();
+ void anchor() override;
public:
EmptyHNode(Node *n) : HNode(n) { }
static inline bool classof(const HNode *n) {
@@ -745,7 +819,7 @@ private:
};
class ScalarHNode : public HNode {
- virtual void anchor();
+ void anchor() override;
public:
ScalarHNode(Node *n, StringRef s) : HNode(n), _value(s) { }
@@ -802,15 +876,15 @@ public:
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;
+ llvm::SourceMgr SrcMgr; // must be before Strm
+ std::unique_ptr<llvm::yaml::Stream> Strm;
+ std::unique_ptr<HNode> TopNode;
+ llvm::error_code EC;
+ llvm::BumpPtrAllocator StringAllocator;
+ llvm::yaml::document_iterator DocIterator;
+ std::vector<bool> BitValuesUsed;
+ HNode *CurrentNode;
+ bool ScalarMatchFound;
};
@@ -825,31 +899,29 @@ public:
Output(llvm::raw_ostream &, void *Ctxt=NULL);
virtual ~Output();
- static bool classof(const IO *io) { return io->outputting(); }
-
- virtual bool outputting() const;
- virtual bool mapTag(StringRef, bool);
- 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);
- virtual bool canElideEmptySequence();
+ bool outputting() override;
+ bool mapTag(StringRef, bool) override;
+ void beginMapping() override;
+ void endMapping() override;
+ bool preflightKey(const char *key, bool, bool, bool &, void *&) override;
+ void postflightKey(void *) override;
+ unsigned beginSequence() override;
+ void endSequence() override;
+ bool preflightElement(unsigned, void *&) override;
+ void postflightElement(void *) override;
+ unsigned beginFlowSequence() override;
+ bool preflightFlowElement(unsigned, void *&) override;
+ void postflightFlowElement(void *) override;
+ void endFlowSequence() override;
+ void beginEnumScalar() override;
+ bool matchEnumScalar(const char*, bool) override;
+ void endEnumScalar() override;
+ bool beginBitSetScalar(bool &) override;
+ bool bitSetMatch(const char *, bool ) override;
+ void endBitSetScalar() override;
+ void scalarString(StringRef &) override;
+ void setError(const Twine &message) override;
+ bool canElideEmptySequence() override;
public:
// These are only used by operator<<. They could be private
// if that templated operator could be made a friend.
@@ -942,7 +1014,7 @@ struct ScalarTraits<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
+typename std::enable_if<has_DocumentListTraits<T>::value, Input &>::type
operator>>(Input &yin, T &docList) {
int i = 0;
while ( yin.setCurrentDocument() ) {
@@ -958,7 +1030,7 @@ operator>>(Input &yin, T &docList) {
// 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
+typename std::enable_if<has_MappingTraits<T>::value, Input &>::type
operator>>(Input &yin, T &docMap) {
yin.setCurrentDocument();
yamlize(yin, docMap, true);
@@ -969,7 +1041,7 @@ operator>>(Input &yin, T &docMap) {
// a document.
template <typename T>
inline
-typename llvm::enable_if_c<has_SequenceTraits<T>::value,Input &>::type
+typename std::enable_if<has_SequenceTraits<T>::value, Input &>::type
operator>>(Input &yin, T &docSeq) {
if (yin.setCurrentDocument())
yamlize(yin, docSeq, true);
@@ -979,7 +1051,7 @@ operator>>(Input &yin, T &docSeq) {
// Provide better error message about types missing a trait specialization
template <typename T>
inline
-typename llvm::enable_if_c<missingTraits<T>::value,Input &>::type
+typename std::enable_if<missingTraits<T>::value, Input &>::type
operator>>(Input &yin, T &docSeq) {
char missing_yaml_trait_for_type[sizeof(MissingTrait<T>)];
return yin;
@@ -989,7 +1061,7 @@ operator>>(Input &yin, T &docSeq) {
// 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
+typename std::enable_if<has_DocumentListTraits<T>::value, Output &>::type
operator<<(Output &yout, T &docList) {
yout.beginDocuments();
const size_t count = DocumentListTraits<T>::size(yout, docList);
@@ -1006,7 +1078,7 @@ operator<<(Output &yout, T &docList) {
// 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
+typename std::enable_if<has_MappingTraits<T>::value, Output &>::type
operator<<(Output &yout, T &map) {
yout.beginDocuments();
if ( yout.preflightDocument(0) ) {
@@ -1020,7 +1092,7 @@ operator<<(Output &yout, T &map) {
// 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
+typename std::enable_if<has_SequenceTraits<T>::value, Output &>::type
operator<<(Output &yout, T &seq) {
yout.beginDocuments();
if ( yout.preflightDocument(0) ) {
@@ -1034,7 +1106,7 @@ operator<<(Output &yout, T &seq) {
// Provide better error message about types missing a trait specialization
template <typename T>
inline
-typename llvm::enable_if_c<missingTraits<T>::value,Output &>::type
+typename std::enable_if<missingTraits<T>::value, Output &>::type
operator<<(Output &yout, T &seq) {
char missing_yaml_trait_for_type[sizeof(MissingTrait<T>)];
return yout;
@@ -1075,6 +1147,7 @@ operator<<(Output &yout, T &seq) {
return seq.size(); \
} \
static _type& element(IO &io, std::vector<_type> &seq, size_t index) {\
+ (void)flow; /* Remove this workaround after PR17897 is fixed */ \
if ( index >= seq.size() ) \
seq.resize(index+1); \
return seq[index]; \
diff --git a/include/llvm/Support/circular_raw_ostream.h b/include/llvm/Support/circular_raw_ostream.h
index 9000306..3114199 100644
--- a/include/llvm/Support/circular_raw_ostream.h
+++ b/include/llvm/Support/circular_raw_ostream.h
@@ -81,12 +81,12 @@ namespace llvm
Filled = false;
}
- virtual void write_impl(const char *Ptr, size_t Size) LLVM_OVERRIDE;
+ void write_impl(const char *Ptr, size_t Size) 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 {
+ uint64_t current_pos() const override {
// This has the same effect as calling TheStream.current_pos(),
// but that interface is private.
return TheStream->tell() - TheStream->GetNumBytesInBuffer();
diff --git a/include/llvm/Support/raw_os_ostream.h b/include/llvm/Support/raw_os_ostream.h
index 4385721..04cf3b6 100644
--- a/include/llvm/Support/raw_os_ostream.h
+++ b/include/llvm/Support/raw_os_ostream.h
@@ -26,11 +26,11 @@ class raw_os_ostream : public raw_ostream {
std::ostream &OS;
/// write_impl - See raw_ostream::write_impl.
- virtual void write_impl(const char *Ptr, size_t Size) LLVM_OVERRIDE;
+ void write_impl(const char *Ptr, size_t Size) 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;
+ uint64_t current_pos() const override;
public:
raw_os_ostream(std::ostream &O) : OS(O) {}
diff --git a/include/llvm/Support/raw_ostream.h b/include/llvm/Support/raw_ostream.h
index ec7e06b..0240035 100644
--- a/include/llvm/Support/raw_ostream.h
+++ b/include/llvm/Support/raw_ostream.h
@@ -322,14 +322,14 @@ class raw_fd_ostream : public raw_ostream {
uint64_t pos;
/// write_impl - See raw_ostream::write_impl.
- virtual void write_impl(const char *Ptr, size_t Size) LLVM_OVERRIDE;
+ void write_impl(const char *Ptr, size_t Size) 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 { return pos; }
+ uint64_t current_pos() const override { return pos; }
/// preferred_buffer_size - Determine an efficient buffer size.
- virtual size_t preferred_buffer_size() const LLVM_OVERRIDE;
+ size_t preferred_buffer_size() const override;
/// error_detected - Set the flag indicating that an output error has
/// been encountered.
@@ -347,7 +347,7 @@ public:
/// file descriptor when it is done (this is necessary to detect
/// output errors).
raw_fd_ostream(const char *Filename, std::string &ErrorInfo,
- sys::fs::OpenFlags Flags = sys::fs::F_None);
+ sys::fs::OpenFlags Flags);
/// raw_fd_ostream ctor - FD is the file descriptor that this writes to. If
/// ShouldClose is true, this closes the file when the stream is destroyed.
@@ -373,15 +373,15 @@ public:
UseAtomicWrites = Value;
}
- virtual raw_ostream &changeColor(enum Colors colors, bool bold=false,
- bool bg=false) LLVM_OVERRIDE;
- virtual raw_ostream &resetColor() LLVM_OVERRIDE;
+ raw_ostream &changeColor(enum Colors colors, bool bold=false,
+ bool bg=false) override;
+ raw_ostream &resetColor() override;
- virtual raw_ostream &reverseColor() LLVM_OVERRIDE;
+ raw_ostream &reverseColor() override;
- virtual bool is_displayed() const LLVM_OVERRIDE;
+ bool is_displayed() const override;
- virtual bool has_colors() const LLVM_OVERRIDE;
+ bool has_colors() const override;
/// has_error - Return the value of the flag in this raw_fd_ostream indicating
/// whether an output error has been encountered.
@@ -427,11 +427,11 @@ class raw_string_ostream : public raw_ostream {
std::string &OS;
/// write_impl - See raw_ostream::write_impl.
- virtual void write_impl(const char *Ptr, size_t Size) LLVM_OVERRIDE;
+ void write_impl(const char *Ptr, size_t Size) 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 { return OS.size(); }
+ uint64_t current_pos() const override { return OS.size(); }
public:
explicit raw_string_ostream(std::string &O) : OS(O) {}
~raw_string_ostream();
@@ -451,11 +451,11 @@ class raw_svector_ostream : public raw_ostream {
SmallVectorImpl<char> &OS;
/// write_impl - See raw_ostream::write_impl.
- virtual void write_impl(const char *Ptr, size_t Size) LLVM_OVERRIDE;
+ void write_impl(const char *Ptr, size_t Size) 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;
+ uint64_t current_pos() const override;
public:
/// Construct a new raw_svector_ostream.
///
@@ -477,11 +477,11 @@ public:
/// raw_null_ostream - A raw_ostream that discards all output.
class raw_null_ostream : public raw_ostream {
/// write_impl - See raw_ostream::write_impl.
- virtual void write_impl(const char *Ptr, size_t size) LLVM_OVERRIDE;
+ void write_impl(const char *Ptr, size_t size) 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;
+ uint64_t current_pos() const override;
public:
explicit raw_null_ostream() {}
diff --git a/include/llvm/Support/system_error.h b/include/llvm/Support/system_error.h
index 43dace6..4ca4b06 100644
--- a/include/llvm/Support/system_error.h
+++ b/include/llvm/Support/system_error.h
@@ -48,10 +48,10 @@ const error_category& generic_category();
const error_category& system_category();
template <class T> struct is_error_code_enum
- : public false_type {};
+ : public std::false_type {};
template <class T> struct is_error_condition_enum
- : public false_type {};
+ : public std::false_type {};
class error_code
{
@@ -203,7 +203,7 @@ enum class errc
wrong_protocol_type // EPROTOTYPE
};
-template <> struct is_error_condition_enum<errc> : true_type { }
+template <> struct is_error_condition_enum<errc> : std::true_type { }
error_code make_error_code(errc e);
error_condition make_error_condition(errc e);
@@ -225,7 +225,6 @@ template <> struct hash<std::error_code>;
*/
#include "llvm/Config/llvm-config.h"
-#include "llvm/Support/type_traits.h"
#include <cerrno>
#include <string>
@@ -474,11 +473,11 @@ namespace llvm {
// is_error_code_enum
-template <class Tp> struct is_error_code_enum : public false_type {};
+template <class Tp> struct is_error_code_enum : public std::false_type {};
// is_error_condition_enum
-template <class Tp> struct is_error_condition_enum : public false_type {};
+template <class Tp> struct is_error_condition_enum : public std::false_type {};
// Some error codes are not present on all platforms, so we provide equivalents
// for them:
@@ -613,9 +612,9 @@ enum _ {
operator int() const {return v_;}
};
-template <> struct is_error_condition_enum<errc> : true_type { };
+template <> struct is_error_condition_enum<errc> : std::true_type { };
-template <> struct is_error_condition_enum<errc::_> : true_type { };
+template <> struct is_error_condition_enum<errc::_> : std::true_type { };
class error_condition;
class error_code;
@@ -629,8 +628,8 @@ class error_category
public:
virtual ~error_category();
-private:
error_category();
+private:
error_category(const error_category&) LLVM_DELETED_FUNCTION;
error_category& operator=(const error_category&) LLVM_DELETED_FUNCTION;
@@ -653,7 +652,7 @@ public:
class _do_message : public error_category
{
public:
- virtual std::string message(int ev) const LLVM_OVERRIDE;
+ std::string message(int ev) const override;
};
const error_category& generic_category();
@@ -675,7 +674,7 @@ public:
: _val_(_val), _cat_(&_cat) {}
template <class E>
- error_condition(E _e, typename enable_if_c<
+ error_condition(E _e, typename std::enable_if<
is_error_condition_enum<E>::value
>::type* = 0)
{*this = make_error_condition(_e);}
@@ -686,13 +685,12 @@ public:
}
template <class E>
- typename enable_if_c
- <
- is_error_condition_enum<E>::value,
- error_condition&
- >::type
- operator=(E _e)
- {*this = make_error_condition(_e); return *this;}
+ typename std::enable_if<is_error_condition_enum<E>::value,
+ error_condition &>::type
+ operator=(E _e) {
+ *this = make_error_condition(_e);
+ return *this;
+ }
void clear() {
_val_ = 0;
@@ -737,7 +735,7 @@ public:
: _val_(_val), _cat_(&_cat) {}
template <class E>
- error_code(E _e, typename enable_if_c<
+ error_code(E _e, typename std::enable_if<
is_error_code_enum<E>::value
>::type* = 0) {
*this = make_error_code(_e);
@@ -749,13 +747,11 @@ public:
}
template <class E>
- typename enable_if_c
- <
- is_error_code_enum<E>::value,
- error_code&
- >::type
- operator=(E _e)
- {*this = make_error_code(_e); return *this;}
+ typename std::enable_if<is_error_code_enum<E>::value, error_code &>::type
+ operator=(E _e) {
+ *this = make_error_code(_e);
+ return *this;
+ }
void clear() {
_val_ = 0;
@@ -892,9 +888,9 @@ enum _ {
};
-template <> struct is_error_code_enum<windows_error> : true_type { };
+template <> struct is_error_code_enum<windows_error> : std::true_type { };
-template <> struct is_error_code_enum<windows_error::_> : true_type { };
+template <> struct is_error_code_enum<windows_error::_> : std::true_type { };
inline error_code make_error_code(windows_error e) {
return error_code(static_cast<int>(e), system_category());
diff --git a/include/llvm/Support/type_traits.h b/include/llvm/Support/type_traits.h
index 906e97c..70953a9 100644
--- a/include/llvm/Support/type_traits.h
+++ b/include/llvm/Support/type_traits.h
@@ -7,18 +7,14 @@
//
//===----------------------------------------------------------------------===//
//
-// This file provides a template class that determines if a type is a class or
-// not. The basic mechanism, based on using the pointer to member function of
-// a zero argument to a function was "boosted" from the boost type_traits
-// library. See http://www.boost.org/ for all the gory details.
+// This file provides useful additions to the standard type_traits library.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_SUPPORT_TYPE_TRAITS_H
#define LLVM_SUPPORT_TYPE_TRAITS_H
-#include "llvm/Support/DataTypes.h"
-#include <cstddef>
+#include <type_traits>
#include <utility>
#ifndef __has_feature
@@ -26,40 +22,8 @@
#define __has_feature(x) 0
#endif
-// This is actually the conforming implementation which works with abstract
-// classes. However, enough compilers have trouble with it that most will use
-// the one in boost/type_traits/object_traits.hpp. This implementation actually
-// works with VC7.0, but other interactions seem to fail when we use it.
-
namespace llvm {
-
-namespace dont_use
-{
- // These two functions should never be used. They are helpers to
- // the is_class template below. They cannot be located inside
- // is_class because doing so causes at least GCC to think that
- // the value of the "value" enumerator is not constant. Placing
- // them out here (for some strange reason) allows the sizeof
- // operator against them to magically be constant. This is
- // important to make the is_class<T>::value idiom zero cost. it
- // evaluates to a constant 1 or 0 depending on whether the
- // parameter T is a class or not (respectively).
- template<typename T> char is_class_helper(void(T::*)());
- template<typename T> double is_class_helper(...);
-}
-template <typename T>
-struct is_class
-{
- // is_class<> metafunction due to Paul Mensonides (leavings@attbi.com). For
- // more details:
- // http://groups.google.com/groups?hl=en&selm=000001c1cc83%24e154d5e0%247772e50c%40c161550a&rnum=1
-public:
- static const bool value =
- sizeof(char) == sizeof(dont_use::is_class_helper<T>(0));
-};
-
-
/// isPodLike - This is a type trait that is used to determine whether a given
/// type can be copied around with memcpy instead of running ctors etc.
template <typename T>
@@ -71,7 +35,7 @@ struct isPodLike {
#else
// If we don't know anything else, we can (at least) assume that all non-class
// types are PODs.
- static const bool value = !is_class<T>::value;
+ static const bool value = !std::is_class<T>::value;
#endif
};
@@ -80,161 +44,45 @@ template<typename T, typename U>
struct isPodLike<std::pair<T, U> > {
static const bool value = isPodLike<T>::value && isPodLike<U>::value;
};
-
-
-template <class T, T v>
-struct integral_constant {
- typedef T value_type;
- static const value_type value = v;
- typedef integral_constant<T,v> type;
- operator value_type() { return value; }
-};
-
-typedef integral_constant<bool, true> true_type;
-typedef integral_constant<bool, false> false_type;
-
-/// \brief Metafunction that determines whether the two given types are
-/// equivalent.
-template<typename T, typename U> struct is_same : public false_type {};
-template<typename T> struct is_same<T, T> : public true_type {};
-
-/// \brief Metafunction that removes const qualification from a type.
-template <typename T> struct remove_const { typedef T type; };
-template <typename T> struct remove_const<const T> { typedef T type; };
-
-/// \brief Metafunction that removes volatile qualification from a type.
-template <typename T> struct remove_volatile { typedef T type; };
-template <typename T> struct remove_volatile<volatile T> { typedef T type; };
-
-/// \brief Metafunction that removes both const and volatile qualification from
-/// a type.
-template <typename T> struct remove_cv {
- typedef typename remove_const<typename remove_volatile<T>::type>::type type;
-};
-
-/// \brief Helper to implement is_integral metafunction.
-template <typename T> struct is_integral_impl : false_type {};
-template <> struct is_integral_impl< bool> : true_type {};
-template <> struct is_integral_impl< char> : true_type {};
-template <> struct is_integral_impl< signed char> : true_type {};
-template <> struct is_integral_impl<unsigned char> : true_type {};
-template <> struct is_integral_impl< wchar_t> : true_type {};
-template <> struct is_integral_impl< short> : true_type {};
-template <> struct is_integral_impl<unsigned short> : true_type {};
-template <> struct is_integral_impl< int> : true_type {};
-template <> struct is_integral_impl<unsigned int> : true_type {};
-template <> struct is_integral_impl< long> : true_type {};
-template <> struct is_integral_impl<unsigned long> : true_type {};
-template <> struct is_integral_impl< long long> : true_type {};
-template <> struct is_integral_impl<unsigned long long> : true_type {};
-
-/// \brief Metafunction that determines whether the given type is an integral
-/// type.
-template <typename T>
-struct is_integral : is_integral_impl<T> {};
-
-/// \brief Metafunction to remove reference from a type.
-template <typename T> struct remove_reference { typedef T type; };
-template <typename T> struct remove_reference<T&> { typedef T type; };
-
-/// \brief Metafunction that determines whether the given type is a pointer
-/// type.
-template <typename T> struct is_pointer : false_type {};
-template <typename T> struct is_pointer<T*> : true_type {};
-template <typename T> struct is_pointer<T* const> : true_type {};
-template <typename T> struct is_pointer<T* volatile> : true_type {};
-template <typename T> struct is_pointer<T* const volatile> : true_type {};
-
-/// \brief Metafunction that determines wheather the given type is a reference.
-template <typename T> struct is_reference : false_type {};
-template <typename T> struct is_reference<T&> : true_type {};
/// \brief Metafunction that determines whether the given type is either an
/// integral type or an enumeration type.
///
-/// Note that this accepts potentially more integral types than we whitelist
-/// above for is_integral because it is based on merely being convertible
-/// implicitly to an integral type.
+/// Note that this accepts potentially more integral types than is_integral
+/// because it is based on merely being convertible implicitly to an integral
+/// type.
template <typename T> class is_integral_or_enum {
- // Provide an overload which can be called with anything implicitly
- // convertible to an unsigned long long. This should catch integer types and
- // enumeration types at least. We blacklist classes with conversion operators
- // below.
- static double check_int_convertible(unsigned long long);
- static char check_int_convertible(...);
-
- typedef typename remove_reference<T>::type UnderlyingT;
- static UnderlyingT &nonce_instance;
+ typedef typename std::remove_reference<T>::type UnderlyingT;
public:
- static const bool
- value = (!is_class<UnderlyingT>::value && !is_pointer<UnderlyingT>::value &&
- !is_same<UnderlyingT, float>::value &&
- !is_same<UnderlyingT, double>::value &&
- sizeof(char) != sizeof(check_int_convertible(nonce_instance)));
-};
-
-// enable_if_c - Enable/disable a template based on a metafunction
-template<bool Cond, typename T = void>
-struct enable_if_c {
- typedef T type;
-};
-
-template<typename T> struct enable_if_c<false, T> { };
-
-// enable_if - Enable/disable a template based on a metafunction
-template<typename Cond, typename T = void>
-struct enable_if : public enable_if_c<Cond::value, T> { };
-
-namespace dont_use {
- template<typename Base> char base_of_helper(const volatile Base*);
- template<typename Base> double base_of_helper(...);
-}
-
-/// is_base_of - Metafunction to determine whether one type is a base class of
-/// (or identical to) another type.
-template<typename Base, typename Derived>
-struct is_base_of {
- static const bool value
- = is_class<Base>::value && is_class<Derived>::value &&
- sizeof(char) == sizeof(dont_use::base_of_helper<Base>((Derived*)0));
+ static const bool value =
+ !std::is_class<UnderlyingT>::value && // Filter conversion operators.
+ !std::is_pointer<UnderlyingT>::value &&
+ !std::is_floating_point<UnderlyingT>::value &&
+ std::is_convertible<UnderlyingT, unsigned long long>::value;
};
-// remove_pointer - Metafunction to turn Foo* into Foo. Defined in
-// C++0x [meta.trans.ptr].
-template <typename T> struct remove_pointer { typedef T type; };
-template <typename T> struct remove_pointer<T*> { typedef T type; };
-template <typename T> struct remove_pointer<T*const> { typedef T type; };
-template <typename T> struct remove_pointer<T*volatile> { typedef T type; };
-template <typename T> struct remove_pointer<T*const volatile> {
- typedef T type; };
-
-// If T is a pointer, just return it. If it is not, return T&.
+/// \brief 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> {
+template <typename T>
+struct add_lvalue_reference_if_not_pointer<
+ T, typename std::enable_if<std::is_pointer<T>::value>::type> {
typedef T type;
};
-// If T is a pointer to X, return a pointer to const X. If it is not, return
-// const T.
+/// \brief 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 <typename T>
+struct add_const_past_pointer<
+ T, typename std::enable_if<std::is_pointer<T>::value>::type> {
+ typedef const typename std::remove_pointer<T>::type *type;
};
-template <bool, typename T, typename F>
-struct conditional { typedef T type; };
-
-template <typename T, typename F>
-struct conditional<false, T, F> { typedef F type; };
-
}
#ifdef LLVM_DEFINED_HAS_FEATURE