diff options
author | dim <dim@FreeBSD.org> | 2015-12-30 13:13:10 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2015-12-30 13:13:10 +0000 |
commit | 9b5bf5c4f53d65d6a48722d7410ed7cb15f5ba3a (patch) | |
tree | b466a4817f79516eb1df8eae92bccf62ecc84003 /contrib/llvm/include/llvm/Support | |
parent | f09a28d1de99fda4f5517fb12670fc36552f4927 (diff) | |
parent | e194cd6d03d91631334d9d5e55b506036f423cc8 (diff) | |
download | FreeBSD-src-9b5bf5c4f53d65d6a48722d7410ed7cb15f5ba3a.zip FreeBSD-src-9b5bf5c4f53d65d6a48722d7410ed7cb15f5ba3a.tar.gz |
Update llvm to trunk r256633.
Diffstat (limited to 'contrib/llvm/include/llvm/Support')
64 files changed, 2324 insertions, 928 deletions
diff --git a/contrib/llvm/include/llvm/Support/ARMTargetParser.def b/contrib/llvm/include/llvm/Support/ARMTargetParser.def new file mode 100644 index 0000000..2f99b07 --- /dev/null +++ b/contrib/llvm/include/llvm/Support/ARMTargetParser.def @@ -0,0 +1,223 @@ +//===- ARMTargetParser.def - ARM target parsing defines ---------*- 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 defines to build up the ARM target parser's logic. +// +//===----------------------------------------------------------------------===// + +// NOTE: NO INCLUDE GUARD DESIRED! + +#ifndef ARM_FPU +#define ARM_FPU(NAME, KIND, VERSION, NEON_SUPPORT, RESTRICTION) +#endif +ARM_FPU("invalid", FK_INVALID, FV_NONE, NS_None, FR_None) +ARM_FPU("none", FK_NONE, FV_NONE, NS_None, FR_None) +ARM_FPU("vfp", FK_VFP, FV_VFPV2, NS_None, FR_None) +ARM_FPU("vfpv2", FK_VFPV2, FV_VFPV2, NS_None, FR_None) +ARM_FPU("vfpv3", FK_VFPV3, FV_VFPV3, NS_None, FR_None) +ARM_FPU("vfpv3-fp16", FK_VFPV3_FP16, FV_VFPV3_FP16, NS_None, FR_None) +ARM_FPU("vfpv3-d16", FK_VFPV3_D16, FV_VFPV3, NS_None, FR_D16) +ARM_FPU("vfpv3-d16-fp16", FK_VFPV3_D16_FP16, FV_VFPV3_FP16, NS_None, FR_D16) +ARM_FPU("vfpv3xd", FK_VFPV3XD, FV_VFPV3, NS_None, FR_SP_D16) +ARM_FPU("vfpv3xd-fp16", FK_VFPV3XD_FP16, FV_VFPV3_FP16, NS_None, FR_SP_D16) +ARM_FPU("vfpv4", FK_VFPV4, FV_VFPV4, NS_None, FR_None) +ARM_FPU("vfpv4-d16", FK_VFPV4_D16, FV_VFPV4, NS_None, FR_D16) +ARM_FPU("fpv4-sp-d16", FK_FPV4_SP_D16, FV_VFPV4, NS_None, FR_SP_D16) +ARM_FPU("fpv5-d16", FK_FPV5_D16, FV_VFPV5, NS_None, FR_D16) +ARM_FPU("fpv5-sp-d16", FK_FPV5_SP_D16, FV_VFPV5, NS_None, FR_SP_D16) +ARM_FPU("fp-armv8", FK_FP_ARMV8, FV_VFPV5, NS_None, FR_None) +ARM_FPU("neon", FK_NEON, FV_VFPV3, NS_Neon, FR_None) +ARM_FPU("neon-fp16", FK_NEON_FP16, FV_VFPV3_FP16, NS_Neon, FR_None) +ARM_FPU("neon-vfpv4", FK_NEON_VFPV4, FV_VFPV4, NS_Neon, FR_None) +ARM_FPU("neon-fp-armv8", FK_NEON_FP_ARMV8, FV_VFPV5, NS_Neon, FR_None) +ARM_FPU("crypto-neon-fp-armv8", FK_CRYPTO_NEON_FP_ARMV8, FV_VFPV5, NS_Crypto, + FR_None) +ARM_FPU("softvfp", FK_SOFTVFP, FV_NONE, NS_None, FR_None) +#undef ARM_FPU + +#ifndef ARM_ARCH +#define ARM_ARCH(NAME, ID, CPU_ATTR, SUB_ARCH, ARCH_ATTR, ARCH_FPU, ARCH_BASE_EXT) +#endif +ARM_ARCH("invalid", AK_INVALID, nullptr, nullptr, + ARMBuildAttrs::CPUArch::Pre_v4, FK_NONE, AEK_NONE) +ARM_ARCH("armv2", AK_ARMV2, "2", "v2", ARMBuildAttrs::CPUArch::Pre_v4, + FK_NONE, AEK_NONE) +ARM_ARCH("armv2a", AK_ARMV2A, "2A", "v2a", ARMBuildAttrs::CPUArch::Pre_v4, + FK_NONE, AEK_NONE) +ARM_ARCH("armv3", AK_ARMV3, "3", "v3", ARMBuildAttrs::CPUArch::Pre_v4, + FK_NONE, AEK_NONE) +ARM_ARCH("armv3m", AK_ARMV3M, "3M", "v3m", ARMBuildAttrs::CPUArch::Pre_v4, + FK_NONE, AEK_NONE) +ARM_ARCH("armv4", AK_ARMV4, "4", "v4", ARMBuildAttrs::CPUArch::v4, + FK_NONE, AEK_NONE) +ARM_ARCH("armv4t", AK_ARMV4T, "4T", "v4t", ARMBuildAttrs::CPUArch::v4T, + FK_NONE, AEK_NONE) +ARM_ARCH("armv5t", AK_ARMV5T, "5T", "v5", ARMBuildAttrs::CPUArch::v5T, + FK_NONE, AEK_NONE) +ARM_ARCH("armv5te", AK_ARMV5TE, "5TE", "v5e", ARMBuildAttrs::CPUArch::v5TE, + FK_NONE, AEK_DSP) +ARM_ARCH("armv5tej", AK_ARMV5TEJ, "5TEJ", "v5e", ARMBuildAttrs::CPUArch::v5TEJ, + FK_NONE, AEK_DSP) +ARM_ARCH("armv6", AK_ARMV6, "6", "v6", ARMBuildAttrs::CPUArch::v6, + FK_VFPV2, AEK_DSP) +ARM_ARCH("armv6k", AK_ARMV6K, "6K", "v6k", ARMBuildAttrs::CPUArch::v6K, + FK_VFPV2, AEK_DSP) +ARM_ARCH("armv6t2", AK_ARMV6T2, "6T2", "v6t2", ARMBuildAttrs::CPUArch::v6T2, + FK_NONE, AEK_DSP) +ARM_ARCH("armv6kz", AK_ARMV6KZ, "6KZ", "v6kz", ARMBuildAttrs::CPUArch::v6KZ, + FK_VFPV2, (AEK_SEC | AEK_DSP)) +ARM_ARCH("armv6-m", AK_ARMV6M, "6-M", "v6m", ARMBuildAttrs::CPUArch::v6_M, + FK_NONE, AEK_NONE) +ARM_ARCH("armv7-a", AK_ARMV7A, "7-A", "v7", ARMBuildAttrs::CPUArch::v7, + FK_NEON, AEK_DSP) +ARM_ARCH("armv7-r", AK_ARMV7R, "7-R", "v7r", ARMBuildAttrs::CPUArch::v7, + FK_NONE, (AEK_HWDIV | AEK_DSP)) +ARM_ARCH("armv7-m", AK_ARMV7M, "7-M", "v7m", ARMBuildAttrs::CPUArch::v7, + FK_NONE, AEK_HWDIV) +ARM_ARCH("armv7e-m", AK_ARMV7EM, "7E-M", "v7em", ARMBuildAttrs::CPUArch::v7E_M, + FK_NONE, (AEK_HWDIV | AEK_DSP)) +ARM_ARCH("armv8-a", AK_ARMV8A, "8-A", "v8", ARMBuildAttrs::CPUArch::v8, + FK_CRYPTO_NEON_FP_ARMV8, (AEK_SEC | AEK_MP | AEK_VIRT | AEK_HWDIVARM | + AEK_HWDIV | AEK_DSP | AEK_CRC)) +ARM_ARCH("armv8.1-a", AK_ARMV8_1A, "8.1-A", "v8.1a", ARMBuildAttrs::CPUArch::v8, + FK_CRYPTO_NEON_FP_ARMV8, (AEK_SEC | AEK_MP | AEK_VIRT | AEK_HWDIVARM | + AEK_HWDIV | AEK_DSP | AEK_CRC)) +ARM_ARCH("armv8.2-a", AK_ARMV8_2A, "8.2-A", "v8.2a", ARMBuildAttrs::CPUArch::v8, + FK_CRYPTO_NEON_FP_ARMV8, (AEK_SEC | AEK_MP | AEK_VIRT | AEK_HWDIVARM | + AEK_HWDIV | AEK_DSP | AEK_CRC)) +// Non-standard Arch names. +ARM_ARCH("iwmmxt", AK_IWMMXT, "iwmmxt", "", ARMBuildAttrs::CPUArch::v5TE, + FK_NONE, AEK_NONE) +ARM_ARCH("iwmmxt2", AK_IWMMXT2, "iwmmxt2", "", ARMBuildAttrs::CPUArch::v5TE, + FK_NONE, AEK_NONE) +ARM_ARCH("xscale", AK_XSCALE, "xscale", "", ARMBuildAttrs::CPUArch::v5TE, + FK_NONE, AEK_NONE) +ARM_ARCH("armv7s", AK_ARMV7S, "7-S", "v7s", ARMBuildAttrs::CPUArch::v7, + FK_NEON_VFPV4, AEK_DSP) +ARM_ARCH("armv7k", AK_ARMV7K, "7-K", "v7k", ARMBuildAttrs::CPUArch::v7, + FK_NONE, AEK_DSP) +#undef ARM_ARCH + +#ifndef ARM_ARCH_EXT_NAME +#define ARM_ARCH_EXT_NAME(NAME, ID, FEATURE, NEGFEATURE) +#endif +// FIXME: This would be nicer were it tablegen +ARM_ARCH_EXT_NAME("invalid", AEK_INVALID, nullptr, nullptr) +ARM_ARCH_EXT_NAME("none", AEK_NONE, nullptr, nullptr) +ARM_ARCH_EXT_NAME("crc", AEK_CRC, "+crc", "-crc") +ARM_ARCH_EXT_NAME("crypto", AEK_CRYPTO, "+crypto","-crypto") +ARM_ARCH_EXT_NAME("fp", AEK_FP, nullptr, nullptr) +ARM_ARCH_EXT_NAME("idiv", (AEK_HWDIVARM | AEK_HWDIV), nullptr, nullptr) +ARM_ARCH_EXT_NAME("mp", AEK_MP, nullptr, nullptr) +ARM_ARCH_EXT_NAME("simd", AEK_SIMD, nullptr, nullptr) +ARM_ARCH_EXT_NAME("sec", AEK_SEC, nullptr, nullptr) +ARM_ARCH_EXT_NAME("virt", AEK_VIRT, nullptr, nullptr) +ARM_ARCH_EXT_NAME("fp16", AEK_FP16, "+fullfp16", "-fullfp16") +ARM_ARCH_EXT_NAME("os", AEK_OS, nullptr, nullptr) +ARM_ARCH_EXT_NAME("iwmmxt", AEK_IWMMXT, nullptr, nullptr) +ARM_ARCH_EXT_NAME("iwmmxt2", AEK_IWMMXT2, nullptr, nullptr) +ARM_ARCH_EXT_NAME("maverick", AEK_MAVERICK, nullptr, nullptr) +ARM_ARCH_EXT_NAME("xscale", AEK_XSCALE, nullptr, nullptr) +#undef ARM_ARCH_EXT_NAME + +#ifndef ARM_HW_DIV_NAME +#define ARM_HW_DIV_NAME(NAME, ID) +#endif +ARM_HW_DIV_NAME("invalid", AEK_INVALID) +ARM_HW_DIV_NAME("none", AEK_NONE) +ARM_HW_DIV_NAME("thumb", AEK_HWDIV) +ARM_HW_DIV_NAME("arm", AEK_HWDIVARM) +ARM_HW_DIV_NAME("arm,thumb", (AEK_HWDIVARM | AEK_HWDIV)) +#undef ARM_HW_DIV_NAME + +#ifndef ARM_CPU_NAME +#define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) +#endif +ARM_CPU_NAME("arm2", AK_ARMV2, FK_NONE, true, AEK_NONE) +ARM_CPU_NAME("arm3", AK_ARMV2A, FK_NONE, true, AEK_NONE) +ARM_CPU_NAME("arm6", AK_ARMV3, FK_NONE, true, AEK_NONE) +ARM_CPU_NAME("arm7m", AK_ARMV3M, FK_NONE, true, AEK_NONE) +ARM_CPU_NAME("arm8", AK_ARMV4, FK_NONE, false, AEK_NONE) +ARM_CPU_NAME("arm810", AK_ARMV4, FK_NONE, false, AEK_NONE) +ARM_CPU_NAME("strongarm", AK_ARMV4, FK_NONE, true, AEK_NONE) +ARM_CPU_NAME("strongarm110", AK_ARMV4, FK_NONE, false, AEK_NONE) +ARM_CPU_NAME("strongarm1100", AK_ARMV4, FK_NONE, false, AEK_NONE) +ARM_CPU_NAME("strongarm1110", AK_ARMV4, FK_NONE, false, AEK_NONE) +ARM_CPU_NAME("arm7tdmi", AK_ARMV4T, FK_NONE, true, AEK_NONE) +ARM_CPU_NAME("arm7tdmi-s", AK_ARMV4T, FK_NONE, false, AEK_NONE) +ARM_CPU_NAME("arm710t", AK_ARMV4T, FK_NONE, false, AEK_NONE) +ARM_CPU_NAME("arm720t", AK_ARMV4T, FK_NONE, false, AEK_NONE) +ARM_CPU_NAME("arm9", AK_ARMV4T, FK_NONE, false, AEK_NONE) +ARM_CPU_NAME("arm9tdmi", AK_ARMV4T, FK_NONE, false, AEK_NONE) +ARM_CPU_NAME("arm920", AK_ARMV4T, FK_NONE, false, AEK_NONE) +ARM_CPU_NAME("arm920t", AK_ARMV4T, FK_NONE, false, AEK_NONE) +ARM_CPU_NAME("arm922t", AK_ARMV4T, FK_NONE, false, AEK_NONE) +ARM_CPU_NAME("arm9312", AK_ARMV4T, FK_NONE, false, AEK_NONE) +ARM_CPU_NAME("arm940t", AK_ARMV4T, FK_NONE, false, AEK_NONE) +ARM_CPU_NAME("ep9312", AK_ARMV4T, FK_NONE, false, AEK_NONE) +ARM_CPU_NAME("arm10tdmi", AK_ARMV5T, FK_NONE, true, AEK_NONE) +ARM_CPU_NAME("arm1020t", AK_ARMV5T, FK_NONE, false, AEK_NONE) +ARM_CPU_NAME("arm9e", AK_ARMV5TE, FK_NONE, false, AEK_NONE) +ARM_CPU_NAME("arm946e-s", AK_ARMV5TE, FK_NONE, false, AEK_NONE) +ARM_CPU_NAME("arm966e-s", AK_ARMV5TE, FK_NONE, false, AEK_NONE) +ARM_CPU_NAME("arm968e-s", AK_ARMV5TE, FK_NONE, false, AEK_NONE) +ARM_CPU_NAME("arm10e", AK_ARMV5TE, FK_NONE, false, AEK_NONE) +ARM_CPU_NAME("arm1020e", AK_ARMV5TE, FK_NONE, false, AEK_NONE) +ARM_CPU_NAME("arm1022e", AK_ARMV5TE, FK_NONE, true, AEK_NONE) +ARM_CPU_NAME("arm926ej-s", AK_ARMV5TEJ, FK_NONE, true, AEK_NONE) +ARM_CPU_NAME("arm1136j-s", AK_ARMV6, FK_NONE, false, AEK_NONE) +ARM_CPU_NAME("arm1136jf-s", AK_ARMV6, FK_VFPV2, true, AEK_NONE) +ARM_CPU_NAME("arm1136jz-s", AK_ARMV6, FK_NONE, false, AEK_NONE) +ARM_CPU_NAME("arm1176j-s", AK_ARMV6K, FK_NONE, true, AEK_NONE) +ARM_CPU_NAME("arm1176jz-s", AK_ARMV6KZ, FK_NONE, false, AEK_NONE) +ARM_CPU_NAME("mpcore", AK_ARMV6K, FK_VFPV2, false, AEK_NONE) +ARM_CPU_NAME("mpcorenovfp", AK_ARMV6K, FK_NONE, false, AEK_NONE) +ARM_CPU_NAME("arm1176jzf-s", AK_ARMV6KZ, FK_VFPV2, true, AEK_NONE) +ARM_CPU_NAME("arm1156t2-s", AK_ARMV6T2, FK_NONE, true, AEK_NONE) +ARM_CPU_NAME("arm1156t2f-s", AK_ARMV6T2, FK_VFPV2, false, AEK_NONE) +ARM_CPU_NAME("cortex-m0", AK_ARMV6M, FK_NONE, true, AEK_NONE) +ARM_CPU_NAME("cortex-m0plus", AK_ARMV6M, FK_NONE, false, AEK_NONE) +ARM_CPU_NAME("cortex-m1", AK_ARMV6M, FK_NONE, false, AEK_NONE) +ARM_CPU_NAME("sc000", AK_ARMV6M, FK_NONE, false, AEK_NONE) +ARM_CPU_NAME("cortex-a5", AK_ARMV7A, FK_NEON_VFPV4, false, (AEK_SEC | AEK_MP)) +ARM_CPU_NAME("cortex-a7", AK_ARMV7A, FK_NEON_VFPV4, false, + (AEK_SEC | AEK_MP | AEK_VIRT | AEK_HWDIVARM | AEK_HWDIV)) +ARM_CPU_NAME("cortex-a8", AK_ARMV7A, FK_NEON, true, AEK_SEC) +ARM_CPU_NAME("cortex-a9", AK_ARMV7A, FK_NEON_FP16, false, (AEK_SEC | AEK_MP)) +ARM_CPU_NAME("cortex-a12", AK_ARMV7A, FK_NEON_VFPV4, false, + (AEK_SEC | AEK_MP | AEK_VIRT | AEK_HWDIVARM | AEK_HWDIV)) +ARM_CPU_NAME("cortex-a15", AK_ARMV7A, FK_NEON_VFPV4, false, + (AEK_SEC | AEK_MP | AEK_VIRT | AEK_HWDIVARM | AEK_HWDIV)) +ARM_CPU_NAME("cortex-a17", AK_ARMV7A, FK_NEON_VFPV4, false, + (AEK_SEC | AEK_MP | AEK_VIRT | AEK_HWDIVARM | AEK_HWDIV)) +ARM_CPU_NAME("krait", AK_ARMV7A, FK_NEON_VFPV4, false, + (AEK_HWDIVARM | AEK_HWDIV)) +ARM_CPU_NAME("cortex-r4", AK_ARMV7R, FK_NONE, true, AEK_NONE) +ARM_CPU_NAME("cortex-r4f", AK_ARMV7R, FK_VFPV3_D16, false, AEK_NONE) +ARM_CPU_NAME("cortex-r5", AK_ARMV7R, FK_VFPV3_D16, false, + (AEK_MP | AEK_HWDIVARM)) +ARM_CPU_NAME("cortex-r7", AK_ARMV7R, FK_VFPV3_D16_FP16, false, + (AEK_MP | AEK_HWDIVARM)) +ARM_CPU_NAME("sc300", AK_ARMV7M, FK_NONE, false, AEK_NONE) +ARM_CPU_NAME("cortex-m3", AK_ARMV7M, FK_NONE, true, AEK_NONE) +ARM_CPU_NAME("cortex-m4", AK_ARMV7EM, FK_FPV4_SP_D16, true, AEK_NONE) +ARM_CPU_NAME("cortex-m7", AK_ARMV7EM, FK_FPV5_D16, false, AEK_NONE) +ARM_CPU_NAME("cortex-a35", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false, AEK_CRC) +ARM_CPU_NAME("cortex-a53", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, true, AEK_CRC) +ARM_CPU_NAME("cortex-a57", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false, AEK_CRC) +ARM_CPU_NAME("cortex-a72", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false, AEK_CRC) +ARM_CPU_NAME("cyclone", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false, AEK_CRC) +// Non-standard Arch names. +ARM_CPU_NAME("iwmmxt", AK_IWMMXT, FK_NONE, true, AEK_NONE) +ARM_CPU_NAME("xscale", AK_XSCALE, FK_NONE, true, AEK_NONE) +ARM_CPU_NAME("swift", AK_ARMV7S, FK_NEON_VFPV4, true, + (AEK_HWDIVARM | AEK_HWDIV)) +// Invalid CPU +ARM_CPU_NAME("invalid", AK_INVALID, FK_INVALID, true, AEK_INVALID) +#undef ARM_CPU_NAME diff --git a/contrib/llvm/include/llvm/Support/AlignOf.h b/contrib/llvm/include/llvm/Support/AlignOf.h index 07da02d..5268c8d 100644 --- a/contrib/llvm/include/llvm/Support/AlignOf.h +++ b/contrib/llvm/include/llvm/Support/AlignOf.h @@ -17,9 +17,15 @@ #include "llvm/Support/Compiler.h" #include <cstddef> +#include <type_traits> namespace llvm { -template <typename T> + +namespace detail { + +// For everything other than an abstract class we can calulate alignment by +// building a class with a single character and a member of the given type. +template <typename T, bool = std::is_abstract<T>::value> struct AlignmentCalcImpl { char x; #if defined(_MSC_VER) @@ -35,6 +41,25 @@ private: AlignmentCalcImpl() {} // Never instantiate. }; +// Abstract base class helper, this will have the minimal alignment and size +// for any abstract class. We don't even define its destructor because this +// type should never be used in a way that requires it. +struct AlignmentCalcImplBase { + virtual ~AlignmentCalcImplBase() = 0; +}; + +// When we have an abstract class type, specialize the alignment computation +// engine to create another abstract class that derives from both an empty +// abstract base class and the provided type. This has the same effect as the +// above except that it handles the fact that we can't actually create a member +// of type T. +template <typename T> +struct AlignmentCalcImpl<T, true> : AlignmentCalcImplBase, T { + virtual ~AlignmentCalcImpl() = 0; +}; + +} // End detail namespace. + /// AlignOf - A templated class that contains an enum value representing /// the alignment of the template argument. For example, /// AlignOf<int>::Alignment represents the alignment of type "int". The @@ -50,11 +75,13 @@ struct AlignOf { // llvm::AlignOf<Y>::<anonymous>' [-Wenum-compare] // by using constexpr instead of enum. // (except on MSVC, since it doesn't support constexpr yet). - static constexpr unsigned Alignment = - static_cast<unsigned int>(sizeof(AlignmentCalcImpl<T>) - sizeof(T)); + static constexpr unsigned Alignment = static_cast<unsigned int>( + sizeof(detail::AlignmentCalcImpl<T>) - sizeof(T)); #else - enum { Alignment = - static_cast<unsigned int>(sizeof(AlignmentCalcImpl<T>) - sizeof(T)) }; + enum { + Alignment = static_cast<unsigned int>(sizeof(detail::AlignmentCalcImpl<T>) - + sizeof(T)) + }; #endif enum { Alignment_GreaterEqual_2Bytes = Alignment >= 2 ? 1 : 0 }; enum { Alignment_GreaterEqual_4Bytes = Alignment >= 4 ? 1 : 0 }; diff --git a/contrib/llvm/include/llvm/Support/Allocator.h b/contrib/llvm/include/llvm/Support/Allocator.h index f9b5cf2..c608736 100644 --- a/contrib/llvm/include/llvm/Support/Allocator.h +++ b/contrib/llvm/include/llvm/Support/Allocator.h @@ -222,6 +222,8 @@ public: // Without this, MemorySanitizer messages for values originated from here // will point to the allocation of the entire slab. __msan_allocated_memory(AlignedPtr, Size); + // Similarly, tell ASan about this space. + __asan_unpoison_memory_region(AlignedPtr, Size); return AlignedPtr; } @@ -229,12 +231,16 @@ public: size_t PaddedSize = Size + Alignment - 1; if (PaddedSize > SizeThreshold) { void *NewSlab = Allocator.Allocate(PaddedSize, 0); + // We own the new slab and don't want anyone reading anyting other than + // pieces returned from this method. So poison the whole slab. + __asan_poison_memory_region(NewSlab, PaddedSize); CustomSizedSlabs.push_back(std::make_pair(NewSlab, PaddedSize)); uintptr_t AlignedAddr = alignAddr(NewSlab, Alignment); assert(AlignedAddr + Size <= (uintptr_t)NewSlab + PaddedSize); char *AlignedPtr = (char*)AlignedAddr; __msan_allocated_memory(AlignedPtr, Size); + __asan_unpoison_memory_region(AlignedPtr, Size); return AlignedPtr; } @@ -246,13 +252,16 @@ public: char *AlignedPtr = (char*)AlignedAddr; CurPtr = AlignedPtr + Size; __msan_allocated_memory(AlignedPtr, Size); + __asan_unpoison_memory_region(AlignedPtr, Size); return AlignedPtr; } // Pull in base class overloads. using AllocatorBase<BumpPtrAllocatorImpl>::Allocate; - void Deallocate(const void * /*Ptr*/, size_t /*Size*/) {} + void Deallocate(const void *Ptr, size_t Size) { + __asan_poison_memory_region(Ptr, Size); + } // Pull in base class overloads. using AllocatorBase<BumpPtrAllocatorImpl>::Deallocate; @@ -310,6 +319,10 @@ private: size_t AllocatedSlabSize = computeSlabSize(Slabs.size()); void *NewSlab = Allocator.Allocate(AllocatedSlabSize, 0); + // We own the new slab and don't want anyone reading anything other than + // pieces returned from this method. So poison the whole slab. + __asan_poison_memory_region(NewSlab, AllocatedSlabSize); + Slabs.push_back(NewSlab); CurPtr = (char *)(NewSlab); End = ((char *)NewSlab) + AllocatedSlabSize; diff --git a/contrib/llvm/include/llvm/Support/BlockFrequency.h b/contrib/llvm/include/llvm/Support/BlockFrequency.h index 4304a25..1b45cc5 100644 --- a/contrib/llvm/include/llvm/Support/BlockFrequency.h +++ b/contrib/llvm/include/llvm/Support/BlockFrequency.h @@ -14,12 +14,12 @@ #ifndef LLVM_SUPPORT_BLOCKFREQUENCY_H #define LLVM_SUPPORT_BLOCKFREQUENCY_H +#include "llvm/Support/BranchProbability.h" #include "llvm/Support/DataTypes.h" namespace llvm { class raw_ostream; -class BranchProbability; // This class represents Block Frequency as a 64-bit value. class BlockFrequency { @@ -37,34 +37,38 @@ public: /// \brief Multiplies with a branch probability. The computation will never /// overflow. - BlockFrequency &operator*=(const BranchProbability &Prob); - const BlockFrequency operator*(const BranchProbability &Prob) const; + BlockFrequency &operator*=(BranchProbability Prob); + BlockFrequency operator*(BranchProbability Prob) const; /// \brief Divide by a non-zero branch probability using saturating /// arithmetic. - BlockFrequency &operator/=(const BranchProbability &Prob); - BlockFrequency operator/(const BranchProbability &Prob) const; + BlockFrequency &operator/=(BranchProbability Prob); + BlockFrequency operator/(BranchProbability Prob) const; /// \brief Adds another block frequency using saturating arithmetic. - BlockFrequency &operator+=(const BlockFrequency &Freq); - const BlockFrequency operator+(const BlockFrequency &Freq) const; + BlockFrequency &operator+=(BlockFrequency Freq); + BlockFrequency operator+(BlockFrequency Freq) const; + + /// \brief Subtracts another block frequency using saturating arithmetic. + BlockFrequency &operator-=(BlockFrequency Freq); + BlockFrequency operator-(BlockFrequency Freq) const; /// \brief Shift block frequency to the right by count digits saturating to 1. BlockFrequency &operator>>=(const unsigned count); - bool operator<(const BlockFrequency &RHS) const { + bool operator<(BlockFrequency RHS) const { return Frequency < RHS.Frequency; } - bool operator<=(const BlockFrequency &RHS) const { + bool operator<=(BlockFrequency RHS) const { return Frequency <= RHS.Frequency; } - bool operator>(const BlockFrequency &RHS) const { + bool operator>(BlockFrequency RHS) const { return Frequency > RHS.Frequency; } - bool operator>=(const BlockFrequency &RHS) const { + bool operator>=(BlockFrequency RHS) const { return Frequency >= RHS.Frequency; } }; diff --git a/contrib/llvm/include/llvm/Support/BranchProbability.h b/contrib/llvm/include/llvm/Support/BranchProbability.h index a6429dd..26bc888 100644 --- a/contrib/llvm/include/llvm/Support/BranchProbability.h +++ b/contrib/llvm/include/llvm/Support/BranchProbability.h @@ -15,36 +15,59 @@ #define LLVM_SUPPORT_BRANCHPROBABILITY_H #include "llvm/Support/DataTypes.h" +#include <algorithm> #include <cassert> +#include <climits> +#include <numeric> namespace llvm { class raw_ostream; -// This class represents Branch Probability as a non-negative fraction. +// This class represents Branch Probability as a non-negative fraction that is +// no greater than 1. It uses a fixed-point-like implementation, in which the +// denominator is always a constant value (here we use 1<<31 for maximum +// precision). class BranchProbability { // Numerator uint32_t N; - // Denominator - uint32_t D; + // Denominator, which is a constant value. + static const uint32_t D = 1u << 31; + static const uint32_t UnknownN = UINT32_MAX; -public: - BranchProbability(uint32_t n, uint32_t d) : N(n), D(d) { - assert(d > 0 && "Denominator cannot be 0!"); - assert(n <= d && "Probability cannot be bigger than 1!"); - } + // Construct a BranchProbability with only numerator assuming the denominator + // is 1<<31. For internal use only. + explicit BranchProbability(uint32_t n) : N(n) {} - static BranchProbability getZero() { return BranchProbability(0, 1); } - static BranchProbability getOne() { return BranchProbability(1, 1); } +public: + BranchProbability() : N(UnknownN) {} + BranchProbability(uint32_t Numerator, uint32_t Denominator); + + bool isZero() const { return N == 0; } + bool isUnknown() const { return N == UnknownN; } + + static BranchProbability getZero() { return BranchProbability(0); } + static BranchProbability getOne() { return BranchProbability(D); } + static BranchProbability getUnknown() { return BranchProbability(UnknownN); } + // Create a BranchProbability object with the given numerator and 1<<31 + // as denominator. + static BranchProbability getRaw(uint32_t N) { return BranchProbability(N); } + // Create a BranchProbability object from 64-bit integers. + static BranchProbability getBranchProbability(uint64_t Numerator, + uint64_t Denominator); + + // Normalize given probabilties so that the sum of them becomes approximate + // one. + template <class ProbabilityIter> + static void normalizeProbabilities(ProbabilityIter Begin, + ProbabilityIter End); uint32_t getNumerator() const { return N; } - uint32_t getDenominator() const { return D; } + static uint32_t getDenominator() { return D; } // Return (1 - Probability). - BranchProbability getCompl() const { - return BranchProbability(D - N, D); - } + BranchProbability getCompl() const { return BranchProbability(D - N); } raw_ostream &print(raw_ostream &OS) const; @@ -66,24 +89,131 @@ public: /// \return \c Num divided by \c this. uint64_t scaleByInverse(uint64_t Num) const; - bool operator==(BranchProbability RHS) const { - return (uint64_t)N * RHS.D == (uint64_t)D * RHS.N; + BranchProbability &operator+=(BranchProbability RHS) { + assert(N != UnknownN && RHS.N != UnknownN && + "Unknown probability cannot participate in arithmetics."); + // Saturate the result in case of overflow. + N = (uint64_t(N) + RHS.N > D) ? D : N + RHS.N; + return *this; + } + + BranchProbability &operator-=(BranchProbability RHS) { + assert(N != UnknownN && RHS.N != UnknownN && + "Unknown probability cannot participate in arithmetics."); + // Saturate the result in case of underflow. + N = N < RHS.N ? 0 : N - RHS.N; + return *this; + } + + BranchProbability &operator*=(BranchProbability RHS) { + assert(N != UnknownN && RHS.N != UnknownN && + "Unknown probability cannot participate in arithmetics."); + N = (static_cast<uint64_t>(N) * RHS.N + D / 2) / D; + return *this; + } + + BranchProbability &operator/=(uint32_t RHS) { + assert(N != UnknownN && + "Unknown probability cannot participate in arithmetics."); + assert(RHS > 0 && "The divider cannot be zero."); + N /= RHS; + return *this; + } + + BranchProbability operator+(BranchProbability RHS) const { + BranchProbability Prob(*this); + return Prob += RHS; + } + + BranchProbability operator-(BranchProbability RHS) const { + BranchProbability Prob(*this); + return Prob -= RHS; + } + + BranchProbability operator*(BranchProbability RHS) const { + BranchProbability Prob(*this); + return Prob *= RHS; } - bool operator!=(BranchProbability RHS) const { - return !(*this == RHS); + + BranchProbability operator/(uint32_t RHS) const { + BranchProbability Prob(*this); + return Prob /= RHS; } + + bool operator==(BranchProbability RHS) const { return N == RHS.N; } + bool operator!=(BranchProbability RHS) const { return !(*this == RHS); } + bool operator<(BranchProbability RHS) const { - return (uint64_t)N * RHS.D < (uint64_t)D * RHS.N; + assert(N != UnknownN && RHS.N != UnknownN && + "Unknown probability cannot participate in comparisons."); + return N < RHS.N; + } + + bool operator>(BranchProbability RHS) const { + assert(N != UnknownN && RHS.N != UnknownN && + "Unknown probability cannot participate in comparisons."); + return RHS < *this; + } + + bool operator<=(BranchProbability RHS) const { + assert(N != UnknownN && RHS.N != UnknownN && + "Unknown probability cannot participate in comparisons."); + return !(RHS < *this); + } + + bool operator>=(BranchProbability RHS) const { + assert(N != UnknownN && RHS.N != UnknownN && + "Unknown probability cannot participate in comparisons."); + return !(*this < RHS); } - bool operator>(BranchProbability RHS) const { return RHS < *this; } - bool operator<=(BranchProbability RHS) const { return !(RHS < *this); } - bool operator>=(BranchProbability RHS) const { return !(*this < RHS); } }; -inline raw_ostream &operator<<(raw_ostream &OS, const BranchProbability &Prob) { +inline raw_ostream &operator<<(raw_ostream &OS, BranchProbability Prob) { return Prob.print(OS); } +template <class ProbabilityIter> +void BranchProbability::normalizeProbabilities(ProbabilityIter Begin, + ProbabilityIter End) { + if (Begin == End) + return; + + unsigned UnknownProbCount = 0; + uint64_t Sum = std::accumulate(Begin, End, uint64_t(0), + [&](uint64_t S, const BranchProbability &BP) { + if (!BP.isUnknown()) + return S + BP.N; + UnknownProbCount++; + return S; + }); + + if (UnknownProbCount > 0) { + BranchProbability ProbForUnknown = BranchProbability::getZero(); + // If the sum of all known probabilities is less than one, evenly distribute + // the complement of sum to unknown probabilities. Otherwise, set unknown + // probabilities to zeros and continue to normalize known probabilities. + if (Sum < BranchProbability::getDenominator()) + ProbForUnknown = BranchProbability::getRaw( + (BranchProbability::getDenominator() - Sum) / UnknownProbCount); + + std::replace_if(Begin, End, + [](const BranchProbability &BP) { return BP.isUnknown(); }, + ProbForUnknown); + + if (Sum <= BranchProbability::getDenominator()) + return; + } + + if (Sum == 0) { + BranchProbability BP(1, std::distance(Begin, End)); + std::fill(Begin, End, BP); + return; + } + + for (auto I = Begin; I != End; ++I) + I->N = (I->N * uint64_t(D) + Sum / 2) / Sum; +} + } #endif diff --git a/contrib/llvm/include/llvm/Support/CBindingWrapping.h b/contrib/llvm/include/llvm/Support/CBindingWrapping.h index 786ba18..d4633aa 100644 --- a/contrib/llvm/include/llvm/Support/CBindingWrapping.h +++ b/contrib/llvm/include/llvm/Support/CBindingWrapping.h @@ -15,6 +15,7 @@ #define LLVM_SUPPORT_CBINDINGWRAPPING_H #include "llvm/Support/Casting.h" +#include "llvm-c/Types.h" #define DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ty, ref) \ inline ty *unwrap(ref P) { \ diff --git a/contrib/llvm/include/llvm/Support/COFF.h b/contrib/llvm/include/llvm/Support/COFF.h index 3c5ee06..0162175 100644 --- a/contrib/llvm/include/llvm/Support/COFF.h +++ b/contrib/llvm/include/llvm/Support/COFF.h @@ -88,6 +88,7 @@ namespace COFF { IMAGE_FILE_MACHINE_AMD64 = 0x8664, IMAGE_FILE_MACHINE_ARM = 0x1C0, IMAGE_FILE_MACHINE_ARMNT = 0x1C4, + IMAGE_FILE_MACHINE_ARM64 = 0xAA64, IMAGE_FILE_MACHINE_EBC = 0xEBC, IMAGE_FILE_MACHINE_I386 = 0x14C, IMAGE_FILE_MACHINE_IA64 = 0x200, @@ -247,6 +248,7 @@ namespace COFF { enum SectionCharacteristics : uint32_t { SC_Invalid = 0xffffffff, + IMAGE_SCN_TYPE_NOLOAD = 0x00000002, IMAGE_SCN_TYPE_NO_PAD = 0x00000008, IMAGE_SCN_CNT_CODE = 0x00000020, IMAGE_SCN_CNT_INITIALIZED_DATA = 0x00000040, diff --git a/contrib/llvm/include/llvm/Support/CommandLine.h b/contrib/llvm/include/llvm/Support/CommandLine.h index 379d06a..943d2df 100644 --- a/contrib/llvm/include/llvm/Support/CommandLine.h +++ b/contrib/llvm/include/llvm/Support/CommandLine.h @@ -33,7 +33,6 @@ namespace llvm { -class BumpPtrStringSaver; class StringSaver; /// cl Namespace - This namespace contains all of the command line option @@ -206,9 +205,9 @@ class Option { unsigned AdditionalVals; // Greater than 0 for multi-valued option. public: - const char *ArgStr; // The argument string itself (ex: "help", "o") - const char *HelpStr; // The descriptive text message for -help - const char *ValueStr; // String describing what the value of this option is + StringRef ArgStr; // The argument string itself (ex: "help", "o") + StringRef HelpStr; // The descriptive text message for -help + StringRef ValueStr; // String describing what the value of this option is OptionCategory *Category; // The Category this option belongs to bool FullyInitialized; // Has addArguemnt been called? @@ -229,14 +228,14 @@ public: inline unsigned getNumAdditionalVals() const { return AdditionalVals; } // hasArgStr - Return true if the argstr != "" - bool hasArgStr() const { return ArgStr[0] != 0; } + bool hasArgStr() const { return !ArgStr.empty(); } //-------------------------------------------------------------------------=== // Accessor functions set by OptionModifiers // - void setArgStr(const char *S); - void setDescription(const char *S) { HelpStr = S; } - void setValueStr(const char *S) { ValueStr = S; } + void setArgStr(StringRef S); + void setDescription(StringRef S) { HelpStr = S; } + void setValueStr(StringRef S) { ValueStr = S; } void setNumOccurrencesFlag(enum NumOccurrencesFlag Val) { Occurrences = Val; } void setValueExpectedFlag(enum ValueExpected Val) { Value = Val; } void setHiddenFlag(enum OptionHidden Val) { HiddenFlag = Val; } @@ -276,7 +275,7 @@ public: virtual void printOptionValue(size_t GlobalWidth, bool Force) const = 0; - virtual void getExtraOptionNames(SmallVectorImpl<const char *> &) {} + virtual void getExtraOptionNames(SmallVectorImpl<StringRef> &) {} // addOccurrence - Wrapper around handleOccurrence that enforces Flags. // @@ -606,7 +605,7 @@ public: void initialize() {} - void getExtraOptionNames(SmallVectorImpl<const char *> &OptionNames) { + void getExtraOptionNames(SmallVectorImpl<StringRef> &OptionNames) { // If there has been no argstr specified, that means that we need to add an // argument for every possible option. This ensures that our options are // vectored to us. @@ -715,14 +714,14 @@ public: // class basic_parser_impl { // non-template implementation of basic_parser<t> public: - basic_parser_impl(Option &O) {} + basic_parser_impl(Option &) {} enum ValueExpected getValueExpectedFlagDefault() const { return ValueRequired; } - void getExtraOptionNames(SmallVectorImpl<const char *> &) {} + void getExtraOptionNames(SmallVectorImpl<StringRef> &) {} void initialize() {} @@ -1206,8 +1205,7 @@ class opt : public Option, enum ValueExpected getValueExpectedFlagDefault() const override { return Parser.getValueExpectedFlagDefault(); } - void - getExtraOptionNames(SmallVectorImpl<const char *> &OptionNames) override { + void getExtraOptionNames(SmallVectorImpl<StringRef> &OptionNames) override { return Parser.getExtraOptionNames(OptionNames); } @@ -1368,8 +1366,7 @@ class list : public Option, public list_storage<DataType, StorageClass> { enum ValueExpected getValueExpectedFlagDefault() const override { return Parser.getValueExpectedFlagDefault(); } - void - getExtraOptionNames(SmallVectorImpl<const char *> &OptionNames) override { + void getExtraOptionNames(SmallVectorImpl<StringRef> &OptionNames) override { return Parser.getExtraOptionNames(OptionNames); } @@ -1508,8 +1505,7 @@ class bits : public Option, public bits_storage<DataType, Storage> { enum ValueExpected getValueExpectedFlagDefault() const override { return Parser.getValueExpectedFlagDefault(); } - void - getExtraOptionNames(SmallVectorImpl<const char *> &OptionNames) override { + void getExtraOptionNames(SmallVectorImpl<StringRef> &OptionNames) override { return Parser.getExtraOptionNames(OptionNames); } diff --git a/contrib/llvm/include/llvm/Support/Compiler.h b/contrib/llvm/include/llvm/Support/Compiler.h index 1416398..b3416bb 100644 --- a/contrib/llvm/include/llvm/Support/Compiler.h +++ b/contrib/llvm/include/llvm/Support/Compiler.h @@ -69,7 +69,7 @@ #if !defined(_MSC_VER) || defined(__clang__) || LLVM_MSC_PREREQ(1900) #define LLVM_NOEXCEPT noexcept #else -#define LLVM_NOEXCEPT +#define LLVM_NOEXCEPT throw() #endif /// \brief Does the compiler support ref-qualifiers for *this? @@ -189,7 +189,7 @@ /// 3.4 supported this but is buggy in various cases and produces unimplemented /// errors, just use it in GCC 4.0 and later. #if __has_attribute(always_inline) || LLVM_GNUC_PREREQ(4, 0, 0) -#define LLVM_ATTRIBUTE_ALWAYS_INLINE inline __attribute__((always_inline)) +#define LLVM_ATTRIBUTE_ALWAYS_INLINE __attribute__((always_inline)) #elif defined(_MSC_VER) #define LLVM_ATTRIBUTE_ALWAYS_INLINE __forceinline #else @@ -293,6 +293,34 @@ # define LLVM_ALIGNAS(x) alignas(x) #endif +/// \macro LLVM_PACKED +/// \brief Used to specify a packed structure. +/// LLVM_PACKED( +/// struct A { +/// int i; +/// int j; +/// int k; +/// long long l; +/// }); +/// +/// LLVM_PACKED_START +/// struct B { +/// int i; +/// int j; +/// int k; +/// long long l; +/// }; +/// LLVM_PACKED_END +#ifdef _MSC_VER +# define LLVM_PACKED(d) __pragma(pack(push, 1)) d __pragma(pack(pop)) +# define LLVM_PACKED_START __pragma(pack(push, 1)) +# define LLVM_PACKED_END __pragma(pack(pop)) +#else +# define LLVM_PACKED(d) d __attribute__((packed)) +# define LLVM_PACKED_START _Pragma("pack(push, 1)") +# define LLVM_PACKED_END _Pragma("pack(pop)") +#endif + /// \macro LLVM_PTR_SIZE /// \brief A constant integer equivalent to the value of sizeof(void*). /// Generally used in combination with LLVM_ALIGNAS or when doing computation in @@ -333,8 +361,50 @@ /// \brief Whether LLVM itself is built with AddressSanitizer instrumentation. #if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__) # define LLVM_ADDRESS_SANITIZER_BUILD 1 +# include <sanitizer/asan_interface.h> #else # define LLVM_ADDRESS_SANITIZER_BUILD 0 +# define __asan_poison_memory_region(p, size) +# define __asan_unpoison_memory_region(p, size) +#endif + +/// \macro LLVM_THREAD_SANITIZER_BUILD +/// \brief Whether LLVM itself is built with ThreadSanitizer instrumentation. +#if __has_feature(thread_sanitizer) || defined(__SANITIZE_THREAD__) +# define LLVM_THREAD_SANITIZER_BUILD 1 +#else +# define LLVM_THREAD_SANITIZER_BUILD 0 +#endif + +#if LLVM_THREAD_SANITIZER_BUILD +// Thread Sanitizer is a tool that finds races in code. +// See http://code.google.com/p/data-race-test/wiki/DynamicAnnotations . +// tsan detects these exact functions by name. +extern "C" { +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); +} + +// This marker is used to define a happens-before arc. The race detector will +// infer an arc from the begin to the end when they share the same pointer +// argument. +# define TsanHappensBefore(cv) AnnotateHappensBefore(__FILE__, __LINE__, cv) + +// This marker defines the destination of a happens-before arc. +# define TsanHappensAfter(cv) AnnotateHappensAfter(__FILE__, __LINE__, cv) + +// Ignore any races on writes between here and the next TsanIgnoreWritesEnd. +# define TsanIgnoreWritesBegin() AnnotateIgnoreWritesBegin(__FILE__, __LINE__) + +// Resume checking for racy writes. +# define TsanIgnoreWritesEnd() AnnotateIgnoreWritesEnd(__FILE__, __LINE__) +#else +# define TsanHappensBefore(cv) +# define TsanHappensAfter(cv) +# define TsanIgnoreWritesBegin() +# define TsanIgnoreWritesEnd() #endif /// \brief Mark debug helper function definitions like dump() that should not be diff --git a/contrib/llvm/include/llvm/Support/CrashRecoveryContext.h b/contrib/llvm/include/llvm/Support/CrashRecoveryContext.h index c08c3c1..1a1c743 100644 --- a/contrib/llvm/include/llvm/Support/CrashRecoveryContext.h +++ b/contrib/llvm/include/llvm/Support/CrashRecoveryContext.h @@ -39,8 +39,6 @@ class CrashRecoveryContextCleanup; /// /// ... no crash was detected ... /// } -/// -/// Crash recovery contexts may not be nested. class CrashRecoveryContext { void *Impl; CrashRecoveryContextCleanup *head; @@ -109,10 +107,11 @@ class CrashRecoveryContextCleanup { protected: CrashRecoveryContext *context; CrashRecoveryContextCleanup(CrashRecoveryContext *context) - : context(context), cleanupFired(false) {} + : context(context), cleanupFired(false) {} + public: bool cleanupFired; - + virtual ~CrashRecoveryContextCleanup(); virtual void recoverResources() = 0; @@ -129,15 +128,16 @@ template<typename DERIVED, typename T> class CrashRecoveryContextCleanupBase : public CrashRecoveryContextCleanup { protected: T *resource; - CrashRecoveryContextCleanupBase(CrashRecoveryContext *context, T* resource) - : CrashRecoveryContextCleanup(context), resource(resource) {} + CrashRecoveryContextCleanupBase(CrashRecoveryContext *context, T *resource) + : CrashRecoveryContextCleanup(context), resource(resource) {} + public: static DERIVED *create(T *x) { if (x) { if (CrashRecoveryContext *context = CrashRecoveryContext::GetCurrent()) return new DERIVED(context, x); } - return 0; + return nullptr; } }; @@ -146,9 +146,9 @@ class CrashRecoveryContextDestructorCleanup : public CrashRecoveryContextCleanupBase<CrashRecoveryContextDestructorCleanup<T>, T> { public: CrashRecoveryContextDestructorCleanup(CrashRecoveryContext *context, - T *resource) - : CrashRecoveryContextCleanupBase< - CrashRecoveryContextDestructorCleanup<T>, T>(context, resource) {} + T *resource) + : CrashRecoveryContextCleanupBase< + CrashRecoveryContextDestructorCleanup<T>, T>(context, resource) {} virtual void recoverResources() { this->resource->~T(); @@ -171,7 +171,7 @@ class CrashRecoveryContextReleaseRefCleanup : public CrashRecoveryContextCleanupBase<CrashRecoveryContextReleaseRefCleanup<T>, T> { public: - CrashRecoveryContextReleaseRefCleanup(CrashRecoveryContext *context, + CrashRecoveryContextReleaseRefCleanup(CrashRecoveryContext *context, T *resource) : CrashRecoveryContextCleanupBase<CrashRecoveryContextReleaseRefCleanup<T>, T>(context, resource) {} @@ -182,6 +182,7 @@ public: template <typename T, typename Cleanup = CrashRecoveryContextDeleteCleanup<T> > class CrashRecoveryContextCleanupRegistrar { CrashRecoveryContextCleanup *cleanup; + public: CrashRecoveryContextCleanupRegistrar(T *x) : cleanup(Cleanup::create(x)) { @@ -189,16 +190,14 @@ public: cleanup->getContext()->registerCleanup(cleanup); } - ~CrashRecoveryContextCleanupRegistrar() { - unregister(); - } - + ~CrashRecoveryContextCleanupRegistrar() { unregister(); } + void unregister() { if (cleanup && !cleanup->cleanupFired) cleanup->getContext()->unregisterCleanup(cleanup); - cleanup = 0; + cleanup = nullptr; } }; -} +} // end namespace llvm -#endif +#endif // LLVM_SUPPORT_CRASHRECOVERYCONTEXT_H diff --git a/contrib/llvm/include/llvm/Support/DOTGraphTraits.h b/contrib/llvm/include/llvm/Support/DOTGraphTraits.h index 95e37c0..4381b5b 100644 --- a/contrib/llvm/include/llvm/Support/DOTGraphTraits.h +++ b/contrib/llvm/include/llvm/Support/DOTGraphTraits.h @@ -72,11 +72,12 @@ public: return ""; } - /// hasNodeAddressLabel - If this method returns true, the address of the node - /// is added to the label of the node. - template<typename GraphType> - static bool hasNodeAddressLabel(const void *, const GraphType &) { - return false; + // getNodeIdentifierLabel - Returns a string representing the + // address or other unique identifier of the node. (Only used if + // non-empty.) + template <typename GraphType> + static std::string getNodeIdentifierLabel(const void *, const GraphType &) { + return ""; } template<typename GraphType> diff --git a/contrib/llvm/include/llvm/Support/Debug.h b/contrib/llvm/include/llvm/Support/Debug.h index fff4f98..6e21347 100644 --- a/contrib/llvm/include/llvm/Support/Debug.h +++ b/contrib/llvm/include/llvm/Support/Debug.h @@ -13,7 +13,7 @@ // // In particular, just wrap your code with the DEBUG() macro, and it will be // enabled automatically if you specify '-debug' on the command-line. -// Alternatively, you can also define the DEBUG_TYPE macro to "foo" specify +// DEBUG() requires the DEBUG_TYPE macro to be defined. Set it to "foo" specify // that your debug code belongs to class "foo". Be careful that you only do // this after including Debug.h and not around any #include of headers. Headers // should define and undef the macro acround the code that needs to use the diff --git a/contrib/llvm/include/llvm/Support/Dwarf.def b/contrib/llvm/include/llvm/Support/Dwarf.def index 4b923b8..b15070b 100644 --- a/contrib/llvm/include/llvm/Support/Dwarf.def +++ b/contrib/llvm/include/llvm/Support/Dwarf.def @@ -99,10 +99,6 @@ HANDLE_DW_TAG(0x0041, type_unit) HANDLE_DW_TAG(0x0042, rvalue_reference_type) HANDLE_DW_TAG(0x0043, template_alias) -// Mock tags we use as discriminators. -HANDLE_DW_TAG(0x0100, auto_variable) // Tag for local (auto) variables. -HANDLE_DW_TAG(0x0101, arg_variable) // Tag for argument variables. - // New in DWARF v5. HANDLE_DW_TAG(0x0044, coarray_type) HANDLE_DW_TAG(0x0045, generic_subrange) @@ -117,6 +113,11 @@ HANDLE_DW_TAG(0x4106, GNU_template_template_param) HANDLE_DW_TAG(0x4107, GNU_template_parameter_pack) HANDLE_DW_TAG(0x4108, GNU_formal_parameter_pack) HANDLE_DW_TAG(0x4200, APPLE_property) +HANDLE_DW_TAG(0xb000, BORLAND_property) +HANDLE_DW_TAG(0xb001, BORLAND_Delphi_string) +HANDLE_DW_TAG(0xb002, BORLAND_Delphi_dynamic_array) +HANDLE_DW_TAG(0xb003, BORLAND_Delphi_set) +HANDLE_DW_TAG(0xb004, BORLAND_Delphi_variant) HANDLE_DW_OP(0x03, addr) HANDLE_DW_OP(0x06, deref) @@ -319,6 +320,7 @@ HANDLE_DW_LANG(0x0021, C_plus_plus_14) HANDLE_DW_LANG(0x0022, Fortran03) HANDLE_DW_LANG(0x0023, Fortran08) HANDLE_DW_LANG(0x8001, Mips_Assembler) +HANDLE_DW_LANG(0xb000, BORLAND_Delphi) // DWARF attribute type encodings. HANDLE_DW_ATE(0x01, address) diff --git a/contrib/llvm/include/llvm/Support/Dwarf.h b/contrib/llvm/include/llvm/Support/Dwarf.h index 17e9c15..cea61bd 100644 --- a/contrib/llvm/include/llvm/Support/Dwarf.h +++ b/contrib/llvm/include/llvm/Support/Dwarf.h @@ -40,6 +40,7 @@ enum LLVMConstants : uint32_t { // LLVM mock tags (see also llvm/Support/Dwarf.def). DW_TAG_invalid = ~0U, // Tag for invalid results. DW_VIRTUALITY_invalid = ~0U, // Virtuality for invalid results. + DW_MACINFO_invalid = ~0U, // Macinfo type for invalid results. // Other constants. DWARF_VERSION = 4, // Default dwarf version we output. @@ -195,6 +196,7 @@ enum Attribute : uint16_t { DW_AT_dwo_name = 0x76, DW_AT_reference = 0x77, DW_AT_rvalue_reference = 0x78, + DW_AT_macros = 0x79, DW_AT_lo_user = 0x2000, DW_AT_hi_user = 0x3fff, @@ -230,6 +232,7 @@ enum Attribute : uint16_t { DW_AT_GNU_template_name = 0x2110, DW_AT_GNU_odr_signature = 0x210f, + DW_AT_GNU_macros = 0x2119, // Extensions for Fission proposal. DW_AT_GNU_dwo_name = 0x2130, @@ -238,6 +241,26 @@ enum Attribute : uint16_t { DW_AT_GNU_addr_base = 0x2133, DW_AT_GNU_pubnames = 0x2134, DW_AT_GNU_pubtypes = 0x2135, + DW_AT_GNU_discriminator = 0x2136, + + // Borland extensions. + DW_AT_BORLAND_property_read = 0x3b11, + DW_AT_BORLAND_property_write = 0x3b12, + DW_AT_BORLAND_property_implements = 0x3b13, + DW_AT_BORLAND_property_index = 0x3b14, + DW_AT_BORLAND_property_default = 0x3b15, + DW_AT_BORLAND_Delphi_unit = 0x3b20, + DW_AT_BORLAND_Delphi_class = 0x3b21, + DW_AT_BORLAND_Delphi_record = 0x3b22, + DW_AT_BORLAND_Delphi_metaclass = 0x3b23, + DW_AT_BORLAND_Delphi_constructor = 0x3b24, + DW_AT_BORLAND_Delphi_destructor = 0x3b25, + DW_AT_BORLAND_Delphi_anonymous_method = 0x3b26, + DW_AT_BORLAND_Delphi_interface = 0x3b27, + DW_AT_BORLAND_Delphi_ABI = 0x3b28, + DW_AT_BORLAND_Delphi_return = 0x3b29, + DW_AT_BORLAND_Delphi_frameptr = 0x3b30, + DW_AT_BORLAND_closure = 0x3b31, // LLVM project extensions. DW_AT_LLVM_include_path = 0x3e00, @@ -370,6 +393,14 @@ enum CallingConvention { DW_CC_program = 0x02, DW_CC_nocall = 0x03, DW_CC_lo_user = 0x40, + DW_CC_GNU_borland_fastcall_i386 = 0x41, + DW_CC_BORLAND_safecall = 0xb0, + DW_CC_BORLAND_stdcall = 0xb1, + DW_CC_BORLAND_pascal = 0xb2, + DW_CC_BORLAND_msfastcall = 0xb3, + DW_CC_BORLAND_msreturn = 0xb4, + DW_CC_BORLAND_thiscall = 0xb5, + DW_CC_BORLAND_fastcall = 0xb6, DW_CC_hi_user = 0xff }; @@ -429,6 +460,24 @@ enum MacinfoRecordType { DW_MACINFO_vendor_ext = 0xff }; +enum MacroEntryType { + // Macro Information Entry Type Encodings + DW_MACRO_define = 0x01, + DW_MACRO_undef = 0x02, + DW_MACRO_start_file = 0x03, + DW_MACRO_end_file = 0x04, + DW_MACRO_define_indirect = 0x05, + DW_MACRO_undef_indirect = 0x06, + DW_MACRO_transparent_include = 0x07, + DW_MACRO_define_indirect_sup = 0x08, + DW_MACRO_undef_indirect_sup = 0x09, + DW_MACRO_transparent_include_sup = 0x0a, + DW_MACRO_define_indirectx = 0x0b, + DW_MACRO_undef_indirectx = 0x0c, + DW_MACRO_lo_user = 0xe0, + DW_MACRO_hi_user = 0xff +}; + enum CallFrameInfo { // Call frame instruction encodings DW_CFA_extended = 0x00, @@ -596,6 +645,7 @@ const char *GDBIndexEntryLinkageString(GDBIndexEntryLinkage Linkage); /// /// \li \a getTag() returns \a DW_TAG_invalid on invalid input. /// \li \a getVirtuality() returns \a DW_VIRTUALITY_invalid on invalid input. +/// \li \a getMacinfo() returns \a DW_MACINFO_invalid on invalid input. /// /// @{ unsigned getTag(StringRef TagString); @@ -603,6 +653,7 @@ unsigned getOperationEncoding(StringRef OperationEncodingString); unsigned getVirtuality(StringRef VirtualityString); unsigned getLanguage(StringRef LanguageString); unsigned getAttributeEncoding(StringRef EncodingString); +unsigned getMacinfo(StringRef MacinfoString); /// @} /// \brief Returns the symbolic string representing Val when used as a value @@ -610,7 +661,7 @@ unsigned getAttributeEncoding(StringRef EncodingString); const char *AttributeValueString(uint16_t Attr, unsigned Val); /// \brief Decsribes an entry of the various gnu_pub* debug sections. -/// +/// /// The gnu_pub* kind looks like: /// /// 0-3 reserved @@ -642,7 +693,6 @@ private: }; }; - } // End of namespace dwarf } // End of namespace llvm diff --git a/contrib/llvm/include/llvm/Support/ELF.h b/contrib/llvm/include/llvm/Support/ELF.h index 94a4bfb..97708a7 100644 --- a/contrib/llvm/include/llvm/Support/ELF.h +++ b/contrib/llvm/include/llvm/Support/ELF.h @@ -429,6 +429,33 @@ enum { #include "ELFRelocs/ARM.def" }; +// AVR specific e_flags +enum : unsigned { + EF_AVR_ARCH_AVR1 = 1, + EF_AVR_ARCH_AVR2 = 2, + EF_AVR_ARCH_AVR25 = 25, + EF_AVR_ARCH_AVR3 = 3, + EF_AVR_ARCH_AVR31 = 31, + EF_AVR_ARCH_AVR35 = 35, + EF_AVR_ARCH_AVR4 = 4, + EF_AVR_ARCH_AVR5 = 5, + EF_AVR_ARCH_AVR51 = 51, + EF_AVR_ARCH_AVR6 = 6, + EF_AVR_ARCH_AVRTINY = 100, + EF_AVR_ARCH_XMEGA1 = 101, + EF_AVR_ARCH_XMEGA2 = 102, + EF_AVR_ARCH_XMEGA3 = 103, + EF_AVR_ARCH_XMEGA4 = 104, + EF_AVR_ARCH_XMEGA5 = 105, + EF_AVR_ARCH_XMEGA6 = 106, + EF_AVR_ARCH_XMEGA7 = 107 +}; + +// ELF Relocation types for AVR +enum { +#include "ELFRelocs/AVR.def" +}; + // Mips Specific e_flags enum : unsigned { EF_MIPS_NOREORDER = 0x00000001, // Don't reorder instructions @@ -522,26 +549,28 @@ enum { ODK_PAGESIZE = 11 // Page size information }; -// Hexagon Specific e_flags -// Release 5 ABI +// Hexagon-specific e_flags enum { - // Object processor version flags, bits[3:0] + // Object processor version flags, bits[11:0] EF_HEXAGON_MACH_V2 = 0x00000001, // Hexagon V2 EF_HEXAGON_MACH_V3 = 0x00000002, // Hexagon V3 EF_HEXAGON_MACH_V4 = 0x00000003, // Hexagon V4 EF_HEXAGON_MACH_V5 = 0x00000004, // Hexagon V5 + EF_HEXAGON_MACH_V55 = 0x00000005, // Hexagon V55 + EF_HEXAGON_MACH_V60 = 0x00000060, // Hexagon V60 // Highest ISA version flags - EF_HEXAGON_ISA_MACH = 0x00000000, // Same as specified in bits[3:0] + EF_HEXAGON_ISA_MACH = 0x00000000, // Same as specified in bits[11:0] // of e_flags EF_HEXAGON_ISA_V2 = 0x00000010, // Hexagon V2 ISA EF_HEXAGON_ISA_V3 = 0x00000020, // Hexagon V3 ISA EF_HEXAGON_ISA_V4 = 0x00000030, // Hexagon V4 ISA - EF_HEXAGON_ISA_V5 = 0x00000040 // Hexagon V5 ISA + EF_HEXAGON_ISA_V5 = 0x00000040, // Hexagon V5 ISA + EF_HEXAGON_ISA_V55 = 0x00000050, // Hexagon V55 ISA + EF_HEXAGON_ISA_V60 = 0x00000060, // Hexagon V60 ISA }; -// Hexagon specific Section indexes for common small data -// Release 5 ABI +// Hexagon-specific section indexes for common small data enum { SHN_HEXAGON_SCOMMON = 0xff00, // Other access sizes SHN_HEXAGON_SCOMMON_1 = 0xff01, // Byte-sized access @@ -747,7 +776,12 @@ enum : unsigned { SHF_MIPS_ADDR = 0x40000000, // Section data is string data by default. - SHF_MIPS_STRING = 0x80000000 + SHF_MIPS_STRING = 0x80000000, + + SHF_AMDGPU_HSA_GLOBAL = 0x00100000, + SHF_AMDGPU_HSA_READONLY = 0x00200000, + SHF_AMDGPU_HSA_CODE = 0x00400000, + SHF_AMDGPU_HSA_AGENT = 0x00800000 }; // Section Group Flags @@ -828,7 +862,12 @@ enum { STT_LOOS = 10, // Lowest operating system-specific symbol type STT_HIOS = 12, // Highest operating system-specific symbol type STT_LOPROC = 13, // Lowest processor-specific symbol type - STT_HIPROC = 15 // Highest processor-specific symbol type + STT_HIPROC = 15, // Highest processor-specific symbol type + + // AMDGPU symbol types + STT_AMDGPU_HSA_KERNEL = 10, + STT_AMDGPU_HSA_INDIRECT_FUNCTION = 11, + STT_AMDGPU_HSA_METADATA = 12 }; enum { @@ -979,7 +1018,13 @@ enum { PT_MIPS_REGINFO = 0x70000000, // Register usage information. PT_MIPS_RTPROC = 0x70000001, // Runtime procedure table. PT_MIPS_OPTIONS = 0x70000002, // Options segment. - PT_MIPS_ABIFLAGS = 0x70000003 // Abiflags segment. + PT_MIPS_ABIFLAGS = 0x70000003, // Abiflags segment. + + // AMDGPU program header types. + PT_AMDGPU_HSA_LOAD_GLOBAL_PROGRAM = 0x60000000, + PT_AMDGPU_HSA_LOAD_GLOBAL_AGENT = 0x60000001, + PT_AMDGPU_HSA_LOAD_READONLY_AGENT = 0x60000002, + PT_AMDGPU_HSA_LOAD_CODE_AGENT = 0x60000003 }; // Segment flag bits. @@ -1139,8 +1184,10 @@ enum { DT_MIPS_GP_VALUE = 0x70000030, // GP value for auxiliary GOTs. DT_MIPS_AUX_DYNAMIC = 0x70000031, // Address of auxiliary .dynamic. DT_MIPS_PLTGOT = 0x70000032, // Address of the base of the PLTGOT. - DT_MIPS_RWPLT = 0x70000034 // Points to the base + DT_MIPS_RWPLT = 0x70000034, // Points to the base // of a writable PLT. + DT_MIPS_RLD_MAP_REL = 0x70000035 // Relative offset of run time loader + // map, used for debugging. }; // DT_FLAGS values. diff --git a/contrib/llvm/include/llvm/Support/ELFRelocs/AVR.def b/contrib/llvm/include/llvm/Support/ELFRelocs/AVR.def new file mode 100644 index 0000000..5692d6c --- /dev/null +++ b/contrib/llvm/include/llvm/Support/ELFRelocs/AVR.def @@ -0,0 +1,40 @@ + +#ifndef ELF_RELOC +#error "ELF_RELOC must be defined" +#endif + +ELF_RELOC(R_AVR_NONE, 0) +ELF_RELOC(R_AVR_32, 1) +ELF_RELOC(R_AVR_7_PCREL, 2) +ELF_RELOC(R_AVR_13_PCREL, 3) +ELF_RELOC(R_AVR_16, 4) +ELF_RELOC(R_AVR_16_PM, 5) +ELF_RELOC(R_AVR_LO8_LDI, 6) +ELF_RELOC(R_AVR_HI8_LDI, 7) +ELF_RELOC(R_AVR_HH8_LDI, 8) +ELF_RELOC(R_AVR_LO8_LDI_NEG, 9) +ELF_RELOC(R_AVR_HI8_LDI_NEG, 10) +ELF_RELOC(R_AVR_HH8_LDI_NEG, 11) +ELF_RELOC(R_AVR_LO8_LDI_PM, 12) +ELF_RELOC(R_AVR_HI8_LDI_PM, 13) +ELF_RELOC(R_AVR_HH8_LDI_PM, 14) +ELF_RELOC(R_AVR_LO8_LDI_PM_NEG, 15) +ELF_RELOC(R_AVR_HI8_LDI_PM_NEG, 16) +ELF_RELOC(R_AVR_HH8_LDI_PM_NEG, 17) +ELF_RELOC(R_AVR_CALL, 18) +ELF_RELOC(R_AVR_LDI, 19) +ELF_RELOC(R_AVR_6, 20) +ELF_RELOC(R_AVR_6_ADIW, 21) +ELF_RELOC(R_AVR_MS8_LDI, 22) +ELF_RELOC(R_AVR_MS8_LDI_NEG, 23) +ELF_RELOC(R_AVR_LO8_LDI_GS, 24) +ELF_RELOC(R_AVR_HI8_LDI_GS, 25) +ELF_RELOC(R_AVR_8, 26) +ELF_RELOC(R_AVR_8_LO8, 27) +ELF_RELOC(R_AVR_8_HI8, 28) +ELF_RELOC(R_AVR_8_HLO8, 29) +ELF_RELOC(R_AVR_SYM_DIFF, 30) +ELF_RELOC(R_AVR_16_LDST, 31) +ELF_RELOC(R_AVR_LDS_STS_16, 33) +ELF_RELOC(R_AVR_PORT6, 34) +ELF_RELOC(R_AVR_PORT5, 35) diff --git a/contrib/llvm/include/llvm/Support/ELFRelocs/PowerPC.def b/contrib/llvm/include/llvm/Support/ELFRelocs/PowerPC.def index b6c3941..e4f8ee0 100644 --- a/contrib/llvm/include/llvm/Support/ELFRelocs/PowerPC.def +++ b/contrib/llvm/include/llvm/Support/ELFRelocs/PowerPC.def @@ -3,6 +3,68 @@ #error "ELF_RELOC must be defined" #endif +// glibc's PowerPC asm/sigcontext.h, when compiling for PPC64, has the +// unfortunate behavior of including asm/elf.h, which defines R_PPC_NONE, etc. +// to their corresponding integer values. As a result, we need to undef them +// here before continuing. + +#undef R_PPC_NONE +#undef R_PPC_ADDR32 +#undef R_PPC_ADDR24 +#undef R_PPC_ADDR16 +#undef R_PPC_ADDR16_LO +#undef R_PPC_ADDR16_HI +#undef R_PPC_ADDR16_HA +#undef R_PPC_ADDR14 +#undef R_PPC_ADDR14_BRTAKEN +#undef R_PPC_ADDR14_BRNTAKEN +#undef R_PPC_REL24 +#undef R_PPC_REL14 +#undef R_PPC_REL14_BRTAKEN +#undef R_PPC_REL14_BRNTAKEN +#undef R_PPC_GOT16 +#undef R_PPC_GOT16_LO +#undef R_PPC_GOT16_HI +#undef R_PPC_GOT16_HA +#undef R_PPC_PLTREL24 +#undef R_PPC_JMP_SLOT +#undef R_PPC_LOCAL24PC +#undef R_PPC_REL32 +#undef R_PPC_TLS +#undef R_PPC_DTPMOD32 +#undef R_PPC_TPREL16 +#undef R_PPC_TPREL16_LO +#undef R_PPC_TPREL16_HI +#undef R_PPC_TPREL16_HA +#undef R_PPC_TPREL32 +#undef R_PPC_DTPREL16 +#undef R_PPC_DTPREL16_LO +#undef R_PPC_DTPREL16_HI +#undef R_PPC_DTPREL16_HA +#undef R_PPC_DTPREL32 +#undef R_PPC_GOT_TLSGD16 +#undef R_PPC_GOT_TLSGD16_LO +#undef R_PPC_GOT_TLSGD16_HI +#undef R_PPC_GOT_TLSGD16_HA +#undef R_PPC_GOT_TLSLD16 +#undef R_PPC_GOT_TLSLD16_LO +#undef R_PPC_GOT_TLSLD16_HI +#undef R_PPC_GOT_TLSLD16_HA +#undef R_PPC_GOT_TPREL16 +#undef R_PPC_GOT_TPREL16_LO +#undef R_PPC_GOT_TPREL16_HI +#undef R_PPC_GOT_TPREL16_HA +#undef R_PPC_GOT_DTPREL16 +#undef R_PPC_GOT_DTPREL16_LO +#undef R_PPC_GOT_DTPREL16_HI +#undef R_PPC_GOT_DTPREL16_HA +#undef R_PPC_TLSGD +#undef R_PPC_TLSLD +#undef R_PPC_REL16 +#undef R_PPC_REL16_LO +#undef R_PPC_REL16_HI +#undef R_PPC_REL16_HA + ELF_RELOC(R_PPC_NONE, 0) /* No relocation. */ ELF_RELOC(R_PPC_ADDR32, 1) ELF_RELOC(R_PPC_ADDR24, 2) diff --git a/contrib/llvm/include/llvm/Support/ELFRelocs/PowerPC64.def b/contrib/llvm/include/llvm/Support/ELFRelocs/PowerPC64.def index 7b2a3cb..3a47c5a 100644 --- a/contrib/llvm/include/llvm/Support/ELFRelocs/PowerPC64.def +++ b/contrib/llvm/include/llvm/Support/ELFRelocs/PowerPC64.def @@ -3,6 +3,97 @@ #error "ELF_RELOC must be defined" #endif +// glibc's PowerPC asm/sigcontext.h, when compiling for PPC64, has the +// unfortunate behavior of including asm/elf.h, which defines R_PPC_NONE, etc. +// to their corresponding integer values. As a result, we need to undef them +// here before continuing. + +#undef R_PPC64_NONE +#undef R_PPC64_ADDR32 +#undef R_PPC64_ADDR24 +#undef R_PPC64_ADDR16 +#undef R_PPC64_ADDR16_LO +#undef R_PPC64_ADDR16_HI +#undef R_PPC64_ADDR16_HA +#undef R_PPC64_ADDR14 +#undef R_PPC64_ADDR14_BRTAKEN +#undef R_PPC64_ADDR14_BRNTAKEN +#undef R_PPC64_REL24 +#undef R_PPC64_REL14 +#undef R_PPC64_REL14_BRTAKEN +#undef R_PPC64_REL14_BRNTAKEN +#undef R_PPC64_GOT16 +#undef R_PPC64_GOT16_LO +#undef R_PPC64_GOT16_HI +#undef R_PPC64_GOT16_HA +#undef R_PPC64_GLOB_DAT +#undef R_PPC64_JMP_SLOT +#undef R_PPC64_RELATIVE +#undef R_PPC64_REL32 +#undef R_PPC64_ADDR64 +#undef R_PPC64_ADDR16_HIGHER +#undef R_PPC64_ADDR16_HIGHERA +#undef R_PPC64_ADDR16_HIGHEST +#undef R_PPC64_ADDR16_HIGHESTA +#undef R_PPC64_REL64 +#undef R_PPC64_TOC16 +#undef R_PPC64_TOC16_LO +#undef R_PPC64_TOC16_HI +#undef R_PPC64_TOC16_HA +#undef R_PPC64_TOC +#undef R_PPC64_ADDR16_DS +#undef R_PPC64_ADDR16_LO_DS +#undef R_PPC64_GOT16_DS +#undef R_PPC64_GOT16_LO_DS +#undef R_PPC64_TOC16_DS +#undef R_PPC64_TOC16_LO_DS +#undef R_PPC64_TLS +#undef R_PPC64_DTPMOD64 +#undef R_PPC64_TPREL16 +#undef R_PPC64_TPREL16_LO +#undef R_PPC64_TPREL16_HI +#undef R_PPC64_TPREL16_HA +#undef R_PPC64_TPREL64 +#undef R_PPC64_DTPREL16 +#undef R_PPC64_DTPREL16_LO +#undef R_PPC64_DTPREL16_HI +#undef R_PPC64_DTPREL16_HA +#undef R_PPC64_DTPREL64 +#undef R_PPC64_GOT_TLSGD16 +#undef R_PPC64_GOT_TLSGD16_LO +#undef R_PPC64_GOT_TLSGD16_HI +#undef R_PPC64_GOT_TLSGD16_HA +#undef R_PPC64_GOT_TLSLD16 +#undef R_PPC64_GOT_TLSLD16_LO +#undef R_PPC64_GOT_TLSLD16_HI +#undef R_PPC64_GOT_TLSLD16_HA +#undef R_PPC64_GOT_TPREL16_DS +#undef R_PPC64_GOT_TPREL16_LO_DS +#undef R_PPC64_GOT_TPREL16_HI +#undef R_PPC64_GOT_TPREL16_HA +#undef R_PPC64_GOT_DTPREL16_DS +#undef R_PPC64_GOT_DTPREL16_LO_DS +#undef R_PPC64_GOT_DTPREL16_HI +#undef R_PPC64_GOT_DTPREL16_HA +#undef R_PPC64_TPREL16_DS +#undef R_PPC64_TPREL16_LO_DS +#undef R_PPC64_TPREL16_HIGHER +#undef R_PPC64_TPREL16_HIGHERA +#undef R_PPC64_TPREL16_HIGHEST +#undef R_PPC64_TPREL16_HIGHESTA +#undef R_PPC64_DTPREL16_DS +#undef R_PPC64_DTPREL16_LO_DS +#undef R_PPC64_DTPREL16_HIGHER +#undef R_PPC64_DTPREL16_HIGHERA +#undef R_PPC64_DTPREL16_HIGHEST +#undef R_PPC64_DTPREL16_HIGHESTA +#undef R_PPC64_TLSGD +#undef R_PPC64_TLSLD +#undef R_PPC64_REL16 +#undef R_PPC64_REL16_LO +#undef R_PPC64_REL16_HI +#undef R_PPC64_REL16_HA + ELF_RELOC(R_PPC64_NONE, 0) ELF_RELOC(R_PPC64_ADDR32, 1) ELF_RELOC(R_PPC64_ADDR24, 2) @@ -21,7 +112,9 @@ ELF_RELOC(R_PPC64_GOT16, 14) ELF_RELOC(R_PPC64_GOT16_LO, 15) ELF_RELOC(R_PPC64_GOT16_HI, 16) ELF_RELOC(R_PPC64_GOT16_HA, 17) +ELF_RELOC(R_PPC64_GLOB_DAT, 20) ELF_RELOC(R_PPC64_JMP_SLOT, 21) +ELF_RELOC(R_PPC64_RELATIVE, 22) ELF_RELOC(R_PPC64_REL32, 26) ELF_RELOC(R_PPC64_ADDR64, 38) ELF_RELOC(R_PPC64_ADDR16_HIGHER, 39) diff --git a/contrib/llvm/include/llvm/Support/Endian.h b/contrib/llvm/include/llvm/Support/Endian.h index fd59009..bc93c9a 100644 --- a/contrib/llvm/include/llvm/Support/Endian.h +++ b/contrib/llvm/include/llvm/Support/Endian.h @@ -77,6 +77,95 @@ inline void write(void *memory, value_type value) { &value, sizeof(value_type)); } + +template <typename value_type> +using make_unsigned_t = typename std::make_unsigned<value_type>::type; + +/// Read a value of a particular endianness from memory, for a location +/// that starts at the given bit offset within the first byte. +template <typename value_type, endianness endian, std::size_t alignment> +inline value_type readAtBitAlignment(const void *memory, uint64_t startBit) { + assert(startBit < 8); + if (startBit == 0) + return read<value_type, endian, alignment>(memory); + else { + // Read two values and compose the result from them. + value_type val[2]; + memcpy(&val[0], + LLVM_ASSUME_ALIGNED( + memory, (detail::PickAlignment<value_type, alignment>::value)), + sizeof(value_type) * 2); + val[0] = byte_swap<value_type, endian>(val[0]); + val[1] = byte_swap<value_type, endian>(val[1]); + + // Shift bits from the lower value into place. + make_unsigned_t<value_type> lowerVal = val[0] >> startBit; + // Mask off upper bits after right shift in case of signed type. + make_unsigned_t<value_type> numBitsFirstVal = + (sizeof(value_type) * 8) - startBit; + lowerVal &= ((make_unsigned_t<value_type>)1 << numBitsFirstVal) - 1; + + // Get the bits from the upper value. + make_unsigned_t<value_type> upperVal = + val[1] & (((make_unsigned_t<value_type>)1 << startBit) - 1); + // Shift them in to place. + upperVal <<= numBitsFirstVal; + + return lowerVal | upperVal; + } +} + +/// Write a value to memory with a particular endianness, for a location +/// that starts at the given bit offset within the first byte. +template <typename value_type, endianness endian, std::size_t alignment> +inline void writeAtBitAlignment(void *memory, value_type value, + uint64_t startBit) { + assert(startBit < 8); + if (startBit == 0) + write<value_type, endian, alignment>(memory, value); + else { + // Read two values and shift the result into them. + value_type val[2]; + memcpy(&val[0], + LLVM_ASSUME_ALIGNED( + memory, (detail::PickAlignment<value_type, alignment>::value)), + sizeof(value_type) * 2); + val[0] = byte_swap<value_type, endian>(val[0]); + val[1] = byte_swap<value_type, endian>(val[1]); + + // Mask off any existing bits in the upper part of the lower value that + // we want to replace. + val[0] &= ((make_unsigned_t<value_type>)1 << startBit) - 1; + make_unsigned_t<value_type> numBitsFirstVal = + (sizeof(value_type) * 8) - startBit; + make_unsigned_t<value_type> lowerVal = value; + if (startBit > 0) { + // Mask off the upper bits in the new value that are not going to go into + // the lower value. This avoids a left shift of a negative value, which + // is undefined behavior. + lowerVal &= (((make_unsigned_t<value_type>)1 << numBitsFirstVal) - 1); + // Now shift the new bits into place + lowerVal <<= startBit; + } + val[0] |= lowerVal; + + // Mask off any existing bits in the lower part of the upper value that + // we want to replace. + val[1] &= ~(((make_unsigned_t<value_type>)1 << startBit) - 1); + // Next shift the bits that go into the upper value into position. + make_unsigned_t<value_type> upperVal = value >> numBitsFirstVal; + // Mask off upper bits after right shift in case of signed type. + upperVal &= ((make_unsigned_t<value_type>)1 << startBit) - 1; + val[1] |= upperVal; + + // Finally, rewrite values. + val[0] = byte_swap<value_type, endian>(val[0]); + val[1] = byte_swap<value_type, endian>(val[1]); + memcpy(LLVM_ASSUME_ALIGNED( + memory, (detail::PickAlignment<value_type, alignment>::value)), + &val[0], sizeof(value_type) * 2); + } +} } // end namespace endian namespace detail { @@ -208,19 +297,47 @@ typedef detail::packed_endian_specific_integral <int64_t, native, unaligned> unaligned_int64_t; namespace endian { -inline uint16_t read16le(const void *p) { return *(const ulittle16_t *)p; } -inline uint32_t read32le(const void *p) { return *(const ulittle32_t *)p; } -inline uint64_t read64le(const void *p) { return *(const ulittle64_t *)p; } -inline uint16_t read16be(const void *p) { return *(const ubig16_t *)p; } -inline uint32_t read32be(const void *p) { return *(const ubig32_t *)p; } -inline uint64_t read64be(const void *p) { return *(const ubig64_t *)p; } - -inline void write16le(void *p, uint16_t v) { *(ulittle16_t *)p = v; } -inline void write32le(void *p, uint32_t v) { *(ulittle32_t *)p = v; } -inline void write64le(void *p, uint64_t v) { *(ulittle64_t *)p = v; } -inline void write16be(void *p, uint16_t v) { *(ubig16_t *)p = v; } -inline void write32be(void *p, uint32_t v) { *(ubig32_t *)p = v; } -inline void write64be(void *p, uint64_t v) { *(ubig64_t *)p = v; } +template <typename T, endianness E> inline T read(const void *P) { + return *(const detail::packed_endian_specific_integral<T, E, unaligned> *)P; +} + +template <endianness E> inline uint16_t read16(const void *P) { + return read<uint16_t, E>(P); +} +template <endianness E> inline uint32_t read32(const void *P) { + return read<uint32_t, E>(P); +} +template <endianness E> inline uint64_t read64(const void *P) { + return read<uint64_t, E>(P); +} + +inline uint16_t read16le(const void *P) { return read16<little>(P); } +inline uint32_t read32le(const void *P) { return read32<little>(P); } +inline uint64_t read64le(const void *P) { return read64<little>(P); } +inline uint16_t read16be(const void *P) { return read16<big>(P); } +inline uint32_t read32be(const void *P) { return read32<big>(P); } +inline uint64_t read64be(const void *P) { return read64<big>(P); } + +template <typename T, endianness E> inline void write(void *P, T V) { + *(detail::packed_endian_specific_integral<T, E, unaligned> *)P = V; +} + +template <endianness E> inline void write16(void *P, uint16_t V) { + write<uint16_t, E>(P, V); +} +template <endianness E> inline void write32(void *P, uint32_t V) { + write<uint32_t, E>(P, V); +} +template <endianness E> inline void write64(void *P, uint64_t V) { + write<uint64_t, E>(P, V); +} + +inline void write16le(void *P, uint16_t V) { write16<little>(P, V); } +inline void write32le(void *P, uint32_t V) { write32<little>(P, V); } +inline void write64le(void *P, uint64_t V) { write64<little>(P, V); } +inline void write16be(void *P, uint16_t V) { write16<big>(P, V); } +inline void write32be(void *P, uint32_t V) { write32<big>(P, V); } +inline void write64be(void *P, uint64_t V) { write64<big>(P, V); } } // end namespace endian } // end namespace support } // end namespace llvm diff --git a/contrib/llvm/include/llvm/Support/ErrorHandling.h b/contrib/llvm/include/llvm/Support/ErrorHandling.h index 9afd52d..32f05e0 100644 --- a/contrib/llvm/include/llvm/Support/ErrorHandling.h +++ b/contrib/llvm/include/llvm/Support/ErrorHandling.h @@ -61,22 +61,22 @@ namespace llvm { ~ScopedFatalErrorHandler() { remove_fatal_error_handler(); } }; - /// Reports a serious error, calling any installed error handler. These - /// functions are intended to be used for error conditions which are outside - /// the control of the compiler (I/O errors, invalid user input, etc.) - /// - /// If no error handler is installed the default is to print the message to - /// standard error, followed by a newline. - /// After the error handler is called this function will call exit(1), it - /// does not return. - LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason, - bool gen_crash_diag = true); - LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const std::string &reason, - bool gen_crash_diag = true); - LLVM_ATTRIBUTE_NORETURN void report_fatal_error(StringRef reason, - bool gen_crash_diag = true); - LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const Twine &reason, - bool gen_crash_diag = true); +/// Reports a serious error, calling any installed error handler. These +/// functions are intended to be used for error conditions which are outside +/// the control of the compiler (I/O errors, invalid user input, etc.) +/// +/// If no error handler is installed the default is to print the message to +/// standard error, followed by a newline. +/// After the error handler is called this function will call exit(1), it +/// does not return. +LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason, + bool gen_crash_diag = true); +LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const std::string &reason, + bool gen_crash_diag = true); +LLVM_ATTRIBUTE_NORETURN void report_fatal_error(StringRef reason, + bool gen_crash_diag = true); +LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const Twine &reason, + bool gen_crash_diag = true); /// This function calls abort(), and prints the optional message to stderr. /// Use the llvm_unreachable macro (that adds location info), instead of diff --git a/contrib/llvm/include/llvm/Support/ErrorOr.h b/contrib/llvm/include/llvm/Support/ErrorOr.h index 589404f..ca6ede7 100644 --- a/contrib/llvm/include/llvm/Support/ErrorOr.h +++ b/contrib/llvm/include/llvm/Support/ErrorOr.h @@ -1,4 +1,4 @@ -//===- llvm/Support/ErrorOr.h - Error Smart Pointer -----------------------===// +//===- llvm/Support/ErrorOr.h - Error Smart Pointer -------------*- C++ -*-===// // // The LLVM Linker // @@ -91,6 +91,7 @@ private: 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; + typedef const typename std::remove_reference<T>::type *const_pointer; public: template <class E> @@ -183,10 +184,14 @@ public: return toPointer(getStorage()); } + const_pointer operator->() const { return toPointer(getStorage()); } + reference operator *() { return *getStorage(); } + const_reference operator*() const { return *getStorage(); } + private: template <class OtherT> void copyConstruct(const ErrorOr<OtherT> &Other) { @@ -246,10 +251,14 @@ private: return Val; } + const_pointer toPointer(const_pointer Val) const { return Val; } + pointer toPointer(wrap *Val) { return &Val->get(); } + const_pointer toPointer(const wrap *Val) const { return &Val->get(); } + storage_type *getStorage() { assert(!HasError && "Cannot get value when an error exists!"); return reinterpret_cast<storage_type*>(TStorage.buffer); diff --git a/contrib/llvm/include/llvm/Support/FileOutputBuffer.h b/contrib/llvm/include/llvm/Support/FileOutputBuffer.h index fd8879c..3bcf64a 100644 --- a/contrib/llvm/include/llvm/Support/FileOutputBuffer.h +++ b/contrib/llvm/include/llvm/Support/FileOutputBuffer.h @@ -17,6 +17,7 @@ #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/DataTypes.h" +#include "llvm/Support/ErrorOr.h" #include "llvm/Support/FileSystem.h" namespace llvm { @@ -37,9 +38,8 @@ public: /// Factory method to create an OutputBuffer object which manages a read/write /// buffer of the specified size. When committed, the buffer will be written /// to the file at the specified path. - static std::error_code create(StringRef FilePath, size_t Size, - std::unique_ptr<FileOutputBuffer> &Result, - unsigned Flags = 0); + static ErrorOr<std::unique_ptr<FileOutputBuffer>> + create(StringRef FilePath, size_t Size, unsigned Flags = 0); /// Returns a pointer to the start of the buffer. uint8_t *getBufferStart() { diff --git a/contrib/llvm/include/llvm/Support/FileSystem.h b/contrib/llvm/include/llvm/Support/FileSystem.h index a736c32..4733ddb 100644 --- a/contrib/llvm/include/llvm/Support/FileSystem.h +++ b/contrib/llvm/include/llvm/Support/FileSystem.h @@ -95,21 +95,21 @@ enum perms { }; // Helper functions so that you can use & and | to manipulate perms bits: -inline perms operator|(perms l , perms r) { - return static_cast<perms>( - static_cast<unsigned short>(l) | static_cast<unsigned short>(r)); +inline perms operator|(perms l, perms r) { + return static_cast<perms>(static_cast<unsigned short>(l) | + static_cast<unsigned short>(r)); } -inline perms operator&(perms l , perms r) { - return static_cast<perms>( - static_cast<unsigned short>(l) & static_cast<unsigned short>(r)); +inline perms operator&(perms l, perms r) { + return static_cast<perms>(static_cast<unsigned short>(l) & + static_cast<unsigned short>(r)); } inline perms &operator|=(perms &l, perms r) { - l = l | r; - return l; + l = l | r; + return l; } inline perms &operator&=(perms &l, perms r) { - l = l & r; - return l; + l = l & r; + return l; } inline perms operator~(perms x) { return static_cast<perms>(~static_cast<unsigned short>(x)); @@ -156,6 +156,7 @@ class file_status friend bool equivalent(file_status A, file_status B); file_type Type; perms Perms; + public: #if defined(LLVM_ON_UNIX) file_status() : fs_st_dev(0), fs_st_ino(0), fs_st_mtime(0), @@ -267,6 +268,20 @@ private: /// @brief Make \a path an absolute path. /// +/// Makes \a path absolute using the \a current_directory if it is not already. +/// An empty \a path will result in the \a current_directory. +/// +/// /absolute/path => /absolute/path +/// relative/../path => <current-directory>/relative/../path +/// +/// @param path A path that is modified to be an absolute path. +/// @returns errc::success if \a path has been made absolute, otherwise a +/// platform-specific error_code. +std::error_code make_absolute(const Twine ¤t_directory, + SmallVectorImpl<char> &path); + +/// @brief Make \a path an absolute path. +/// /// Makes \a path absolute using the current directory if it is not already. An /// empty \a path will result in the current directory. /// @@ -285,7 +300,8 @@ std::error_code make_absolute(SmallVectorImpl<char> &path); /// specific error_code. If IgnoreExisting is false, also returns /// error if the directory already existed. std::error_code create_directories(const Twine &path, - bool IgnoreExisting = true); + bool IgnoreExisting = true, + perms Perms = owner_all | group_all); /// @brief Create the directory in path. /// @@ -293,7 +309,8 @@ std::error_code create_directories(const Twine &path, /// @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. -std::error_code create_directory(const Twine &path, bool IgnoreExisting = true); +std::error_code create_directory(const Twine &path, bool IgnoreExisting = true, + perms Perms = owner_all | group_all); /// @brief Create a link from \a from to \a to. /// @@ -375,9 +392,7 @@ inline bool exists(const Twine &Path) { /// /// @param Path Input path. /// @returns True if we can execute it, false otherwise. -inline bool can_execute(const Twine &Path) { - return !access(Path, AccessMode::Execute); -} +bool can_execute(const Twine &Path); /// @brief Can we write this file? /// @@ -531,15 +546,15 @@ std::error_code status_known(const Twine &path, bool &result); /// /// Generates a unique path suitable for a temporary file and then opens it as a /// file. The name is based on \a model with '%' replaced by a random char in -/// [0-9a-f]. If \a model is not an absolute path, a suitable temporary -/// directory will be prepended. +/// [0-9a-f]. If \a model is not an absolute path, the temporary file will be +/// created in the current directory. /// /// Example: clang-%%-%%-%%-%%-%%.s => clang-a0-b1-c2-d3-e4.s /// /// This is an atomic operation. Either the file is created and opened, or the /// file system is left untouched. /// -/// The intendend use is for files that are to be kept, possibly after +/// The intended use is for files that are to be kept, possibly after /// renaming them. For example, when running 'clang -c foo.o', the file can /// be first created as foo-abc123.o and then renamed. /// diff --git a/contrib/llvm/include/llvm/Support/Format.h b/contrib/llvm/include/llvm/Support/Format.h index 4319a3b..f0b437a 100644 --- a/contrib/llvm/include/llvm/Support/Format.h +++ b/contrib/llvm/include/llvm/Support/Format.h @@ -118,6 +118,7 @@ class FormattedString { unsigned Width; bool RightJustify; friend class raw_ostream; + public: FormattedString(StringRef S, unsigned W, bool R) : Str(S), Width(W), RightJustify(R) { } @@ -146,6 +147,7 @@ class FormattedNumber { bool Upper; bool HexPrefix; friend class raw_ostream; + public: FormattedNumber(uint64_t HV, int64_t DV, unsigned W, bool H, bool U, bool Prefix) @@ -178,7 +180,7 @@ inline FormattedNumber format_hex_no_prefix(uint64_t N, unsigned Width, return FormattedNumber(N, 0, Width, true, Upper, false); } -/// format_decimal - Output \p N as a right justified, fixed-width decimal. If +/// format_decimal - Output \p N as a right justified, fixed-width decimal. If /// number will not fit in width, full number is still printed. Examples: /// OS << format_decimal(0, 5) => " 0" /// OS << format_decimal(255, 5) => " 255" @@ -188,7 +190,6 @@ inline FormattedNumber format_decimal(int64_t N, unsigned Width) { return FormattedNumber(0, N, Width, false, false, false); } - } // end namespace llvm #endif diff --git a/contrib/llvm/include/llvm/Support/GCOV.h b/contrib/llvm/include/llvm/Support/GCOV.h index c2e34bd..544434f 100644 --- a/contrib/llvm/include/llvm/Support/GCOV.h +++ b/contrib/llvm/include/llvm/Support/GCOV.h @@ -30,12 +30,11 @@ class GCOVBlock; class FileInfo; namespace GCOV { -enum GCOVVersion { V402, V404 }; -} // end GCOV namespace +enum GCOVVersion { V402, V404, V704 }; -/// GCOVOptions - A struct for passing gcov options between functions. -struct GCOVOptions { - GCOVOptions(bool A, bool B, bool C, bool F, bool P, bool U, bool L, bool N) +/// \brief A struct for passing gcov options between functions. +struct Options { + Options(bool A, bool B, bool C, bool F, bool P, bool U, bool L, bool N) : AllBlocks(A), BranchInfo(B), BranchCount(C), FuncCoverage(F), PreservePaths(P), UncondBranch(U), LongFileNames(L), NoOutput(N) {} @@ -48,6 +47,7 @@ struct GCOVOptions { bool LongFileNames; bool NoOutput; }; +} // end GCOV namespace /// GCOVBuffer - A wrapper around MemoryBuffer to provide GCOV specific /// read operations. @@ -90,6 +90,11 @@ public: Version = GCOV::V404; return true; } + if (VersionStr == "*704") { + Cursor += 4; + Version = GCOV::V704; + return true; + } errs() << "Unexpected version: " << VersionStr << ".\n"; return false; } @@ -390,7 +395,7 @@ class FileInfo { }; public: - FileInfo(const GCOVOptions &Options) + FileInfo(const GCOV::Options &Options) : Options(Options), LineInfo(), RunCount(0), ProgramCount(0) {} void addBlockLine(StringRef Filename, uint32_t Line, const GCOVBlock *Block) { @@ -424,7 +429,7 @@ private: void printFuncCoverage(raw_ostream &OS) const; void printFileCoverage(raw_ostream &OS) const; - const GCOVOptions &Options; + const GCOV::Options &Options; StringMap<LineData> LineInfo; uint32_t RunCount; uint32_t ProgramCount; diff --git a/contrib/llvm/include/llvm/Support/GenericDomTree.h b/contrib/llvm/include/llvm/Support/GenericDomTree.h index 63678bb..8751f27 100644 --- a/contrib/llvm/include/llvm/Support/GenericDomTree.h +++ b/contrib/llvm/include/llvm/Support/GenericDomTree.h @@ -371,8 +371,9 @@ public: void releaseMemory() { reset(); } /// getNode - return the (Post)DominatorTree node for the specified basic - /// block. This is the same as using operator[] on this class. - /// + /// block. This is the same as using operator[] on this class. The result + /// may (but is not required to) be null for a forward (backwards) + /// statically unreachable block. DomTreeNodeBase<NodeT> *getNode(NodeT *BB) const { auto I = DomTreeNodes.find(BB); if (I != DomTreeNodes.end()) @@ -380,6 +381,7 @@ public: return nullptr; } + /// See getNode. DomTreeNodeBase<NodeT> *operator[](NodeT *BB) const { return getNode(BB); } /// getRootNode - This returns the entry node for the CFG of the function. If @@ -732,13 +734,13 @@ public: 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); + 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] = nullptr; - this->DomTreeNodes[I] = nullptr; + this->IDoms[&*I] = nullptr; + this->DomTreeNodes[&*I] = nullptr; } Calculate<FT, Inverse<NodeT *>>(*this, F); diff --git a/contrib/llvm/include/llvm/Support/GenericDomTreeConstruction.h b/contrib/llvm/include/llvm/Support/GenericDomTreeConstruction.h index 7c065f9..3e867dc 100644 --- a/contrib/llvm/include/llvm/Support/GenericDomTreeConstruction.h +++ b/contrib/llvm/include/llvm/Support/GenericDomTreeConstruction.h @@ -21,7 +21,6 @@ /// //===----------------------------------------------------------------------===// - #ifndef LLVM_SUPPORT_GENERICDOMTREECONSTRUCTION_H #define LLVM_SUPPORT_GENERICDOMTREECONSTRUCTION_H @@ -88,7 +87,7 @@ unsigned DFSPass(DominatorTreeBase<typename GraphT::NodeType>& DT, // 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; @@ -103,9 +102,9 @@ unsigned DFSPass(DominatorTreeBase<typename GraphT::NodeType>& DT, return N; } -template<class GraphT> -typename GraphT::NodeType* -Eval(DominatorTreeBase<typename GraphT::NodeType>& DT, +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]; @@ -117,7 +116,7 @@ Eval(DominatorTreeBase<typename GraphT::NodeType>& DT, if (VInInfo.Parent >= LastLinked) Work.push_back(VIn); - + while (!Work.empty()) { typename GraphT::NodeType* V = Work.back(); typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &VInfo = @@ -128,8 +127,8 @@ Eval(DominatorTreeBase<typename GraphT::NodeType>& DT, if (Visited.insert(VAncestor).second && VInfo.Parent >= LastLinked) { Work.push_back(VAncestor); continue; - } - Work.pop_back(); + } + Work.pop_back(); // Update VInfo based on Ancestor info if (VInfo.Parent < LastLinked) @@ -169,7 +168,7 @@ void Calculate(DominatorTreeBase<typename GraphTraits<NodeT>::NodeType>& DT, 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 + // 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)); @@ -287,7 +286,6 @@ void Calculate(DominatorTreeBase<typename GraphTraits<NodeT>::NodeType>& DT, DT.updateDFSNumbers(); } - } #endif diff --git a/contrib/llvm/include/llvm/Support/GraphWriter.h b/contrib/llvm/include/llvm/Support/GraphWriter.h index b1af3d7..86985c5 100644 --- a/contrib/llvm/include/llvm/Support/GraphWriter.h +++ b/contrib/llvm/include/llvm/Support/GraphWriter.h @@ -175,8 +175,9 @@ public: O << DOT::EscapeString(DTraits.getNodeLabel(Node, G)); // If we should include the address of the node in the label, do so now. - if (DTraits.hasNodeAddressLabel(Node, G)) - O << "|" << static_cast<const void*>(Node); + std::string Id = DTraits.getNodeIdentifierLabel(Node, G); + if (!Id.empty()) + O << "|" << DOT::EscapeString(Id); std::string NodeDesc = DTraits.getNodeDescription(Node, G); if (!NodeDesc.empty()) @@ -199,8 +200,9 @@ public: O << DOT::EscapeString(DTraits.getNodeLabel(Node, G)); // If we should include the address of the node in the label, do so now. - if (DTraits.hasNodeAddressLabel(Node, G)) - O << "|" << static_cast<const void*>(Node); + std::string Id = DTraits.getNodeIdentifierLabel(Node, G); + if (!Id.empty()) + O << "|" << DOT::EscapeString(Id); std::string NodeDesc = DTraits.getNodeDescription(Node, G); if (!NodeDesc.empty()) diff --git a/contrib/llvm/include/llvm/Support/JamCRC.h b/contrib/llvm/include/llvm/Support/JamCRC.h new file mode 100644 index 0000000..20c28a5 --- /dev/null +++ b/contrib/llvm/include/llvm/Support/JamCRC.h @@ -0,0 +1,48 @@ +//===-- llvm/Support/JamCRC.h - Cyclic Redundancy Check ---------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains an implementation of JamCRC. +// +// We will use the "Rocksoft^tm Model CRC Algorithm" to describe the properties +// of this CRC: +// Width : 32 +// Poly : 04C11DB7 +// Init : FFFFFFFF +// RefIn : True +// RefOut : True +// XorOut : 00000000 +// Check : 340BC6D9 (result of CRC for "123456789") +// +// N.B. We permit flexibility of the "Init" value. Some consumers of this need +// it to be zero. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_JAMCRC_H +#define LLVM_SUPPORT_JAMCRC_H + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/Support/DataTypes.h" + +namespace llvm { +class JamCRC { +public: + JamCRC(uint32_t Init = 0xFFFFFFFFU) : CRC(Init) {} + + // \brief Update the CRC calculation with Data. + void update(ArrayRef<char> Data); + + uint32_t getCRC() const { return CRC; } + +private: + uint32_t CRC; +}; +} // End of namespace llvm + +#endif diff --git a/contrib/llvm/include/llvm/Support/MachO.h b/contrib/llvm/include/llvm/Support/MachO.h index 7751275..54b8745 100644 --- a/contrib/llvm/include/llvm/Support/MachO.h +++ b/contrib/llvm/include/llvm/Support/MachO.h @@ -132,7 +132,9 @@ namespace llvm { LC_DYLIB_CODE_SIGN_DRS = 0x0000002Bu, LC_ENCRYPTION_INFO_64 = 0x0000002Cu, LC_LINKER_OPTION = 0x0000002Du, - LC_LINKER_OPTIMIZATION_HINT = 0x0000002Eu + LC_LINKER_OPTIMIZATION_HINT = 0x0000002Eu, + LC_VERSION_MIN_TVOS = 0x0000002Fu, + LC_VERSION_MIN_WATCHOS = 0x00000030u, }; enum : uint32_t { @@ -142,7 +144,6 @@ namespace llvm { SG_NORELOC = 0x4u, SG_PROTECTED_VERSION_1 = 0x8u, - // Constant masks for the "flags" field in llvm::MachO::section and // llvm::MachO::section_64 SECTION_TYPE = 0x000000ffu, // SECTION_TYPE @@ -334,7 +335,6 @@ namespace llvm { EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE = 0x02u }; - enum { // Constant masks for the "n_type" field in llvm::MachO::nlist and // llvm::MachO::nlist_64 @@ -385,7 +385,7 @@ namespace llvm { SELF_LIBRARY_ORDINAL = 0x0, MAX_LIBRARY_ORDINAL = 0xfd, DYNAMIC_LOOKUP_ORDINAL = 0xfe, - EXECUTABLE_ORDINAL = 0xff + EXECUTABLE_ORDINAL = 0xff }; enum StabType { @@ -506,7 +506,6 @@ namespace llvm { // 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 @@ -530,7 +529,6 @@ namespace llvm { VM_PROT_EXECUTE = 0x4 }; - // Structs from <mach-o/loader.h> struct mach_header { @@ -784,7 +782,6 @@ namespace llvm { flags:8; }; - struct twolevel_hints_command { uint32_t cmd; uint32_t cmdsize; @@ -924,7 +921,6 @@ namespace llvm { uint64_t stacksize; }; - // Structs from <mach-o/fat.h> struct fat_header { uint32_t magic; @@ -995,7 +991,6 @@ namespace llvm { uint64_t n_value; }; - // Byte order swapping functions for MachO structs inline void swapStruct(mach_header &mh) { diff --git a/contrib/llvm/include/llvm/Support/ManagedStatic.h b/contrib/llvm/include/llvm/Support/ManagedStatic.h index addd34e..2e131e4 100644 --- a/contrib/llvm/include/llvm/Support/ManagedStatic.h +++ b/contrib/llvm/include/llvm/Support/ManagedStatic.h @@ -15,8 +15,8 @@ #define LLVM_SUPPORT_MANAGEDSTATIC_H #include "llvm/Support/Atomic.h" +#include "llvm/Support/Compiler.h" #include "llvm/Support/Threading.h" -#include "llvm/Support/Valgrind.h" namespace llvm { diff --git a/contrib/llvm/include/llvm/Support/MathExtras.h b/contrib/llvm/include/llvm/Support/MathExtras.h index 2cf7e0e..8111aee 100644 --- a/contrib/llvm/include/llvm/Support/MathExtras.h +++ b/contrib/llvm/include/llvm/Support/MathExtras.h @@ -63,7 +63,7 @@ template <typename T, std::size_t SizeOfT> struct TrailingZerosCounter { } }; -#if __GNUC__ >= 4 || _MSC_VER +#if __GNUC__ >= 4 || defined(_MSC_VER) template <typename T> struct TrailingZerosCounter<T, 4> { static std::size_t count(T Val, ZeroBehavior ZB) { if (ZB != ZB_Undefined && Val == 0) @@ -71,7 +71,7 @@ template <typename T> struct TrailingZerosCounter<T, 4> { #if __has_builtin(__builtin_ctz) || LLVM_GNUC_PREREQ(4, 0, 0) return __builtin_ctz(Val); -#elif _MSC_VER +#elif defined(_MSC_VER) unsigned long Index; _BitScanForward(&Index, Val); return Index; @@ -87,7 +87,7 @@ template <typename T> struct TrailingZerosCounter<T, 8> { #if __has_builtin(__builtin_ctzll) || LLVM_GNUC_PREREQ(4, 0, 0) return __builtin_ctzll(Val); -#elif _MSC_VER +#elif defined(_MSC_VER) unsigned long Index; _BitScanForward64(&Index, Val); return Index; @@ -132,7 +132,7 @@ template <typename T, std::size_t SizeOfT> struct LeadingZerosCounter { } }; -#if __GNUC__ >= 4 || _MSC_VER +#if __GNUC__ >= 4 || defined(_MSC_VER) template <typename T> struct LeadingZerosCounter<T, 4> { static std::size_t count(T Val, ZeroBehavior ZB) { if (ZB != ZB_Undefined && Val == 0) @@ -140,7 +140,7 @@ template <typename T> struct LeadingZerosCounter<T, 4> { #if __has_builtin(__builtin_clz) || LLVM_GNUC_PREREQ(4, 0, 0) return __builtin_clz(Val); -#elif _MSC_VER +#elif defined(_MSC_VER) unsigned long Index; _BitScanReverse(&Index, Val); return Index ^ 31; @@ -156,7 +156,7 @@ template <typename T> struct LeadingZerosCounter<T, 8> { #if __has_builtin(__builtin_clzll) || LLVM_GNUC_PREREQ(4, 0, 0) return __builtin_clzll(Val); -#elif _MSC_VER +#elif defined(_MSC_VER) unsigned long Index; _BitScanReverse64(&Index, Val); return Index ^ 63; @@ -313,7 +313,7 @@ inline bool isShiftedUInt(uint64_t x) { /// isUIntN - Checks if an unsigned integer fits into the given (dynamic) /// bit width. inline bool isUIntN(unsigned N, uint64_t x) { - return x == (x & (~0ULL >> (64 - N))); + return N >= 64 || x < (UINT64_C(1)<<(N)); } /// isIntN - Checks if an signed integer fits into the given (dynamic) @@ -552,7 +552,7 @@ inline uint32_t FloatToBits(float Float) { inline uint64_t MinAlign(uint64_t A, uint64_t B) { // The largest power of 2 that divides both A and B. // - // Replace "-Value" by "1+~Value" in the following commented code to avoid + // Replace "-Value" by "1+~Value" in the following commented code to avoid // MSVC warning C4146 // return (A | B) & -(A | B); return (A | B) & (1 + ~(A | B)); @@ -599,15 +599,27 @@ inline uint64_t PowerOf2Floor(uint64_t A) { /// 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. /// +/// If non-zero \p Skew is specified, the return value will be a minimal +/// integer that is greater than or equal to \p Value and equal to +/// \p Align * N + \p Skew for some integer N. If \p Skew is larger than +/// \p Align, its value is adjusted to '\p Skew mod \p Align'. +/// /// Examples: /// \code /// RoundUpToAlignment(5, 8) = 8 /// RoundUpToAlignment(17, 8) = 24 /// RoundUpToAlignment(~0LL, 8) = 0 /// RoundUpToAlignment(321, 255) = 510 +/// +/// RoundUpToAlignment(5, 8, 7) = 7 +/// RoundUpToAlignment(17, 8, 1) = 17 +/// RoundUpToAlignment(~0LL, 8, 3) = 3 +/// RoundUpToAlignment(321, 255, 42) = 552 /// \endcode -inline uint64_t RoundUpToAlignment(uint64_t Value, uint64_t Align) { - return (Value + Align - 1) / Align * Align; +inline uint64_t RoundUpToAlignment(uint64_t Value, uint64_t Align, + uint64_t Skew = 0) { + Skew %= Align; + return (Value + Align - 1 - Skew) / Align * Align + Skew; } /// Returns the offset to the next integer (mod 2**64) that is greater than @@ -641,6 +653,70 @@ inline int64_t SignExtend64(uint64_t X, unsigned B) { return int64_t(X << (64 - B)) >> (64 - B); } +/// \brief Add two unsigned integers, X and Y, of type T. +/// Clamp the result to the maximum representable value of T on overflow. +/// ResultOverflowed indicates if the result is larger than the maximum +/// representable value of type T. +template <typename T> +typename std::enable_if<std::is_unsigned<T>::value, T>::type +SaturatingAdd(T X, T Y, bool *ResultOverflowed = nullptr) { + bool Dummy; + bool &Overflowed = ResultOverflowed ? *ResultOverflowed : Dummy; + // Hacker's Delight, p. 29 + T Z = X + Y; + Overflowed = (Z < X || Z < Y); + if (Overflowed) + return std::numeric_limits<T>::max(); + else + return Z; +} + +/// \brief Multiply two unsigned integers, X and Y, of type T. +/// Clamp the result to the maximum representable value of T on overflow. +/// ResultOverflowed indicates if the result is larger than the maximum +/// representable value of type T. +template <typename T> +typename std::enable_if<std::is_unsigned<T>::value, T>::type +SaturatingMultiply(T X, T Y, bool *ResultOverflowed = nullptr) { + bool Dummy; + bool &Overflowed = ResultOverflowed ? *ResultOverflowed : Dummy; + + // Hacker's Delight, p. 30 has a different algorithm, but we don't use that + // because it fails for uint16_t (where multiplication can have undefined + // behavior due to promotion to int), and requires a division in addition + // to the multiplication. + + Overflowed = false; + + // Log2(Z) would be either Log2Z or Log2Z + 1. + // Special case: if X or Y is 0, Log2_64 gives -1, and Log2Z + // will necessarily be less than Log2Max as desired. + int Log2Z = Log2_64(X) + Log2_64(Y); + const T Max = std::numeric_limits<T>::max(); + int Log2Max = Log2_64(Max); + if (Log2Z < Log2Max) { + return X * Y; + } + if (Log2Z > Log2Max) { + Overflowed = true; + return Max; + } + + // We're going to use the top bit, and maybe overflow one + // bit past it. Multiply all but the bottom bit then add + // that on at the end. + T Z = (X >> 1) * Y; + if (Z & ~(Max >> 1)) { + Overflowed = true; + return Max; + } + Z <<= 1; + if (X & 1) + return SaturatingAdd(Z, Y, ResultOverflowed); + + return Z; +} + extern const float huge_valf; } // End llvm namespace diff --git a/contrib/llvm/include/llvm/Support/Memory.h b/contrib/llvm/include/llvm/Support/Memory.h index b4305cb..8103aea 100644 --- a/contrib/llvm/include/llvm/Support/Memory.h +++ b/contrib/llvm/include/llvm/Support/Memory.h @@ -1,4 +1,4 @@ -//===- llvm/Support/Memory.h - Memory Support --------------------*- C++ -*-===// +//===- llvm/Support/Memory.h - Memory Support -------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -32,6 +32,7 @@ namespace sys { MemoryBlock(void *addr, size_t size) : Address(addr), Size(size) { } void *base() const { return Address; } size_t size() const { return Size; } + private: void *Address; ///< Address of first byte of memory area size_t Size; ///< Size, in bytes of the memory area @@ -70,7 +71,7 @@ namespace sys { /// If the address following \p NearBlock is not so aligned, it will be /// rounded up to the next allocation granularity boundary. /// - /// \r a non-null MemoryBlock if the function was successful, + /// \r a non-null MemoryBlock if the function was successful, /// otherwise a null MemoryBlock is with \p EC describing the error. /// /// @brief Allocate mapped memory. @@ -86,7 +87,7 @@ namespace sys { /// /// \r error_success if the function was successful, or an error_code /// describing the failure if an error occurred. - /// + /// /// @brief Release mapped memory. static std::error_code releaseMappedMemory(MemoryBlock &Block); @@ -131,7 +132,6 @@ namespace sys { /// @brief Release Read/Write/Execute memory. static bool ReleaseRWX(MemoryBlock &block, std::string *ErrMsg = nullptr); - /// InvalidateInstructionCache - Before the JIT can run a block of code /// that has been emitted it must invalidate the instruction cache on some /// platforms. @@ -155,6 +155,31 @@ namespace sys { /// as writable. static bool setRangeWritable(const void *Addr, size_t Size); }; + + /// Owning version of MemoryBlock. + class OwningMemoryBlock { + public: + OwningMemoryBlock() = default; + explicit OwningMemoryBlock(MemoryBlock M) : M(M) {} + OwningMemoryBlock(OwningMemoryBlock &&Other) { + M = Other.M; + Other.M = MemoryBlock(); + } + OwningMemoryBlock& operator=(OwningMemoryBlock &&Other) { + M = Other.M; + Other.M = MemoryBlock(); + return *this; + } + ~OwningMemoryBlock() { + Memory::releaseMappedMemory(M); + } + void *base() const { return M.base(); } + size_t size() const { return M.size(); } + MemoryBlock getMemoryBlock() const { return M; } + private: + MemoryBlock M; + }; + } } diff --git a/contrib/llvm/include/llvm/Support/MemoryBuffer.h b/contrib/llvm/include/llvm/Support/MemoryBuffer.h index 81616d8..73d6435 100644 --- a/contrib/llvm/include/llvm/Support/MemoryBuffer.h +++ b/contrib/llvm/include/llvm/Support/MemoryBuffer.h @@ -14,7 +14,6 @@ #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/DataTypes.h" @@ -122,7 +121,8 @@ public: /// Open the specified file as a MemoryBuffer, or open stdin if the Filename /// is "-". static ErrorOr<std::unique_ptr<MemoryBuffer>> - getFileOrSTDIN(const Twine &Filename, int64_t FileSize = -1); + getFileOrSTDIN(const Twine &Filename, int64_t FileSize = -1, + bool RequiresNullTerminator = true); /// Map a subrange of the specified file as a MemoryBuffer. static ErrorOr<std::unique_ptr<MemoryBuffer>> @@ -151,6 +151,8 @@ class MemoryBufferRef { public: MemoryBufferRef() {} + MemoryBufferRef(MemoryBuffer& Buffer) + : Buffer(Buffer.getBuffer()), Identifier(Buffer.getBufferIdentifier()) {} MemoryBufferRef(StringRef Buffer, StringRef Identifier) : Buffer(Buffer), Identifier(Identifier) {} diff --git a/contrib/llvm/include/llvm/Support/OnDiskHashTable.h b/contrib/llvm/include/llvm/Support/OnDiskHashTable.h index 08e277a..ac978d4 100644 --- a/contrib/llvm/include/llvm/Support/OnDiskHashTable.h +++ b/contrib/llvm/include/llvm/Support/OnDiskHashTable.h @@ -53,6 +53,8 @@ namespace llvm { /// /// Write Data to Out. DataLen is the length from EmitKeyDataLength. /// static void EmitData(raw_ostream &Out, key_type_ref Key, /// data_type_ref Data, offset_type DataLen); +/// /// Determine if two keys are equal. Optional, only needed by contains. +/// static bool EqualKey(key_type_ref Key1, key_type_ref Key2); /// }; /// \endcode template <typename Info> class OnDiskChainedHashTableGenerator { @@ -122,13 +124,21 @@ public: /// Uses the provided Info instead of a stack allocated one. void insert(typename Info::key_type_ref Key, typename Info::data_type_ref Data, Info &InfoObj) { - ++NumEntries; if (4 * NumEntries >= 3 * NumBuckets) resize(NumBuckets * 2); insert(Buckets, NumBuckets, new (BA.Allocate()) Item(Key, Data, InfoObj)); } + /// \brief Determine whether an entry has been inserted. + bool contains(typename Info::key_type_ref Key, Info &InfoObj) { + unsigned Hash = InfoObj.ComputeHash(Key); + for (Item *I = Buckets[Hash & (NumBuckets - 1)].Head; I; I = I->Next) + if (I->Hash == Hash && InfoObj.EqualKey(I->Key, Key)) + return true; + return false; + } + /// \brief Emit the table to Out, which must not be at offset 0. offset_type Emit(raw_ostream &Out) { Info InfoObj; @@ -161,8 +171,22 @@ public: LE.write<typename Info::hash_value_type>(I->Hash); const std::pair<offset_type, offset_type> &Len = InfoObj.EmitKeyDataLength(Out, I->Key, I->Data); +#ifdef NDEBUG InfoObj.EmitKey(Out, I->Key, Len.first); InfoObj.EmitData(Out, I->Key, I->Data, Len.second); +#else + // In asserts mode, check that the users length matches the data they + // wrote. + uint64_t KeyStart = Out.tell(); + InfoObj.EmitKey(Out, I->Key, Len.first); + uint64_t DataStart = Out.tell(); + InfoObj.EmitData(Out, I->Key, I->Data, Len.second); + uint64_t End = Out.tell(); + assert(offset_type(DataStart - KeyStart) == Len.first && + "key length does not match bytes written"); + assert(offset_type(End - DataStart) == Len.second && + "data length does not match bytes written"); +#endif } } @@ -239,11 +263,12 @@ template <typename Info> class OnDiskChainedHashTable { Info InfoObj; public: + typedef Info InfoType; typedef typename Info::internal_key_type internal_key_type; typedef typename Info::external_key_type external_key_type; - typedef typename Info::data_type data_type; - typedef typename Info::hash_value_type hash_value_type; - typedef typename Info::offset_type offset_type; + typedef typename Info::data_type data_type; + typedef typename Info::hash_value_type hash_value_type; + typedef typename Info::offset_type offset_type; OnDiskChainedHashTable(offset_type NumBuckets, offset_type NumEntries, const unsigned char *Buckets, @@ -255,6 +280,21 @@ public: "'buckets' must have a 4-byte alignment"); } + /// Read the number of buckets and the number of entries from a hash table + /// produced by OnDiskHashTableGenerator::Emit, and advance the Buckets + /// pointer past them. + static std::pair<offset_type, offset_type> + readNumBucketsAndEntries(const unsigned char *&Buckets) { + assert((reinterpret_cast<uintptr_t>(Buckets) & 0x3) == 0 && + "buckets should be 4-byte aligned."); + using namespace llvm::support; + offset_type NumBuckets = + endian::readNext<offset_type, little, aligned>(Buckets); + offset_type NumEntries = + endian::readNext<offset_type, little, aligned>(Buckets); + return std::make_pair(NumBuckets, NumEntries); + } + offset_type getNumBuckets() const { return NumBuckets; } offset_type getNumEntries() const { return NumEntries; } const unsigned char *getBase() const { return Base; } @@ -275,6 +315,10 @@ public: : Key(K), Data(D), Len(L), InfoObj(InfoObj) {} data_type operator*() const { return InfoObj->ReadData(Key, Data, Len); } + + const unsigned char *getDataPtr() const { return Data; } + offset_type getDataLen() const { return Len; } + bool operator==(const iterator &X) const { return X.Data == Data; } bool operator!=(const iterator &X) const { return X.Data != Data; } }; @@ -356,17 +400,11 @@ public: static OnDiskChainedHashTable *Create(const unsigned char *Buckets, const unsigned char *const Base, const Info &InfoObj = Info()) { - using namespace llvm::support; assert(Buckets > Base); - assert((reinterpret_cast<uintptr_t>(Buckets) & 0x3) == 0 && - "buckets should be 4-byte aligned."); - - offset_type NumBuckets = - endian::readNext<offset_type, little, aligned>(Buckets); - offset_type NumEntries = - endian::readNext<offset_type, little, aligned>(Buckets); - return new OnDiskChainedHashTable<Info>(NumBuckets, NumEntries, Buckets, - Base, InfoObj); + auto NumBucketsAndEntries = readNumBucketsAndEntries(Buckets); + return new OnDiskChainedHashTable<Info>(NumBucketsAndEntries.first, + NumBucketsAndEntries.second, + Buckets, Base, InfoObj); } }; @@ -385,40 +423,30 @@ public: typedef typename base_type::hash_value_type hash_value_type; typedef typename base_type::offset_type offset_type; - OnDiskIterableChainedHashTable(offset_type NumBuckets, offset_type NumEntries, - const unsigned char *Buckets, - const unsigned char *Payload, - const unsigned char *Base, - const Info &InfoObj = Info()) - : base_type(NumBuckets, NumEntries, Buckets, Base, InfoObj), - Payload(Payload) {} - +private: /// \brief Iterates over all of the keys in the table. - class key_iterator { + class iterator_base { const unsigned char *Ptr; offset_type NumItemsInBucketLeft; offset_type NumEntriesLeft; - Info *InfoObj; public: typedef external_key_type value_type; - key_iterator(const unsigned char *const Ptr, offset_type NumEntries, - Info *InfoObj) - : Ptr(Ptr), NumItemsInBucketLeft(0), NumEntriesLeft(NumEntries), - InfoObj(InfoObj) {} - key_iterator() - : Ptr(nullptr), NumItemsInBucketLeft(0), NumEntriesLeft(0), - InfoObj(0) {} + iterator_base(const unsigned char *const Ptr, offset_type NumEntries) + : Ptr(Ptr), NumItemsInBucketLeft(0), NumEntriesLeft(NumEntries) {} + iterator_base() + : Ptr(nullptr), NumItemsInBucketLeft(0), NumEntriesLeft(0) {} - friend bool operator==(const key_iterator &X, const key_iterator &Y) { + friend bool operator==(const iterator_base &X, const iterator_base &Y) { return X.NumEntriesLeft == Y.NumEntriesLeft; } - friend bool operator!=(const key_iterator &X, const key_iterator &Y) { + friend bool operator!=(const iterator_base &X, const iterator_base &Y) { return X.NumEntriesLeft != Y.NumEntriesLeft; } - key_iterator &operator++() { // Preincrement + /// Move to the next item. + void advance() { using namespace llvm::support; if (!NumItemsInBucketLeft) { // 'Items' starts with a 16-bit unsigned integer representing the @@ -435,25 +463,58 @@ public: --NumItemsInBucketLeft; assert(NumEntriesLeft); --NumEntriesLeft; + } + + /// Get the start of the item as written by the trait (after the hash and + /// immediately before the key and value length). + const unsigned char *getItem() const { + return Ptr + (NumItemsInBucketLeft ? 0 : 2) + sizeof(hash_value_type); + } + }; + +public: + OnDiskIterableChainedHashTable(offset_type NumBuckets, offset_type NumEntries, + const unsigned char *Buckets, + const unsigned char *Payload, + const unsigned char *Base, + const Info &InfoObj = Info()) + : base_type(NumBuckets, NumEntries, Buckets, Base, InfoObj), + Payload(Payload) {} + + /// \brief Iterates over all of the keys in the table. + class key_iterator : public iterator_base { + Info *InfoObj; + + public: + typedef external_key_type value_type; + + key_iterator(const unsigned char *const Ptr, offset_type NumEntries, + Info *InfoObj) + : iterator_base(Ptr, NumEntries), InfoObj(InfoObj) {} + key_iterator() : iterator_base(), InfoObj() {} + + key_iterator &operator++() { + this->advance(); return *this; } key_iterator operator++(int) { // Postincrement - key_iterator tmp = *this; ++*this; return tmp; + key_iterator tmp = *this; + ++*this; + return tmp; } - value_type operator*() const { - const unsigned char *LocalPtr = Ptr; - if (!NumItemsInBucketLeft) - LocalPtr += 2; // number of items in bucket - LocalPtr += sizeof(hash_value_type); // Skip the hash. + internal_key_type getInternalKey() const { + auto *LocalPtr = this->getItem(); // Determine the length of the key and the data. - const std::pair<offset_type, offset_type> &L = - Info::ReadKeyDataLength(LocalPtr); + auto L = Info::ReadKeyDataLength(LocalPtr); // Read the key. - const internal_key_type &Key = InfoObj->ReadKey(LocalPtr, L.first); - return InfoObj->GetExternalKey(Key); + return InfoObj->ReadKey(LocalPtr, L.first); + } + + value_type operator*() const { + return InfoObj->GetExternalKey(getInternalKey()); } }; @@ -467,10 +528,7 @@ public: } /// \brief Iterates over all the entries in the table, returning the data. - class data_iterator { - const unsigned char *Ptr; - offset_type NumItemsInBucketLeft; - offset_type NumEntriesLeft; + class data_iterator : public iterator_base { Info *InfoObj; public: @@ -478,51 +536,24 @@ public: data_iterator(const unsigned char *const Ptr, offset_type NumEntries, Info *InfoObj) - : Ptr(Ptr), NumItemsInBucketLeft(0), NumEntriesLeft(NumEntries), - InfoObj(InfoObj) {} - data_iterator() - : Ptr(nullptr), NumItemsInBucketLeft(0), NumEntriesLeft(0), - InfoObj(nullptr) {} - - bool operator==(const data_iterator &X) const { - return X.NumEntriesLeft == NumEntriesLeft; - } - bool operator!=(const data_iterator &X) const { - return X.NumEntriesLeft != NumEntriesLeft; - } + : iterator_base(Ptr, NumEntries), InfoObj(InfoObj) {} + data_iterator() : iterator_base(), InfoObj() {} data_iterator &operator++() { // Preincrement - using namespace llvm::support; - if (!NumItemsInBucketLeft) { - // 'Items' starts with a 16-bit unsigned integer representing the - // number of items in this bucket. - NumItemsInBucketLeft = - endian::readNext<uint16_t, little, unaligned>(Ptr); - } - Ptr += sizeof(hash_value_type); // Skip the hash. - // Determine the length of the key and the data. - const std::pair<offset_type, offset_type> &L = - Info::ReadKeyDataLength(Ptr); - Ptr += L.first + L.second; - assert(NumItemsInBucketLeft); - --NumItemsInBucketLeft; - assert(NumEntriesLeft); - --NumEntriesLeft; + this->advance(); return *this; } data_iterator operator++(int) { // Postincrement - data_iterator tmp = *this; ++*this; return tmp; + data_iterator tmp = *this; + ++*this; + return tmp; } value_type operator*() const { - const unsigned char *LocalPtr = Ptr; - if (!NumItemsInBucketLeft) - LocalPtr += 2; // number of items in bucket - LocalPtr += sizeof(hash_value_type); // Skip the hash. + auto *LocalPtr = this->getItem(); // Determine the length of the key and the data. - const std::pair<offset_type, offset_type> &L = - Info::ReadKeyDataLength(LocalPtr); + auto L = Info::ReadKeyDataLength(LocalPtr); // Read the key. const internal_key_type &Key = InfoObj->ReadKey(LocalPtr, L.first); @@ -555,17 +586,12 @@ public: static OnDiskIterableChainedHashTable * Create(const unsigned char *Buckets, const unsigned char *const Payload, const unsigned char *const Base, const Info &InfoObj = Info()) { - using namespace llvm::support; assert(Buckets > Base); - assert((reinterpret_cast<uintptr_t>(Buckets) & 0x3) == 0 && - "buckets should be 4-byte aligned."); - - offset_type NumBuckets = - endian::readNext<offset_type, little, aligned>(Buckets); - offset_type NumEntries = - endian::readNext<offset_type, little, aligned>(Buckets); + auto NumBucketsAndEntries = + OnDiskIterableChainedHashTable<Info>::readNumBucketsAndEntries(Buckets); return new OnDiskIterableChainedHashTable<Info>( - NumBuckets, NumEntries, Buckets, Payload, Base, InfoObj); + NumBucketsAndEntries.first, NumBucketsAndEntries.second, + Buckets, Payload, Base, InfoObj); } }; diff --git a/contrib/llvm/include/llvm/Support/Options.h b/contrib/llvm/include/llvm/Support/Options.h index 2742d39..7b61b23 100644 --- a/contrib/llvm/include/llvm/Support/Options.h +++ b/contrib/llvm/include/llvm/Support/Options.h @@ -71,7 +71,7 @@ private: /// \param Key unique key for option /// \param O option to map to \p Key /// - /// Allocated cl::Options are owened by the OptionRegistry and are deallocated + /// Allocated cl::Options are owned by the OptionRegistry and are deallocated /// on destruction or removal void addOption(void *Key, cl::Option *O); @@ -91,7 +91,7 @@ public: /// Options are keyed off the template parameters to generate unique static /// characters. The template parameters are (1) the type of the data the /// option stores (\p ValT), the class that will read the option (\p Base), - /// and the memeber that the class will store the data into (\p Mem). + /// and the member that the class will store the data into (\p Mem). template <typename ValT, typename Base, ValT(Base::*Mem)> static void registerOption(const char *ArgStr, const char *Desc, const ValT &InitValue) { diff --git a/contrib/llvm/include/llvm/Support/OutputBuffer.h b/contrib/llvm/include/llvm/Support/OutputBuffer.h deleted file mode 100644 index 6b98e99..0000000 --- a/contrib/llvm/include/llvm/Support/OutputBuffer.h +++ /dev/null @@ -1,166 +0,0 @@ -//=== OutputBuffer.h - Output Buffer ----------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Methods to output values to a data buffer. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_SUPPORT_OUTPUTBUFFER_H -#define LLVM_SUPPORT_OUTPUTBUFFER_H - -#include <cassert> -#include <string> -#include <vector> - -namespace llvm { - - class OutputBuffer { - /// Output buffer. - std::vector<unsigned char> &Output; - - /// is64Bit/isLittleEndian - This information is inferred from the target - /// machine directly, indicating what header values and flags to set. - bool is64Bit, isLittleEndian; - public: - OutputBuffer(std::vector<unsigned char> &Out, - bool is64bit, bool le) - : Output(Out), is64Bit(is64bit), isLittleEndian(le) {} - - // align - Emit padding into the file until the current output position is - // aligned to the specified power of two boundary. - void align(unsigned Boundary) { - assert(Boundary && (Boundary & (Boundary - 1)) == 0 && - "Must align to 2^k boundary"); - size_t Size = Output.size(); - - if (Size & (Boundary - 1)) { - // Add padding to get alignment to the correct place. - size_t Pad = Boundary - (Size & (Boundary - 1)); - Output.resize(Size + Pad); - } - } - - //===------------------------------------------------------------------===// - // Out Functions - Output the specified value to the data buffer. - - void outbyte(unsigned char X) { - Output.push_back(X); - } - void outhalf(unsigned short X) { - if (isLittleEndian) { - Output.push_back(X & 255); - Output.push_back(X >> 8); - } else { - Output.push_back(X >> 8); - Output.push_back(X & 255); - } - } - void outword(unsigned X) { - if (isLittleEndian) { - Output.push_back((X >> 0) & 255); - Output.push_back((X >> 8) & 255); - Output.push_back((X >> 16) & 255); - Output.push_back((X >> 24) & 255); - } else { - Output.push_back((X >> 24) & 255); - Output.push_back((X >> 16) & 255); - Output.push_back((X >> 8) & 255); - Output.push_back((X >> 0) & 255); - } - } - void outxword(uint64_t X) { - if (isLittleEndian) { - Output.push_back(unsigned(X >> 0) & 255); - Output.push_back(unsigned(X >> 8) & 255); - Output.push_back(unsigned(X >> 16) & 255); - Output.push_back(unsigned(X >> 24) & 255); - Output.push_back(unsigned(X >> 32) & 255); - Output.push_back(unsigned(X >> 40) & 255); - Output.push_back(unsigned(X >> 48) & 255); - Output.push_back(unsigned(X >> 56) & 255); - } else { - Output.push_back(unsigned(X >> 56) & 255); - Output.push_back(unsigned(X >> 48) & 255); - Output.push_back(unsigned(X >> 40) & 255); - Output.push_back(unsigned(X >> 32) & 255); - Output.push_back(unsigned(X >> 24) & 255); - Output.push_back(unsigned(X >> 16) & 255); - Output.push_back(unsigned(X >> 8) & 255); - Output.push_back(unsigned(X >> 0) & 255); - } - } - void outaddr32(unsigned X) { - outword(X); - } - void outaddr64(uint64_t X) { - outxword(X); - } - void outaddr(uint64_t X) { - if (!is64Bit) - outword((unsigned)X); - else - outxword(X); - } - void outstring(const std::string &S, unsigned Length) { - unsigned len_to_copy = static_cast<unsigned>(S.length()) < Length - ? static_cast<unsigned>(S.length()) : Length; - unsigned len_to_fill = static_cast<unsigned>(S.length()) < Length - ? Length - static_cast<unsigned>(S.length()) : 0; - - for (unsigned i = 0; i < len_to_copy; ++i) - outbyte(S[i]); - - for (unsigned i = 0; i < len_to_fill; ++i) - outbyte(0); - } - - //===------------------------------------------------------------------===// - // Fix Functions - Replace an existing entry at an offset. - - void fixhalf(unsigned short X, unsigned Offset) { - unsigned char *P = &Output[Offset]; - P[0] = (X >> (isLittleEndian ? 0 : 8)) & 255; - P[1] = (X >> (isLittleEndian ? 8 : 0)) & 255; - } - void fixword(unsigned X, unsigned Offset) { - unsigned char *P = &Output[Offset]; - P[0] = (X >> (isLittleEndian ? 0 : 24)) & 255; - P[1] = (X >> (isLittleEndian ? 8 : 16)) & 255; - P[2] = (X >> (isLittleEndian ? 16 : 8)) & 255; - P[3] = (X >> (isLittleEndian ? 24 : 0)) & 255; - } - void fixxword(uint64_t X, unsigned Offset) { - unsigned char *P = &Output[Offset]; - P[0] = (X >> (isLittleEndian ? 0 : 56)) & 255; - P[1] = (X >> (isLittleEndian ? 8 : 48)) & 255; - P[2] = (X >> (isLittleEndian ? 16 : 40)) & 255; - P[3] = (X >> (isLittleEndian ? 24 : 32)) & 255; - P[4] = (X >> (isLittleEndian ? 32 : 24)) & 255; - P[5] = (X >> (isLittleEndian ? 40 : 16)) & 255; - P[6] = (X >> (isLittleEndian ? 48 : 8)) & 255; - P[7] = (X >> (isLittleEndian ? 56 : 0)) & 255; - } - void fixaddr(uint64_t X, unsigned Offset) { - if (!is64Bit) - fixword((unsigned)X, Offset); - else - fixxword(X, Offset); - } - - unsigned char &operator[](unsigned Index) { - return Output[Index]; - } - const unsigned char &operator[](unsigned Index) const { - return Output[Index]; - } - }; - -} // end llvm namespace - -#endif // LLVM_SUPPORT_OUTPUTBUFFER_H diff --git a/contrib/llvm/include/llvm/Support/Path.h b/contrib/llvm/include/llvm/Support/Path.h index 8fae853..955cc99 100644 --- a/contrib/llvm/include/llvm/Support/Path.h +++ b/contrib/llvm/include/llvm/Support/Path.h @@ -61,7 +61,6 @@ public: reference operator*() const { return Component; } pointer operator->() const { return &Component; } const_iterator &operator++(); // preincrement - const_iterator &operator++(int); // postincrement bool operator==(const const_iterator &RHS) const; bool operator!=(const const_iterator &RHS) const { return !(*this == RHS); } @@ -87,7 +86,6 @@ public: reference operator*() const { return Component; } pointer operator->() const { return &Component; } reverse_iterator &operator++(); // preincrement - reverse_iterator &operator++(int); // postincrement bool operator==(const reverse_iterator &RHS) const; bool operator!=(const reverse_iterator &RHS) const { return !(*this == RHS); } }; @@ -218,7 +216,7 @@ StringRef root_name(StringRef path); /// @result The root directory of \a path if it has one, otherwise /// "". StringRef root_directory(StringRef path); - + /// @brief Get root path. /// /// Equivalent to root_name + root_directory. @@ -310,7 +308,7 @@ bool is_separator(char value); /// @result StringRef of the preferred separator, null-terminated. StringRef get_separator(); -/// @brief Get the typical temporary directory for the system, e.g., +/// @brief Get the typical temporary directory for the system, e.g., /// "/var/tmp" or "C:/TEMP" /// /// @param erasedOnReboot Whether to favor a path that is erased on reboot @@ -327,6 +325,22 @@ void system_temp_directory(bool erasedOnReboot, SmallVectorImpl<char> &result); /// @result True if a home directory is set, false otherwise. bool home_directory(SmallVectorImpl<char> &result); +/// @brief Get the user's cache directory. +/// +/// Expect the resulting path to be a directory shared with other +/// applications/services used by the user. Params \p Path1 to \p Path3 can be +/// used to append additional directory names to the resulting path. Recommended +/// pattern is <user_cache_directory>/<vendor>/<application>. +/// +/// @param Result Holds the resulting path. +/// @param Path1 Additional path to be appended to the user's cache directory +/// path. "" can be used to append nothing. +/// @param Path2 Second additional path to be appended. +/// @param Path3 Third additional path to be appended. +/// @result True if a cache directory path is set, false otherwise. +bool user_cache_directory(SmallVectorImpl<char> &Result, const Twine &Path1, + const Twine &Path2 = "", const Twine &Path3 = ""); + /// @brief Has root name? /// /// root_name != "" @@ -403,6 +417,19 @@ bool is_absolute(const Twine &path); /// @result True if the path is relative, false if it is not. bool is_relative(const Twine &path); +/// @brief Remove redundant leading "./" pieces and consecutive separators. +/// +/// @param path Input path. +/// @result The cleaned-up \a path. +StringRef remove_leading_dotslash(StringRef path); + +/// @brief In-place remove any './' and optionally '../' components from a path. +/// +/// @param path processed path +/// @param remove_dot_dot specify if '../' should be removed +/// @result True if path was changed +bool remove_dots(SmallVectorImpl<char> &path, bool remove_dot_dot = false); + } // end namespace path } // end namespace sys } // end namespace llvm diff --git a/contrib/llvm/include/llvm/Support/PointerLikeTypeTraits.h b/contrib/llvm/include/llvm/Support/PointerLikeTypeTraits.h index 8370821..c12d237 100644 --- a/contrib/llvm/include/llvm/Support/PointerLikeTypeTraits.h +++ b/contrib/llvm/include/llvm/Support/PointerLikeTypeTraits.h @@ -15,59 +15,70 @@ #ifndef LLVM_SUPPORT_POINTERLIKETYPETRAITS_H #define LLVM_SUPPORT_POINTERLIKETYPETRAITS_H +#include "llvm/Support/AlignOf.h" #include "llvm/Support/DataTypes.h" namespace llvm { - -/// PointerLikeTypeTraits - This is a traits object that is used to handle -/// pointer types and things that are just wrappers for pointers as a uniform -/// entity. -template <typename T> -class PointerLikeTypeTraits { + +/// A traits type that is used to handle pointer types and things that are just +/// wrappers for pointers as a uniform entity. +template <typename T> class PointerLikeTypeTraits { // getAsVoidPointer // getFromVoidPointer // getNumLowBitsAvailable }; +namespace detail { +/// A tiny meta function to compute the log2 of a compile time constant. +template <size_t N> +struct ConstantLog2 + : std::integral_constant<size_t, ConstantLog2<N / 2>::value + 1> {}; +template <> struct ConstantLog2<1> : std::integral_constant<size_t, 0> {}; +} + // Provide PointerLikeTypeTraits for non-cvr pointers. -template<typename T> -class PointerLikeTypeTraits<T*> { -public: - static inline void *getAsVoidPointer(T* P) { return P; } - static inline T *getFromVoidPointer(void *P) { - return static_cast<T*>(P); - } - - /// Note, we assume here that malloc returns objects at least 4-byte aligned. - /// However, this may be wrong, or pointers may be from something other than - /// malloc. In this case, you should specialize this template to reduce this. +template <typename T> struct PointerLikeTypeTraits<T *> { + static inline void *getAsVoidPointer(T *P) { return P; } + static inline T *getFromVoidPointer(void *P) { return static_cast<T *>(P); } + + enum { + NumLowBitsAvailable = detail::ConstantLog2<AlignOf<T>::Alignment>::value + }; +}; + +template <> struct PointerLikeTypeTraits<void *> { + static inline void *getAsVoidPointer(void *P) { return P; } + static inline void *getFromVoidPointer(void *P) { return P; } + + /// Note, we assume here that void* is related to raw malloc'ed memory and + /// that malloc returns objects at least 4-byte aligned. However, this may be + /// wrong, or pointers may be from something other than malloc. In this case, + /// you should specify a real typed pointer or avoid this template. /// /// All clients should use assertions to do a run-time check to ensure that /// this is actually true. enum { NumLowBitsAvailable = 2 }; }; - + // Provide PointerLikeTypeTraits for const pointers. -template<typename T> -class PointerLikeTypeTraits<const T*> { - typedef PointerLikeTypeTraits<T*> NonConst; +template <typename T> class PointerLikeTypeTraits<const T *> { + typedef PointerLikeTypeTraits<T *> NonConst; public: - static inline const void *getAsVoidPointer(const T* P) { - return NonConst::getAsVoidPointer(const_cast<T*>(P)); + static inline const void *getAsVoidPointer(const T *P) { + return NonConst::getAsVoidPointer(const_cast<T *>(P)); } static inline const T *getFromVoidPointer(const void *P) { - return NonConst::getFromVoidPointer(const_cast<void*>(P)); + return NonConst::getFromVoidPointer(const_cast<void *>(P)); } enum { NumLowBitsAvailable = NonConst::NumLowBitsAvailable }; }; // Provide PointerLikeTypeTraits for uintptr_t. -template<> -class PointerLikeTypeTraits<uintptr_t> { +template <> class PointerLikeTypeTraits<uintptr_t> { public: static inline void *getAsVoidPointer(uintptr_t P) { - return reinterpret_cast<void*>(P); + return reinterpret_cast<void *>(P); } static inline uintptr_t getFromVoidPointer(void *P) { return reinterpret_cast<uintptr_t>(P); @@ -75,7 +86,7 @@ public: // No bits are available! enum { NumLowBitsAvailable = 0 }; }; - + } // end namespace llvm #endif diff --git a/contrib/llvm/include/llvm/Support/PrettyStackTrace.h b/contrib/llvm/include/llvm/Support/PrettyStackTrace.h index 96afb60..027f943 100644 --- a/contrib/llvm/include/llvm/Support/PrettyStackTrace.h +++ b/contrib/llvm/include/llvm/Support/PrettyStackTrace.h @@ -66,6 +66,18 @@ namespace llvm { void print(raw_ostream &OS) const override; }; + /// Returns the topmost element of the "pretty" stack state. + const void* SavePrettyStackState(); + + /// Restores the topmost element of the "pretty" stack state to State, which + /// should come from a previous call to SavePrettyStackState(). This is + /// useful when using a CrashRecoveryContext in code that also uses + /// PrettyStackTraceEntries, to make sure the stack that's printed if a crash + /// happens after a crash that's been recovered by CrashRecoveryContext + /// doesn't have frames on it that were added in code unwound by the + /// CrashRecoveryContext. + void RestorePrettyStackState(const void* State); + } // end namespace llvm #endif diff --git a/contrib/llvm/include/llvm/Support/Printable.h b/contrib/llvm/include/llvm/Support/Printable.h new file mode 100644 index 0000000..5c1b8d5 --- /dev/null +++ b/contrib/llvm/include/llvm/Support/Printable.h @@ -0,0 +1,52 @@ +//===--- Printable.h - Print function helpers -------------------*- 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 Printable struct. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_PRINTABLE_H +#define LLVM_SUPPORT_PRINTABLE_H + +#include <functional> + +namespace llvm { + +class raw_ostream; + +/// Simple wrapper around std::function<void(raw_ostream&)>. +/// This class is usefull to construct print helpers for raw_ostream. +/// +/// Example: +/// Printable PrintRegister(unsigned Register) { +/// return Printable([Register](raw_ostream &OS) { +/// OS << getRegisterName(Register); +/// } +/// } +/// ... OS << PrintRegister(Register); ... +/// +/// Implementation note: Ideally this would just be a typedef, but doing so +/// leads to operator << being ambiguous as function has matching constructors +/// in some STL versions. I have seen the problem on gcc 4.6 libstdc++ and +/// microsoft STL. +class Printable { +public: + std::function<void(raw_ostream &OS)> Print; + Printable(const std::function<void(raw_ostream &OS)> Print) + : Print(Print) {} +}; + +static inline raw_ostream &operator<<(raw_ostream &OS, const Printable &P) { + P.Print(OS); + return OS; +} + +} + +#endif diff --git a/contrib/llvm/include/llvm/Support/Program.h b/contrib/llvm/include/llvm/Support/Program.h index b89a0f7..4330210 100644 --- a/contrib/llvm/include/llvm/Support/Program.h +++ b/contrib/llvm/include/llvm/Support/Program.h @@ -67,8 +67,7 @@ struct ProcessInfo { /// \returns The fully qualified path to the first \p Name in \p Paths if it /// exists. \p Name if \p Name has slashes in it. Otherwise an error. ErrorOr<std::string> - findProgramByName(StringRef Name, - ArrayRef<StringRef> Paths = ArrayRef<StringRef>()); + findProgramByName(StringRef Name, ArrayRef<StringRef> Paths = None); // These functions change the specified standard stream (stdin or stdout) to // binary mode. They return errc::success if the specified stream diff --git a/contrib/llvm/include/llvm/Support/Recycler.h b/contrib/llvm/include/llvm/Support/Recycler.h index e97f36a..a38050d 100644 --- a/contrib/llvm/include/llvm/Support/Recycler.h +++ b/contrib/llvm/include/llvm/Support/Recycler.h @@ -28,53 +28,36 @@ namespace llvm { /// void PrintRecyclerStats(size_t Size, size_t Align, size_t FreeListSize); -/// RecyclerStruct - Implementation detail for Recycler. This is a -/// class that the recycler imposes on free'd memory to carve out -/// next/prev pointers. -struct RecyclerStruct { - RecyclerStruct *Prev, *Next; -}; - -template<> -struct ilist_traits<RecyclerStruct> : - public ilist_default_traits<RecyclerStruct> { - static RecyclerStruct *getPrev(const RecyclerStruct *t) { return t->Prev; } - static RecyclerStruct *getNext(const RecyclerStruct *t) { return t->Next; } - static void setPrev(RecyclerStruct *t, RecyclerStruct *p) { t->Prev = p; } - static void setNext(RecyclerStruct *t, RecyclerStruct *n) { t->Next = n; } - - mutable RecyclerStruct Sentinel; - RecyclerStruct *createSentinel() const { - return &Sentinel; - } - static void destroySentinel(RecyclerStruct *) {} - - RecyclerStruct *provideInitialHead() const { return createSentinel(); } - RecyclerStruct *ensureHead(RecyclerStruct*) const { return createSentinel(); } - static void noteHead(RecyclerStruct*, RecyclerStruct*) {} - - static void deleteNode(RecyclerStruct *) { - llvm_unreachable("Recycler's ilist_traits shouldn't see a deleteNode call!"); - } -}; - /// Recycler - This class manages a linked-list of deallocated nodes /// and facilitates reusing deallocated memory in place of allocating /// new memory. /// template<class T, size_t Size = sizeof(T), size_t Align = AlignOf<T>::Alignment> class Recycler { - /// FreeList - Doubly-linked list of nodes that have deleted contents and - /// are not in active use. - /// - iplist<RecyclerStruct> FreeList; + struct FreeNode { + FreeNode *Next; + }; + + /// List of nodes that have deleted contents and are not in active use. + FreeNode *FreeList = nullptr; + + FreeNode *pop_val() { + auto *Val = FreeList; + FreeList = FreeList->Next; + return Val; + } + + void push(FreeNode *N) { + N->Next = FreeList; + FreeList = N; + } public: ~Recycler() { // If this fails, either the callee has lost track of some allocation, // or the callee isn't tracking allocations and should just call // clear() before deleting the Recycler. - assert(FreeList.empty() && "Non-empty recycler deleted!"); + assert(!FreeList && "Non-empty recycler deleted!"); } /// clear - Release all the tracked allocations to the allocator. The @@ -82,8 +65,8 @@ public: /// deleted; calling clear is one way to ensure this. template<class AllocatorType> void clear(AllocatorType &Allocator) { - while (!FreeList.empty()) { - T *t = reinterpret_cast<T *>(FreeList.remove(FreeList.begin())); + while (FreeList) { + T *t = reinterpret_cast<T *>(pop_val()); Allocator.Deallocate(t); } } @@ -93,9 +76,7 @@ public: /// /// There is no need to traverse the free list, pulling all the objects into /// cache. - void clear(BumpPtrAllocator&) { - FreeList.clearAndLeakNodesUnsafely(); - } + void clear(BumpPtrAllocator &) { FreeList = nullptr; } template<class SubClass, class AllocatorType> SubClass *Allocate(AllocatorType &Allocator) { @@ -103,9 +84,8 @@ public: "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)); + return FreeList ? reinterpret_cast<SubClass *>(pop_val()) + : static_cast<SubClass *>(Allocator.Allocate(Size, Align)); } template<class AllocatorType> @@ -115,14 +95,20 @@ public: template<class SubClass, class AllocatorType> void Deallocate(AllocatorType & /*Allocator*/, SubClass* Element) { - FreeList.push_front(reinterpret_cast<RecyclerStruct *>(Element)); + push(reinterpret_cast<FreeNode *>(Element)); } - void PrintStats() { - PrintRecyclerStats(Size, Align, FreeList.size()); - } + void PrintStats(); }; +template <class T, size_t Size, size_t Align> +void Recycler<T, Size, Align>::PrintStats() { + size_t S = 0; + for (auto *I = FreeList; I; I = I->Next) + ++S; + PrintRecyclerStats(Size, Align, S); +} + } #endif diff --git a/contrib/llvm/include/llvm/Support/Registry.h b/contrib/llvm/include/llvm/Support/Registry.h index 95c4e96..bbea97b 100644 --- a/contrib/llvm/include/llvm/Support/Registry.h +++ b/contrib/llvm/include/llvm/Support/Registry.h @@ -37,7 +37,6 @@ namespace llvm { std::unique_ptr<T> instantiate() const { return Ctor(); } }; - /// Traits for registry entries. If using other than SimpleRegistryEntry, it /// is necessary to define an alternate traits class. template <typename T> @@ -53,7 +52,6 @@ namespace llvm { static const char *descof(const entry &Entry) { return Entry.getDesc(); } }; - /// A global registry used in conjunction with static constructors to make /// pluggable components (like targets or garbage collectors) "just work" when /// linked with an executable. @@ -102,7 +100,6 @@ namespace llvm { } }; - /// Iterators for registry entries. /// class iterator { @@ -122,10 +119,9 @@ namespace llvm { static iterator end() { return iterator(nullptr); } static iterator_range<iterator> entries() { - return iterator_range<iterator>(begin(), end()); + return make_range(begin(), end()); } - /// Abstract base class for registry listeners, which are informed when new /// entries are added to the registry. Simply subclass and instantiate: /// @@ -160,7 +156,7 @@ namespace llvm { } public: - listener() : Prev(ListenerTail), Next(0) { + listener() : Prev(ListenerTail), Next(nullptr) { if (Prev) Prev->Next = this; else @@ -180,7 +176,6 @@ namespace llvm { } }; - /// A static registration template. Use like such: /// /// Registry<Collector>::Add<FancyGC> @@ -210,7 +205,6 @@ namespace llvm { }; /// Registry::Parser now lives in llvm/Support/RegistryParser.h. - }; // Since these are defined in a header file, plugins must be sure to export @@ -228,6 +222,6 @@ namespace llvm { template <typename T, typename U> typename Registry<T,U>::listener *Registry<T,U>::ListenerTail; -} +} // end namespace llvm -#endif +#endif // LLVM_SUPPORT_REGISTRY_H diff --git a/contrib/llvm/include/llvm/Support/SMLoc.h b/contrib/llvm/include/llvm/Support/SMLoc.h index d5b4c57..c6e9a14 100644 --- a/contrib/llvm/include/llvm/Support/SMLoc.h +++ b/contrib/llvm/include/llvm/Support/SMLoc.h @@ -22,6 +22,7 @@ namespace llvm { /// Represents a location in source code. class SMLoc { const char *Ptr; + public: SMLoc() : Ptr(nullptr) {} @@ -53,11 +54,10 @@ public: assert(Start.isValid() == End.isValid() && "Start and end should either both be valid or both be invalid!"); } - + bool isValid() const { return Start.isValid(); } }; - + } // end namespace llvm #endif - diff --git a/contrib/llvm/include/llvm/Support/ScaledNumber.h b/contrib/llvm/include/llvm/Support/ScaledNumber.h index 0a4262b..c6421ef 100644 --- a/contrib/llvm/include/llvm/Support/ScaledNumber.h +++ b/contrib/llvm/include/llvm/Support/ScaledNumber.h @@ -282,7 +282,7 @@ int compare(DigitsT LDigits, int16_t LScale, DigitsT RDigits, int16_t RScale) { /// /// As a convenience, returns the matching scale. If the output value of one /// number is zero, returns the scale of the other. If both are zero, which -/// scale is returned is unspecifed. +/// scale is returned is unspecified. template <class DigitsT> int16_t matchScales(DigitsT &LDigits, int16_t &LScale, DigitsT &RDigits, int16_t &RScale) { @@ -334,7 +334,7 @@ std::pair<DigitsT, int16_t> getSum(DigitsT LDigits, int16_t LScale, DigitsT RDigits, int16_t RScale) { static_assert(!std::numeric_limits<DigitsT>::is_signed, "expected unsigned"); - // Check inputs up front. This is only relevent if addition overflows, but + // Check inputs up front. This is only relevant if addition overflows, but // testing here should catch more bugs. assert(LScale < INT16_MAX && "scale too large"); assert(RScale < INT16_MAX && "scale too large"); diff --git a/contrib/llvm/include/llvm/Support/Signals.h b/contrib/llvm/include/llvm/Support/Signals.h index 7e165d7..2a4d84b 100644 --- a/contrib/llvm/include/llvm/Support/Signals.h +++ b/contrib/llvm/include/llvm/Support/Signals.h @@ -47,6 +47,9 @@ namespace sys { /// \brief Print the stack trace using the given \c raw_ostream object. void PrintStackTrace(raw_ostream &OS); + // Run all registered signal handlers. + void RunSignalHandlers(); + /// AddSignalHandler - Add a function to be called when an abort/kill signal /// is delivered to the process. The handler can have a cookie passed to it /// to identify what instance of the handler it is. diff --git a/contrib/llvm/include/llvm/Support/StreamingMemoryObject.h b/contrib/llvm/include/llvm/Support/StreamingMemoryObject.h index 7cb6438..a5980c2 100644 --- a/contrib/llvm/include/llvm/Support/StreamingMemoryObject.h +++ b/contrib/llvm/include/llvm/Support/StreamingMemoryObject.h @@ -50,8 +50,10 @@ public: /// starts (although it can be called anytime). void setKnownObjectSize(size_t size); + /// The number of bytes read at a time from the data streamer. + static const uint32_t kChunkSize = 4096 * 4; + private: - const static uint32_t kChunkSize = 4096 * 4; mutable std::vector<unsigned char> Bytes; std::unique_ptr<DataStreamer> Streamer; mutable size_t BytesRead; // Bytes read from stream diff --git a/contrib/llvm/include/llvm/Support/StringSaver.h b/contrib/llvm/include/llvm/Support/StringSaver.h index f3853ee..38fb7bb 100644 --- a/contrib/llvm/include/llvm/Support/StringSaver.h +++ b/contrib/llvm/include/llvm/Support/StringSaver.h @@ -18,25 +18,15 @@ namespace llvm { /// \brief Saves strings in the inheritor's stable storage and returns a stable /// raw character pointer. -class StringSaver { -protected: - ~StringSaver() {} - virtual const char *saveImpl(StringRef S); +class StringSaver final { + BumpPtrAllocator &Alloc; public: StringSaver(BumpPtrAllocator &Alloc) : Alloc(Alloc) {} const char *save(const char *S) { return save(StringRef(S)); } - const char *save(StringRef S) { return saveImpl(S); } + const char *save(StringRef S); const char *save(const Twine &S) { return save(StringRef(S.str())); } const char *save(std::string &S) { return save(StringRef(S)); } - -private: - BumpPtrAllocator &Alloc; -}; - -class BumpPtrStringSaver final : public StringSaver { -public: - BumpPtrStringSaver(BumpPtrAllocator &Alloc) : StringSaver(Alloc) {} }; } #endif diff --git a/contrib/llvm/include/llvm/Support/TargetParser.h b/contrib/llvm/include/llvm/Support/TargetParser.h index dab7248..c21019d 100644 --- a/contrib/llvm/include/llvm/Support/TargetParser.h +++ b/contrib/llvm/include/llvm/Support/TargetParser.h @@ -20,7 +20,7 @@ #include <vector> namespace llvm { - class StringRef; +class StringRef; // Target specific information into their own namespaces. These should be // generated from TableGen because the information is already there, and there @@ -29,177 +29,117 @@ namespace llvm { // even if the back-end is not compiled with LLVM, plus we need to create a new // back-end to TableGen to create these clean tables. namespace ARM { - // FPU names. - enum FPUKind { - FK_INVALID = 0, - FK_NONE, - FK_VFP, - FK_VFPV2, - FK_VFPV3, - FK_VFPV3_FP16, - FK_VFPV3_D16, - FK_VFPV3_D16_FP16, - FK_VFPV3XD, - FK_VFPV3XD_FP16, - FK_VFPV4, - FK_VFPV4_D16, - FK_FPV4_SP_D16, - FK_FPV5_D16, - FK_FPV5_SP_D16, - FK_FP_ARMV8, - FK_NEON, - FK_NEON_FP16, - FK_NEON_VFPV4, - FK_NEON_FP_ARMV8, - FK_CRYPTO_NEON_FP_ARMV8, - FK_SOFTVFP, - FK_LAST - }; - - // FPU Version - enum FPUVersion { - FV_NONE = 0, - FV_VFPV2, - FV_VFPV3, - FV_VFPV3_FP16, - FV_VFPV4, - FV_VFPV5 - }; - - // An FPU name implies one of three levels of Neon support: - enum NeonSupportLevel { - NS_None = 0, ///< No Neon - NS_Neon, ///< Neon - NS_Crypto ///< Neon with Crypto - }; - - // An FPU name restricts the FPU in one of three ways: - enum FPURestriction { - FR_None = 0, ///< No restriction - FR_D16, ///< Only 16 D registers - FR_SP_D16 ///< Only single-precision instructions, with 16 D registers - }; - - // Arch names. - enum ArchKind { - AK_INVALID = 0, - AK_ARMV2, - AK_ARMV2A, - AK_ARMV3, - AK_ARMV3M, - AK_ARMV4, - AK_ARMV4T, - AK_ARMV5T, - AK_ARMV5TE, - AK_ARMV5TEJ, - AK_ARMV6, - AK_ARMV6K, - AK_ARMV6T2, - AK_ARMV6Z, - AK_ARMV6ZK, - AK_ARMV6M, - AK_ARMV6SM, - AK_ARMV7A, - AK_ARMV7R, - AK_ARMV7M, - AK_ARMV7EM, - AK_ARMV8A, - AK_ARMV8_1A, - // Non-standard Arch names. - AK_IWMMXT, - AK_IWMMXT2, - AK_XSCALE, - AK_ARMV5, - AK_ARMV5E, - AK_ARMV6J, - AK_ARMV6HL, - AK_ARMV7, - AK_ARMV7L, - AK_ARMV7HL, - AK_ARMV7S, - AK_LAST - }; - - // Arch extension modifiers for CPUs. - enum ArchExtKind { - AEK_INVALID = 0, - AEK_CRC, - AEK_CRYPTO, - AEK_FP, - AEK_HWDIV, - AEK_MP, - AEK_SIMD, - AEK_SEC, - AEK_VIRT, - // Unsupported extensions. - AEK_OS, - AEK_IWMMXT, - AEK_IWMMXT2, - AEK_MAVERICK, - AEK_XSCALE, - AEK_LAST - }; - - // ISA kinds. - enum ISAKind { - IK_INVALID = 0, - IK_ARM, - IK_THUMB, - IK_AARCH64 - }; - - // Endianness - // FIXME: BE8 vs. BE32? - enum EndianKind { - EK_INVALID = 0, - EK_LITTLE, - EK_BIG - }; - - // v6/v7/v8 Profile - enum ProfileKind { - PK_INVALID = 0, - PK_A, - PK_R, - PK_M - }; -} // namespace ARM -// Target Parsers, one per architecture. -class ARMTargetParser { - static StringRef getFPUSynonym(StringRef FPU); - static StringRef getArchSynonym(StringRef Arch); - -public: - static StringRef getCanonicalArchName(StringRef Arch); - - // Information by ID - static const char * getFPUName(unsigned FPUKind); - static unsigned getFPUVersion(unsigned FPUKind); - static unsigned getFPUNeonSupportLevel(unsigned FPUKind); - static unsigned getFPURestriction(unsigned FPUKind); - // FIXME: This should be moved to TargetTuple once it exists - static bool getFPUFeatures(unsigned FPUKind, - std::vector<const char*> &Features); - static const char * getArchName(unsigned ArchKind); - static unsigned getArchAttr(unsigned ArchKind); - static const char * getCPUAttr(unsigned ArchKind); - static const char * getSubArch(unsigned ArchKind); - static const char * getArchExtName(unsigned ArchExtKind); - static const char * getDefaultCPU(StringRef Arch); - - // Parser - static unsigned parseFPU(StringRef FPU); - static unsigned parseArch(StringRef Arch); - static unsigned parseArchExt(StringRef ArchExt); - static unsigned parseCPUArch(StringRef CPU); - static unsigned parseArchISA(StringRef Arch); - static unsigned parseArchEndian(StringRef Arch); - static unsigned parseArchProfile(StringRef Arch); - static unsigned parseArchVersion(StringRef Arch); +// FPU names. +enum FPUKind { +#define ARM_FPU(NAME, KIND, VERSION, NEON_SUPPORT, RESTRICTION) KIND, +#include "ARMTargetParser.def" + FK_LAST +}; + +// FPU Version +enum FPUVersion { + FV_NONE = 0, + FV_VFPV2, + FV_VFPV3, + FV_VFPV3_FP16, + FV_VFPV4, + FV_VFPV5 +}; + +// An FPU name implies one of three levels of Neon support: +enum NeonSupportLevel { + NS_None = 0, ///< No Neon + NS_Neon, ///< Neon + NS_Crypto ///< Neon with Crypto +}; + +// An FPU name restricts the FPU in one of three ways: +enum FPURestriction { + FR_None = 0, ///< No restriction + FR_D16, ///< Only 16 D registers + FR_SP_D16 ///< Only single-precision instructions, with 16 D registers +}; + +// Arch names. +enum ArchKind { +#define ARM_ARCH(NAME, ID, CPU_ATTR, SUB_ARCH, ARCH_ATTR, ARCH_FPU, ARCH_BASE_EXT) ID, +#include "ARMTargetParser.def" + AK_LAST +}; +// Arch extension modifiers for CPUs. +enum ArchExtKind : unsigned { + AEK_INVALID = 0x0, + AEK_NONE = 0x1, + AEK_CRC = 0x2, + AEK_CRYPTO = 0x4, + AEK_FP = 0x8, + AEK_HWDIV = 0x10, + AEK_HWDIVARM = 0x20, + AEK_MP = 0x40, + AEK_SIMD = 0x80, + AEK_SEC = 0x100, + AEK_VIRT = 0x200, + AEK_DSP = 0x400, + AEK_FP16 = 0x800, + // Unsupported extensions. + AEK_OS = 0x8000000, + AEK_IWMMXT = 0x10000000, + AEK_IWMMXT2 = 0x20000000, + AEK_MAVERICK = 0x40000000, + AEK_XSCALE = 0x80000000, }; +// ISA kinds. +enum ISAKind { IK_INVALID = 0, IK_ARM, IK_THUMB, IK_AARCH64 }; + +// Endianness +// FIXME: BE8 vs. BE32? +enum EndianKind { EK_INVALID = 0, EK_LITTLE, EK_BIG }; + +// v6/v7/v8 Profile +enum ProfileKind { PK_INVALID = 0, PK_A, PK_R, PK_M }; + +StringRef getCanonicalArchName(StringRef Arch); + +// Information by ID +StringRef getFPUName(unsigned FPUKind); +unsigned getFPUVersion(unsigned FPUKind); +unsigned getFPUNeonSupportLevel(unsigned FPUKind); +unsigned getFPURestriction(unsigned FPUKind); + +// FIXME: These should be moved to TargetTuple once it exists +bool getFPUFeatures(unsigned FPUKind, std::vector<const char *> &Features); +bool getHWDivFeatures(unsigned HWDivKind, std::vector<const char *> &Features); +bool getExtensionFeatures(unsigned Extensions, + std::vector<const char*> &Features); + +StringRef getArchName(unsigned ArchKind); +unsigned getArchAttr(unsigned ArchKind); +StringRef getCPUAttr(unsigned ArchKind); +StringRef getSubArch(unsigned ArchKind); +StringRef getArchExtName(unsigned ArchExtKind); +const char *getArchExtFeature(StringRef ArchExt); +StringRef getHWDivName(unsigned HWDivKind); + +// Information by Name +unsigned getDefaultFPU(StringRef CPU, unsigned ArchKind); +unsigned getDefaultExtensions(StringRef CPU, unsigned ArchKind); +StringRef getDefaultCPU(StringRef Arch); + +// Parser +unsigned parseHWDiv(StringRef HWDiv); +unsigned parseFPU(StringRef FPU); +unsigned parseArch(StringRef Arch); +unsigned parseArchExt(StringRef ArchExt); +unsigned parseCPUArch(StringRef CPU); +unsigned parseArchISA(StringRef Arch); +unsigned parseArchEndian(StringRef Arch); +unsigned parseArchProfile(StringRef Arch); +unsigned parseArchVersion(StringRef Arch); + +} // namespace ARM } // namespace llvm #endif diff --git a/contrib/llvm/include/llvm/Support/TargetRegistry.h b/contrib/llvm/include/llvm/Support/TargetRegistry.h index 40bf6fb..aec181b 100644 --- a/contrib/llvm/include/llvm/Support/TargetRegistry.h +++ b/contrib/llvm/include/llvm/Support/TargetRegistry.h @@ -115,7 +115,7 @@ public: const MCRegisterInfo &MRI, const Triple &TT, StringRef CPU); typedef MCTargetAsmParser *(*MCAsmParserCtorTy)( - MCSubtargetInfo &STI, MCAsmParser &P, const MCInstrInfo &MII, + const MCSubtargetInfo &STI, MCAsmParser &P, const MCInstrInfo &MII, const MCTargetOptions &Options); typedef MCDisassembler *(*MCDisassemblerCtorTy)(const Target &T, const MCSubtargetInfo &STI, @@ -141,7 +141,8 @@ public: typedef MCStreamer *(*COFFStreamerCtorTy)(MCContext &Ctx, MCAsmBackend &TAB, raw_pwrite_stream &OS, MCCodeEmitter *Emitter, - bool RelaxAll); + bool RelaxAll, + bool IncrementalLinkerCompatible); typedef MCTargetStreamer *(*NullTargetStreamerCtorTy)(MCStreamer &S); typedef MCTargetStreamer *(*AsmTargetStreamerCtorTy)( MCStreamer &S, formatted_raw_ostream &OS, MCInstPrinter *InstPrint, @@ -382,7 +383,7 @@ public: /// /// \param Parser The target independent parser implementation to use for /// parsing and lexing. - MCTargetAsmParser *createMCAsmParser(MCSubtargetInfo &STI, + MCTargetAsmParser *createMCAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser, const MCInstrInfo &MII, const MCTargetOptions &Options) const { @@ -437,6 +438,7 @@ public: MCAsmBackend &TAB, raw_pwrite_stream &OS, MCCodeEmitter *Emitter, const MCSubtargetInfo &STI, bool RelaxAll, + bool IncrementalLinkerCompatible, bool DWARFMustBeAtTheEnd) const { MCStreamer *S; switch (T.getObjectFormat()) { @@ -444,7 +446,8 @@ public: llvm_unreachable("Unknown object format"); case Triple::COFF: assert(T.isOSWindows() && "only Windows COFF is supported"); - S = COFFStreamerCtorFn(Ctx, TAB, OS, Emitter, RelaxAll); + S = COFFStreamerCtorFn(Ctx, TAB, OS, Emitter, RelaxAll, + IncrementalLinkerCompatible); break; case Triple::MachO: if (MachOStreamerCtorFn) @@ -1133,8 +1136,8 @@ template <class MCAsmParserImpl> struct RegisterMCAsmParser { } private: - static MCTargetAsmParser *Allocator(MCSubtargetInfo &STI, MCAsmParser &P, - const MCInstrInfo &MII, + static MCTargetAsmParser *Allocator(const MCSubtargetInfo &STI, + MCAsmParser &P, const MCInstrInfo &MII, const MCTargetOptions &Options) { return new MCAsmParserImpl(STI, P, MII, Options); } diff --git a/contrib/llvm/include/llvm/Support/TargetSelect.h b/contrib/llvm/include/llvm/Support/TargetSelect.h index a86e953..582785c 100644 --- a/contrib/llvm/include/llvm/Support/TargetSelect.h +++ b/contrib/llvm/include/llvm/Support/TargetSelect.h @@ -25,11 +25,11 @@ extern "C" { #define LLVM_TARGET(TargetName) void LLVMInitialize##TargetName##Target(); #include "llvm/Config/Targets.def" - + // Declare all of the target-MC-initialization functions that are available. #define LLVM_TARGET(TargetName) void LLVMInitialize##TargetName##TargetMC(); #include "llvm/Config/Targets.def" - + // Declare all of the available assembly printer initialization functions. #define LLVM_ASM_PRINTER(TargetName) void LLVMInitialize##TargetName##AsmPrinter(); #include "llvm/Config/AsmPrinters.def" @@ -54,7 +54,7 @@ namespace llvm { #define LLVM_TARGET(TargetName) LLVMInitialize##TargetName##TargetInfo(); #include "llvm/Config/Targets.def" } - + /// InitializeAllTargets - The main program should call this function if it /// wants access to all available target machines that LLVM is configured to /// support, to make them available via the TargetRegistry. @@ -67,7 +67,7 @@ namespace llvm { #define LLVM_TARGET(TargetName) LLVMInitialize##TargetName##Target(); #include "llvm/Config/Targets.def" } - + /// InitializeAllTargetMCs - The main program should call this function if it /// wants access to all available target MC that LLVM is configured to /// support, to make them available via the TargetRegistry. @@ -77,7 +77,7 @@ namespace llvm { #define LLVM_TARGET(TargetName) LLVMInitialize##TargetName##TargetMC(); #include "llvm/Config/Targets.def" } - + /// InitializeAllAsmPrinters - The main program should call this function if /// it wants all asm printers that LLVM is configured to support, to make them /// available via the TargetRegistry. @@ -87,7 +87,7 @@ namespace llvm { #define LLVM_ASM_PRINTER(TargetName) LLVMInitialize##TargetName##AsmPrinter(); #include "llvm/Config/AsmPrinters.def" } - + /// InitializeAllAsmParsers - The main program should call this function if it /// wants all asm parsers that LLVM is configured to support, to make them /// available via the TargetRegistry. @@ -97,7 +97,7 @@ namespace llvm { #define LLVM_ASM_PARSER(TargetName) LLVMInitialize##TargetName##AsmParser(); #include "llvm/Config/AsmParsers.def" } - + /// InitializeAllDisassemblers - The main program should call this function if /// it wants all disassemblers that LLVM is configured to support, to make /// them available via the TargetRegistry. @@ -107,9 +107,9 @@ namespace llvm { #define LLVM_DISASSEMBLER(TargetName) LLVMInitialize##TargetName##Disassembler(); #include "llvm/Config/Disassemblers.def" } - + /// InitializeNativeTarget - The main program should call this function to - /// initialize the native target corresponding to the host. This is useful + /// initialize the native target corresponding to the host. This is useful /// for JIT applications to ensure that the target gets linked in correctly. /// /// It is legal for a client to make multiple calls to this function. @@ -123,7 +123,7 @@ namespace llvm { #else return true; #endif - } + } /// InitializeNativeTargetAsmPrinter - The main program should call /// this function to initialize the native target asm printer. @@ -135,7 +135,7 @@ namespace llvm { #else return true; #endif - } + } /// InitializeNativeTargetAsmParser - The main program should call /// this function to initialize the native target asm parser. @@ -147,7 +147,7 @@ namespace llvm { #else return true; #endif - } + } /// InitializeNativeTargetDisassembler - The main program should call /// this function to initialize the native target disassembler. @@ -159,8 +159,7 @@ namespace llvm { #else return true; #endif - } - + } } #endif diff --git a/contrib/llvm/include/llvm/Support/ThreadPool.h b/contrib/llvm/include/llvm/Support/ThreadPool.h new file mode 100644 index 0000000..745334d --- /dev/null +++ b/contrib/llvm/include/llvm/Support/ThreadPool.h @@ -0,0 +1,136 @@ +//===-- llvm/Support/ThreadPool.h - A ThreadPool implementation -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines a crude C++11 based thread pool. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_THREAD_POOL_H +#define LLVM_SUPPORT_THREAD_POOL_H + +#include "llvm/Support/thread.h" + +#ifdef _MSC_VER +// concrt.h depends on eh.h for __uncaught_exception declaration +// even if we disable exceptions. +#include <eh.h> + +// Disable warnings from ppltasks.h transitively included by <future>. +#pragma warning(push) +#pragma warning(disable:4530) +#pragma warning(disable:4062) +#endif + +#include <future> + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +#include <condition_variable> +#include <functional> +#include <memory> +#include <mutex> +#include <queue> +#include <utility> + +namespace llvm { + +/// A ThreadPool for asynchronous parallel execution on a defined number of +/// threads. +/// +/// The pool keeps a vector of threads alive, waiting on a condition variable +/// for some work to become available. +class ThreadPool { +public: +#ifndef _MSC_VER + using VoidTy = void; + using TaskTy = std::function<void()>; + using PackagedTaskTy = std::packaged_task<void()>; +#else + // MSVC 2013 has a bug and can't use std::packaged_task<void()>; + // We force it to use bool(bool) instead. + using VoidTy = bool; + using TaskTy = std::function<bool(bool)>; + using PackagedTaskTy = std::packaged_task<bool(bool)>; +#endif + + /// Construct a pool with the number of core available on the system (or + /// whatever the value returned by std::thread::hardware_concurrency() is). + ThreadPool(); + + /// Construct a pool of \p ThreadCount threads + ThreadPool(unsigned ThreadCount); + + /// Blocking destructor: the pool will wait for all the threads to complete. + ~ThreadPool(); + + /// Asynchronous submission of a task to the pool. The returned future can be + /// used to wait for the task to finish and is *non-blocking* on destruction. + template <typename Function, typename... Args> + inline std::shared_future<VoidTy> async(Function &&F, Args &&... ArgList) { + auto Task = + std::bind(std::forward<Function>(F), std::forward<Args>(ArgList)...); +#ifndef _MSC_VER + return asyncImpl(std::move(Task)); +#else + // This lambda has to be marked mutable because MSVC 2013's std::bind call + // operator isn't const qualified. + return asyncImpl([Task](VoidTy) mutable -> VoidTy { + Task(); + return VoidTy(); + }); +#endif + } + + /// Asynchronous submission of a task to the pool. The returned future can be + /// used to wait for the task to finish and is *non-blocking* on destruction. + template <typename Function> + inline std::shared_future<VoidTy> async(Function &&F) { +#ifndef _MSC_VER + return asyncImpl(std::forward<Function>(F)); +#else + return asyncImpl([F] (VoidTy) -> VoidTy { F(); return VoidTy(); }); +#endif + } + + /// Blocking wait for all the threads to complete and the queue to be empty. + /// It is an error to try to add new tasks while blocking on this call. + void wait(); + +private: + /// Asynchronous submission of a task to the pool. The returned future can be + /// used to wait for the task to finish and is *non-blocking* on destruction. + std::shared_future<VoidTy> asyncImpl(TaskTy F); + + /// Threads in flight + std::vector<llvm::thread> Threads; + + /// Tasks waiting for execution in the pool. + std::queue<PackagedTaskTy> Tasks; + + /// Locking and signaling for accessing the Tasks queue. + std::mutex QueueLock; + std::condition_variable QueueCondition; + + /// Locking and signaling for job completion + std::mutex CompletionLock; + std::condition_variable CompletionCondition; + + /// Keep track of the number of thread actually busy + std::atomic<unsigned> ActiveThreads; + +#if LLVM_ENABLE_THREADS // avoids warning for unused variable + /// Signal for the destruction of the pool, asking thread to exit. + bool EnableFlag; +#endif +}; +} + +#endif // LLVM_SUPPORT_THREAD_POOL_H diff --git a/contrib/llvm/include/llvm/Support/Threading.h b/contrib/llvm/include/llvm/Support/Threading.h index 3cca1d6..9007c13 100644 --- a/contrib/llvm/include/llvm/Support/Threading.h +++ b/contrib/llvm/include/llvm/Support/Threading.h @@ -21,7 +21,7 @@ namespace llvm { bool llvm_is_multithreaded(); /// llvm_execute_on_thread - Execute the given \p UserFn on a separate - /// thread, passing it the provided \p UserData and waits for thread + /// thread, passing it the provided \p UserData and waits for thread /// completion. /// /// This function does not guarantee that the code will actually be executed diff --git a/contrib/llvm/include/llvm/Support/Timer.h b/contrib/llvm/include/llvm/Support/Timer.h index 2cd30e2..499fe7b 100644 --- a/contrib/llvm/include/llvm/Support/Timer.h +++ b/contrib/llvm/include/llvm/Support/Timer.h @@ -30,26 +30,25 @@ class TimeRecord { ssize_t MemUsed; // Memory allocated (in bytes) public: TimeRecord() : WallTime(0), UserTime(0), SystemTime(0), MemUsed(0) {} - + /// getCurrentTime - Get the current time and memory usage. If Start is true /// we get the memory usage before the time, otherwise we get time before /// memory usage. This matters if the time to get the memory usage is /// significant and shouldn't be counted as part of a duration. static TimeRecord getCurrentTime(bool Start = true); - - double getProcessTime() const { return UserTime+SystemTime; } + + double getProcessTime() const { return UserTime + SystemTime; } double getUserTime() const { return UserTime; } double getSystemTime() const { return SystemTime; } double getWallTime() const { return WallTime; } ssize_t getMemUsed() const { return MemUsed; } - - + // operator< - Allow sorting. bool operator<(const TimeRecord &T) const { // Sort by Wall Time elapsed, as it is the only thing really accurate return WallTime < T.WallTime; } - + void operator+=(const TimeRecord &RHS) { WallTime += RHS.WallTime; UserTime += RHS.UserTime; @@ -62,12 +61,12 @@ public: SystemTime -= RHS.SystemTime; MemUsed -= RHS.MemUsed; } - - /// print - Print the current timer to standard error, and reset the "Started" - /// flag. + + /// Print the current time record to \p OS, with a breakdown showing + /// contributions to the \p Total time record. void print(const TimeRecord &Total, raw_ostream &OS) const; }; - + /// Timer - This class is used to track the amount of time spent between /// invocations of its startTimer()/stopTimer() methods. Given appropriate OS /// support it can also keep track of the RSS of the program at various points. @@ -77,11 +76,13 @@ public: /// if they are never started. /// class Timer { - TimeRecord Time; + TimeRecord Time; // The total time captured + TimeRecord StartTime; // The time startTimer() was last called std::string Name; // The name of this time variable. - bool Started; // Has this time variable ever been started? + bool Running; // Is the timer currently running? + bool Triggered; // Has the timer ever been triggered? TimerGroup *TG; // The TimerGroup this Timer is in. - + Timer **Prev, *Next; // Doubly linked list of timers in the group. public: explicit Timer(StringRef N) : TG(nullptr) { init(N); } @@ -99,25 +100,31 @@ public: explicit Timer() : TG(nullptr) {} void init(StringRef N); void init(StringRef N, TimerGroup &tg); - + const std::string &getName() const { return Name; } bool isInitialized() const { return TG != nullptr; } - - /// startTimer - Start the timer running. Time between calls to - /// startTimer/stopTimer is counted by the Timer class. Note that these calls - /// must be correctly paired. - /// + + /// Check if startTimer() has ever been called on this timer. + bool hasTriggered() const { return Triggered; } + + /// Start the timer running. Time between calls to startTimer/stopTimer is + /// counted by the Timer class. Note that these calls must be correctly + /// paired. void startTimer(); - /// stopTimer - Stop the timer. - /// + /// Stop the timer. void stopTimer(); + /// Clear the timer state. + void clear(); + + /// Return the duration for which this timer has been running. + TimeRecord getTotalTime() const { return Time; } + private: friend class TimerGroup; }; - /// The TimeRegion class is used as a helper class to call the startTimer() and /// stopTimer() methods of the Timer class. When the object is constructed, it /// starts the timer specified as its argument. When it is destroyed, it stops @@ -126,6 +133,7 @@ private: class TimeRegion { Timer *T; TimeRegion(const TimeRegion &) = delete; + public: explicit TimeRegion(Timer &t) : T(&t) { T->startTimer(); @@ -138,7 +146,6 @@ public: } }; - /// NamedRegionTimer - This class is basically a combination of TimeRegion and /// Timer. It allows you to declare a new timer, AND specify the region to /// time, all in one statement. All timers with the same name are merged. This @@ -151,7 +158,6 @@ struct NamedRegionTimer : public TimeRegion { bool Enabled = true); }; - /// The TimerGroup class is used to group together related timers into a single /// report that is printed when the TimerGroup is destroyed. It is illegal to /// destroy a TimerGroup object before all of the Timers in it are gone. A @@ -160,11 +166,12 @@ struct NamedRegionTimer : public TimeRegion { class TimerGroup { std::string Name; Timer *FirstTimer; // First timer in the group. - std::vector<std::pair<TimeRecord, std::string> > TimersToPrint; - + std::vector<std::pair<TimeRecord, std::string>> TimersToPrint; + TimerGroup **Prev, *Next; // Doubly linked list of TimerGroup's. TimerGroup(const TimerGroup &TG) = delete; void operator=(const TimerGroup &TG) = delete; + public: explicit TimerGroup(StringRef name); ~TimerGroup(); @@ -173,10 +180,10 @@ public: /// print - Print any started timers in this group and zero them. void print(raw_ostream &OS); - + /// printAll - This static method prints all timers and clears them all out. static void printAll(raw_ostream &OS); - + private: friend class Timer; void addTimer(Timer &T); diff --git a/contrib/llvm/include/llvm/Support/TrailingObjects.h b/contrib/llvm/include/llvm/Support/TrailingObjects.h new file mode 100644 index 0000000..8529746 --- /dev/null +++ b/contrib/llvm/include/llvm/Support/TrailingObjects.h @@ -0,0 +1,349 @@ +//===--- TrailingObjects.h - Variable-length classes ------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// This header defines support for implementing classes that have +/// some trailing object (or arrays of objects) appended to them. The +/// main purpose is to make it obvious where this idiom is being used, +/// and to make the usage more idiomatic and more difficult to get +/// wrong. +/// +/// The TrailingObject template abstracts away the reinterpret_cast, +/// pointer arithmetic, and size calculations used for the allocation +/// and access of appended arrays of objects, and takes care that they +/// are all allocated at their required alignment. Additionally, it +/// ensures that the base type is final -- deriving from a class that +/// expects data appended immediately after it is typically not safe. +/// +/// Users are expected to derive from this template, and provide +/// numTrailingObjects implementations for each trailing type except +/// the last, e.g. like this sample: +/// +/// \code +/// class VarLengthObj : private TrailingObjects<VarLengthObj, int, double> { +/// friend TrailingObjects; +/// +/// unsigned NumInts, NumDoubles; +/// size_t numTrailingObjects(OverloadToken<int>) const { return NumInts; } +/// }; +/// \endcode +/// +/// You can access the appended arrays via 'getTrailingObjects', and +/// determine the size needed for allocation via +/// 'additionalSizeToAlloc' and 'totalSizeToAlloc'. +/// +/// All the methods implemented by this class are are intended for use +/// by the implementation of the class, not as part of its interface +/// (thus, private inheritance is suggested). +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_TRAILINGOBJECTS_H +#define LLVM_SUPPORT_TRAILINGOBJECTS_H + +#include "llvm/Support/AlignOf.h" +#include "llvm/Support/Compiler.h" +#include "llvm/Support/MathExtras.h" +#include "llvm/Support/type_traits.h" +#include <new> +#include <type_traits> + +namespace llvm { + +namespace trailing_objects_internal { +/// Helper template to calculate the max alignment requirement for a set of +/// objects. +template <typename First, typename... Rest> class AlignmentCalcHelper { +private: + enum { + FirstAlignment = AlignOf<First>::Alignment, + RestAlignment = AlignmentCalcHelper<Rest...>::Alignment, + }; + +public: + enum { + Alignment = FirstAlignment > RestAlignment ? FirstAlignment : RestAlignment + }; +}; + +template <typename First> class AlignmentCalcHelper<First> { +public: + enum { Alignment = AlignOf<First>::Alignment }; +}; + +/// The base class for TrailingObjects* classes. +class TrailingObjectsBase { +protected: + /// OverloadToken's purpose is to allow specifying function overloads + /// for different types, without actually taking the types as + /// parameters. (Necessary because member function templates cannot + /// be specialized, so overloads must be used instead of + /// specialization.) + template <typename T> struct OverloadToken {}; +}; + +/// This helper template works-around MSVC 2013's lack of useful +/// alignas() support. The argument to LLVM_ALIGNAS(), in MSVC, is +/// required to be a literal integer. But, you *can* use template +/// specialization to select between a bunch of different LLVM_ALIGNAS +/// expressions... +template <int Align> +class TrailingObjectsAligner : public TrailingObjectsBase {}; +template <> +class LLVM_ALIGNAS(1) TrailingObjectsAligner<1> : public TrailingObjectsBase {}; +template <> +class LLVM_ALIGNAS(2) TrailingObjectsAligner<2> : public TrailingObjectsBase {}; +template <> +class LLVM_ALIGNAS(4) TrailingObjectsAligner<4> : public TrailingObjectsBase {}; +template <> +class LLVM_ALIGNAS(8) TrailingObjectsAligner<8> : public TrailingObjectsBase {}; +template <> +class LLVM_ALIGNAS(16) TrailingObjectsAligner<16> : public TrailingObjectsBase { +}; +template <> +class LLVM_ALIGNAS(32) TrailingObjectsAligner<32> : public TrailingObjectsBase { +}; + +// Just a little helper for transforming a type pack into the same +// number of a different type. e.g.: +// ExtractSecondType<Foo..., int>::type +template <typename Ty1, typename Ty2> struct ExtractSecondType { + typedef Ty2 type; +}; + +// TrailingObjectsImpl is somewhat complicated, because it is a +// recursively inheriting template, in order to handle the template +// varargs. Each level of inheritance picks off a single trailing type +// then recurses on the rest. The "Align", "BaseTy", and +// "TopTrailingObj" arguments are passed through unchanged through the +// recursion. "PrevTy" is, at each level, the type handled by the +// level right above it. + +template <int Align, typename BaseTy, typename TopTrailingObj, typename PrevTy, + typename... MoreTys> +struct TrailingObjectsImpl { + // The main template definition is never used -- the two + // specializations cover all possibilities. +}; + +template <int Align, typename BaseTy, typename TopTrailingObj, typename PrevTy, + typename NextTy, typename... MoreTys> +struct TrailingObjectsImpl<Align, BaseTy, TopTrailingObj, PrevTy, NextTy, + MoreTys...> + : public TrailingObjectsImpl<Align, BaseTy, TopTrailingObj, NextTy, + MoreTys...> { + + typedef TrailingObjectsImpl<Align, BaseTy, TopTrailingObj, NextTy, MoreTys...> + ParentType; + + // Ensure the methods we inherit are not hidden. + using ParentType::getTrailingObjectsImpl; + using ParentType::additionalSizeToAllocImpl; + + static LLVM_CONSTEXPR bool requiresRealignment() { + return llvm::AlignOf<PrevTy>::Alignment < llvm::AlignOf<NextTy>::Alignment; + } + + // These two functions are helper functions for + // TrailingObjects::getTrailingObjects. They recurse to the left -- + // the result for each type in the list of trailing types depends on + // the result of calling the function on the type to the + // left. However, the function for the type to the left is + // implemented by a *subclass* of this class, so we invoke it via + // the TopTrailingObj, which is, via the + // curiously-recurring-template-pattern, the most-derived type in + // this recursion, and thus, contains all the overloads. + static const NextTy * + getTrailingObjectsImpl(const BaseTy *Obj, + TrailingObjectsBase::OverloadToken<NextTy>) { + auto *Ptr = TopTrailingObj::getTrailingObjectsImpl( + Obj, TrailingObjectsBase::OverloadToken<PrevTy>()) + + TopTrailingObj::callNumTrailingObjects( + Obj, TrailingObjectsBase::OverloadToken<PrevTy>()); + + if (requiresRealignment()) + return reinterpret_cast<const NextTy *>( + llvm::alignAddr(Ptr, llvm::alignOf<NextTy>())); + else + return reinterpret_cast<const NextTy *>(Ptr); + } + + static NextTy * + getTrailingObjectsImpl(BaseTy *Obj, + TrailingObjectsBase::OverloadToken<NextTy>) { + auto *Ptr = TopTrailingObj::getTrailingObjectsImpl( + Obj, TrailingObjectsBase::OverloadToken<PrevTy>()) + + TopTrailingObj::callNumTrailingObjects( + Obj, TrailingObjectsBase::OverloadToken<PrevTy>()); + + if (requiresRealignment()) + return reinterpret_cast<NextTy *>( + llvm::alignAddr(Ptr, llvm::alignOf<NextTy>())); + else + return reinterpret_cast<NextTy *>(Ptr); + } + + // Helper function for TrailingObjects::additionalSizeToAlloc: this + // function recurses to superclasses, each of which requires one + // fewer size_t argument, and adds its own size. + static LLVM_CONSTEXPR size_t additionalSizeToAllocImpl( + size_t SizeSoFar, size_t Count1, + typename ExtractSecondType<MoreTys, size_t>::type... MoreCounts) { + return additionalSizeToAllocImpl( + (requiresRealignment() + ? llvm::RoundUpToAlignment(SizeSoFar, llvm::alignOf<NextTy>()) + : SizeSoFar) + + sizeof(NextTy) * Count1, + MoreCounts...); + } +}; + +// The base case of the TrailingObjectsImpl inheritance recursion, +// when there's no more trailing types. +template <int Align, typename BaseTy, typename TopTrailingObj, typename PrevTy> +struct TrailingObjectsImpl<Align, BaseTy, TopTrailingObj, PrevTy> + : public TrailingObjectsAligner<Align> { + // This is a dummy method, only here so the "using" doesn't fail -- + // it will never be called, because this function recurses backwards + // up the inheritance chain to subclasses. + static void getTrailingObjectsImpl(); + + static LLVM_CONSTEXPR size_t additionalSizeToAllocImpl(size_t SizeSoFar) { + return SizeSoFar; + } + + template <bool CheckAlignment> static void verifyTrailingObjectsAlignment() {} +}; + +} // end namespace trailing_objects_internal + +// Finally, the main type defined in this file, the one intended for users... + +/// See the file comment for details on the usage of the +/// TrailingObjects type. +template <typename BaseTy, typename... TrailingTys> +class TrailingObjects : private trailing_objects_internal::TrailingObjectsImpl< + trailing_objects_internal::AlignmentCalcHelper< + TrailingTys...>::Alignment, + BaseTy, TrailingObjects<BaseTy, TrailingTys...>, + BaseTy, TrailingTys...> { + + template <int A, typename B, typename T, typename P, typename... M> + friend struct trailing_objects_internal::TrailingObjectsImpl; + + template <typename... Tys> class Foo {}; + + typedef trailing_objects_internal::TrailingObjectsImpl< + trailing_objects_internal::AlignmentCalcHelper<TrailingTys...>::Alignment, + BaseTy, TrailingObjects<BaseTy, TrailingTys...>, BaseTy, TrailingTys...> + ParentType; + using TrailingObjectsBase = trailing_objects_internal::TrailingObjectsBase; + + using ParentType::getTrailingObjectsImpl; + + // This function contains only a static_assert BaseTy is final. The + // static_assert must be in a function, and not at class-level + // because BaseTy isn't complete at class instantiation time, but + // will be by the time this function is instantiated. + static void verifyTrailingObjectsAssertions() { +#ifdef LLVM_IS_FINAL + static_assert(LLVM_IS_FINAL(BaseTy), "BaseTy must be final."); +#endif + } + + // These two methods are the base of the recursion for this method. + static const BaseTy * + getTrailingObjectsImpl(const BaseTy *Obj, + TrailingObjectsBase::OverloadToken<BaseTy>) { + return Obj; + } + + static BaseTy * + getTrailingObjectsImpl(BaseTy *Obj, + TrailingObjectsBase::OverloadToken<BaseTy>) { + return Obj; + } + + // callNumTrailingObjects simply calls numTrailingObjects on the + // provided Obj -- except when the type being queried is BaseTy + // itself. There is always only one of the base object, so that case + // is handled here. (An additional benefit of indirecting through + // this function is that consumers only say "friend + // TrailingObjects", and thus, only this class itself can call the + // numTrailingObjects function.) + static size_t + callNumTrailingObjects(const BaseTy *Obj, + TrailingObjectsBase::OverloadToken<BaseTy>) { + return 1; + } + + template <typename T> + static size_t callNumTrailingObjects(const BaseTy *Obj, + TrailingObjectsBase::OverloadToken<T>) { + return Obj->numTrailingObjects(TrailingObjectsBase::OverloadToken<T>()); + } + +public: + // make this (privately inherited) class public. + using ParentType::OverloadToken; + + /// Returns a pointer to the trailing object array of the given type + /// (which must be one of those specified in the class template). The + /// array may have zero or more elements in it. + template <typename T> const T *getTrailingObjects() const { + verifyTrailingObjectsAssertions(); + // Forwards to an impl function with overloads, since member + // function templates can't be specialized. + return this->getTrailingObjectsImpl( + static_cast<const BaseTy *>(this), + TrailingObjectsBase::OverloadToken<T>()); + } + + /// Returns a pointer to the trailing object array of the given type + /// (which must be one of those specified in the class template). The + /// array may have zero or more elements in it. + template <typename T> T *getTrailingObjects() { + verifyTrailingObjectsAssertions(); + // Forwards to an impl function with overloads, since member + // function templates can't be specialized. + return this->getTrailingObjectsImpl( + static_cast<BaseTy *>(this), TrailingObjectsBase::OverloadToken<T>()); + } + + /// Returns the size of the trailing data, if an object were + /// allocated with the given counts (The counts are in the same order + /// as the template arguments). This does not include the size of the + /// base object. The template arguments must be the same as those + /// used in the class; they are supplied here redundantly only so + /// that it's clear what the counts are counting in callers. + template <typename... Tys> + static LLVM_CONSTEXPR typename std::enable_if< + std::is_same<Foo<TrailingTys...>, Foo<Tys...>>::value, size_t>::type + additionalSizeToAlloc( + typename trailing_objects_internal::ExtractSecondType< + TrailingTys, size_t>::type... Counts) { + return ParentType::additionalSizeToAllocImpl(0, Counts...); + } + + /// Returns the total size of an object if it were allocated with the + /// given trailing object counts. This is the same as + /// additionalSizeToAlloc, except it *does* include the size of the base + /// object. + template <typename... Tys> + static LLVM_CONSTEXPR typename std::enable_if< + std::is_same<Foo<TrailingTys...>, Foo<Tys...>>::value, size_t>::type + totalSizeToAlloc(typename trailing_objects_internal::ExtractSecondType< + TrailingTys, size_t>::type... Counts) { + return sizeof(BaseTy) + ParentType::additionalSizeToAllocImpl(0, Counts...); + } +}; + +} // end namespace llvm + +#endif diff --git a/contrib/llvm/include/llvm/Support/UnicodeCharRanges.h b/contrib/llvm/include/llvm/Support/UnicodeCharRanges.h index 9f738df..134698c 100644 --- a/contrib/llvm/include/llvm/Support/UnicodeCharRanges.h +++ b/contrib/llvm/include/llvm/Support/UnicodeCharRanges.h @@ -51,6 +51,11 @@ public: /// the constructor, so it makes sense to create as few UnicodeCharSet /// instances per each array of ranges, as possible. #ifdef NDEBUG + + // FIXME: This could use constexpr + static_assert. This way we + // may get rid of NDEBUG in this header. Unfortunately there are some + // problems to get this working with MSVC 2013. Change this when + // the support for MSVC 2013 is dropped. LLVM_CONSTEXPR UnicodeCharSet(CharRanges Ranges) : Ranges(Ranges) {} #else UnicodeCharSet(CharRanges Ranges) : Ranges(Ranges) { diff --git a/contrib/llvm/include/llvm/Support/Valgrind.h b/contrib/llvm/include/llvm/Support/Valgrind.h index cebf75c..12b0dc9 100644 --- a/contrib/llvm/include/llvm/Support/Valgrind.h +++ b/contrib/llvm/include/llvm/Support/Valgrind.h @@ -20,17 +20,6 @@ #include "llvm/Support/Compiler.h" #include <stddef.h> -#if LLVM_ENABLE_THREADS != 0 && !defined(NDEBUG) -// tsan (Thread Sanitizer) is a valgrind-based tool that detects these exact -// functions by name. -extern "C" { -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 - namespace llvm { namespace sys { // True if Valgrind is controlling this process. @@ -39,34 +28,6 @@ namespace sys { // Discard valgrind's translation of code in the range [Addr .. Addr + Len). // Otherwise valgrind may continue to execute the old version of the code. void ValgrindDiscardTranslations(const void *Addr, size_t Len); - -#if LLVM_ENABLE_THREADS != 0 && !defined(NDEBUG) - // Thread Sanitizer is a valgrind tool that finds races in code. - // See http://code.google.com/p/data-race-test/wiki/DynamicAnnotations . - - // This marker is used to define a happens-before arc. The race detector will - // infer an arc from the begin to the end when they share the same pointer - // argument. - #define TsanHappensBefore(cv) \ - AnnotateHappensBefore(__FILE__, __LINE__, cv) - - // This marker defines the destination of a happens-before arc. - #define TsanHappensAfter(cv) \ - AnnotateHappensAfter(__FILE__, __LINE__, cv) - - // Ignore any races on writes between here and the next TsanIgnoreWritesEnd. - #define TsanIgnoreWritesBegin() \ - AnnotateIgnoreWritesBegin(__FILE__, __LINE__) - - // Resume checking for racy writes. - #define TsanIgnoreWritesEnd() \ - AnnotateIgnoreWritesEnd(__FILE__, __LINE__) -#else - #define TsanHappensBefore(cv) - #define TsanHappensAfter(cv) - #define TsanIgnoreWritesBegin() - #define TsanIgnoreWritesEnd() -#endif } } diff --git a/contrib/llvm/include/llvm/Support/YAMLParser.h b/contrib/llvm/include/llvm/Support/YAMLParser.h index 0fbb7d2..b056ab6 100644 --- a/contrib/llvm/include/llvm/Support/YAMLParser.h +++ b/contrib/llvm/include/llvm/Support/YAMLParser.h @@ -145,11 +145,12 @@ public: unsigned int getType() const { return TypeID; } void *operator new(size_t Size, BumpPtrAllocator &Alloc, - size_t Alignment = 16) throw() { + size_t Alignment = 16) LLVM_NOEXCEPT { return Alloc.Allocate(Size, Alignment); } - void operator delete(void *Ptr, BumpPtrAllocator &Alloc, size_t Size) throw() { + void operator delete(void *Ptr, BumpPtrAllocator &Alloc, + size_t Size) LLVM_NOEXCEPT { Alloc.Deallocate(Ptr, Size); } @@ -157,7 +158,7 @@ protected: std::unique_ptr<Document> &Doc; SMRange SourceRange; - void operator delete(void *) throw() {} + void operator delete(void *) LLVM_NOEXCEPT = delete; ~Node() = default; diff --git a/contrib/llvm/include/llvm/Support/YAMLTraits.h b/contrib/llvm/include/llvm/Support/YAMLTraits.h index c04294a..fb2badf 100644 --- a/contrib/llvm/include/llvm/Support/YAMLTraits.h +++ b/contrib/llvm/include/llvm/Support/YAMLTraits.h @@ -10,7 +10,6 @@ #ifndef LLVM_SUPPORT_YAMLTRAITS_H #define LLVM_SUPPORT_YAMLTRAITS_H - #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseMapInfo.h" #include "llvm/ADT/Optional.h" @@ -29,7 +28,6 @@ namespace llvm { namespace yaml { - /// This class should be specialized by any type that needs to be converted /// to/from a YAML mapping. For example: /// @@ -52,7 +50,6 @@ struct MappingTraits { // static const bool flow = true; }; - /// This class should be specialized by any integral type that converts /// to/from a YAML scalar where there is a one-to-one mapping between /// in-memory values and a string in YAML. For example: @@ -70,7 +67,6 @@ struct ScalarEnumerationTraits { // static void enumeration(IO &io, T &value); }; - /// This class should be specialized by any integer type that is a union /// of bit values and the YAML representation is a flow sequence of /// strings. For example: @@ -88,7 +84,6 @@ struct ScalarBitSetTraits { // static void bitset(IO &io, T &value); }; - /// This class should be specialized by type that requires custom conversion /// to/from a yaml scalar. For example: /// @@ -149,7 +144,6 @@ struct BlockScalarTraits { // static StringRef input(StringRef Scalar, void *ctxt, T &Value); }; - /// This class should be specialized by any type that needs to be converted /// to/from a YAML sequence. For example: /// @@ -175,7 +169,6 @@ struct SequenceTraits { // static const bool flow = true; }; - /// This class should be specialized by any type that needs to be converted /// to/from a list of YAML documents. template<typename T> @@ -185,7 +178,6 @@ struct DocumentListTraits { // static T::value_type& element(IO &io, T &seq, size_t index); }; - // Only used by compiler if both template types are the same template <typename T, T> struct SameType; @@ -194,8 +186,6 @@ struct SameType; template <typename T> struct MissingTrait; - - // Test if ScalarEnumerationTraits<T> is defined on type T. template <class T> struct has_ScalarEnumerationTraits @@ -213,7 +203,6 @@ public: (sizeof(test<ScalarEnumerationTraits<T> >(nullptr)) == 1); }; - // Test if ScalarBitSetTraits<T> is defined on type T. template <class T> struct has_ScalarBitSetTraits @@ -230,7 +219,6 @@ public: static bool const value = (sizeof(test<ScalarBitSetTraits<T> >(nullptr)) == 1); }; - // Test if ScalarTraits<T> is defined on type T. template <class T> struct has_ScalarTraits @@ -252,7 +240,6 @@ public: (sizeof(test<ScalarTraits<T>>(nullptr, nullptr, nullptr)) == 1); }; - // Test if BlockScalarTraits<T> is defined on type T. template <class T> struct has_BlockScalarTraits @@ -272,7 +259,6 @@ public: (sizeof(test<BlockScalarTraits<T>>(nullptr, nullptr)) == 1); }; - // Test if MappingTraits<T> is defined on type T. template <class T> struct has_MappingTraits @@ -305,8 +291,6 @@ public: static bool const value = (sizeof(test<MappingTraits<T> >(nullptr)) == 1); }; - - // Test if SequenceTraits<T> is defined on type T. template <class T> struct has_SequenceMethodTraits @@ -323,7 +307,6 @@ public: static bool const value = (sizeof(test<SequenceTraits<T> >(nullptr)) == 1); }; - // has_FlowTraits<int> will cause an error with some compilers because // it subclasses int. Using this wrapper only instantiates the // real has_FlowTraits only if the template type is a class. @@ -353,14 +336,11 @@ public: static bool const value = sizeof(f<Derived>(nullptr)) == 2; }; - - // Test if SequenceTraits<T> is defined on type T template<typename T> struct has_SequenceTraits : public std::integral_constant<bool, has_SequenceMethodTraits<T>::value > { }; - // Test if DocumentListTraits<T> is defined on type T template <class T> struct has_DocumentListTraits @@ -453,7 +433,6 @@ inline bool needsQuotes(StringRef S) { return false; } - template<typename T> struct missingTraits : public std::integral_constant<bool, !has_ScalarEnumerationTraits<T>::value @@ -654,8 +633,6 @@ private: void *Ctxt; }; - - template<typename T> typename std::enable_if<has_ScalarEnumerationTraits<T>::value,void>::type yamlize(IO &io, T &Val, bool) { @@ -676,7 +653,6 @@ yamlize(IO &io, T &Val, bool) { } } - template<typename T> typename std::enable_if<has_ScalarTraits<T>::value,void>::type yamlize(IO &io, T &Val, bool) { @@ -791,7 +767,6 @@ yamlize(IO &io, T &Seq, bool) { } } - template<> struct ScalarTraits<bool> { static void output(const bool &, void*, llvm::raw_ostream &); @@ -883,8 +858,6 @@ struct ScalarTraits<double> { static bool mustQuote(StringRef) { return false; } }; - - // Utility for use within MappingTraits<>::mapping() method // to [de]normalize an object for use with YAML conversion. template <typename TNorm, typename TFinal> @@ -917,14 +890,12 @@ private: TFinal &Result; }; - - // Utility for use within MappingTraits<>::mapping() method // to [de]normalize an object for use with YAML conversion. template <typename TNorm, typename TFinal> struct MappingNormalizationHeap { MappingNormalizationHeap(IO &i_o, TFinal &Obj) - : io(i_o), BufPtr(NULL), Result(Obj) { + : io(i_o), BufPtr(nullptr), Result(Obj) { if ( io.outputting() ) { BufPtr = new (&Buffer) TNorm(io, Obj); } @@ -953,8 +924,6 @@ private: TFinal &Result; }; - - /// /// The Input class is used to parse a yaml document into in-memory structs /// and vectors. @@ -1083,7 +1052,6 @@ private: void setError(HNode *hnode, const Twine &message); void setError(Node *node, const Twine &message); - public: // These are only used by operator>>. They could be private // if those templated things could be made friends. @@ -1105,9 +1073,6 @@ private: bool ScalarMatchFound; }; - - - /// /// The Output class is used to generate a yaml document from in-memory structs /// and vectors. @@ -1181,9 +1146,6 @@ private: bool NeedsNewLine; }; - - - /// YAML I/O does conversion based on types. But often native data types /// are just a typedef of built in intergral types (e.g. int). But the C++ /// type matching system sees through the typedef and all the typedefed types @@ -1206,8 +1168,6 @@ private: _base value; \ }; - - /// /// Use these types instead of uintXX_t in any mapping to have /// its yaml output formatted as hexadecimal. @@ -1217,7 +1177,6 @@ LLVM_YAML_STRONG_TYPEDEF(uint16_t, Hex16) LLVM_YAML_STRONG_TYPEDEF(uint32_t, Hex32) LLVM_YAML_STRONG_TYPEDEF(uint64_t, Hex64) - template<> struct ScalarTraits<Hex8> { static void output(const Hex8 &, void*, llvm::raw_ostream &); @@ -1246,7 +1205,6 @@ struct ScalarTraits<Hex64> { static bool mustQuote(StringRef) { return false; } }; - // Define non-member operator>> so that Input can stream in a document list. template <typename T> inline @@ -1303,7 +1261,6 @@ operator>>(Input &yin, T &docSeq) { return yin; } - // Define non-member operator<< so that Output can stream out document list. template <typename T> inline @@ -1372,11 +1329,9 @@ operator<<(Output &yout, T &seq) { return yout; } - } // namespace yaml } // namespace llvm - /// Utility for declaring that a std::vector of a particular type /// should be considered a YAML sequence. #define LLVM_YAML_IS_SEQUENCE_VECTOR(_type) \ @@ -1436,6 +1391,4 @@ operator<<(Output &yout, T &seq) { } \ } - - #endif // LLVM_SUPPORT_YAMLTRAITS_H diff --git a/contrib/llvm/include/llvm/Support/circular_raw_ostream.h b/contrib/llvm/include/llvm/Support/circular_raw_ostream.h index 19f9c2c..b46fd7f 100644 --- a/contrib/llvm/include/llvm/Support/circular_raw_ostream.h +++ b/contrib/llvm/include/llvm/Support/circular_raw_ostream.h @@ -17,8 +17,7 @@ #include "llvm/Support/raw_ostream.h" -namespace llvm -{ +namespace llvm { /// circular_raw_ostream - A raw_ostream which *can* save its data /// to a circular buffer, or can pass it through directly to an /// underlying stream if specified with a buffer of zero. @@ -154,5 +153,4 @@ namespace llvm }; } // end llvm namespace - #endif diff --git a/contrib/llvm/include/llvm/Support/raw_ostream.h b/contrib/llvm/include/llvm/Support/raw_ostream.h index 28e512c..d1e96f8 100644 --- a/contrib/llvm/include/llvm/Support/raw_ostream.h +++ b/contrib/llvm/include/llvm/Support/raw_ostream.h @@ -218,14 +218,13 @@ public: // Formatted output, see the leftJustify() function in Support/Format.h. raw_ostream &operator<<(const FormattedString &); - + // Formatted output, see the formatHex() function in Support/Format.h. raw_ostream &operator<<(const FormattedNumber &); - + /// indent - Insert 'NumSpaces' spaces. raw_ostream &indent(unsigned NumSpaces); - /// Changes the foreground color of text that will be output from this point /// forward. /// @param Color ANSI color to use, the special SAVEDCOLOR can be used to @@ -246,7 +245,7 @@ public: /// outputting colored text, or before program exit. virtual raw_ostream &resetColor() { return *this; } - /// Reverses the forground and background colors. + /// Reverses the foreground and background colors. virtual raw_ostream &reverseColor() { return *this; } /// This function determines if this stream is connected to a "tty" or @@ -316,7 +315,7 @@ private: }; /// An abstract base class for streams implementations that also support a -/// pwrite operation. This is usefull for code that can mostly stream out data, +/// pwrite operation. This is useful for code that can mostly stream out data, /// but needs to patch in a header that needs to know the output size. class raw_pwrite_stream : public raw_ostream { virtual void pwrite_impl(const char *Ptr, size_t Size, uint64_t Offset) = 0; @@ -350,10 +349,6 @@ class raw_fd_ostream : public raw_pwrite_stream { /// bool Error; - /// Controls whether the stream should attempt to use atomic writes, when - /// possible. - bool UseAtomicWrites; - uint64_t pos; bool SupportsSeeking; @@ -403,16 +398,6 @@ public: /// to the offset specified from the beginning of the file. uint64_t seek(uint64_t off); - /// Set the stream to attempt to use atomic writes for individual output - /// routines where possible. - /// - /// Note that because raw_ostream's are typically buffered, this flag is only - /// sensible when used on unbuffered streams which will flush their output - /// immediately. - void SetUseAtomicWrites(bool Value) { - UseAtomicWrites = Value; - } - raw_ostream &changeColor(enum Colors colors, bool bold=false, bool bg=false) override; raw_ostream &resetColor() override; @@ -471,6 +456,7 @@ class raw_string_ostream : public raw_ostream { /// Return the current position within the stream, not counting the bytes /// currently in the buffer. uint64_t current_pos() const override { return OS.size(); } + public: explicit raw_string_ostream(std::string &O) : OS(O) {} ~raw_string_ostream() override; @@ -485,6 +471,9 @@ public: /// A raw_ostream that writes to an SmallVector or SmallString. This is a /// simple adaptor class. This class does not encounter output errors. +/// raw_svector_ostream operates without a buffer, delegating all memory +/// management to the SmallString. Thus the SmallString is always up-to-date, +/// may be used directly and there is no need to call flush(). class raw_svector_ostream : public raw_pwrite_stream { SmallVectorImpl<char> &OS; @@ -493,32 +482,23 @@ class raw_svector_ostream : public raw_pwrite_stream { void pwrite_impl(const char *Ptr, size_t Size, uint64_t Offset) override; - /// Return the current position within the stream, not counting the bytes - /// currently in the buffer. + /// Return the current position within the stream. uint64_t current_pos() const override; -protected: - // Like the regular constructor, but doesn't call init. - explicit raw_svector_ostream(SmallVectorImpl<char> &O, unsigned); - void init(); - public: /// Construct a new raw_svector_ostream. /// /// \param O The vector to write to; this should generally have at least 128 /// bytes free to avoid any extraneous memory overhead. - explicit raw_svector_ostream(SmallVectorImpl<char> &O); - ~raw_svector_ostream() override; - + explicit raw_svector_ostream(SmallVectorImpl<char> &O) : OS(O) { + SetUnbuffered(); + } + ~raw_svector_ostream() override {} - /// This is called when the SmallVector we're appending to is changed outside - /// of the raw_svector_ostream's control. It is only safe to do this if the - /// raw_svector_ostream has previously been flushed. - void resync(); + void flush() = delete; - /// Flushes the stream contents to the target vector and return a StringRef - /// for the vector contents. - StringRef str(); + /// Return a StringRef for the vector contents. + StringRef str() { return StringRef(OS.data(), OS.size()); } }; /// A raw_ostream that discards all output. @@ -541,12 +521,10 @@ class buffer_ostream : public raw_svector_ostream { SmallVector<char, 0> Buffer; public: - buffer_ostream(raw_ostream &OS) : raw_svector_ostream(Buffer, 0), OS(OS) { - init(); - } - ~buffer_ostream() { OS << str(); } + buffer_ostream(raw_ostream &OS) : raw_svector_ostream(Buffer), OS(OS) {} + ~buffer_ostream() override { OS << str(); } }; } // end llvm namespace -#endif +#endif // LLVM_SUPPORT_RAW_OSTREAM_H diff --git a/contrib/llvm/include/llvm/Support/thread.h b/contrib/llvm/include/llvm/Support/thread.h new file mode 100644 index 0000000..2d13041 --- /dev/null +++ b/contrib/llvm/include/llvm/Support/thread.h @@ -0,0 +1,66 @@ +//===-- llvm/Support/thread.h - Wrapper for <thread> ------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This header is a wrapper for <thread> that works around problems with the +// MSVC headers when exceptions are disabled. It also provides llvm::thread, +// which is either a typedef of std::thread or a replacement that calls the +// function synchronously depending on the value of LLVM_ENABLE_THREADS. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_THREAD_H +#define LLVM_SUPPORT_THREAD_H + +#include "llvm/Config/llvm-config.h" + +#if LLVM_ENABLE_THREADS + +#ifdef _MSC_VER +// concrt.h depends on eh.h for __uncaught_exception declaration +// even if we disable exceptions. +#include <eh.h> + +// Suppress 'C++ exception handler used, but unwind semantics are not enabled.' +#pragma warning(push) +#pragma warning(disable:4530) +#endif + +#include <thread> + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +namespace llvm { +typedef std::thread thread; +} + +#else // !LLVM_ENABLE_THREADS + +#include <utility> + +namespace llvm { + +struct thread { + thread() {} + thread(thread &&other) {} + template <class Function, class... Args> + explicit thread(Function &&f, Args &&... args) { + f(std::forward<Args>(args)...); + } + thread(const thread &) = delete; + + void join() {} +}; + +} + +#endif // LLVM_ENABLE_THREADS + +#endif diff --git a/contrib/llvm/include/llvm/Support/type_traits.h b/contrib/llvm/include/llvm/Support/type_traits.h index 45465ae..88385c3 100644 --- a/contrib/llvm/include/llvm/Support/type_traits.h +++ b/contrib/llvm/include/llvm/Support/type_traits.h @@ -93,6 +93,15 @@ struct add_const_past_pointer< } +// If the compiler supports detecting whether a class is final, define +// an LLVM_IS_FINAL macro. If it cannot be defined properly, this +// macro will be left undefined. +#if __cplusplus >= 201402L +#define LLVM_IS_FINAL(Ty) std::is_final<Ty>() +#elif __has_feature(is_final) || LLVM_GNUC_PREREQ(4, 7, 0) +#define LLVM_IS_FINAL(Ty) __is_final(Ty) +#endif + #ifdef LLVM_DEFINED_HAS_FEATURE #undef __has_feature #endif |