aboutsummaryrefslogtreecommitdiff
path: root/include/llvm/Support
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/Support')
-rw-r--r--include/llvm/Support/AArch64TargetParser.def72
-rw-r--r--include/llvm/Support/AIXDataTypesFix.h25
-rw-r--r--include/llvm/Support/ARMBuildAttributes.h6
-rw-r--r--include/llvm/Support/ARMTargetParser.def270
-rw-r--r--include/llvm/Support/AlignOf.h21
-rw-r--r--include/llvm/Support/Allocator.h2
-rw-r--r--include/llvm/Support/Atomic.h9
-rw-r--r--include/llvm/Support/AtomicOrdering.h153
-rw-r--r--include/llvm/Support/BranchProbability.h2
-rw-r--r--include/llvm/Support/COFF.h29
-rw-r--r--include/llvm/Support/CachePruning.h69
-rw-r--r--include/llvm/Support/CodeGen.h47
-rw-r--r--include/llvm/Support/CodeGenCWrappers.h64
-rw-r--r--include/llvm/Support/CommandLine.h89
-rw-r--r--include/llvm/Support/Compiler.h35
-rw-r--r--include/llvm/Support/ConvertUTF.h35
-rw-r--r--include/llvm/Support/CrashRecoveryContext.h11
-rw-r--r--include/llvm/Support/DataTypes.h.cmake41
-rw-r--r--include/llvm/Support/DataTypes.h.in123
-rw-r--r--include/llvm/Support/Dwarf.def23
-rw-r--r--include/llvm/Support/Dwarf.h23
-rw-r--r--include/llvm/Support/ELF.h58
-rw-r--r--include/llvm/Support/ELFRelocs/AMDGPU.def12
-rw-r--r--include/llvm/Support/ELFRelocs/BPF.def9
-rw-r--r--include/llvm/Support/ELFRelocs/Hexagon.def1
-rw-r--r--include/llvm/Support/ELFRelocs/Lanai.def19
-rw-r--r--include/llvm/Support/ELFRelocs/Mips.def4
-rw-r--r--include/llvm/Support/ELFRelocs/i386.def2
-rw-r--r--include/llvm/Support/ELFRelocs/x86_64.def3
-rw-r--r--include/llvm/Support/Endian.h4
-rw-r--r--include/llvm/Support/EndianStream.h5
-rw-r--r--include/llvm/Support/Error.h950
-rw-r--r--include/llvm/Support/ErrorHandling.h2
-rw-r--r--include/llvm/Support/ErrorOr.h29
-rw-r--r--include/llvm/Support/FileSystem.h88
-rw-r--r--include/llvm/Support/Format.h8
-rw-r--r--include/llvm/Support/GenericDomTree.h24
-rw-r--r--include/llvm/Support/Host.h2
-rw-r--r--include/llvm/Support/JamCRC.h3
-rw-r--r--include/llvm/Support/Locale.h4
-rw-r--r--include/llvm/Support/LockFileManager.h13
-rw-r--r--include/llvm/Support/MD5.h15
-rw-r--r--include/llvm/Support/MachO.def106
-rw-r--r--include/llvm/Support/MachO.h150
-rw-r--r--include/llvm/Support/ManagedStatic.h53
-rw-r--r--include/llvm/Support/MathExtras.h140
-rw-r--r--include/llvm/Support/OnDiskHashTable.h18
-rw-r--r--include/llvm/Support/Path.h21
-rw-r--r--include/llvm/Support/PointerLikeTypeTraits.h6
-rw-r--r--include/llvm/Support/PrettyStackTrace.h10
-rw-r--r--include/llvm/Support/Printable.h4
-rw-r--r--include/llvm/Support/Process.h5
-rw-r--r--include/llvm/Support/Program.h4
-rw-r--r--include/llvm/Support/RandomNumberGenerator.h2
-rw-r--r--include/llvm/Support/Registry.h179
-rw-r--r--include/llvm/Support/RegistryParser.h55
-rw-r--r--include/llvm/Support/SHA1.h82
-rw-r--r--include/llvm/Support/ScaledNumber.h4
-rw-r--r--include/llvm/Support/ScopedPrinter.h378
-rw-r--r--include/llvm/Support/Signals.h10
-rw-r--r--include/llvm/Support/StreamingMemoryObject.h10
-rw-r--r--include/llvm/Support/SwapByteOrder.h1
-rw-r--r--include/llvm/Support/TargetParser.h56
-rw-r--r--include/llvm/Support/TargetRegistry.h86
-rw-r--r--include/llvm/Support/ThreadPool.h1
-rw-r--r--include/llvm/Support/Threading.h81
-rw-r--r--include/llvm/Support/Timer.h3
-rw-r--r--include/llvm/Support/TrailingObjects.h49
-rw-r--r--include/llvm/Support/TypeName.h65
-rw-r--r--include/llvm/Support/Unicode.h4
-rw-r--r--include/llvm/Support/Valgrind.h12
-rw-r--r--include/llvm/Support/YAMLParser.h1
-rw-r--r--include/llvm/Support/YAMLTraits.h44
-rw-r--r--include/llvm/Support/raw_sha1_ostream.h47
-rw-r--r--include/llvm/Support/thread.h1
-rw-r--r--include/llvm/Support/type_traits.h12
76 files changed, 3213 insertions, 891 deletions
diff --git a/include/llvm/Support/AArch64TargetParser.def b/include/llvm/Support/AArch64TargetParser.def
new file mode 100644
index 000000000000..67f981b8f2fa
--- /dev/null
+++ b/include/llvm/Support/AArch64TargetParser.def
@@ -0,0 +1,72 @@
+//===- AARCH64TargetParser.def - AARCH64 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 AARCH64 target parser's logic.
+//
+//===----------------------------------------------------------------------===//
+
+// NOTE: NO INCLUDE GUARD DESIRED!
+
+#ifndef AARCH64_ARCH
+#define AARCH64_ARCH(NAME, ID, CPU_ATTR, SUB_ARCH, ARCH_ATTR, ARCH_FPU, ARCH_BASE_EXT)
+#endif
+AARCH64_ARCH("armv8-a", AK_ARMV8A, "8-A", "v8", ARMBuildAttrs::CPUArch::v8_A,
+ FK_CRYPTO_NEON_FP_ARMV8,
+ (AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_FP |
+ AArch64::AEK_SIMD | AArch64::AEK_FP16 | AArch64::AEK_PROFILE))
+AARCH64_ARCH("armv8.1-a", AK_ARMV8_1A, "8.1-A", "v8.1a",
+ ARMBuildAttrs::CPUArch::v8_A, FK_CRYPTO_NEON_FP_ARMV8,
+ (AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_FP |
+ AArch64::AEK_SIMD | AArch64::AEK_FP16 | AArch64::AEK_PROFILE))
+AARCH64_ARCH("armv8.2-a", AK_ARMV8_2A, "8.2-A", "v8.2a",
+ ARMBuildAttrs::CPUArch::v8_A, FK_CRYPTO_NEON_FP_ARMV8,
+ (AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_FP |
+ AArch64::AEK_SIMD | AArch64::AEK_FP16 | AArch64::AEK_PROFILE |
+ AArch64::AEK_RAS))
+#undef AARCH64_ARCH
+
+#ifndef AARCH64_ARCH_EXT_NAME
+#define AARCH64_ARCH_EXT_NAME(NAME, ID, FEATURE, NEGFEATURE)
+#endif
+// FIXME: This would be nicer were it tablegen
+AARCH64_ARCH_EXT_NAME("invalid", AArch64::AEK_INVALID, nullptr, nullptr)
+AARCH64_ARCH_EXT_NAME("none", AArch64::AEK_NONE, nullptr, nullptr)
+AARCH64_ARCH_EXT_NAME("crc", AArch64::AEK_CRC, "+crc", "-crc")
+AARCH64_ARCH_EXT_NAME("crypto", AArch64::AEK_CRYPTO, "+crypto","-crypto")
+AARCH64_ARCH_EXT_NAME("fp", AArch64::AEK_FP, "+fp-armv8", "-fp-armv8")
+AARCH64_ARCH_EXT_NAME("simd", AArch64::AEK_SIMD, "+neon", "-neon")
+AARCH64_ARCH_EXT_NAME("fp16", AArch64::AEK_FP16, "+fullfp16", "-fullfp16")
+AARCH64_ARCH_EXT_NAME("profile", AArch64::AEK_PROFILE, "+spe", "-spe")
+AARCH64_ARCH_EXT_NAME("ras", AArch64::AEK_RAS, "+ras", "-ras")
+#undef AARCH64_ARCH_EXT_NAME
+
+#ifndef AARCH64_CPU_NAME
+#define AARCH64_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT)
+#endif
+AARCH64_CPU_NAME("cortex-a35", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false,
+ (AArch64::AEK_SIMD | AArch64::AEK_CRC | AArch64::AEK_CRYPTO))
+AARCH64_CPU_NAME("cortex-a53", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, true,
+ ( AArch64::AEK_SIMD | AArch64::AEK_CRC | AArch64::AEK_CRYPTO))
+AARCH64_CPU_NAME("cortex-a57", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false,
+ (AArch64::AEK_SIMD | AArch64::AEK_CRC | AArch64::AEK_CRYPTO))
+AARCH64_CPU_NAME("cortex-a72", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false,
+ (AArch64::AEK_SIMD | AArch64::AEK_CRC | AArch64::AEK_CRYPTO))
+AARCH64_CPU_NAME("cortex-a73", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false,
+ (AArch64::AEK_SIMD | AArch64::AEK_CRC | AArch64::AEK_CRYPTO))
+AARCH64_CPU_NAME("cyclone", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false,
+ (AArch64::AEK_SIMD | AArch64::AEK_CRYPTO))
+AARCH64_CPU_NAME("exynos-m1", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false,
+ (AArch64::AEK_SIMD | AArch64::AEK_CRC | AArch64::AEK_CRYPTO))
+AARCH64_CPU_NAME("kryo", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false,
+ (AArch64::AEK_SIMD | AArch64::AEK_CRC | AArch64::AEK_CRYPTO))
+AARCH64_CPU_NAME("vulcan", AK_ARMV8_1A, FK_CRYPTO_NEON_FP_ARMV8, false,
+ (AArch64::AEK_SIMD | AArch64::AEK_CRC | AArch64::AEK_CRYPTO))
+// Invalid CPU
+AARCH64_CPU_NAME("invalid", AK_INVALID, FK_INVALID, true, AArch64::AEK_INVALID)
+#undef AARCH64_CPU_NAME
diff --git a/include/llvm/Support/AIXDataTypesFix.h b/include/llvm/Support/AIXDataTypesFix.h
deleted file mode 100644
index a9a9147de294..000000000000
--- a/include/llvm/Support/AIXDataTypesFix.h
+++ /dev/null
@@ -1,25 +0,0 @@
-//===-- llvm/Support/AIXDataTypesFix.h - Fix datatype defs ------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file overrides default system-defined types and limits which cannot be
-// done in DataTypes.h.in because it is processed by autoheader first, which
-// comments out any #undef statement
-//
-//===----------------------------------------------------------------------===//
-
-// No include guards desired!
-
-#ifndef SUPPORT_DATATYPES_H
-#error "AIXDataTypesFix.h must only be included via DataTypes.h!"
-#endif
-
-// GCC is strict about defining large constants: they must have LL modifier.
-// These will be defined properly at the end of DataTypes.h
-#undef INT64_MAX
-#undef INT64_MIN
diff --git a/include/llvm/Support/ARMBuildAttributes.h b/include/llvm/Support/ARMBuildAttributes.h
index fc14cb2d0b0c..f447cd072b5f 100644
--- a/include/llvm/Support/ARMBuildAttributes.h
+++ b/include/llvm/Support/ARMBuildAttributes.h
@@ -67,6 +67,7 @@ enum AttrType {
ABI_FP_16bit_format = 38,
MPextension_use = 42, // recoded from 70 (ABI r2.08)
DIV_use = 44,
+ DSP_extension = 46,
also_compatible_with = 65,
conformance = 67,
Virtualization_use = 68,
@@ -106,7 +107,9 @@ enum CPUArch {
v6_M = 11, // e.g. Cortex M1
v6S_M = 12, // v6_M with the System extensions
v7E_M = 13, // v7_M with DSP extensions
- v8 = 14, // v8,v8.1a AArch32
+ v8_A = 14, // v8_A AArch32
+ v8_M_Base= 16, // v8_M_Base AArch32
+ v8_M_Main= 17, // v8_M_Main AArch32
};
enum CPUArchProfile { // (=7), uleb128
@@ -126,6 +129,7 @@ enum {
// Tag_THUMB_ISA_use, (=9), uleb128
AllowThumb32 = 2, // 32-bit Thumb (implies 16-bit instructions)
+ AllowThumbDerived = 3, // Thumb allowed, derived from arch/profile
// Tag_FP_arch (=10), uleb128 (formerly Tag_VFP_arch = 10)
AllowFPv2 = 2, // v2 FP ISA permitted (implies use of the v1 FP ISA)
diff --git a/include/llvm/Support/ARMTargetParser.def b/include/llvm/Support/ARMTargetParser.def
index d94a51b8bcf9..195f7112d6a0 100644
--- a/include/llvm/Support/ARMTargetParser.def
+++ b/include/llvm/Support/ARMTargetParser.def
@@ -45,180 +45,198 @@ ARM_FPU("softvfp", FK_SOFTVFP, FV_NONE, NS_None, FR_None)
#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)
+ ARMBuildAttrs::CPUArch::Pre_v4, FK_NONE, ARM::AEK_NONE)
ARM_ARCH("armv2", AK_ARMV2, "2", "v2", ARMBuildAttrs::CPUArch::Pre_v4,
- FK_NONE, AEK_NONE)
+ FK_NONE, ARM::AEK_NONE)
ARM_ARCH("armv2a", AK_ARMV2A, "2A", "v2a", ARMBuildAttrs::CPUArch::Pre_v4,
- FK_NONE, AEK_NONE)
+ FK_NONE, ARM::AEK_NONE)
ARM_ARCH("armv3", AK_ARMV3, "3", "v3", ARMBuildAttrs::CPUArch::Pre_v4,
- FK_NONE, AEK_NONE)
+ FK_NONE, ARM::AEK_NONE)
ARM_ARCH("armv3m", AK_ARMV3M, "3M", "v3m", ARMBuildAttrs::CPUArch::Pre_v4,
- FK_NONE, AEK_NONE)
+ FK_NONE, ARM::AEK_NONE)
ARM_ARCH("armv4", AK_ARMV4, "4", "v4", ARMBuildAttrs::CPUArch::v4,
- FK_NONE, AEK_NONE)
+ FK_NONE, ARM::AEK_NONE)
ARM_ARCH("armv4t", AK_ARMV4T, "4T", "v4t", ARMBuildAttrs::CPUArch::v4T,
- FK_NONE, AEK_NONE)
+ FK_NONE, ARM::AEK_NONE)
ARM_ARCH("armv5t", AK_ARMV5T, "5T", "v5", ARMBuildAttrs::CPUArch::v5T,
- FK_NONE, AEK_NONE)
+ FK_NONE, ARM::AEK_NONE)
ARM_ARCH("armv5te", AK_ARMV5TE, "5TE", "v5e", ARMBuildAttrs::CPUArch::v5TE,
- FK_NONE, AEK_DSP)
+ FK_NONE, ARM::AEK_DSP)
ARM_ARCH("armv5tej", AK_ARMV5TEJ, "5TEJ", "v5e", ARMBuildAttrs::CPUArch::v5TEJ,
- FK_NONE, AEK_DSP)
+ FK_NONE, ARM::AEK_DSP)
ARM_ARCH("armv6", AK_ARMV6, "6", "v6", ARMBuildAttrs::CPUArch::v6,
- FK_VFPV2, AEK_DSP)
+ FK_VFPV2, ARM::AEK_DSP)
ARM_ARCH("armv6k", AK_ARMV6K, "6K", "v6k", ARMBuildAttrs::CPUArch::v6K,
- FK_VFPV2, AEK_DSP)
+ FK_VFPV2, ARM::AEK_DSP)
ARM_ARCH("armv6t2", AK_ARMV6T2, "6T2", "v6t2", ARMBuildAttrs::CPUArch::v6T2,
- FK_NONE, AEK_DSP)
+ FK_NONE, ARM::AEK_DSP)
ARM_ARCH("armv6kz", AK_ARMV6KZ, "6KZ", "v6kz", ARMBuildAttrs::CPUArch::v6KZ,
- FK_VFPV2, (AEK_SEC | AEK_DSP))
+ FK_VFPV2, (ARM::AEK_SEC | ARM::AEK_DSP))
ARM_ARCH("armv6-m", AK_ARMV6M, "6-M", "v6m", ARMBuildAttrs::CPUArch::v6_M,
- FK_NONE, AEK_NONE)
+ FK_NONE, ARM::AEK_NONE)
ARM_ARCH("armv7-a", AK_ARMV7A, "7-A", "v7", ARMBuildAttrs::CPUArch::v7,
- FK_NEON, AEK_DSP)
+ FK_NEON, ARM::AEK_DSP)
ARM_ARCH("armv7-r", AK_ARMV7R, "7-R", "v7r", ARMBuildAttrs::CPUArch::v7,
- FK_NONE, (AEK_HWDIV | AEK_DSP))
+ FK_NONE, (ARM::AEK_HWDIV | ARM::AEK_DSP))
ARM_ARCH("armv7-m", AK_ARMV7M, "7-M", "v7m", ARMBuildAttrs::CPUArch::v7,
- FK_NONE, AEK_HWDIV)
+ FK_NONE, ARM::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))
+ FK_NONE, (ARM::AEK_HWDIV | ARM::AEK_DSP))
+ARM_ARCH("armv8-a", AK_ARMV8A, "8-A", "v8", ARMBuildAttrs::CPUArch::v8_A,
+ FK_CRYPTO_NEON_FP_ARMV8,
+ (ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
+ ARM::AEK_HWDIV | ARM::AEK_DSP | ARM::AEK_CRC))
+ARM_ARCH("armv8.1-a", AK_ARMV8_1A, "8.1-A", "v8.1a",
+ ARMBuildAttrs::CPUArch::v8_A, FK_CRYPTO_NEON_FP_ARMV8,
+ (ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
+ ARM::AEK_HWDIV | ARM::AEK_DSP | ARM::AEK_CRC | ARM::AEK_RAS))
+ARM_ARCH("armv8.2-a", AK_ARMV8_2A, "8.2-A", "v8.2a",
+ ARMBuildAttrs::CPUArch::v8_A, FK_CRYPTO_NEON_FP_ARMV8,
+ (ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
+ ARM::AEK_HWDIV | ARM::AEK_DSP | ARM::AEK_CRC))
+ARM_ARCH("armv8-m.base", AK_ARMV8MBaseline, "8-M.Baseline", "v8m.base",
+ ARMBuildAttrs::CPUArch::v8_M_Base, FK_NONE, ARM::AEK_HWDIV)
+ARM_ARCH("armv8-m.main", AK_ARMV8MMainline, "8-M.Mainline", "v8m.main",
+ ARMBuildAttrs::CPUArch::v8_M_Main, FK_FPV5_D16, ARM::AEK_HWDIV)
// Non-standard Arch names.
ARM_ARCH("iwmmxt", AK_IWMMXT, "iwmmxt", "", ARMBuildAttrs::CPUArch::v5TE,
- FK_NONE, AEK_NONE)
+ FK_NONE, ARM::AEK_NONE)
ARM_ARCH("iwmmxt2", AK_IWMMXT2, "iwmmxt2", "", ARMBuildAttrs::CPUArch::v5TE,
- FK_NONE, AEK_NONE)
+ FK_NONE, ARM::AEK_NONE)
ARM_ARCH("xscale", AK_XSCALE, "xscale", "v5e", ARMBuildAttrs::CPUArch::v5TE,
- FK_NONE, AEK_NONE)
+ FK_NONE, ARM::AEK_NONE)
ARM_ARCH("armv7s", AK_ARMV7S, "7-S", "v7s", ARMBuildAttrs::CPUArch::v7,
- FK_NEON_VFPV4, AEK_DSP)
+ FK_NEON_VFPV4, ARM::AEK_DSP)
ARM_ARCH("armv7k", AK_ARMV7K, "7-K", "v7k", ARMBuildAttrs::CPUArch::v7,
- FK_NONE, AEK_DSP)
+ FK_NONE, ARM::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)
+ARM_ARCH_EXT_NAME("invalid", ARM::AEK_INVALID, nullptr, nullptr)
+ARM_ARCH_EXT_NAME("none", ARM::AEK_NONE, nullptr, nullptr)
+ARM_ARCH_EXT_NAME("crc", ARM::AEK_CRC, "+crc", "-crc")
+ARM_ARCH_EXT_NAME("crypto", ARM::AEK_CRYPTO, "+crypto","-crypto")
+ARM_ARCH_EXT_NAME("dsp", ARM::AEK_DSP, "+dsp", "-dsp")
+ARM_ARCH_EXT_NAME("fp", ARM::AEK_FP, nullptr, nullptr)
+ARM_ARCH_EXT_NAME("idiv", (ARM::AEK_HWDIVARM | ARM::AEK_HWDIV), nullptr, nullptr)
+ARM_ARCH_EXT_NAME("mp", ARM::AEK_MP, nullptr, nullptr)
+ARM_ARCH_EXT_NAME("simd", ARM::AEK_SIMD, nullptr, nullptr)
+ARM_ARCH_EXT_NAME("sec", ARM::AEK_SEC, nullptr, nullptr)
+ARM_ARCH_EXT_NAME("virt", ARM::AEK_VIRT, nullptr, nullptr)
+ARM_ARCH_EXT_NAME("fp16", ARM::AEK_FP16, "+fullfp16", "-fullfp16")
+ARM_ARCH_EXT_NAME("ras", ARM::AEK_RAS, "+ras", "-ras")
+ARM_ARCH_EXT_NAME("os", ARM::AEK_OS, nullptr, nullptr)
+ARM_ARCH_EXT_NAME("iwmmxt", ARM::AEK_IWMMXT, nullptr, nullptr)
+ARM_ARCH_EXT_NAME("iwmmxt2", ARM::AEK_IWMMXT2, nullptr, nullptr)
+ARM_ARCH_EXT_NAME("maverick", ARM::AEK_MAVERICK, nullptr, nullptr)
+ARM_ARCH_EXT_NAME("xscale", ARM::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))
+ARM_HW_DIV_NAME("invalid", ARM::AEK_INVALID)
+ARM_HW_DIV_NAME("none", ARM::AEK_NONE)
+ARM_HW_DIV_NAME("thumb", ARM::AEK_HWDIV)
+ARM_HW_DIV_NAME("arm", ARM::AEK_HWDIVARM)
+ARM_HW_DIV_NAME("arm,thumb", (ARM::AEK_HWDIVARM | ARM::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("arm2", AK_ARMV2, FK_NONE, true, ARM::AEK_NONE)
+ARM_CPU_NAME("arm3", AK_ARMV2A, FK_NONE, true, ARM::AEK_NONE)
+ARM_CPU_NAME("arm6", AK_ARMV3, FK_NONE, true, ARM::AEK_NONE)
+ARM_CPU_NAME("arm7m", AK_ARMV3M, FK_NONE, true, ARM::AEK_NONE)
+ARM_CPU_NAME("arm8", AK_ARMV4, FK_NONE, false, ARM::AEK_NONE)
+ARM_CPU_NAME("arm810", AK_ARMV4, FK_NONE, false, ARM::AEK_NONE)
+ARM_CPU_NAME("strongarm", AK_ARMV4, FK_NONE, true, ARM::AEK_NONE)
+ARM_CPU_NAME("strongarm110", AK_ARMV4, FK_NONE, false, ARM::AEK_NONE)
+ARM_CPU_NAME("strongarm1100", AK_ARMV4, FK_NONE, false, ARM::AEK_NONE)
+ARM_CPU_NAME("strongarm1110", AK_ARMV4, FK_NONE, false, ARM::AEK_NONE)
+ARM_CPU_NAME("arm7tdmi", AK_ARMV4T, FK_NONE, true, ARM::AEK_NONE)
+ARM_CPU_NAME("arm7tdmi-s", AK_ARMV4T, FK_NONE, false, ARM::AEK_NONE)
+ARM_CPU_NAME("arm710t", AK_ARMV4T, FK_NONE, false, ARM::AEK_NONE)
+ARM_CPU_NAME("arm720t", AK_ARMV4T, FK_NONE, false, ARM::AEK_NONE)
+ARM_CPU_NAME("arm9", AK_ARMV4T, FK_NONE, false, ARM::AEK_NONE)
+ARM_CPU_NAME("arm9tdmi", AK_ARMV4T, FK_NONE, false, ARM::AEK_NONE)
+ARM_CPU_NAME("arm920", AK_ARMV4T, FK_NONE, false, ARM::AEK_NONE)
+ARM_CPU_NAME("arm920t", AK_ARMV4T, FK_NONE, false, ARM::AEK_NONE)
+ARM_CPU_NAME("arm922t", AK_ARMV4T, FK_NONE, false, ARM::AEK_NONE)
+ARM_CPU_NAME("arm9312", AK_ARMV4T, FK_NONE, false, ARM::AEK_NONE)
+ARM_CPU_NAME("arm940t", AK_ARMV4T, FK_NONE, false, ARM::AEK_NONE)
+ARM_CPU_NAME("ep9312", AK_ARMV4T, FK_NONE, false, ARM::AEK_NONE)
+ARM_CPU_NAME("arm10tdmi", AK_ARMV5T, FK_NONE, true, ARM::AEK_NONE)
+ARM_CPU_NAME("arm1020t", AK_ARMV5T, FK_NONE, false, ARM::AEK_NONE)
+ARM_CPU_NAME("arm9e", AK_ARMV5TE, FK_NONE, false, ARM::AEK_NONE)
+ARM_CPU_NAME("arm946e-s", AK_ARMV5TE, FK_NONE, false, ARM::AEK_NONE)
+ARM_CPU_NAME("arm966e-s", AK_ARMV5TE, FK_NONE, false, ARM::AEK_NONE)
+ARM_CPU_NAME("arm968e-s", AK_ARMV5TE, FK_NONE, false, ARM::AEK_NONE)
+ARM_CPU_NAME("arm10e", AK_ARMV5TE, FK_NONE, false, ARM::AEK_NONE)
+ARM_CPU_NAME("arm1020e", AK_ARMV5TE, FK_NONE, false, ARM::AEK_NONE)
+ARM_CPU_NAME("arm1022e", AK_ARMV5TE, FK_NONE, true, ARM::AEK_NONE)
+ARM_CPU_NAME("arm926ej-s", AK_ARMV5TEJ, FK_NONE, true, ARM::AEK_NONE)
+ARM_CPU_NAME("arm1136j-s", AK_ARMV6, FK_NONE, false, ARM::AEK_NONE)
+ARM_CPU_NAME("arm1136jf-s", AK_ARMV6, FK_VFPV2, true, ARM::AEK_NONE)
+ARM_CPU_NAME("arm1136jz-s", AK_ARMV6, FK_NONE, false, ARM::AEK_NONE)
+ARM_CPU_NAME("arm1176j-s", AK_ARMV6K, FK_NONE, true, ARM::AEK_NONE)
+ARM_CPU_NAME("arm1176jz-s", AK_ARMV6KZ, FK_NONE, false, ARM::AEK_NONE)
+ARM_CPU_NAME("mpcore", AK_ARMV6K, FK_VFPV2, false, ARM::AEK_NONE)
+ARM_CPU_NAME("mpcorenovfp", AK_ARMV6K, FK_NONE, false, ARM::AEK_NONE)
+ARM_CPU_NAME("arm1176jzf-s", AK_ARMV6KZ, FK_VFPV2, true, ARM::AEK_NONE)
+ARM_CPU_NAME("arm1156t2-s", AK_ARMV6T2, FK_NONE, true, ARM::AEK_NONE)
+ARM_CPU_NAME("arm1156t2f-s", AK_ARMV6T2, FK_VFPV2, false, ARM::AEK_NONE)
+ARM_CPU_NAME("cortex-m0", AK_ARMV6M, FK_NONE, true, ARM::AEK_NONE)
+ARM_CPU_NAME("cortex-m0plus", AK_ARMV6M, FK_NONE, false, ARM::AEK_NONE)
+ARM_CPU_NAME("cortex-m1", AK_ARMV6M, FK_NONE, false, ARM::AEK_NONE)
+ARM_CPU_NAME("sc000", AK_ARMV6M, FK_NONE, false, ARM::AEK_NONE)
+ARM_CPU_NAME("cortex-a5", AK_ARMV7A, FK_NEON_VFPV4, false,
+ (ARM::AEK_SEC | ARM::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::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
+ ARM::AEK_HWDIV))
+ARM_CPU_NAME("cortex-a8", AK_ARMV7A, FK_NEON, true, ARM::AEK_SEC)
+ARM_CPU_NAME("cortex-a9", AK_ARMV7A, FK_NEON_FP16, false, (ARM::AEK_SEC | ARM::AEK_MP))
ARM_CPU_NAME("cortex-a12", AK_ARMV7A, FK_NEON_VFPV4, false,
- (AEK_SEC | AEK_MP | AEK_VIRT | AEK_HWDIVARM | AEK_HWDIV))
+ (ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
+ ARM::AEK_HWDIV))
ARM_CPU_NAME("cortex-a15", AK_ARMV7A, FK_NEON_VFPV4, false,
- (AEK_SEC | AEK_MP | AEK_VIRT | AEK_HWDIVARM | AEK_HWDIV))
+ (ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
+ ARM::AEK_HWDIV))
ARM_CPU_NAME("cortex-a17", AK_ARMV7A, FK_NEON_VFPV4, false,
- (AEK_SEC | AEK_MP | AEK_VIRT | AEK_HWDIVARM | AEK_HWDIV))
+ (ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
+ ARM::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::AEK_HWDIVARM | ARM::AEK_HWDIV))
+ARM_CPU_NAME("cortex-r4", AK_ARMV7R, FK_NONE, true, ARM::AEK_NONE)
+ARM_CPU_NAME("cortex-r4f", AK_ARMV7R, FK_VFPV3_D16, false, ARM::AEK_NONE)
ARM_CPU_NAME("cortex-r5", AK_ARMV7R, FK_VFPV3_D16, false,
- (AEK_MP | AEK_HWDIVARM))
+ (ARM::AEK_MP | ARM::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)
-ARM_CPU_NAME("exynos-m1", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false, AEK_CRC)
+ (ARM::AEK_MP | ARM::AEK_HWDIVARM))
+ARM_CPU_NAME("cortex-r8", AK_ARMV7R, FK_VFPV3_D16_FP16, false,
+ (ARM::AEK_MP | ARM::AEK_HWDIVARM))
+ARM_CPU_NAME("sc300", AK_ARMV7M, FK_NONE, false, ARM::AEK_NONE)
+ARM_CPU_NAME("cortex-m3", AK_ARMV7M, FK_NONE, true, ARM::AEK_NONE)
+ARM_CPU_NAME("cortex-m4", AK_ARMV7EM, FK_FPV4_SP_D16, true, ARM::AEK_NONE)
+ARM_CPU_NAME("cortex-m7", AK_ARMV7EM, FK_FPV5_D16, false, ARM::AEK_NONE)
+ARM_CPU_NAME("cortex-a32", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false, ARM::AEK_CRC)
+ARM_CPU_NAME("cortex-a35", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false, ARM::AEK_CRC)
+ARM_CPU_NAME("cortex-a53", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, true, ARM::AEK_CRC)
+ARM_CPU_NAME("cortex-a57", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false, ARM::AEK_CRC)
+ARM_CPU_NAME("cortex-a72", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false, ARM::AEK_CRC)
+ARM_CPU_NAME("cortex-a73", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false, ARM::AEK_CRC)
+ARM_CPU_NAME("cyclone", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false, ARM::AEK_CRC)
+ARM_CPU_NAME("exynos-m1", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false, ARM::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("iwmmxt", AK_IWMMXT, FK_NONE, true, ARM::AEK_NONE)
+ARM_CPU_NAME("xscale", AK_XSCALE, FK_NONE, true, ARM::AEK_NONE)
ARM_CPU_NAME("swift", AK_ARMV7S, FK_NEON_VFPV4, true,
- (AEK_HWDIVARM | AEK_HWDIV))
+ (ARM::AEK_HWDIVARM | ARM::AEK_HWDIV))
// Invalid CPU
-ARM_CPU_NAME("invalid", AK_INVALID, FK_INVALID, true, AEK_INVALID)
+ARM_CPU_NAME("invalid", AK_INVALID, FK_INVALID, true, ARM::AEK_INVALID)
#undef ARM_CPU_NAME
diff --git a/include/llvm/Support/AlignOf.h b/include/llvm/Support/AlignOf.h
index 5268c8d16986..af7f20028b6d 100644
--- a/include/llvm/Support/AlignOf.h
+++ b/include/llvm/Support/AlignOf.h
@@ -38,7 +38,7 @@ struct AlignmentCalcImpl {
#endif
T t;
private:
- AlignmentCalcImpl() {} // Never instantiate.
+ AlignmentCalcImpl() = delete;
};
// Abstract base class helper, this will have the minimal alignment and size
@@ -55,7 +55,7 @@ struct AlignmentCalcImplBase {
// of type T.
template <typename T>
struct AlignmentCalcImpl<T, true> : AlignmentCalcImplBase, T {
- virtual ~AlignmentCalcImpl() = 0;
+ ~AlignmentCalcImpl() override = 0;
};
} // End detail namespace.
@@ -79,8 +79,8 @@ struct AlignOf {
sizeof(detail::AlignmentCalcImpl<T>) - sizeof(T));
#else
enum {
- Alignment = static_cast<unsigned int>(sizeof(detail::AlignmentCalcImpl<T>) -
- sizeof(T))
+ Alignment = static_cast<unsigned int>(
+ sizeof(::llvm::detail::AlignmentCalcImpl<T>) - sizeof(T))
};
#endif
enum { Alignment_GreaterEqual_2Bytes = Alignment >= 2 ? 1 : 0 };
@@ -223,7 +223,7 @@ template <typename T1,
class AlignerImpl {
T1 t1; T2 t2; T3 t3; T4 t4; T5 t5; T6 t6; T7 t7; T8 t8; T9 t9; T10 t10;
- AlignerImpl(); // Never defined or instantiated.
+ AlignerImpl() = delete;
};
template <typename T1,
@@ -249,10 +249,11 @@ template <typename T1,
typename T5 = char, typename T6 = char, typename T7 = char,
typename T8 = char, typename T9 = char, typename T10 = char>
struct AlignedCharArrayUnion : llvm::AlignedCharArray<
- AlignOf<detail::AlignerImpl<T1, T2, T3, T4, T5,
- T6, T7, T8, T9, T10> >::Alignment,
- sizeof(detail::SizerImpl<T1, T2, T3, T4, T5,
- T6, T7, T8, T9, T10>)> {
+ AlignOf<llvm::detail::AlignerImpl<T1, T2, T3, T4, T5,
+ T6, T7, T8, T9, T10> >::Alignment,
+ sizeof(::llvm::detail::SizerImpl<T1, T2, T3, T4, T5,
+ T6, T7, T8, T9, T10>)> {
};
} // end namespace llvm
-#endif
+
+#endif // LLVM_SUPPORT_ALIGNOF_H
diff --git a/include/llvm/Support/Allocator.h b/include/llvm/Support/Allocator.h
index 043d82314609..1c9508661d6f 100644
--- a/include/llvm/Support/Allocator.h
+++ b/include/llvm/Support/Allocator.h
@@ -278,6 +278,8 @@ public:
return TotalMemory;
}
+ size_t getBytesAllocated() const { return BytesAllocated; }
+
void PrintStats() const {
detail::printBumpPtrAllocatorStats(Slabs.size(), BytesAllocated,
getTotalMemory());
diff --git a/include/llvm/Support/Atomic.h b/include/llvm/Support/Atomic.h
index 9ec23e827023..d03714b009c5 100644
--- a/include/llvm/Support/Atomic.h
+++ b/include/llvm/Support/Atomic.h
@@ -9,6 +9,10 @@
//
// This file declares the llvm::sys atomic operations.
//
+// DO NOT USE IN NEW CODE!
+//
+// New code should always rely on the std::atomic facilities in C++11.
+//
//===----------------------------------------------------------------------===//
#ifndef LLVM_SUPPORT_ATOMIC_H
@@ -28,11 +32,6 @@ namespace llvm {
cas_flag CompareAndSwap(volatile cas_flag* ptr,
cas_flag new_value,
cas_flag old_value);
- cas_flag AtomicIncrement(volatile cas_flag* ptr);
- cas_flag AtomicDecrement(volatile cas_flag* ptr);
- cas_flag AtomicAdd(volatile cas_flag* ptr, cas_flag val);
- cas_flag AtomicMul(volatile cas_flag* ptr, cas_flag val);
- cas_flag AtomicDiv(volatile cas_flag* ptr, cas_flag val);
}
}
diff --git a/include/llvm/Support/AtomicOrdering.h b/include/llvm/Support/AtomicOrdering.h
new file mode 100644
index 000000000000..8837fab19575
--- /dev/null
+++ b/include/llvm/Support/AtomicOrdering.h
@@ -0,0 +1,153 @@
+//===-- llvm/Support/AtomicOrdering.h ---Atomic Ordering---------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Atomic ordering constants.
+///
+/// These values are used by LLVM to represent atomic ordering for C++11's
+/// memory model and more, as detailed in docs/Atomics.rst.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_ATOMICORDERING_H
+#define LLVM_SUPPORT_ATOMICORDERING_H
+
+#include <cstddef>
+
+namespace llvm {
+
+/// Atomic ordering for C11 / C++11's memody models.
+///
+/// These values cannot change because they are shared with standard library
+/// implementations as well as with other compilers.
+enum class AtomicOrderingCABI {
+ relaxed = 0,
+ consume = 1,
+ acquire = 2,
+ release = 3,
+ acq_rel = 4,
+ seq_cst = 5,
+};
+
+bool operator<(AtomicOrderingCABI, AtomicOrderingCABI) = delete;
+bool operator>(AtomicOrderingCABI, AtomicOrderingCABI) = delete;
+bool operator<=(AtomicOrderingCABI, AtomicOrderingCABI) = delete;
+bool operator>=(AtomicOrderingCABI, AtomicOrderingCABI) = delete;
+
+// Validate an integral value which isn't known to fit within the enum's range
+// is a valid AtomicOrderingCABI.
+template <typename Int> static inline bool isValidAtomicOrderingCABI(Int I) {
+ return (Int)AtomicOrderingCABI::relaxed <= I &&
+ I <= (Int)AtomicOrderingCABI::seq_cst;
+}
+
+/// Atomic ordering for LLVM's memory model.
+///
+/// C++ defines ordering as a lattice. LLVM supplements this with NotAtomic and
+/// Unordered, which are both below the C++ orders.
+///
+/// not_atomic-->unordered-->relaxed-->release--------------->acq_rel-->seq_cst
+/// \-->consume-->acquire--/
+enum class AtomicOrdering {
+ NotAtomic = 0,
+ Unordered = 1,
+ Monotonic = 2, // Equivalent to C++'s relaxed.
+ // Consume = 3, // Not specified yet.
+ Acquire = 4,
+ Release = 5,
+ AcquireRelease = 6,
+ SequentiallyConsistent = 7
+};
+
+bool operator<(AtomicOrdering, AtomicOrdering) = delete;
+bool operator>(AtomicOrdering, AtomicOrdering) = delete;
+bool operator<=(AtomicOrdering, AtomicOrdering) = delete;
+bool operator>=(AtomicOrdering, AtomicOrdering) = delete;
+
+// Validate an integral value which isn't known to fit within the enum's range
+// is a valid AtomicOrdering.
+template <typename Int> static inline bool isValidAtomicOrdering(Int I) {
+ return (Int)AtomicOrdering::NotAtomic <= I &&
+ I <= (Int)AtomicOrdering::SequentiallyConsistent;
+}
+
+/// String used by LLVM IR to represent atomic ordering.
+static inline const char *toIRString(AtomicOrdering ao) {
+ static const char *names[8] = {"not_atomic", "unordered", "monotonic",
+ "consume", "acquire", "release",
+ "acq_rel", "seq_cst"};
+ return names[(size_t)ao];
+}
+
+/// Returns true if ao is stronger than other as defined by the AtomicOrdering
+/// lattice, which is based on C++'s definition.
+static inline bool isStrongerThan(AtomicOrdering ao, AtomicOrdering other) {
+ static const bool lookup[8][8] = {
+ // NA UN RX CO AC RE AR SC
+ /* NotAtomic */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* Unordered */ {1, 0, 0, 0, 0, 0, 0, 0},
+ /* relaxed */ {1, 1, 0, 0, 0, 0, 0, 0},
+ /* consume */ {1, 1, 1, 0, 0, 0, 0, 0},
+ /* acquire */ {1, 1, 1, 1, 0, 0, 0, 0},
+ /* release */ {1, 1, 1, 0, 0, 0, 0, 0},
+ /* acq_rel */ {1, 1, 1, 1, 1, 1, 0, 0},
+ /* seq_cst */ {1, 1, 1, 1, 1, 1, 1, 0},
+ };
+ return lookup[(size_t)ao][(size_t)other];
+}
+
+static inline bool isAtLeastOrStrongerThan(AtomicOrdering ao,
+ AtomicOrdering other) {
+ static const bool lookup[8][8] = {
+ // NA UN RX CO AC RE AR SC
+ /* NotAtomic */ {1, 0, 0, 0, 0, 0, 0, 0},
+ /* Unordered */ {1, 1, 0, 0, 0, 0, 0, 0},
+ /* relaxed */ {1, 1, 1, 0, 0, 0, 0, 0},
+ /* consume */ {1, 1, 1, 1, 0, 0, 0, 0},
+ /* acquire */ {1, 1, 1, 1, 1, 0, 0, 0},
+ /* release */ {1, 1, 1, 0, 0, 1, 0, 0},
+ /* acq_rel */ {1, 1, 1, 1, 1, 1, 1, 0},
+ /* seq_cst */ {1, 1, 1, 1, 1, 1, 1, 1},
+ };
+ return lookup[(size_t)ao][(size_t)other];
+}
+
+static inline bool isStrongerThanUnordered(AtomicOrdering ao) {
+ return isStrongerThan(ao, AtomicOrdering::Unordered);
+}
+
+static inline bool isStrongerThanMonotonic(AtomicOrdering ao) {
+ return isStrongerThan(ao, AtomicOrdering::Monotonic);
+}
+
+static inline bool isAcquireOrStronger(AtomicOrdering ao) {
+ return isAtLeastOrStrongerThan(ao, AtomicOrdering::Acquire);
+}
+
+static inline bool isReleaseOrStronger(AtomicOrdering ao) {
+ return isAtLeastOrStrongerThan(ao, AtomicOrdering::Release);
+}
+
+static inline AtomicOrderingCABI toCABI(AtomicOrdering ao) {
+ static const AtomicOrderingCABI lookup[8] = {
+ /* NotAtomic */ AtomicOrderingCABI::relaxed,
+ /* Unordered */ AtomicOrderingCABI::relaxed,
+ /* relaxed */ AtomicOrderingCABI::relaxed,
+ /* consume */ AtomicOrderingCABI::consume,
+ /* acquire */ AtomicOrderingCABI::acquire,
+ /* release */ AtomicOrderingCABI::release,
+ /* acq_rel */ AtomicOrderingCABI::acq_rel,
+ /* seq_cst */ AtomicOrderingCABI::seq_cst,
+ };
+ return lookup[(size_t)ao];
+}
+
+} // end namespace llvm
+
+#endif // LLVM_SUPPORT_ATOMICORDERING_H
diff --git a/include/llvm/Support/BranchProbability.h b/include/llvm/Support/BranchProbability.h
index 26bc888d1cab..e8eb50d53eb6 100644
--- a/include/llvm/Support/BranchProbability.h
+++ b/include/llvm/Support/BranchProbability.h
@@ -203,7 +203,7 @@ void BranchProbability::normalizeProbabilities(ProbabilityIter Begin,
if (Sum <= BranchProbability::getDenominator())
return;
}
-
+
if (Sum == 0) {
BranchProbability BP(1, std::distance(Begin, End));
std::fill(Begin, End, BP);
diff --git a/include/llvm/Support/COFF.h b/include/llvm/Support/COFF.h
index 0245632c96a0..7dad3e82bda6 100644
--- a/include/llvm/Support/COFF.h
+++ b/include/llvm/Support/COFF.h
@@ -377,7 +377,6 @@ namespace COFF {
uint8_t unused[10];
};
- /// These are not documented in the spec, but are located in WinNT.h.
enum WeakExternalCharacteristics {
IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY = 1,
IMAGE_WEAK_EXTERN_SEARCH_LIBRARY = 2,
@@ -530,7 +529,7 @@ namespace COFF {
EXCEPTION_TABLE,
CERTIFICATE_TABLE,
BASE_RELOCATION_TABLE,
- DEBUG,
+ DEBUG_DIRECTORY,
ARCHITECTURE,
GLOBAL_PTR,
TLS_TABLE,
@@ -599,7 +598,13 @@ namespace COFF {
IMAGE_DEBUG_TYPE_OMAP_TO_SRC = 7,
IMAGE_DEBUG_TYPE_OMAP_FROM_SRC = 8,
IMAGE_DEBUG_TYPE_BORLAND = 9,
- IMAGE_DEBUG_TYPE_CLSID = 11
+ IMAGE_DEBUG_TYPE_RESERVED10 = 10,
+ IMAGE_DEBUG_TYPE_CLSID = 11,
+ IMAGE_DEBUG_TYPE_VC_FEATURE = 12,
+ IMAGE_DEBUG_TYPE_POGO = 13,
+ IMAGE_DEBUG_TYPE_ILTCG = 14,
+ IMAGE_DEBUG_TYPE_MPX = 15,
+ IMAGE_DEBUG_TYPE_REPRO = 16,
};
enum BaseRelocationType {
@@ -656,26 +661,8 @@ namespace COFF {
}
};
- enum CodeViewLine : unsigned {
- CVL_LineNumberStartBits = 24,
- CVL_LineNumberEndDeltaBits = 7,
- CVL_LineNumberEndDeltaMask = (1U << CVL_LineNumberEndDeltaBits) - 1,
- CVL_MaxLineNumber = (1U << CVL_LineNumberStartBits) - 1,
- CVL_IsStatement = 1U << 31,
- CVL_MaxColumnNumber = UINT16_MAX,
- };
-
enum CodeViewIdentifiers {
- DEBUG_LINE_TABLES_HAVE_COLUMN_RECORDS = 0x1,
DEBUG_SECTION_MAGIC = 0x4,
- DEBUG_SYMBOL_SUBSECTION = 0xF1,
- DEBUG_LINE_TABLE_SUBSECTION = 0xF2,
- DEBUG_STRING_TABLE_SUBSECTION = 0xF3,
- DEBUG_INDEX_SUBSECTION = 0xF4,
-
- // Symbol subsections are split into records of different types.
- DEBUG_SYMBOL_TYPE_PROC_START = 0x1147,
- DEBUG_SYMBOL_TYPE_PROC_END = 0x114F
};
inline bool isReservedSectionNumber(int32_t SectionNumber) {
diff --git a/include/llvm/Support/CachePruning.h b/include/llvm/Support/CachePruning.h
new file mode 100644
index 000000000000..383414119139
--- /dev/null
+++ b/include/llvm/Support/CachePruning.h
@@ -0,0 +1,69 @@
+//=- CachePruning.h - Helper to manage the pruning of a cache dir -*- C++ -*-=//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements pruning of a directory intended for cache storage, using
+// various policies.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_CACHE_PRUNING_H
+#define LLVM_SUPPORT_CACHE_PRUNING_H
+
+#include "llvm/ADT/StringRef.h"
+
+namespace llvm {
+
+/// Handle pruning a directory provided a path and some options to control what
+/// to prune.
+class CachePruning {
+public:
+ /// Prepare to prune \p Path.
+ CachePruning(StringRef Path) : Path(Path) {}
+
+ /// Define the pruning interval. This is intended to be used to avoid scanning
+ /// the directory too often. It does not impact the decision of which file to
+ /// prune. A value of 0 forces the scan to occurs.
+ CachePruning &setPruningInterval(int PruningInterval) {
+ Interval = PruningInterval;
+ return *this;
+ }
+
+ /// Define the expiration for a file. When a file hasn't been accessed for
+ /// \p ExpireAfter seconds, it is removed from the cache. A value of 0 disable
+ /// the expiration-based pruning.
+ CachePruning &setEntryExpiration(unsigned ExpireAfter) {
+ Expiration = ExpireAfter;
+ return *this;
+ }
+
+ /// Define the maximum size for the cache directory, in terms of percentage of
+ /// the available space on the the disk. Set to 100 to indicate no limit, 50
+ /// to indicate that the cache size will not be left over half the
+ /// available disk space. A value over 100 will be reduced to 100. A value of
+ /// 0 disable the size-based pruning.
+ CachePruning &setMaxSize(unsigned Percentage) {
+ PercentageOfAvailableSpace = std::min(100u, Percentage);
+ return *this;
+ }
+
+ /// Peform pruning using the supplied options, returns true if pruning
+ /// occured, i.e. if PruningInterval was expired.
+ bool prune();
+
+private:
+ // Options that matches the setters above.
+ std::string Path;
+ unsigned Expiration = 0;
+ unsigned Interval = 0;
+ unsigned PercentageOfAvailableSpace = 0;
+};
+
+} // namespace llvm
+
+#endif \ No newline at end of file
diff --git a/include/llvm/Support/CodeGen.h b/include/llvm/Support/CodeGen.h
index 243f2dd7498c..e19abf8271eb 100644
--- a/include/llvm/Support/CodeGen.h
+++ b/include/llvm/Support/CodeGen.h
@@ -15,22 +15,25 @@
#ifndef LLVM_SUPPORT_CODEGEN_H
#define LLVM_SUPPORT_CODEGEN_H
-#include "llvm-c/TargetMachine.h"
-#include "llvm/Support/ErrorHandling.h"
-
namespace llvm {
// Relocation model types.
namespace Reloc {
- enum Model { Default, Static, PIC_, DynamicNoPIC };
+ enum Model { Static, PIC_, DynamicNoPIC };
}
// Code model types.
namespace CodeModel {
+ // Sync changes with CodeGenCWrappers.h.
enum Model { Default, JITDefault, Small, Kernel, Medium, Large };
}
namespace PICLevel {
+ // This is used to map -fpic/-fPIC.
+ enum Level { NotPIC=0, SmallPIC=1, BigPIC=2 };
+ }
+
+ namespace PIELevel {
enum Level { Default=0, Small=1, Large=2 };
}
@@ -54,42 +57,6 @@ namespace llvm {
};
}
- // Create wrappers for C Binding types (see CBindingWrapping.h).
- inline CodeModel::Model unwrap(LLVMCodeModel Model) {
- switch (Model) {
- case LLVMCodeModelDefault:
- return CodeModel::Default;
- case LLVMCodeModelJITDefault:
- return CodeModel::JITDefault;
- case LLVMCodeModelSmall:
- return CodeModel::Small;
- case LLVMCodeModelKernel:
- return CodeModel::Kernel;
- case LLVMCodeModelMedium:
- return CodeModel::Medium;
- case LLVMCodeModelLarge:
- return CodeModel::Large;
- }
- return CodeModel::Default;
- }
-
- inline LLVMCodeModel wrap(CodeModel::Model Model) {
- switch (Model) {
- case CodeModel::Default:
- return LLVMCodeModelDefault;
- case CodeModel::JITDefault:
- return LLVMCodeModelJITDefault;
- case CodeModel::Small:
- return LLVMCodeModelSmall;
- case CodeModel::Kernel:
- return LLVMCodeModelKernel;
- case CodeModel::Medium:
- return LLVMCodeModelMedium;
- case CodeModel::Large:
- return LLVMCodeModelLarge;
- }
- llvm_unreachable("Bad CodeModel!");
- }
} // end llvm namespace
#endif
diff --git a/include/llvm/Support/CodeGenCWrappers.h b/include/llvm/Support/CodeGenCWrappers.h
new file mode 100644
index 000000000000..6db4433a4350
--- /dev/null
+++ b/include/llvm/Support/CodeGenCWrappers.h
@@ -0,0 +1,64 @@
+//===- llvm/Support/CodeGenCWrappers.h - CodeGen C Wrappers -----*- 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 C bindings wrappers for enums in llvm/Support/CodeGen.h
+// that need them. The wrappers are separated to avoid adding an indirect
+// dependency on llvm/Config/Targets.def to CodeGen.h.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_CODEGENCWRAPPERS_H
+#define LLVM_SUPPORT_CODEGENCWRAPPERS_H
+
+#include "llvm-c/TargetMachine.h"
+#include "llvm/Support/CodeGen.h"
+#include "llvm/Support/ErrorHandling.h"
+
+namespace llvm {
+
+inline CodeModel::Model unwrap(LLVMCodeModel Model) {
+ switch (Model) {
+ case LLVMCodeModelDefault:
+ return CodeModel::Default;
+ case LLVMCodeModelJITDefault:
+ return CodeModel::JITDefault;
+ case LLVMCodeModelSmall:
+ return CodeModel::Small;
+ case LLVMCodeModelKernel:
+ return CodeModel::Kernel;
+ case LLVMCodeModelMedium:
+ return CodeModel::Medium;
+ case LLVMCodeModelLarge:
+ return CodeModel::Large;
+ }
+ return CodeModel::Default;
+}
+
+inline LLVMCodeModel wrap(CodeModel::Model Model) {
+ switch (Model) {
+ case CodeModel::Default:
+ return LLVMCodeModelDefault;
+ case CodeModel::JITDefault:
+ return LLVMCodeModelJITDefault;
+ case CodeModel::Small:
+ return LLVMCodeModelSmall;
+ case CodeModel::Kernel:
+ return LLVMCodeModelKernel;
+ case CodeModel::Medium:
+ return LLVMCodeModelMedium;
+ case CodeModel::Large:
+ return LLVMCodeModelLarge;
+ }
+ llvm_unreachable("Bad CodeModel!");
+}
+
+} // end llvm namespace
+
+#endif
+
diff --git a/include/llvm/Support/CommandLine.h b/include/llvm/Support/CommandLine.h
index 943d2df37708..70465a0e3fd3 100644
--- a/include/llvm/Support/CommandLine.h
+++ b/include/llvm/Support/CommandLine.h
@@ -21,10 +21,12 @@
#define LLVM_SUPPORT_COMMANDLINE_H
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/Support/ManagedStatic.h"
#include <cassert>
#include <climits>
#include <cstdarg>
@@ -43,8 +45,9 @@ namespace cl {
//===----------------------------------------------------------------------===//
// ParseCommandLineOptions - Command line option processing entry point.
//
-void ParseCommandLineOptions(int argc, const char *const *argv,
- const char *Overview = nullptr);
+bool ParseCommandLineOptions(int argc, const char *const *argv,
+ const char *Overview = nullptr,
+ bool IgnoreErrors = false);
//===----------------------------------------------------------------------===//
// ParseEnvironmentOptions - Environment variable option processing alternate
@@ -171,6 +174,45 @@ public:
extern OptionCategory GeneralCategory;
//===----------------------------------------------------------------------===//
+// SubCommand class
+//
+class SubCommand {
+private:
+ const char *const Name = nullptr;
+ const char *const Description = nullptr;
+
+protected:
+ void registerSubCommand();
+ void unregisterSubCommand();
+
+public:
+ SubCommand(const char *const Name, const char *const Description = nullptr)
+ : Name(Name), Description(Description) {
+ registerSubCommand();
+ }
+ SubCommand() {}
+
+ void reset();
+
+ operator bool() const;
+
+ const char *getName() const { return Name; }
+ const char *getDescription() const { return Description; }
+
+ SmallVector<Option *, 4> PositionalOpts;
+ SmallVector<Option *, 4> SinkOpts;
+ StringMap<Option *> OptionsMap;
+
+ Option *ConsumeAfterOpt = nullptr; // The ConsumeAfter option if it exists.
+};
+
+// A special subcommand representing no subcommand
+extern ManagedStatic<SubCommand> TopLevelSubCommand;
+
+// A special subcommand that can be used to put an option into all subcommands.
+extern ManagedStatic<SubCommand> AllSubCommands;
+
+//===----------------------------------------------------------------------===//
// Option Base class
//
class alias;
@@ -209,6 +251,7 @@ public:
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
+ SmallPtrSet<SubCommand *, 4> Subs; // The subcommands this option belongs to.
bool FullyInitialized; // Has addArguemnt been called?
inline enum NumOccurrencesFlag getNumOccurrencesFlag() const {
@@ -229,6 +272,16 @@ public:
// hasArgStr - Return true if the argstr != ""
bool hasArgStr() const { return !ArgStr.empty(); }
+ bool isPositional() const { return getFormattingFlag() == cl::Positional; }
+ bool isSink() const { return getMiscFlags() & cl::Sink; }
+ bool isConsumeAfter() const {
+ return getNumOccurrencesFlag() == cl::ConsumeAfter;
+ }
+ bool isInAllSubCommands() const {
+ return std::any_of(Subs.begin(), Subs.end(), [](const SubCommand *SC) {
+ return SC == &*AllSubCommands;
+ });
+ }
//-------------------------------------------------------------------------===
// Accessor functions set by OptionModifiers
@@ -243,6 +296,7 @@ public:
void setMiscFlag(enum MiscFlags M) { Misc |= M; }
void setPosition(unsigned pos) { Position = pos; }
void setCategory(OptionCategory &C) { Category = &C; }
+ void addSubCommand(SubCommand &S) { Subs.insert(&S); }
protected:
explicit Option(enum NumOccurrencesFlag OccurrencesFlag,
@@ -287,6 +341,7 @@ public:
public:
inline int getNumOccurrences() const { return NumOccurrences; }
+ inline void reset() { NumOccurrences = 0; }
virtual ~Option() {}
};
@@ -349,6 +404,14 @@ struct cat {
template <class Opt> void apply(Opt &O) const { O.setCategory(Category); }
};
+// sub - Specify the subcommand that this option belongs to.
+struct sub {
+ SubCommand &Sub;
+ sub(SubCommand &S) : Sub(S) {}
+
+ template <class Opt> void apply(Opt &O) const { O.addSubCommand(Sub); }
+};
+
//===----------------------------------------------------------------------===//
// OptionValue class
@@ -946,7 +1009,7 @@ public:
// getValueName - Overload in subclass to provide a better default value.
const char *getValueName() const override { return "string"; }
- void printOptionDiff(const Option &O, StringRef V, OptVal Default,
+ void printOptionDiff(const Option &O, StringRef V, const OptVal &Default,
size_t GlobalWidth) const;
// An out-of-line virtual method to provide a 'home' for this class.
@@ -1589,6 +1652,7 @@ class alias : public Option {
error("cl::alias must have argument name specified!");
if (!AliasFor)
error("cl::alias must have an cl::aliasopt(option) specified!");
+ Subs = AliasFor->Subs;
addArgument();
}
@@ -1669,7 +1733,7 @@ void PrintHelpMessage(bool Hidden = false, bool Categorized = false);
/// Hopefully this API can be depricated soon. Any situation where options need
/// to be modified by tools or libraries should be handled by sane APIs rather
/// than just handing around a global list.
-StringMap<Option *> &getRegisteredOptions();
+StringMap<Option *> &getRegisteredOptions(SubCommand &Sub = *TopLevelSubCommand);
//===----------------------------------------------------------------------===//
// Standalone command line processing utilities.
@@ -1737,7 +1801,8 @@ bool ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer,
/// Some tools (like clang-format) like to be able to hide all options that are
/// not specific to the tool. This function allows a tool to specify a single
/// option category to display in the -help output.
-void HideUnrelatedOptions(cl::OptionCategory &Category);
+void HideUnrelatedOptions(cl::OptionCategory &Category,
+ SubCommand &Sub = *TopLevelSubCommand);
/// \brief Mark all options not part of the categories as cl::ReallyHidden.
///
@@ -1746,7 +1811,19 @@ void HideUnrelatedOptions(cl::OptionCategory &Category);
/// Some tools (like clang-format) like to be able to hide all options that are
/// not specific to the tool. This function allows a tool to specify a single
/// option category to display in the -help output.
-void HideUnrelatedOptions(ArrayRef<const cl::OptionCategory *> Categories);
+void HideUnrelatedOptions(ArrayRef<const cl::OptionCategory *> Categories,
+ SubCommand &Sub = *TopLevelSubCommand);
+
+/// \brief Reset all command line options to a state that looks as if they have
+/// never appeared on the command line. This is useful for being able to parse
+/// a command line multiple times (especially useful for writing tests).
+void ResetAllOptionOccurrences();
+
+/// \brief Reset the command line parser back to its initial state. This
+/// removes
+/// all options, categories, and subcommands and returns the parser to a state
+/// where no options are supported.
+void ResetCommandLineParser();
} // End namespace cl
diff --git a/include/llvm/Support/Compiler.h b/include/llvm/Support/Compiler.h
index b3416bbfffb6..fae0d8f4419e 100644
--- a/include/llvm/Support/Compiler.h
+++ b/include/llvm/Support/Compiler.h
@@ -17,6 +17,10 @@
#include "llvm/Config/llvm-config.h"
+#if defined(_MSC_VER)
+#include <sal.h>
+#endif
+
#ifndef __has_feature
# define __has_feature(x) 0
#endif
@@ -92,7 +96,7 @@
#define LLVM_LVALUE_FUNCTION
#endif
-#if __has_feature(cxx_constexpr) || defined(__GXX_EXPERIMENTAL_CXX0X__)
+#if __has_feature(cxx_constexpr) || defined(__GXX_EXPERIMENTAL_CXX0X__) || LLVM_MSC_PREREQ(1900)
# define LLVM_CONSTEXPR constexpr
#else
# define LLVM_CONSTEXPR
@@ -124,6 +128,8 @@
#if __has_attribute(warn_unused_result) || LLVM_GNUC_PREREQ(3, 4, 0)
#define LLVM_ATTRIBUTE_UNUSED_RESULT __attribute__((__warn_unused_result__))
+#elif defined(_MSC_VER)
+#define LLVM_ATTRIBUTE_UNUSED_RESULT _Check_return_
#else
#define LLVM_ATTRIBUTE_UNUSED_RESULT
#endif
@@ -206,6 +212,8 @@
#if __has_attribute(returns_nonnull) || LLVM_GNUC_PREREQ(4, 9, 0)
#define LLVM_ATTRIBUTE_RETURNS_NONNULL __attribute__((returns_nonnull))
+#elif defined(_MSC_VER)
+#define LLVM_ATTRIBUTE_RETURNS_NONNULL _Ret_notnull_
#else
#define LLVM_ATTRIBUTE_RETURNS_NONNULL
#endif
@@ -266,6 +274,23 @@
# define LLVM_BUILTIN_TRAP *(volatile int*)0x11 = 0
#endif
+/// LLVM_BUILTIN_DEBUGTRAP - On compilers which support it, expands to
+/// an expression which causes the program to break while running
+/// under a debugger.
+#if __has_builtin(__builtin_debugtrap)
+# define LLVM_BUILTIN_DEBUGTRAP __builtin_debugtrap()
+#elif defined(_MSC_VER)
+// The __debugbreak intrinsic is supported by MSVC and breaks while
+// running under the debugger, and also supports invoking a debugger
+// when the OS is configured appropriately.
+# define LLVM_BUILTIN_DEBUGTRAP __debugbreak()
+#else
+// Just continue execution when built with compilers that have no
+// support. This is a debugging aid and not intended to force the
+// program to abort if encountered.
+# define LLVM_BUILTIN_DEBUGTRAP
+#endif
+
/// \macro LLVM_ASSUME_ALIGNED
/// \brief Returns a pointer with an assumed alignment.
#if __has_builtin(__builtin_assume_aligned) || LLVM_GNUC_PREREQ(4, 7, 0)
@@ -407,6 +432,14 @@ void AnnotateIgnoreWritesEnd(const char *file, int line);
# define TsanIgnoreWritesEnd()
#endif
+/// \macro LLVM_NO_SANITIZE
+/// \brief Disable a particular sanitizer for a function.
+#if __has_attribute(no_sanitize)
+#define LLVM_NO_SANITIZE(KIND) __attribute__((no_sanitize(KIND)))
+#else
+#define LLVM_NO_SANITIZE(KIND)
+#endif
+
/// \brief Mark debug helper function definitions like dump() that should not be
/// stripped from debug builds.
// FIXME: Move this to a private config.h as it's not usable in public headers.
diff --git a/include/llvm/Support/ConvertUTF.h b/include/llvm/Support/ConvertUTF.h
index 38952ec99e61..5de5774f9db5 100644
--- a/include/llvm/Support/ConvertUTF.h
+++ b/include/llvm/Support/ConvertUTF.h
@@ -180,10 +180,13 @@ unsigned getNumBytesForUTF8(UTF8 firstByte);
/*************************************************************************/
/* Below are LLVM-specific wrappers of the functions above. */
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/StringRef.h"
+#include <string>
+#include <cstddef>
namespace llvm {
+template <typename T> class ArrayRef;
+template <typename T> class SmallVectorImpl;
+class StringRef;
/**
* Convert an UTF8 StringRef to UTF8, UTF16, or UTF32 depending on
@@ -198,6 +201,25 @@ bool ConvertUTF8toWide(unsigned WideCharWidth, llvm::StringRef Source,
char *&ResultPtr, const UTF8 *&ErrorPtr);
/**
+* Converts a UTF-8 StringRef to a std::wstring.
+* \return true on success.
+*/
+bool ConvertUTF8toWide(llvm::StringRef Source, std::wstring &Result);
+
+/**
+* Converts a UTF-8 C-string to a std::wstring.
+* \return true on success.
+*/
+bool ConvertUTF8toWide(const char *Source, std::wstring &Result);
+
+/**
+* Converts a std::wstring to a UTF-8 encoded std::string.
+* \return true on success.
+*/
+bool convertWideToUTF8(const std::wstring &Source, std::string &Result);
+
+
+/**
* Convert an Unicode code point to UTF8 sequence.
*
* \param Source a Unicode code point.
@@ -252,6 +274,15 @@ bool hasUTF16ByteOrderMark(ArrayRef<char> SrcBytes);
bool convertUTF16ToUTF8String(ArrayRef<char> SrcBytes, std::string &Out);
/**
+* Converts a UTF16 string into a UTF8 std::string.
+*
+* \param [in] Src A buffer of UTF-16 encoded text.
+* \param [out] Out Converted UTF-8 is stored here on success.
+* \returns true on success
+*/
+bool convertUTF16ToUTF8String(ArrayRef<UTF16> Src, std::string &Out);
+
+/**
* Converts a UTF-8 string into a UTF-16 string with native endianness.
*
* \returns true on success
diff --git a/include/llvm/Support/CrashRecoveryContext.h b/include/llvm/Support/CrashRecoveryContext.h
index 1a1c74368761..6cbc331d2731 100644
--- a/include/llvm/Support/CrashRecoveryContext.h
+++ b/include/llvm/Support/CrashRecoveryContext.h
@@ -11,7 +11,6 @@
#define LLVM_SUPPORT_CRASHRECOVERYCONTEXT_H
#include "llvm/ADT/STLExtras.h"
-#include <string>
namespace llvm {
class CrashRecoveryContextCleanup;
@@ -70,8 +69,7 @@ public:
/// \return True if the function completed successfully, and false if the
/// function crashed (or HandleCrash was called explicitly). Clients should
/// make as little assumptions as possible about the program state when
- /// RunSafely has returned false. Clients can use getBacktrace() to retrieve
- /// the backtrace of the crash on failures.
+ /// RunSafely has returned false.
bool RunSafely(function_ref<void()> Fn);
bool RunSafely(void (*Fn)(void*), void *UserData) {
return RunSafely([&]() { Fn(UserData); });
@@ -94,13 +92,6 @@ public:
/// \brief Explicitly trigger a crash recovery in the current process, and
/// return failure from RunSafely(). This function does not return.
void HandleCrash();
-
- /// \brief Return a string containing the backtrace where the crash was
- /// detected; or empty if the backtrace wasn't recovered.
- ///
- /// This function is only valid when a crash has been detected (i.e.,
- /// RunSafely() has returned false.
- const std::string &getBacktrace() const;
};
class CrashRecoveryContextCleanup {
diff --git a/include/llvm/Support/DataTypes.h.cmake b/include/llvm/Support/DataTypes.h.cmake
index c90bf51afaee..541dbc3d635d 100644
--- a/include/llvm/Support/DataTypes.h.cmake
+++ b/include/llvm/Support/DataTypes.h.cmake
@@ -21,8 +21,6 @@
/* Please leave this file C-compatible. */
-/* Please keep this file in sync with DataTypes.h.in */
-
#ifndef SUPPORT_DATATYPES_H
#define SUPPORT_DATATYPES_H
@@ -37,36 +35,43 @@
#include <math.h>
#endif
+#ifdef __cplusplus
+#include <cinttypes>
+#else
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#endif
+#endif
+#ifdef __cplusplus
+#include <cstdint>
+#else
#ifdef HAVE_STDINT_H
#include <stdint.h>
#else
#error "Compiler must provide an implementation of stdint.h"
#endif
+#endif
#ifndef _MSC_VER
-/* Note that this header's correct operation depends on __STDC_LIMIT_MACROS
- being defined. We would define it here, but in order to prevent Bad Things
- happening when system headers or C++ STL headers include stdint.h before we
- define it here, we define it on the g++ command line (in Makefile.rules). */
-#if !defined(__STDC_LIMIT_MACROS)
-# error "Must #define __STDC_LIMIT_MACROS before #including Support/DataTypes.h"
+#if !defined(UINT32_MAX)
+# error "The standard header <cstdint> is not C++11 compliant. Must #define "\
+ "__STDC_LIMIT_MACROS before #including Support/DataTypes.h"
#endif
-#if !defined(__STDC_CONSTANT_MACROS)
-# error "Must #define __STDC_CONSTANT_MACROS before " \
- "#including Support/DataTypes.h"
+#if !defined(UINT32_C)
+# error "The standard header <cstdint> is not C++11 compliant. Must #define "\
+ "__STDC_CONSTANT_MACROS before #including Support/DataTypes.h"
#endif
/* Note that <inttypes.h> includes <stdint.h>, if this is a C99 system. */
#include <sys/types.h>
#ifdef _AIX
-#include "llvm/Support/AIXDataTypesFix.h"
+// GCC is strict about defining large constants: they must have LL modifier.
+#undef INT64_MAX
+#undef INT64_MIN
#endif
/* Handle incorrect definition of uint64_t as u_int64_t */
@@ -79,14 +84,14 @@ typedef u_int64_t uint64_t;
#endif
#else /* _MSC_VER */
-#include <stdlib.h>
-#include <stddef.h>
-#include <sys/types.h>
#ifdef __cplusplus
-#include <cmath>
+#include <cstdlib>
+#include <cstddef>
#else
-#include <math.h>
+#include <stdlib.h>
+#include <stddef.h>
#endif
+#include <sys/types.h>
#if defined(_WIN64)
typedef signed __int64 ssize_t;
@@ -127,4 +132,4 @@ typedef signed int ssize_t;
#define HUGE_VALF (float)HUGE_VAL
#endif
-#endif /* SUPPORT_DATATYPES_H */
+#endif /* SUPPORT_DATATYPES_H */
diff --git a/include/llvm/Support/DataTypes.h.in b/include/llvm/Support/DataTypes.h.in
deleted file mode 100644
index b8b2ba56ff30..000000000000
--- a/include/llvm/Support/DataTypes.h.in
+++ /dev/null
@@ -1,123 +0,0 @@
-/*===-- include/Support/DataTypes.h - Define fixed size types -----*- C -*-===*\
-|* *|
-|* The LLVM Compiler Infrastructure *|
-|* *|
-|* This file is distributed under the University of Illinois Open Source *|
-|* License. See LICENSE.TXT for details. *|
-|* *|
-|*===----------------------------------------------------------------------===*|
-|* *|
-|* This file contains definitions to figure out the size of _HOST_ data types.*|
-|* This file is important because different host OS's define different macros,*|
-|* which makes portability tough. This file exports the following *|
-|* definitions: *|
-|* *|
-|* [u]int(32|64)_t : typedefs for signed and unsigned 32/64 bit system types*|
-|* [U]INT(8|16|32|64)_(MIN|MAX) : Constants for the min and max values. *|
-|* *|
-|* No library is required when using these functions. *|
-|* *|
-|*===----------------------------------------------------------------------===*/
-
-/* Please leave this file C-compatible. */
-
-/* Please keep this file in sync with DataTypes.h.cmake */
-
-#ifndef SUPPORT_DATATYPES_H
-#define SUPPORT_DATATYPES_H
-
-#undef HAVE_INTTYPES_H
-#undef HAVE_STDINT_H
-#undef HAVE_UINT64_T
-#undef HAVE_U_INT64_T
-
-#ifdef __cplusplus
-#include <cmath>
-#else
-#include <math.h>
-#endif
-
-#ifdef HAVE_INTTYPES_H
-#include <inttypes.h>
-#endif
-
-#ifdef HAVE_STDINT_H
-#include <stdint.h>
-#else
-#error "Compiler must provide an implementation of stdint.h"
-#endif
-
-#ifndef _MSC_VER
-
-/* Note that this header's correct operation depends on __STDC_LIMIT_MACROS
- being defined. We would define it here, but in order to prevent Bad Things
- happening when system headers or C++ STL headers include stdint.h before we
- define it here, we define it on the g++ command line (in Makefile.rules). */
-#if !defined(__STDC_LIMIT_MACROS)
-# error "Must #define __STDC_LIMIT_MACROS before #including Support/DataTypes.h"
-#endif
-
-#if !defined(__STDC_CONSTANT_MACROS)
-# error "Must #define __STDC_CONSTANT_MACROS before " \
- "#including Support/DataTypes.h"
-#endif
-
-/* Note that <inttypes.h> includes <stdint.h>, if this is a C99 system. */
-#include <sys/types.h>
-
-#ifdef _AIX
-#include "llvm/Support/AIXDataTypesFix.h"
-#endif
-
-/* Handle incorrect definition of uint64_t as u_int64_t */
-#ifndef HAVE_UINT64_T
-#ifdef HAVE_U_INT64_T
-typedef u_int64_t uint64_t;
-#else
-# error "Don't have a definition for uint64_t on this platform"
-#endif
-#endif
-
-#else /* _MSC_VER */
-#include <stdlib.h>
-#include <stddef.h>
-#include <sys/types.h>
-#ifdef __cplusplus
-#include <cmath>
-#else
-#include <math.h>
-#endif
-
-#if defined(_WIN64)
-typedef signed __int64 ssize_t;
-#else
-typedef signed int ssize_t;
-#endif /* _WIN64 */
-
-#ifndef HAVE_INTTYPES_H
-#define PRId64 "I64d"
-#define PRIi64 "I64i"
-#define PRIo64 "I64o"
-#define PRIu64 "I64u"
-#define PRIx64 "I64x"
-#define PRIX64 "I64X"
-#endif /* HAVE_INTTYPES_H */
-
-#endif /* _MSC_VER */
-
-/* Set defaults for constants which we cannot find. */
-#if !defined(INT64_MAX)
-# define INT64_MAX 9223372036854775807LL
-#endif
-#if !defined(INT64_MIN)
-# define INT64_MIN ((-INT64_MAX)-1)
-#endif
-#if !defined(UINT64_MAX)
-# define UINT64_MAX 0xffffffffffffffffULL
-#endif
-
-#ifndef HUGE_VALF
-#define HUGE_VALF (float)HUGE_VAL
-#endif
-
-#endif /* SUPPORT_DATATYPES_H */
diff --git a/include/llvm/Support/Dwarf.def b/include/llvm/Support/Dwarf.def
index b15070b3e9b0..b73f2aed5311 100644
--- a/include/llvm/Support/Dwarf.def
+++ b/include/llvm/Support/Dwarf.def
@@ -14,7 +14,7 @@
// TODO: Add other DW-based macros.
#if !(defined HANDLE_DW_TAG || defined HANDLE_DW_OP || \
defined HANDLE_DW_LANG || defined HANDLE_DW_ATE || \
- defined HANDLE_DW_VIRTUALITY)
+ defined HANDLE_DW_VIRTUALITY || defined HANDLE_DW_CC)
#error "Missing macro definition of HANDLE_DW*"
#endif
@@ -38,6 +38,11 @@
#define HANDLE_DW_VIRTUALITY(ID, NAME)
#endif
+#ifndef HANDLE_DW_CC
+#define HANDLE_DW_CC(ID, NAME)
+#endif
+
+
HANDLE_DW_TAG(0x0001, array_type)
HANDLE_DW_TAG(0x0002, class_type)
HANDLE_DW_TAG(0x0003, entry_point)
@@ -320,6 +325,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(0x8e57, GOOGLE_RenderScript)
HANDLE_DW_LANG(0xb000, BORLAND_Delphi)
// DWARF attribute type encodings.
@@ -345,8 +351,23 @@ HANDLE_DW_VIRTUALITY(0x00, none)
HANDLE_DW_VIRTUALITY(0x01, virtual)
HANDLE_DW_VIRTUALITY(0x02, pure_virtual)
+// DWARF calling convention codes.
+HANDLE_DW_CC(0x01, normal)
+HANDLE_DW_CC(0x02, program)
+HANDLE_DW_CC(0x03, nocall)
+HANDLE_DW_CC(0x41, GNU_borland_fastcall_i386)
+HANDLE_DW_CC(0xb0, BORLAND_safecall)
+HANDLE_DW_CC(0xb1, BORLAND_stdcall)
+HANDLE_DW_CC(0xb2, BORLAND_pascal)
+HANDLE_DW_CC(0xb3, BORLAND_msfastcall)
+HANDLE_DW_CC(0xb4, BORLAND_msreturn)
+HANDLE_DW_CC(0xb5, BORLAND_thiscall)
+HANDLE_DW_CC(0xb6, BORLAND_fastcall)
+HANDLE_DW_CC(0xc0, LLVM_vectorcall)
+
#undef HANDLE_DW_TAG
#undef HANDLE_DW_OP
#undef HANDLE_DW_LANG
#undef HANDLE_DW_ATE
#undef HANDLE_DW_VIRTUALITY
+#undef HANDLE_DW_CC
diff --git a/include/llvm/Support/Dwarf.h b/include/llvm/Support/Dwarf.h
index cea61bd75833..86b19676c345 100644
--- a/include/llvm/Support/Dwarf.h
+++ b/include/llvm/Support/Dwarf.h
@@ -20,11 +20,11 @@
#ifndef LLVM_SUPPORT_DWARF_H
#define LLVM_SUPPORT_DWARF_H
-#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataTypes.h"
namespace llvm {
+class StringRef;
namespace dwarf {
@@ -389,18 +389,9 @@ enum CaseSensitivity {
enum CallingConvention {
// Calling convention codes
- DW_CC_normal = 0x01,
- DW_CC_program = 0x02,
- DW_CC_nocall = 0x03,
+#define HANDLE_DW_CC(ID, NAME) DW_CC_##NAME = ID,
+#include "llvm/Support/Dwarf.def"
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
};
@@ -547,7 +538,7 @@ enum LocationListEntry : unsigned char {
DW_LLE_offset_pair_entry
};
-/// Contstants for the DW_APPLE_PROPERTY_attributes attribute.
+/// Constants for the DW_APPLE_PROPERTY_attributes attribute.
/// Keep this list in sync with clang's DeclSpec.h ObjCPropertyAttributeKind.
enum ApplePropertyAttributes {
// Apple Objective-C Property Attributes
@@ -562,7 +553,10 @@ enum ApplePropertyAttributes {
DW_APPLE_PROPERTY_atomic = 0x100,
DW_APPLE_PROPERTY_weak = 0x200,
DW_APPLE_PROPERTY_strong = 0x400,
- DW_APPLE_PROPERTY_unsafe_unretained = 0x800
+ DW_APPLE_PROPERTY_unsafe_unretained = 0x800,
+ DW_APPLE_PROPERTY_nullability = 0x1000,
+ DW_APPLE_PROPERTY_null_resettable = 0x2000,
+ DW_APPLE_PROPERTY_class = 0x4000
};
// Constants for the DWARF5 Accelerator Table Proposal
@@ -652,6 +646,7 @@ unsigned getTag(StringRef TagString);
unsigned getOperationEncoding(StringRef OperationEncodingString);
unsigned getVirtuality(StringRef VirtualityString);
unsigned getLanguage(StringRef LanguageString);
+unsigned getCallingConvention(StringRef LanguageString);
unsigned getAttributeEncoding(StringRef EncodingString);
unsigned getMacinfo(StringRef MacinfoString);
/// @}
diff --git a/include/llvm/Support/ELF.h b/include/llvm/Support/ELF.h
index e24420fc1fe4..70b9daab8360 100644
--- a/include/llvm/Support/ELF.h
+++ b/include/llvm/Support/ELF.h
@@ -310,6 +310,8 @@ enum {
EM_NORC = 218, // Nanoradio Optimized RISC
EM_CSR_KALIMBA = 219, // CSR Kalimba architecture family
EM_AMDGPU = 224, // AMD GPU architecture
+ EM_LANAI = 244, // Lanai 32-bit processor
+ EM_BPF = 247, // Linux kernel bpf virtual machine
// A request has been made to the maintainer of the official registry for
// such numbers for an official value for WebAssembly. As soon as one is
@@ -481,6 +483,7 @@ enum : unsigned {
EF_MIPS_ABI = 0x0000f000, // Mask for selecting EF_MIPS_ABI_ variant.
// MIPS machine variant
+ EF_MIPS_MACH_NONE = 0x00000000, // A standard MIPS implementation.
EF_MIPS_MACH_3900 = 0x00810000, // Toshiba R3900
EF_MIPS_MACH_4010 = 0x00820000, // LSI R4010
EF_MIPS_MACH_4100 = 0x00830000, // NEC VR4100
@@ -589,6 +592,11 @@ enum {
#include "ELFRelocs/Hexagon.def"
};
+// ELF Relocation type for Lanai.
+enum {
+#include "ELFRelocs/Lanai.def"
+};
+
// ELF Relocation types for S390/zSeries
enum {
#include "ELFRelocs/SystemZ.def"
@@ -604,6 +612,16 @@ enum {
#include "ELFRelocs/WebAssembly.def"
};
+// ELF Relocation types for AMDGPU
+enum {
+#include "ELFRelocs/AMDGPU.def"
+};
+
+// ELF Relocation types for BPF
+enum {
+#include "ELFRelocs/BPF.def"
+};
+
#undef ELF_RELOC
// Section header.
@@ -730,6 +748,9 @@ enum : unsigned {
// This section holds Thread-Local Storage.
SHF_TLS = 0x400U,
+ // Identifies a section containing compressed data.
+ SHF_COMPRESSED = 0x800U,
+
// This section is excluded from the final executable or shared library.
SHF_EXCLUDE = 0x80000000U,
@@ -1116,6 +1137,8 @@ enum {
DT_HIPROC = 0x7FFFFFFF, // End of processor specific tags.
DT_GNU_HASH = 0x6FFFFEF5, // Reference to the GNU hash table.
+ DT_TLSDESC_PLT = 0x6FFFFEF6, // Location of PLT entry for TLS descriptor resolver calls.
+ DT_TLSDESC_GOT = 0x6FFFFEF7, // Location of GOT entry used by TLS descriptor resolver PLT entry.
DT_RELACOUNT = 0x6FFFFFF9, // ELF32_Rela count.
DT_RELCOUNT = 0x6FFFFFFA, // ELF32_Rel count.
@@ -1199,8 +1222,12 @@ enum {
DT_MIPS_PLTGOT = 0x70000032, // Address of the base of the PLTGOT.
DT_MIPS_RWPLT = 0x70000034, // Points to the base
// of a writable PLT.
- DT_MIPS_RLD_MAP_REL = 0x70000035 // Relative offset of run time loader
+ DT_MIPS_RLD_MAP_REL = 0x70000035, // Relative offset of run time loader
// map, used for debugging.
+
+ // Sun machine-independent extensions.
+ DT_AUXILIARY = 0x7FFFFFFD, // Shared object to load before self
+ DT_FILTER = 0x7FFFFFFF // Shared object to get values from
};
// DT_FLAGS values.
@@ -1294,6 +1321,35 @@ enum {
VER_NEED_CURRENT = 1
};
+// SHT_NOTE section types
+enum {
+ NT_GNU_BUILD_ID = 3
+};
+
+// Compressed section header for ELF32.
+struct Elf32_Chdr {
+ Elf32_Word ch_type;
+ Elf32_Word ch_size;
+ Elf32_Word ch_addralign;
+};
+
+// Compressed section header for ELF64.
+struct Elf64_Chdr {
+ Elf64_Word ch_type;
+ Elf64_Word ch_reserved;
+ Elf64_Xword ch_size;
+ Elf64_Xword ch_addralign;
+};
+
+// Legal values for ch_type field of compressed section header.
+enum {
+ ELFCOMPRESS_ZLIB = 1, // ZLIB/DEFLATE algorithm.
+ ELFCOMPRESS_LOOS = 0x60000000, // Start of OS-specific.
+ ELFCOMPRESS_HIOS = 0x6fffffff, // End of OS-specific.
+ ELFCOMPRESS_LOPROC = 0x70000000, // Start of processor-specific.
+ ELFCOMPRESS_HIPROC = 0x7fffffff // End of processor-specific.
+};
+
} // end namespace ELF
} // end namespace llvm
diff --git a/include/llvm/Support/ELFRelocs/AMDGPU.def b/include/llvm/Support/ELFRelocs/AMDGPU.def
new file mode 100644
index 000000000000..c1e6797fdb0d
--- /dev/null
+++ b/include/llvm/Support/ELFRelocs/AMDGPU.def
@@ -0,0 +1,12 @@
+#ifndef ELF_RELOC
+#error "ELF_RELOC must be defined"
+#endif
+
+ELF_RELOC(R_AMDGPU_NONE, 0)
+ELF_RELOC(R_AMDGPU_ABS32_LO, 1)
+ELF_RELOC(R_AMDGPU_ABS32_HI, 2)
+ELF_RELOC(R_AMDGPU_ABS64, 3)
+ELF_RELOC(R_AMDGPU_REL32, 4)
+ELF_RELOC(R_AMDGPU_REL64, 5)
+ELF_RELOC(R_AMDGPU_ABS32, 6)
+ELF_RELOC(R_AMDGPU_GOTPCREL, 7)
diff --git a/include/llvm/Support/ELFRelocs/BPF.def b/include/llvm/Support/ELFRelocs/BPF.def
new file mode 100644
index 000000000000..868974d683c7
--- /dev/null
+++ b/include/llvm/Support/ELFRelocs/BPF.def
@@ -0,0 +1,9 @@
+#ifndef ELF_RELOC
+#error "ELF_RELOC must be defined"
+#endif
+
+// No relocation
+ELF_RELOC(R_BPF_NONE, 0)
+// Map index in "maps" section to file descriptor
+// within ld_64 instruction.
+ELF_RELOC(R_BPF_MAP_FD, 1)
diff --git a/include/llvm/Support/ELFRelocs/Hexagon.def b/include/llvm/Support/ELFRelocs/Hexagon.def
index a698ecb89e16..74e1d405cebd 100644
--- a/include/llvm/Support/ELFRelocs/Hexagon.def
+++ b/include/llvm/Support/ELFRelocs/Hexagon.def
@@ -98,3 +98,4 @@ ELF_RELOC(R_HEX_LD_GOT_16, 90)
ELF_RELOC(R_HEX_LD_GOT_32_6_X, 91)
ELF_RELOC(R_HEX_LD_GOT_16_X, 92)
ELF_RELOC(R_HEX_LD_GOT_11_X, 93)
+ELF_RELOC(R_HEX_23_REG, 94)
diff --git a/include/llvm/Support/ELFRelocs/Lanai.def b/include/llvm/Support/ELFRelocs/Lanai.def
new file mode 100644
index 000000000000..77ecb048403d
--- /dev/null
+++ b/include/llvm/Support/ELFRelocs/Lanai.def
@@ -0,0 +1,19 @@
+
+#ifndef ELF_RELOC
+#error "ELF_RELOC must be defined"
+#endif
+
+// No relocation
+ELF_RELOC(R_LANAI_NONE, 0)
+// 21-bit symbol relocation
+ELF_RELOC(R_LANAI_21, 1)
+// 21-bit symbol relocation with last two bits masked to 0
+ELF_RELOC(R_LANAI_21_F, 2)
+// 25-bit branch targets
+ELF_RELOC(R_LANAI_25, 3)
+// General 32-bit relocation
+ELF_RELOC(R_LANAI_32, 4)
+// Upper 16-bits of a symbolic relocation
+ELF_RELOC(R_LANAI_HI16, 5)
+// Lower 16-bits of a symbolic relocation
+ELF_RELOC(R_LANAI_LO16, 6)
diff --git a/include/llvm/Support/ELFRelocs/Mips.def b/include/llvm/Support/ELFRelocs/Mips.def
index 77e7f8e8712b..bc0088dff3f4 100644
--- a/include/llvm/Support/ELFRelocs/Mips.def
+++ b/include/llvm/Support/ELFRelocs/Mips.def
@@ -108,8 +108,8 @@ ELF_RELOC(R_MICROMIPS_TLS_TPREL_HI16, 169)
ELF_RELOC(R_MICROMIPS_TLS_TPREL_LO16, 170)
ELF_RELOC(R_MICROMIPS_GPREL7_S2, 172)
ELF_RELOC(R_MICROMIPS_PC23_S2, 173)
-ELF_RELOC(R_MICROMIPS_PC21_S2, 174)
-ELF_RELOC(R_MICROMIPS_PC26_S2, 175)
+ELF_RELOC(R_MICROMIPS_PC21_S1, 174)
+ELF_RELOC(R_MICROMIPS_PC26_S1, 175)
ELF_RELOC(R_MICROMIPS_PC18_S3, 176)
ELF_RELOC(R_MICROMIPS_PC19_S2, 177)
ELF_RELOC(R_MIPS_NUM, 218)
diff --git a/include/llvm/Support/ELFRelocs/i386.def b/include/llvm/Support/ELFRelocs/i386.def
index 45eae7fe426b..1d28cf595cd5 100644
--- a/include/llvm/Support/ELFRelocs/i386.def
+++ b/include/llvm/Support/ELFRelocs/i386.def
@@ -44,4 +44,4 @@ ELF_RELOC(R_386_TLS_GOTDESC, 39)
ELF_RELOC(R_386_TLS_DESC_CALL, 40)
ELF_RELOC(R_386_TLS_DESC, 41)
ELF_RELOC(R_386_IRELATIVE, 42)
-ELF_RELOC(R_386_NUM, 43)
+ELF_RELOC(R_386_GOT32X, 43)
diff --git a/include/llvm/Support/ELFRelocs/x86_64.def b/include/llvm/Support/ELFRelocs/x86_64.def
index 36ad0618eb2d..18fdcf9472dc 100644
--- a/include/llvm/Support/ELFRelocs/x86_64.def
+++ b/include/llvm/Support/ELFRelocs/x86_64.def
@@ -41,4 +41,5 @@ ELF_RELOC(R_X86_64_GOTPC32_TLSDESC, 34)
ELF_RELOC(R_X86_64_TLSDESC_CALL, 35)
ELF_RELOC(R_X86_64_TLSDESC, 36)
ELF_RELOC(R_X86_64_IRELATIVE, 37)
-
+ELF_RELOC(R_X86_64_GOTPCRELX, 41)
+ELF_RELOC(R_X86_64_REX_GOTPCRELX, 42)
diff --git a/include/llvm/Support/Endian.h b/include/llvm/Support/Endian.h
index bc93c9a66eef..cb5cd8e511b1 100644
--- a/include/llvm/Support/Endian.h
+++ b/include/llvm/Support/Endian.h
@@ -173,6 +173,10 @@ template<typename value_type,
endianness endian,
std::size_t alignment>
struct packed_endian_specific_integral {
+ packed_endian_specific_integral() = default;
+
+ explicit packed_endian_specific_integral(value_type val) { *this = val; }
+
operator value_type() const {
return endian::read<value_type, endian, alignment>(
(const void*)Value.buffer);
diff --git a/include/llvm/Support/EndianStream.h b/include/llvm/Support/EndianStream.h
index d44a9b3b7ce8..43ecd4a5c97e 100644
--- a/include/llvm/Support/EndianStream.h
+++ b/include/llvm/Support/EndianStream.h
@@ -15,6 +15,7 @@
#ifndef LLVM_SUPPORT_ENDIANSTREAM_H
#define LLVM_SUPPORT_ENDIANSTREAM_H
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/raw_ostream.h"
@@ -26,6 +27,10 @@ namespace endian {
template <endianness endian> struct Writer {
raw_ostream &OS;
Writer(raw_ostream &OS) : OS(OS) {}
+ template <typename value_type> void write(ArrayRef<value_type> Vals) {
+ for (value_type V : Vals)
+ write(V);
+ }
template <typename value_type> void write(value_type Val) {
Val = byte_swap<value_type, endian>(Val);
OS.write((const char *)&Val, sizeof(value_type));
diff --git a/include/llvm/Support/Error.h b/include/llvm/Support/Error.h
new file mode 100644
index 000000000000..5f515a88a021
--- /dev/null
+++ b/include/llvm/Support/Error.h
@@ -0,0 +1,950 @@
+//===----- llvm/Support/Error.h - Recoverable error handling ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines an API used to report recoverable errors.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_ERROR_H
+#define LLVM_SUPPORT_ERROR_H
+
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/ErrorOr.h"
+#include "llvm/Support/raw_ostream.h"
+#include <vector>
+
+namespace llvm {
+
+class Error;
+class ErrorList;
+
+/// Base class for error info classes. Do not extend this directly: Extend
+/// the ErrorInfo template subclass instead.
+class ErrorInfoBase {
+public:
+ virtual ~ErrorInfoBase() {}
+
+ /// Print an error message to an output stream.
+ virtual void log(raw_ostream &OS) const = 0;
+
+ /// Return the error message as a string.
+ virtual std::string message() const {
+ std::string Msg;
+ raw_string_ostream OS(Msg);
+ log(OS);
+ return OS.str();
+ }
+
+ /// Convert this error to a std::error_code.
+ ///
+ /// This is a temporary crutch to enable interaction with code still
+ /// using std::error_code. It will be removed in the future.
+ virtual std::error_code convertToErrorCode() const = 0;
+
+ // Check whether this instance is a subclass of the class identified by
+ // ClassID.
+ virtual bool isA(const void *const ClassID) const {
+ return ClassID == classID();
+ }
+
+ // Check whether this instance is a subclass of ErrorInfoT.
+ template <typename ErrorInfoT> bool isA() const {
+ return isA(ErrorInfoT::classID());
+ }
+
+ // Returns the class ID for this type.
+ static const void *classID() { return &ID; }
+
+private:
+ virtual void anchor();
+ static char ID;
+};
+
+/// Lightweight error class with error context and mandatory checking.
+///
+/// Instances of this class wrap a ErrorInfoBase pointer. Failure states
+/// are represented by setting the pointer to a ErrorInfoBase subclass
+/// instance containing information describing the failure. Success is
+/// represented by a null pointer value.
+///
+/// Instances of Error also contains a 'Checked' flag, which must be set
+/// before the destructor is called, otherwise the destructor will trigger a
+/// runtime error. This enforces at runtime the requirement that all Error
+/// instances be checked or returned to the caller.
+///
+/// There are two ways to set the checked flag, depending on what state the
+/// Error instance is in. For Error instances indicating success, it
+/// is sufficient to invoke the boolean conversion operator. E.g.:
+///
+/// Error foo(<...>);
+///
+/// if (auto E = foo(<...>))
+/// return E; // <- Return E if it is in the error state.
+/// // We have verified that E was in the success state. It can now be safely
+/// // destroyed.
+///
+/// A success value *can not* be dropped. For example, just calling 'foo(<...>)'
+/// without testing the return value will raise a runtime error, even if foo
+/// returns success.
+///
+/// For Error instances representing failure, you must use either the
+/// handleErrors or handleAllErrors function with a typed handler. E.g.:
+///
+/// class MyErrorInfo : public ErrorInfo<MyErrorInfo> {
+/// // Custom error info.
+/// };
+///
+/// Error foo(<...>) { return make_error<MyErrorInfo>(...); }
+///
+/// auto E = foo(<...>); // <- foo returns failure with MyErrorInfo.
+/// auto NewE =
+/// handleErrors(E,
+/// [](const MyErrorInfo &M) {
+/// // Deal with the error.
+/// },
+/// [](std::unique_ptr<OtherError> M) -> Error {
+/// if (canHandle(*M)) {
+/// // handle error.
+/// return Error::success();
+/// }
+/// // Couldn't handle this error instance. Pass it up the stack.
+/// return Error(std::move(M));
+/// );
+/// // Note - we must check or return NewE in case any of the handlers
+/// // returned a new error.
+///
+/// The handleAllErrors function is identical to handleErrors, except
+/// that it has a void return type, and requires all errors to be handled and
+/// no new errors be returned. It prevents errors (assuming they can all be
+/// handled) from having to be bubbled all the way to the top-level.
+///
+/// *All* Error instances must be checked before destruction, even if
+/// they're moved-assigned or constructed from Success values that have already
+/// been checked. This enforces checking through all levels of the call stack.
+class Error {
+
+ // ErrorList needs to be able to yank ErrorInfoBase pointers out of this
+ // class to add to the error list.
+ friend class ErrorList;
+
+ // handleErrors needs to be able to set the Checked flag.
+ template <typename... HandlerTs>
+ friend Error handleErrors(Error E, HandlerTs &&... Handlers);
+
+ // Expected<T> needs to be able to steal the payload when constructed from an
+ // error.
+ template <typename T> class Expected;
+
+public:
+ /// Create a success value. Prefer using 'Error::success()' for readability
+ /// where possible.
+ Error() {
+ setPtr(nullptr);
+ setChecked(false);
+ }
+
+ /// Create a success value. This is equivalent to calling the default
+ /// constructor, but should be preferred for readability where possible.
+ static Error success() { return Error(); }
+
+ // Errors are not copy-constructable.
+ Error(const Error &Other) = delete;
+
+ /// Move-construct an error value. The newly constructed error is considered
+ /// unchecked, even if the source error had been checked. The original error
+ /// becomes a checked Success value, regardless of its original state.
+ Error(Error &&Other) {
+ setChecked(true);
+ *this = std::move(Other);
+ }
+
+ /// Create an error value. Prefer using the 'make_error' function, but
+ /// this constructor can be useful when "re-throwing" errors from handlers.
+ Error(std::unique_ptr<ErrorInfoBase> Payload) {
+ setPtr(Payload.release());
+ setChecked(false);
+ }
+
+ // Errors are not copy-assignable.
+ Error &operator=(const Error &Other) = delete;
+
+ /// Move-assign an error value. The current error must represent success, you
+ /// you cannot overwrite an unhandled error. The current error is then
+ /// considered unchecked. The source error becomes a checked success value,
+ /// regardless of its original state.
+ Error &operator=(Error &&Other) {
+ // Don't allow overwriting of unchecked values.
+ assertIsChecked();
+ setPtr(Other.getPtr());
+
+ // This Error is unchecked, even if the source error was checked.
+ setChecked(false);
+
+ // Null out Other's payload and set its checked bit.
+ Other.setPtr(nullptr);
+ Other.setChecked(true);
+
+ return *this;
+ }
+
+ /// Destroy a Error. Fails with a call to abort() if the error is
+ /// unchecked.
+ ~Error() {
+ assertIsChecked();
+ delete getPtr();
+ }
+
+ /// Bool conversion. Returns true if this Error is in a failure state,
+ /// and false if it is in an accept state. If the error is in a Success state
+ /// it will be considered checked.
+ explicit operator bool() {
+ setChecked(getPtr() == nullptr);
+ return getPtr() != nullptr;
+ }
+
+ /// Check whether one error is a subclass of another.
+ template <typename ErrT> bool isA() const {
+ return getPtr() && getPtr()->isA(ErrT::classID());
+ }
+
+private:
+ void assertIsChecked() {
+#ifndef NDEBUG
+ if (!getChecked() || getPtr()) {
+ dbgs() << "Program aborted due to an unhandled Error:\n";
+ if (getPtr())
+ getPtr()->log(dbgs());
+ else
+ dbgs()
+ << "Error value was Success. (Note: Success values must still be "
+ "checked prior to being destroyed).\n";
+ abort();
+ }
+#endif
+ }
+
+ ErrorInfoBase *getPtr() const {
+#ifndef NDEBUG
+ return PayloadAndCheckedBit.getPointer();
+#else
+ return Payload;
+#endif
+ }
+
+ void setPtr(ErrorInfoBase *EI) {
+#ifndef NDEBUG
+ PayloadAndCheckedBit.setPointer(EI);
+#else
+ Payload = EI;
+#endif
+ }
+
+ bool getChecked() const {
+#ifndef NDEBUG
+ return PayloadAndCheckedBit.getInt();
+#else
+ return true;
+#endif
+ }
+
+ void setChecked(bool V) {
+#ifndef NDEBUG
+ PayloadAndCheckedBit.setInt(V);
+#endif
+ }
+
+ std::unique_ptr<ErrorInfoBase> takePayload() {
+ std::unique_ptr<ErrorInfoBase> Tmp(getPtr());
+ setPtr(nullptr);
+ setChecked(true);
+ return Tmp;
+ }
+
+#ifndef NDEBUG
+ PointerIntPair<ErrorInfoBase *, 1> PayloadAndCheckedBit;
+#else
+ ErrorInfoBase *Payload;
+#endif
+};
+
+/// Make a Error instance representing failure using the given error info
+/// type.
+template <typename ErrT, typename... ArgTs> Error make_error(ArgTs &&... Args) {
+ return Error(llvm::make_unique<ErrT>(std::forward<ArgTs>(Args)...));
+}
+
+/// Base class for user error types. Users should declare their error types
+/// like:
+///
+/// class MyError : public ErrorInfo<MyError> {
+/// ....
+/// };
+///
+/// This class provides an implementation of the ErrorInfoBase::kind
+/// method, which is used by the Error RTTI system.
+template <typename ThisErrT, typename ParentErrT = ErrorInfoBase>
+class ErrorInfo : public ParentErrT {
+public:
+ bool isA(const void *const ClassID) const override {
+ return ClassID == classID() || ParentErrT::isA(ClassID);
+ }
+
+ static const void *classID() { return &ThisErrT::ID; }
+};
+
+/// Special ErrorInfo subclass representing a list of ErrorInfos.
+/// Instances of this class are constructed by joinError.
+class ErrorList final : public ErrorInfo<ErrorList> {
+
+ // handleErrors needs to be able to iterate the payload list of an
+ // ErrorList.
+ template <typename... HandlerTs>
+ friend Error handleErrors(Error E, HandlerTs &&... Handlers);
+
+ // joinErrors is implemented in terms of join.
+ friend Error joinErrors(Error, Error);
+
+public:
+ void log(raw_ostream &OS) const override {
+ OS << "Multiple errors:\n";
+ for (auto &ErrPayload : Payloads) {
+ ErrPayload->log(OS);
+ OS << "\n";
+ }
+ }
+
+ std::error_code convertToErrorCode() const override;
+
+ // Used by ErrorInfo::classID.
+ static char ID;
+
+private:
+ ErrorList(std::unique_ptr<ErrorInfoBase> Payload1,
+ std::unique_ptr<ErrorInfoBase> Payload2) {
+ assert(!Payload1->isA<ErrorList>() && !Payload2->isA<ErrorList>() &&
+ "ErrorList constructor payloads should be singleton errors");
+ Payloads.push_back(std::move(Payload1));
+ Payloads.push_back(std::move(Payload2));
+ }
+
+ static Error join(Error E1, Error E2) {
+ if (!E1)
+ return E2;
+ if (!E2)
+ return E1;
+ if (E1.isA<ErrorList>()) {
+ auto &E1List = static_cast<ErrorList &>(*E1.getPtr());
+ if (E2.isA<ErrorList>()) {
+ auto E2Payload = E2.takePayload();
+ auto &E2List = static_cast<ErrorList &>(*E2Payload);
+ for (auto &Payload : E2List.Payloads)
+ E1List.Payloads.push_back(std::move(Payload));
+ } else
+ E1List.Payloads.push_back(E2.takePayload());
+
+ return E1;
+ }
+ if (E2.isA<ErrorList>()) {
+ auto &E2List = static_cast<ErrorList &>(*E2.getPtr());
+ E2List.Payloads.insert(E2List.Payloads.begin(), E1.takePayload());
+ return E2;
+ }
+ return Error(std::unique_ptr<ErrorList>(
+ new ErrorList(E1.takePayload(), E2.takePayload())));
+ }
+
+ std::vector<std::unique_ptr<ErrorInfoBase>> Payloads;
+};
+
+/// Concatenate errors. The resulting Error is unchecked, and contains the
+/// ErrorInfo(s), if any, contained in E1, followed by the
+/// ErrorInfo(s), if any, contained in E2.
+inline Error joinErrors(Error E1, Error E2) {
+ return ErrorList::join(std::move(E1), std::move(E2));
+}
+
+/// Helper for testing applicability of, and applying, handlers for
+/// ErrorInfo types.
+template <typename HandlerT>
+class ErrorHandlerTraits
+ : public ErrorHandlerTraits<decltype(
+ &std::remove_reference<HandlerT>::type::operator())> {};
+
+// Specialization functions of the form 'Error (const ErrT&)'.
+template <typename ErrT> class ErrorHandlerTraits<Error (&)(ErrT &)> {
+public:
+ static bool appliesTo(const ErrorInfoBase &E) {
+ return E.template isA<ErrT>();
+ }
+
+ template <typename HandlerT>
+ static Error apply(HandlerT &&H, std::unique_ptr<ErrorInfoBase> E) {
+ assert(appliesTo(*E) && "Applying incorrect handler");
+ return H(static_cast<ErrT &>(*E));
+ }
+};
+
+// Specialization functions of the form 'void (const ErrT&)'.
+template <typename ErrT> class ErrorHandlerTraits<void (&)(ErrT &)> {
+public:
+ static bool appliesTo(const ErrorInfoBase &E) {
+ return E.template isA<ErrT>();
+ }
+
+ template <typename HandlerT>
+ static Error apply(HandlerT &&H, std::unique_ptr<ErrorInfoBase> E) {
+ assert(appliesTo(*E) && "Applying incorrect handler");
+ H(static_cast<ErrT &>(*E));
+ return Error::success();
+ }
+};
+
+/// Specialization for functions of the form 'Error (std::unique_ptr<ErrT>)'.
+template <typename ErrT>
+class ErrorHandlerTraits<Error (&)(std::unique_ptr<ErrT>)> {
+public:
+ static bool appliesTo(const ErrorInfoBase &E) {
+ return E.template isA<ErrT>();
+ }
+
+ template <typename HandlerT>
+ static Error apply(HandlerT &&H, std::unique_ptr<ErrorInfoBase> E) {
+ assert(appliesTo(*E) && "Applying incorrect handler");
+ std::unique_ptr<ErrT> SubE(static_cast<ErrT *>(E.release()));
+ return H(std::move(SubE));
+ }
+};
+
+/// Specialization for functions of the form 'Error (std::unique_ptr<ErrT>)'.
+template <typename ErrT>
+class ErrorHandlerTraits<void (&)(std::unique_ptr<ErrT>)> {
+public:
+ static bool appliesTo(const ErrorInfoBase &E) {
+ return E.template isA<ErrT>();
+ }
+
+ template <typename HandlerT>
+ static Error apply(HandlerT &&H, std::unique_ptr<ErrorInfoBase> E) {
+ assert(appliesTo(*E) && "Applying incorrect handler");
+ std::unique_ptr<ErrT> SubE(static_cast<ErrT *>(E.release()));
+ H(std::move(SubE));
+ return Error::success();
+ }
+};
+
+// Specialization for member functions of the form 'RetT (const ErrT&)'.
+template <typename C, typename RetT, typename ErrT>
+class ErrorHandlerTraits<RetT (C::*)(ErrT &)>
+ : public ErrorHandlerTraits<RetT (&)(ErrT &)> {};
+
+// Specialization for member functions of the form 'RetT (const ErrT&) const'.
+template <typename C, typename RetT, typename ErrT>
+class ErrorHandlerTraits<RetT (C::*)(ErrT &) const>
+ : public ErrorHandlerTraits<RetT (&)(ErrT &)> {};
+
+// Specialization for member functions of the form 'RetT (const ErrT&)'.
+template <typename C, typename RetT, typename ErrT>
+class ErrorHandlerTraits<RetT (C::*)(const ErrT &)>
+ : public ErrorHandlerTraits<RetT (&)(ErrT &)> {};
+
+// Specialization for member functions of the form 'RetT (const ErrT&) const'.
+template <typename C, typename RetT, typename ErrT>
+class ErrorHandlerTraits<RetT (C::*)(const ErrT &) const>
+ : public ErrorHandlerTraits<RetT (&)(ErrT &)> {};
+
+/// Specialization for member functions of the form
+/// 'RetT (std::unique_ptr<ErrT>) const'.
+template <typename C, typename RetT, typename ErrT>
+class ErrorHandlerTraits<RetT (C::*)(std::unique_ptr<ErrT>)>
+ : public ErrorHandlerTraits<RetT (&)(std::unique_ptr<ErrT>)> {};
+
+/// Specialization for member functions of the form
+/// 'RetT (std::unique_ptr<ErrT>) const'.
+template <typename C, typename RetT, typename ErrT>
+class ErrorHandlerTraits<RetT (C::*)(std::unique_ptr<ErrT>) const>
+ : public ErrorHandlerTraits<RetT (&)(std::unique_ptr<ErrT>)> {};
+
+inline Error handleErrorImpl(std::unique_ptr<ErrorInfoBase> Payload) {
+ return Error(std::move(Payload));
+}
+
+template <typename HandlerT, typename... HandlerTs>
+Error handleErrorImpl(std::unique_ptr<ErrorInfoBase> Payload,
+ HandlerT &&Handler, HandlerTs &&... Handlers) {
+ if (ErrorHandlerTraits<HandlerT>::appliesTo(*Payload))
+ return ErrorHandlerTraits<HandlerT>::apply(std::forward<HandlerT>(Handler),
+ std::move(Payload));
+ return handleErrorImpl(std::move(Payload),
+ std::forward<HandlerTs>(Handlers)...);
+}
+
+/// Pass the ErrorInfo(s) contained in E to their respective handlers. Any
+/// unhandled errors (or Errors returned by handlers) are re-concatenated and
+/// returned.
+/// Because this function returns an error, its result must also be checked
+/// or returned. If you intend to handle all errors use handleAllErrors
+/// (which returns void, and will abort() on unhandled errors) instead.
+template <typename... HandlerTs>
+Error handleErrors(Error E, HandlerTs &&... Hs) {
+ if (!E)
+ return Error::success();
+
+ std::unique_ptr<ErrorInfoBase> Payload = E.takePayload();
+
+ if (Payload->isA<ErrorList>()) {
+ ErrorList &List = static_cast<ErrorList &>(*Payload);
+ Error R;
+ for (auto &P : List.Payloads)
+ R = ErrorList::join(
+ std::move(R),
+ handleErrorImpl(std::move(P), std::forward<HandlerTs>(Hs)...));
+ return R;
+ }
+
+ return handleErrorImpl(std::move(Payload), std::forward<HandlerTs>(Hs)...);
+}
+
+/// Behaves the same as handleErrors, except that it requires that all
+/// errors be handled by the given handlers. If any unhandled error remains
+/// after the handlers have run, abort() will be called.
+template <typename... HandlerTs>
+void handleAllErrors(Error E, HandlerTs &&... Handlers) {
+ auto F = handleErrors(std::move(E), std::forward<HandlerTs>(Handlers)...);
+ // Cast 'F' to bool to set the 'Checked' flag if it's a success value:
+ (void)!F;
+}
+
+/// Check that E is a non-error, then drop it.
+inline void handleAllErrors(Error E) {
+ // Cast 'E' to a bool to set the 'Checked' flag if it's a success value:
+ (void)!E;
+}
+
+/// Log all errors (if any) in E to OS. If there are any errors, ErrorBanner
+/// will be printed before the first one is logged. A newline will be printed
+/// after each error.
+///
+/// This is useful in the base level of your program to allow clean termination
+/// (allowing clean deallocation of resources, etc.), while reporting error
+/// information to the user.
+void logAllUnhandledErrors(Error E, raw_ostream &OS, Twine ErrorBanner);
+
+/// Write all error messages (if any) in E to a string. The newline character
+/// is used to separate error messages.
+inline std::string toString(Error E) {
+ SmallVector<std::string, 2> Errors;
+ handleAllErrors(std::move(E), [&Errors](const ErrorInfoBase &EI) {
+ Errors.push_back(EI.message());
+ });
+ return join(Errors.begin(), Errors.end(), "\n");
+}
+
+/// Consume a Error without doing anything. This method should be used
+/// only where an error can be considered a reasonable and expected return
+/// value.
+///
+/// Uses of this method are potentially indicative of design problems: If it's
+/// legitimate to do nothing while processing an "error", the error-producer
+/// might be more clearly refactored to return an Optional<T>.
+inline void consumeError(Error Err) {
+ handleAllErrors(std::move(Err), [](const ErrorInfoBase &) {});
+}
+
+/// Helper for Errors used as out-parameters.
+///
+/// This helper is for use with the Error-as-out-parameter idiom, where an error
+/// is passed to a function or method by reference, rather than being returned.
+/// In such cases it is helpful to set the checked bit on entry to the function
+/// so that the error can be written to (unchecked Errors abort on assignment)
+/// and clear the checked bit on exit so that clients cannot accidentally forget
+/// to check the result. This helper performs these actions automatically using
+/// RAII:
+///
+/// Result foo(Error &Err) {
+/// ErrorAsOutParameter ErrAsOutParam(Err); // 'Checked' flag set
+/// // <body of foo>
+/// // <- 'Checked' flag auto-cleared when ErrAsOutParam is destructed.
+/// }
+class ErrorAsOutParameter {
+public:
+ ErrorAsOutParameter(Error &Err) : Err(Err) {
+ // Raise the checked bit if Err is success.
+ (void)!!Err;
+ }
+ ~ErrorAsOutParameter() {
+ // Clear the checked bit.
+ if (!Err)
+ Err = Error::success();
+ }
+
+private:
+ Error &Err;
+};
+
+/// Tagged union holding either a T or a Error.
+///
+/// This class parallels ErrorOr, but replaces error_code with Error. Since
+/// Error cannot be copied, this class replaces getError() with
+/// takeError(). It also adds an bool errorIsA<ErrT>() method for testing the
+/// error class type.
+template <class T> class Expected {
+ template <class OtherT> friend class Expected;
+ static const bool isRef = std::is_reference<T>::value;
+ typedef ReferenceStorage<typename std::remove_reference<T>::type> wrap;
+
+ typedef std::unique_ptr<ErrorInfoBase> error_type;
+
+public:
+ typedef typename std::conditional<isRef, wrap, T>::type storage_type;
+ typedef T value_type;
+
+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:
+ /// Create an Expected<T> error value from the given Error.
+ Expected(Error Err)
+ : HasError(true)
+#ifndef NDEBUG
+ ,
+ Checked(false)
+#endif
+ {
+ assert(Err && "Cannot create Expected<T> from Error success value.");
+ new (getErrorStorage()) Error(std::move(Err));
+ }
+
+ /// Create an Expected<T> success value from the given OtherT value, which
+ /// must be convertible to T.
+ template <typename OtherT>
+ Expected(OtherT &&Val,
+ typename std::enable_if<std::is_convertible<OtherT, T>::value>::type
+ * = nullptr)
+ : HasError(false)
+#ifndef NDEBUG
+ ,
+ Checked(false)
+#endif
+ {
+ new (getStorage()) storage_type(std::forward<OtherT>(Val));
+ }
+
+ /// Move construct an Expected<T> value.
+ Expected(Expected &&Other) { moveConstruct(std::move(Other)); }
+
+ /// Move construct an Expected<T> value from an Expected<OtherT>, where OtherT
+ /// must be convertible to T.
+ template <class OtherT>
+ Expected(Expected<OtherT> &&Other,
+ typename std::enable_if<std::is_convertible<OtherT, T>::value>::type
+ * = nullptr) {
+ moveConstruct(std::move(Other));
+ }
+
+ /// Move construct an Expected<T> value from an Expected<OtherT>, where OtherT
+ /// isn't convertible to T.
+ template <class OtherT>
+ explicit Expected(
+ Expected<OtherT> &&Other,
+ typename std::enable_if<!std::is_convertible<OtherT, T>::value>::type * =
+ nullptr) {
+ moveConstruct(std::move(Other));
+ }
+
+ /// Move-assign from another Expected<T>.
+ Expected &operator=(Expected &&Other) {
+ moveAssign(std::move(Other));
+ return *this;
+ }
+
+ /// Destroy an Expected<T>.
+ ~Expected() {
+ assertIsChecked();
+ if (!HasError)
+ getStorage()->~storage_type();
+ else
+ getErrorStorage()->~error_type();
+ }
+
+ /// \brief Return false if there is an error.
+ explicit operator bool() {
+#ifndef NDEBUG
+ Checked = !HasError;
+#endif
+ return !HasError;
+ }
+
+ /// \brief Returns a reference to the stored T value.
+ reference get() {
+ assertIsChecked();
+ return *getStorage();
+ }
+
+ /// \brief Returns a const reference to the stored T value.
+ const_reference get() const {
+ assertIsChecked();
+ return const_cast<Expected<T> *>(this)->get();
+ }
+
+ /// \brief Check that this Expected<T> is an error of type ErrT.
+ template <typename ErrT> bool errorIsA() const {
+ return HasError && getErrorStorage()->template isA<ErrT>();
+ }
+
+ /// \brief Take ownership of the stored error.
+ /// After calling this the Expected<T> is in an indeterminate state that can
+ /// only be safely destructed. No further calls (beside the destructor) should
+ /// be made on the Expected<T> vaule.
+ Error takeError() {
+#ifndef NDEBUG
+ Checked = true;
+#endif
+ return HasError ? Error(std::move(*getErrorStorage())) : Error::success();
+ }
+
+ /// \brief Returns a pointer to the stored T value.
+ pointer operator->() {
+ assertIsChecked();
+ return toPointer(getStorage());
+ }
+
+ /// \brief Returns a const pointer to the stored T value.
+ const_pointer operator->() const {
+ assertIsChecked();
+ return toPointer(getStorage());
+ }
+
+ /// \brief Returns a reference to the stored T value.
+ reference operator*() {
+ assertIsChecked();
+ return *getStorage();
+ }
+
+ /// \brief Returns a const reference to the stored T value.
+ const_reference operator*() const {
+ assertIsChecked();
+ return *getStorage();
+ }
+
+private:
+ template <class T1>
+ static bool compareThisIfSameType(const T1 &a, const T1 &b) {
+ return &a == &b;
+ }
+
+ template <class T1, class T2>
+ static bool compareThisIfSameType(const T1 &a, const T2 &b) {
+ return false;
+ }
+
+ template <class OtherT> void moveConstruct(Expected<OtherT> &&Other) {
+ HasError = Other.HasError;
+
+#ifndef NDEBUG
+ Checked = false;
+ Other.Checked = true;
+#endif
+
+ if (!HasError)
+ new (getStorage()) storage_type(std::move(*Other.getStorage()));
+ else
+ new (getErrorStorage()) error_type(std::move(*Other.getErrorStorage()));
+ }
+
+ template <class OtherT> void moveAssign(Expected<OtherT> &&Other) {
+ assertIsChecked();
+
+ if (compareThisIfSameType(*this, Other))
+ return;
+
+ this->~Expected();
+ new (this) Expected(std::move(Other));
+ }
+
+ pointer toPointer(pointer Val) { 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);
+ }
+
+ const storage_type *getStorage() const {
+ assert(!HasError && "Cannot get value when an error exists!");
+ return reinterpret_cast<const storage_type *>(TStorage.buffer);
+ }
+
+ error_type *getErrorStorage() {
+ assert(HasError && "Cannot get error when a value exists!");
+ return reinterpret_cast<error_type *>(ErrorStorage.buffer);
+ }
+
+ void assertIsChecked() {
+#ifndef NDEBUG
+ if (!Checked) {
+ dbgs() << "Expected<T> must be checked before access or destruction.\n";
+ if (HasError) {
+ dbgs() << "Unchecked Expected<T> contained error:\n";
+ (*getErrorStorage())->log(dbgs());
+ } else
+ dbgs() << "Expected<T> value was in success state. (Note: Expected<T> "
+ "values in success mode must still be checked prior to being "
+ "destroyed).\n";
+ abort();
+ }
+#endif
+ }
+
+ union {
+ AlignedCharArrayUnion<storage_type> TStorage;
+ AlignedCharArrayUnion<error_type> ErrorStorage;
+ };
+ bool HasError : 1;
+#ifndef NDEBUG
+ bool Checked : 1;
+#endif
+};
+
+/// This class wraps a std::error_code in a Error.
+///
+/// This is useful if you're writing an interface that returns a Error
+/// (or Expected) and you want to call code that still returns
+/// std::error_codes.
+class ECError : public ErrorInfo<ECError> {
+ friend Error errorCodeToError(std::error_code);
+public:
+ void setErrorCode(std::error_code EC) { this->EC = EC; }
+ std::error_code convertToErrorCode() const override { return EC; }
+ void log(raw_ostream &OS) const override { OS << EC.message(); }
+
+ // Used by ErrorInfo::classID.
+ static char ID;
+
+protected:
+ ECError() = default;
+ ECError(std::error_code EC) : EC(EC) {}
+ std::error_code EC;
+};
+
+/// The value returned by this function can be returned from convertToErrorCode
+/// for Error values where no sensible translation to std::error_code exists.
+/// It should only be used in this situation, and should never be used where a
+/// sensible conversion to std::error_code is available, as attempts to convert
+/// to/from this error will result in a fatal error. (i.e. it is a programmatic
+///error to try to convert such a value).
+std::error_code inconvertibleErrorCode();
+
+/// Helper for converting an std::error_code to a Error.
+Error errorCodeToError(std::error_code EC);
+
+/// Helper for converting an ECError to a std::error_code.
+///
+/// This method requires that Err be Error() or an ECError, otherwise it
+/// will trigger a call to abort().
+std::error_code errorToErrorCode(Error Err);
+
+/// Convert an ErrorOr<T> to an Expected<T>.
+template <typename T> Expected<T> errorOrToExpected(ErrorOr<T> &&EO) {
+ if (auto EC = EO.getError())
+ return errorCodeToError(EC);
+ return std::move(*EO);
+}
+
+/// Convert an Expected<T> to an ErrorOr<T>.
+template <typename T> ErrorOr<T> expectedToErrorOr(Expected<T> &&E) {
+ if (auto Err = E.takeError())
+ return errorToErrorCode(std::move(Err));
+ return std::move(*E);
+}
+
+/// This class wraps a string in an Error.
+///
+/// StringError is useful in cases where the client is not expected to be able
+/// to consume the specific error message programmatically (for example, if the
+/// error message is to be presented to the user).
+class StringError : public ErrorInfo<StringError> {
+public:
+ static char ID;
+ StringError(const Twine &S, std::error_code EC);
+ void log(raw_ostream &OS) const override;
+ std::error_code convertToErrorCode() const override;
+private:
+ std::string Msg;
+ std::error_code EC;
+};
+
+/// Helper for check-and-exit error handling.
+///
+/// For tool use only. NOT FOR USE IN LIBRARY CODE.
+///
+class ExitOnError {
+public:
+ /// Create an error on exit helper.
+ ExitOnError(std::string Banner = "", int DefaultErrorExitCode = 1)
+ : Banner(std::move(Banner)),
+ GetExitCode([=](const Error &) { return DefaultErrorExitCode; }) {}
+
+ /// Set the banner string for any errors caught by operator().
+ void setBanner(std::string Banner) { this->Banner = std::move(Banner); }
+
+ /// Set the exit-code mapper function.
+ void setExitCodeMapper(std::function<int(const Error &)> GetExitCode) {
+ this->GetExitCode = std::move(GetExitCode);
+ }
+
+ /// Check Err. If it's in a failure state log the error(s) and exit.
+ void operator()(Error Err) const { checkError(std::move(Err)); }
+
+ /// Check E. If it's in a success state then return the contained value. If
+ /// it's in a failure state log the error(s) and exit.
+ template <typename T> T operator()(Expected<T> &&E) const {
+ checkError(E.takeError());
+ return std::move(*E);
+ }
+
+ /// Check E. If it's in a success state then return the contained reference. If
+ /// it's in a failure state log the error(s) and exit.
+ template <typename T> T& operator()(Expected<T&> &&E) const {
+ checkError(E.takeError());
+ return *E;
+ }
+
+private:
+ void checkError(Error Err) const {
+ if (Err) {
+ int ExitCode = GetExitCode(Err);
+ logAllUnhandledErrors(std::move(Err), errs(), Banner);
+ exit(ExitCode);
+ }
+ }
+
+ std::string Banner;
+ std::function<int(const Error &)> GetExitCode;
+};
+
+/// Report a serious error, calling any installed error handler. See
+/// ErrorHandling.h.
+LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err,
+ bool gen_crash_diag = true);
+
+} // namespace llvm
+
+#endif // LLVM_SUPPORT_ERROR_H
diff --git a/include/llvm/Support/ErrorHandling.h b/include/llvm/Support/ErrorHandling.h
index 32f05e0e9610..7c1edd801571 100644
--- a/include/llvm/Support/ErrorHandling.h
+++ b/include/llvm/Support/ErrorHandling.h
@@ -15,11 +15,11 @@
#ifndef LLVM_SUPPORT_ERRORHANDLING_H
#define LLVM_SUPPORT_ERRORHANDLING_H
-#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Compiler.h"
#include <string>
namespace llvm {
+class StringRef;
class Twine;
/// An error handler callback.
diff --git a/include/llvm/Support/ErrorOr.h b/include/llvm/Support/ErrorOr.h
index ca6ede73e8df..877f4063cd23 100644
--- a/include/llvm/Support/ErrorOr.h
+++ b/include/llvm/Support/ErrorOr.h
@@ -23,20 +23,6 @@
#include <type_traits>
namespace llvm {
-template<class T, class V>
-typename std::enable_if< std::is_constructible<T, V>::value
- , typename std::remove_reference<V>::type>::type &&
- moveIfMoveConstructible(V &Val) {
- return std::move(Val);
-}
-
-template<class T, class V>
-typename std::enable_if< !std::is_constructible<T, V>::value
- , typename std::remove_reference<V>::type>::type &
-moveIfMoveConstructible(V &Val) {
- return Val;
-}
-
/// \brief Stores a reference that can be changed.
template <typename T>
class ReferenceStorage {
@@ -72,7 +58,7 @@ public:
/// unary * and -> operators provide pointer like access to the value. Accessing
/// the value when there is an error has undefined behavior.
///
-/// When T is a reference type the behaivor is slightly different. The reference
+/// When T is a reference type the behavior is slightly different. The reference
/// is held in a std::reference_wrapper<std::remove_reference<T>::type>, and
/// there is special handling to make operator -> work as if T was not a
/// reference.
@@ -98,7 +84,7 @@ public:
ErrorOr(E ErrorCode,
typename std::enable_if<std::is_error_code_enum<E>::value ||
std::is_error_condition_enum<E>::value,
- void *>::type = 0)
+ void *>::type = nullptr)
: HasError(true) {
new (getErrorStorage()) std::error_code(make_error_code(ErrorCode));
}
@@ -107,8 +93,12 @@ public:
new (getErrorStorage()) std::error_code(EC);
}
- ErrorOr(T Val) : HasError(false) {
- new (getStorage()) storage_type(moveIfMoveConstructible<storage_type>(Val));
+ template <class OtherT>
+ ErrorOr(OtherT &&Val,
+ typename std::enable_if<std::is_convertible<OtherT, T>::value>::type
+ * = nullptr)
+ : HasError(false) {
+ new (getStorage()) storage_type(std::forward<OtherT>(Val));
}
ErrorOr(const ErrorOr &Other) {
@@ -278,7 +268,6 @@ private:
return const_cast<ErrorOr<T> *>(this)->getErrorStorage();
}
-
union {
AlignedCharArrayUnion<storage_type> TStorage;
AlignedCharArrayUnion<std::error_code> ErrorStorage;
@@ -295,4 +284,4 @@ operator==(const ErrorOr<T> &Err, E Code) {
}
} // end namespace llvm
-#endif
+#endif // LLVM_SUPPORT_ERROROR_H
diff --git a/include/llvm/Support/FileSystem.h b/include/llvm/Support/FileSystem.h
index 4733ddb77575..42a6180e0eb3 100644
--- a/include/llvm/Support/FileSystem.h
+++ b/include/llvm/Support/FileSystem.h
@@ -29,12 +29,15 @@
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/TimeValue.h"
+#include <cassert>
+#include <cstdint>
#include <ctime>
-#include <iterator>
#include <stack>
#include <string>
#include <system_error>
@@ -140,11 +143,14 @@ class file_status
#if defined(LLVM_ON_UNIX)
dev_t fs_st_dev;
ino_t fs_st_ino;
+ time_t fs_st_atime;
time_t fs_st_mtime;
uid_t fs_st_uid;
gid_t fs_st_gid;
off_t fs_st_size;
#elif defined (LLVM_ON_WIN32)
+ uint32_t LastAccessedTimeHigh;
+ uint32_t LastAccessedTimeLow;
uint32_t LastWriteTimeHigh;
uint32_t LastWriteTimeLow;
uint32_t VolumeSerialNumber;
@@ -159,43 +165,51 @@ class file_status
public:
#if defined(LLVM_ON_UNIX)
- file_status() : fs_st_dev(0), fs_st_ino(0), fs_st_mtime(0),
+ file_status()
+ : fs_st_dev(0), fs_st_ino(0), fs_st_atime(0), fs_st_mtime(0),
fs_st_uid(0), fs_st_gid(0), fs_st_size(0),
Type(file_type::status_error), Perms(perms_not_known) {}
- file_status(file_type Type) : fs_st_dev(0), fs_st_ino(0), fs_st_mtime(0),
+ file_status(file_type Type)
+ : fs_st_dev(0), fs_st_ino(0), fs_st_atime(0), fs_st_mtime(0),
fs_st_uid(0), fs_st_gid(0), fs_st_size(0), Type(Type),
Perms(perms_not_known) {}
- file_status(file_type Type, perms Perms, dev_t Dev, ino_t Ino, time_t MTime,
- uid_t UID, gid_t GID, off_t Size)
- : fs_st_dev(Dev), fs_st_ino(Ino), fs_st_mtime(MTime), fs_st_uid(UID),
- fs_st_gid(GID), fs_st_size(Size), Type(Type), Perms(Perms) {}
+ file_status(file_type Type, perms Perms, dev_t Dev, ino_t Ino, time_t ATime,
+ time_t MTime, uid_t UID, gid_t GID, off_t Size)
+ : fs_st_dev(Dev), fs_st_ino(Ino), fs_st_atime(ATime), fs_st_mtime(MTime),
+ fs_st_uid(UID), fs_st_gid(GID), fs_st_size(Size), Type(Type),
+ Perms(Perms) {}
#elif defined(LLVM_ON_WIN32)
- file_status() : LastWriteTimeHigh(0), LastWriteTimeLow(0),
- VolumeSerialNumber(0), FileSizeHigh(0), FileSizeLow(0),
- FileIndexHigh(0), FileIndexLow(0), Type(file_type::status_error),
- Perms(perms_not_known) {}
+ file_status()
+ : LastAccessedTimeHigh(0), LastAccessedTimeLow(0), LastWriteTimeHigh(0),
+ LastWriteTimeLow(0), VolumeSerialNumber(0), FileSizeHigh(0),
+ FileSizeLow(0), FileIndexHigh(0), FileIndexLow(0),
+ Type(file_type::status_error), Perms(perms_not_known) {}
- file_status(file_type Type) : LastWriteTimeHigh(0), LastWriteTimeLow(0),
- VolumeSerialNumber(0), FileSizeHigh(0), FileSizeLow(0),
- FileIndexHigh(0), FileIndexLow(0), Type(Type),
+ file_status(file_type Type)
+ : LastAccessedTimeHigh(0), LastAccessedTimeLow(0), LastWriteTimeHigh(0),
+ LastWriteTimeLow(0), VolumeSerialNumber(0), FileSizeHigh(0),
+ FileSizeLow(0), FileIndexHigh(0), FileIndexLow(0), Type(Type),
Perms(perms_not_known) {}
- file_status(file_type Type, uint32_t LastWriteTimeHigh,
- uint32_t LastWriteTimeLow, uint32_t VolumeSerialNumber,
- uint32_t FileSizeHigh, uint32_t FileSizeLow,
- uint32_t FileIndexHigh, uint32_t FileIndexLow)
- : LastWriteTimeHigh(LastWriteTimeHigh),
- LastWriteTimeLow(LastWriteTimeLow),
- VolumeSerialNumber(VolumeSerialNumber), FileSizeHigh(FileSizeHigh),
- FileSizeLow(FileSizeLow), FileIndexHigh(FileIndexHigh),
- FileIndexLow(FileIndexLow), Type(Type), Perms(perms_not_known) {}
+ file_status(file_type Type, uint32_t LastAccessTimeHigh,
+ uint32_t LastAccessTimeLow, uint32_t LastWriteTimeHigh,
+ uint32_t LastWriteTimeLow, uint32_t VolumeSerialNumber,
+ uint32_t FileSizeHigh, uint32_t FileSizeLow,
+ uint32_t FileIndexHigh, uint32_t FileIndexLow)
+ : LastAccessedTimeHigh(LastAccessTimeHigh), LastAccessedTimeLow(LastAccessTimeLow),
+ LastWriteTimeHigh(LastWriteTimeHigh),
+ LastWriteTimeLow(LastWriteTimeLow),
+ VolumeSerialNumber(VolumeSerialNumber), FileSizeHigh(FileSizeHigh),
+ FileSizeLow(FileSizeLow), FileIndexHigh(FileIndexHigh),
+ FileIndexLow(FileIndexLow), Type(Type), Perms(perms_not_known) {}
#endif
// getters
file_type type() const { return Type; }
perms permissions() const { return Perms; }
+ TimeValue getLastAccessedTime() const;
TimeValue getLastModificationTime() const;
UniqueID getUniqueID() const;
@@ -251,7 +265,7 @@ struct file_magic {
};
bool is_object() const {
- return V == unknown ? false : true;
+ return V != unknown;
}
file_magic() : V(unknown) {}
@@ -590,6 +604,12 @@ std::error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix,
std::error_code createUniqueDirectory(const Twine &Prefix,
SmallVectorImpl<char> &ResultPath);
+/// @brief Fetch a path to an open file, as specified by a file descriptor
+///
+/// @param FD File descriptor to a currently open file
+/// @param ResultPath The buffer into which to write the path
+std::error_code getPathFromOpenFD(int FD, SmallVectorImpl<char> &ResultPath);
+
enum OpenFlags : unsigned {
F_None = 0,
@@ -622,7 +642,8 @@ inline OpenFlags &operator|=(OpenFlags &A, OpenFlags B) {
std::error_code openFileForWrite(const Twine &Name, int &ResultFD,
OpenFlags Flags, unsigned Mode = 0666);
-std::error_code openFileForRead(const Twine &Name, int &ResultFD);
+std::error_code openFileForRead(const Twine &Name, int &ResultFD,
+ SmallVectorImpl<char> *RealPath = nullptr);
/// @brief Identify the type of a binary file based on how magical it is.
file_magic identify_magic(StringRef magic);
@@ -637,6 +658,17 @@ std::error_code identify_magic(const Twine &path, file_magic &result);
std::error_code getUniqueID(const Twine Path, UniqueID &Result);
+/// @brief Get disk space usage information.
+///
+/// Note: Users must be careful about "Time Of Check, Time Of Use" kind of bug.
+/// Note: Windows reports results according to the quota allocated to the user.
+///
+/// @param Path Input path.
+/// @returns a space_info structure filled with the capacity, free, and
+/// available space on the device \a Path is on. A platform specific error_code
+/// is returned on error.
+ErrorOr<space_info> disk_space(const Twine &Path);
+
/// This class represents a memory mapped file. It is based on
/// boost::iostreams::mapped_file.
class mapped_file_region {
@@ -739,7 +771,7 @@ namespace detail {
intptr_t IterationHandle;
directory_entry CurrentEntry;
};
-}
+} // end namespace detail
/// directory_iterator - Iterates through the entries in path. There is no
/// operator++ because we need an error_code. If it's really needed we can make
@@ -801,7 +833,7 @@ namespace detail {
uint16_t Level;
bool HasNoPushRequest;
};
-}
+} // end namespace detail
/// recursive_directory_iterator - Same as directory_iterator except for it
/// recurses down into child directories.
@@ -900,4 +932,4 @@ public:
} // end namespace sys
} // end namespace llvm
-#endif
+#endif // LLVM_SUPPORT_FILESYSTEM_H
diff --git a/include/llvm/Support/Format.h b/include/llvm/Support/Format.h
index f0b437a0cbed..d5c301cd7e2b 100644
--- a/include/llvm/Support/Format.h
+++ b/include/llvm/Support/Format.h
@@ -170,13 +170,13 @@ inline FormattedNumber format_hex(uint64_t N, unsigned Width,
/// format_hex_no_prefix - Output \p N as a fixed width hexadecimal. Does not
/// prepend '0x' to the outputted string. If number will not fit in width,
/// full number is still printed. Examples:
-/// OS << format_hex_no_prefix(255, 4) => ff
-/// OS << format_hex_no_prefix(255, 4, true) => FF
-/// OS << format_hex_no_prefix(255, 6) => 00ff
/// OS << format_hex_no_prefix(255, 2) => ff
+/// OS << format_hex_no_prefix(255, 2, true) => FF
+/// OS << format_hex_no_prefix(255, 4) => 00ff
+/// OS << format_hex_no_prefix(255, 1) => ff
inline FormattedNumber format_hex_no_prefix(uint64_t N, unsigned Width,
bool Upper = false) {
- assert(Width <= 18 && "hex width must be <= 18");
+ assert(Width <= 16 && "hex width must be <= 16");
return FormattedNumber(N, 0, Width, true, Upper, false);
}
diff --git a/include/llvm/Support/GenericDomTree.h b/include/llvm/Support/GenericDomTree.h
index 8bae582d18c7..77b5ba7e3e97 100644
--- a/include/llvm/Support/GenericDomTree.h
+++ b/include/llvm/Support/GenericDomTree.h
@@ -109,13 +109,13 @@ public:
return true;
SmallPtrSet<const NodeT *, 4> OtherChildren;
- for (const_iterator I = Other->begin(), E = Other->end(); I != E; ++I) {
- const NodeT *Nd = (*I)->getBlock();
+ for (const DomTreeNodeBase *I : *Other) {
+ const NodeT *Nd = I->getBlock();
OtherChildren.insert(Nd);
}
- for (const_iterator I = begin(), E = end(); I != E; ++I) {
- const NodeT *N = (*I)->getBlock();
+ for (const DomTreeNodeBase *I : *this) {
+ const NodeT *N = I->getBlock();
if (OtherChildren.count(N) == 0)
return true;
}
@@ -138,8 +138,9 @@ public:
}
}
- /// getDFSNumIn/getDFSNumOut - These are an internal implementation detail, do
- /// not call them.
+ /// getDFSNumIn/getDFSNumOut - These return the DFS visitation order for nodes
+ /// in the dominator tree. They are only guaranteed valid if
+ /// updateDFSNumbers() has been called.
unsigned getDFSNumIn() const { return DFSNumIn; }
unsigned getDFSNumOut() const { return DFSNumOut; }
@@ -348,17 +349,14 @@ public:
if (DomTreeNodes.size() != OtherDomTreeNodes.size())
return true;
- for (typename DomTreeNodeMapType::const_iterator
- I = this->DomTreeNodes.begin(),
- E = this->DomTreeNodes.end();
- I != E; ++I) {
- NodeT *BB = I->first;
+ for (const auto &DomTreeNode : this->DomTreeNodes) {
+ NodeT *BB = DomTreeNode.first;
typename DomTreeNodeMapType::const_iterator OI =
OtherDomTreeNodes.find(BB);
if (OI == OtherDomTreeNodes.end())
return true;
- DomTreeNodeBase<NodeT> &MyNd = *I->second;
+ DomTreeNodeBase<NodeT> &MyNd = *DomTreeNode.second;
DomTreeNodeBase<NodeT> &OtherNd = *OI->second;
if (MyNd.compare(&OtherNd))
@@ -453,7 +451,7 @@ public:
// Compare the result of the tree walk and the dfs numbers, if expensive
// checks are enabled.
-#ifdef XDEBUG
+#ifdef EXPENSIVE_CHECKS
assert((!DFSInfoValid ||
(dominatedBySlowTreeWalk(A, B) == B->DominatedBy(A))) &&
"Tree walk disagrees with dfs numbers!");
diff --git a/include/llvm/Support/Host.h b/include/llvm/Support/Host.h
index 8f4bf3c1ba56..8114f9bf846b 100644
--- a/include/llvm/Support/Host.h
+++ b/include/llvm/Support/Host.h
@@ -16,7 +16,7 @@
#include "llvm/ADT/StringMap.h"
-#if defined(__linux__) || defined(__GNU__)
+#if defined(__linux__) || defined(__GNU__) || defined(__HAIKU__)
#include <endian.h>
#else
#if !defined(BYTE_ORDER) && !defined(LLVM_ON_WIN32)
diff --git a/include/llvm/Support/JamCRC.h b/include/llvm/Support/JamCRC.h
index 20c28a5f8e45..5268bbd9ba1e 100644
--- a/include/llvm/Support/JamCRC.h
+++ b/include/llvm/Support/JamCRC.h
@@ -27,10 +27,11 @@
#ifndef LLVM_SUPPORT_JAMCRC_H
#define LLVM_SUPPORT_JAMCRC_H
-#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/DataTypes.h"
namespace llvm {
+template <typename T> class ArrayRef;
+
class JamCRC {
public:
JamCRC(uint32_t Init = 0xFFFFFFFFU) : CRC(Init) {}
diff --git a/include/llvm/Support/Locale.h b/include/llvm/Support/Locale.h
index b384d58baea7..f7a2c036ed5e 100644
--- a/include/llvm/Support/Locale.h
+++ b/include/llvm/Support/Locale.h
@@ -1,9 +1,9 @@
#ifndef LLVM_SUPPORT_LOCALE_H
#define LLVM_SUPPORT_LOCALE_H
-#include "llvm/ADT/StringRef.h"
-
namespace llvm {
+class StringRef;
+
namespace sys {
namespace locale {
diff --git a/include/llvm/Support/LockFileManager.h b/include/llvm/Support/LockFileManager.h
index 8e88d4279bd8..13d252425b93 100644
--- a/include/llvm/Support/LockFileManager.h
+++ b/include/llvm/Support/LockFileManager.h
@@ -11,11 +11,12 @@
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/StringRef.h"
#include <system_error>
#include <utility> // for std::pair
namespace llvm {
+class StringRef;
+
/// \brief Class that manages the creation of a lock file to aid
/// implicit coordination between different processes.
///
@@ -56,6 +57,7 @@ private:
Optional<std::pair<std::string, int> > Owner;
Optional<std::error_code> Error;
+ std::string ErrorDiagMsg;
LockFileManager(const LockFileManager &) = delete;
LockFileManager &operator=(const LockFileManager &) = delete;
@@ -81,6 +83,15 @@ public:
/// \brief Remove the lock file. This may delete a different lock file than
/// the one previously read if there is a race.
std::error_code unsafeRemoveLockFile();
+
+ /// \brief Get error message, or "" if there is no error.
+ std::string getErrorMessage() const;
+
+ /// \brief Set error and error message
+ void setError(std::error_code &EC, StringRef ErrorMsg = "") {
+ Error = EC;
+ ErrorDiagMsg = ErrorMsg.str();
+ }
};
} // end namespace llvm
diff --git a/include/llvm/Support/MD5.h b/include/llvm/Support/MD5.h
index f6e1e92c9fa8..42d8ca8a1ebb 100644
--- a/include/llvm/Support/MD5.h
+++ b/include/llvm/Support/MD5.h
@@ -28,11 +28,12 @@
#ifndef LLVM_SUPPORT_MD5_H
#define LLVM_SUPPORT_MD5_H
-#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/Endian.h"
namespace llvm {
+template <typename T> class ArrayRef;
class MD5 {
// Any 32-bit or wider unsigned integer data type will do.
@@ -65,6 +66,18 @@ private:
const uint8_t *body(ArrayRef<uint8_t> Data);
};
+/// Helper to compute and return lower 64 bits of the given string's MD5 hash.
+inline uint64_t MD5Hash(StringRef Str) {
+ MD5 Hash;
+ Hash.update(Str);
+ llvm::MD5::MD5Result Result;
+ Hash.final(Result);
+ // Return the least significant 8 bytes. Our MD5 implementation returns the
+ // result in little endian, so we may need to swap bytes.
+ using namespace llvm::support;
+ return endian::read<uint64_t, little, unaligned>(Result);
+}
+
}
#endif
diff --git a/include/llvm/Support/MachO.def b/include/llvm/Support/MachO.def
new file mode 100644
index 000000000000..9ca6440dd82b
--- /dev/null
+++ b/include/llvm/Support/MachO.def
@@ -0,0 +1,106 @@
+//,,,-- llvm/Support/MachO.def - The MachO file definitions -----*- C++ -*-,,,//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//,,,----------------------------------------------------------------------,,,//
+//
+// Definitions for MachO files
+//
+//,,,----------------------------------------------------------------------,,,//
+
+#ifdef HANDLE_LOAD_COMMAND
+
+HANDLE_LOAD_COMMAND(LC_SEGMENT, 0x00000001u, segment_command)
+HANDLE_LOAD_COMMAND(LC_SYMTAB, 0x00000002u, symtab_command)
+HANDLE_LOAD_COMMAND(LC_SYMSEG, 0x00000003u, symseg_command)
+HANDLE_LOAD_COMMAND(LC_THREAD, 0x00000004u, thread_command)
+HANDLE_LOAD_COMMAND(LC_UNIXTHREAD, 0x00000005u, thread_command)
+HANDLE_LOAD_COMMAND(LC_LOADFVMLIB, 0x00000006u, fvmlib_command)
+HANDLE_LOAD_COMMAND(LC_IDFVMLIB, 0x00000007u, fvmlib_command)
+HANDLE_LOAD_COMMAND(LC_IDENT, 0x00000008u, ident_command)
+HANDLE_LOAD_COMMAND(LC_FVMFILE, 0x00000009u, fvmfile_command)
+HANDLE_LOAD_COMMAND(LC_PREPAGE, 0x0000000Au, load_command)
+HANDLE_LOAD_COMMAND(LC_DYSYMTAB, 0x0000000Bu, dysymtab_command)
+HANDLE_LOAD_COMMAND(LC_LOAD_DYLIB, 0x0000000Cu, dylib_command)
+HANDLE_LOAD_COMMAND(LC_ID_DYLIB, 0x0000000Du, dylib_command)
+HANDLE_LOAD_COMMAND(LC_LOAD_DYLINKER, 0x0000000Eu, dylinker_command)
+HANDLE_LOAD_COMMAND(LC_ID_DYLINKER, 0x0000000Fu, dylinker_command)
+HANDLE_LOAD_COMMAND(LC_PREBOUND_DYLIB, 0x00000010u, prebound_dylib_command)
+HANDLE_LOAD_COMMAND(LC_ROUTINES, 0x00000011u, routines_command)
+HANDLE_LOAD_COMMAND(LC_SUB_FRAMEWORK, 0x00000012u, sub_framework_command)
+HANDLE_LOAD_COMMAND(LC_SUB_UMBRELLA, 0x00000013u, sub_umbrella_command)
+HANDLE_LOAD_COMMAND(LC_SUB_CLIENT, 0x00000014u, sub_client_command)
+HANDLE_LOAD_COMMAND(LC_SUB_LIBRARY, 0x00000015u, sub_library_command)
+HANDLE_LOAD_COMMAND(LC_TWOLEVEL_HINTS, 0x00000016u, twolevel_hints_command)
+HANDLE_LOAD_COMMAND(LC_PREBIND_CKSUM, 0x00000017u, prebind_cksum_command)
+HANDLE_LOAD_COMMAND(LC_LOAD_WEAK_DYLIB, 0x80000018u, dylib_command)
+HANDLE_LOAD_COMMAND(LC_SEGMENT_64, 0x00000019u, segment_command_64)
+HANDLE_LOAD_COMMAND(LC_ROUTINES_64, 0x0000001Au, routines_command_64)
+HANDLE_LOAD_COMMAND(LC_UUID, 0x0000001Bu, uuid_command)
+HANDLE_LOAD_COMMAND(LC_RPATH, 0x8000001Cu, rpath_command)
+HANDLE_LOAD_COMMAND(LC_CODE_SIGNATURE, 0x0000001Du, linkedit_data_command)
+HANDLE_LOAD_COMMAND(LC_SEGMENT_SPLIT_INFO, 0x0000001Eu, linkedit_data_command)
+HANDLE_LOAD_COMMAND(LC_REEXPORT_DYLIB, 0x8000001Fu, dylib_command)
+HANDLE_LOAD_COMMAND(LC_LAZY_LOAD_DYLIB, 0x00000020u, dylib_command)
+HANDLE_LOAD_COMMAND(LC_ENCRYPTION_INFO, 0x00000021u, encryption_info_command)
+HANDLE_LOAD_COMMAND(LC_DYLD_INFO, 0x00000022u, dyld_info_command)
+HANDLE_LOAD_COMMAND(LC_DYLD_INFO_ONLY, 0x80000022u, dyld_info_command)
+HANDLE_LOAD_COMMAND(LC_LOAD_UPWARD_DYLIB, 0x80000023u, dylib_command)
+HANDLE_LOAD_COMMAND(LC_VERSION_MIN_MACOSX, 0x00000024u, version_min_command)
+HANDLE_LOAD_COMMAND(LC_VERSION_MIN_IPHONEOS, 0x00000025u, version_min_command)
+HANDLE_LOAD_COMMAND(LC_FUNCTION_STARTS, 0x00000026u, linkedit_data_command)
+HANDLE_LOAD_COMMAND(LC_DYLD_ENVIRONMENT, 0x00000027u, dylinker_command)
+HANDLE_LOAD_COMMAND(LC_MAIN, 0x80000028u, entry_point_command)
+HANDLE_LOAD_COMMAND(LC_DATA_IN_CODE, 0x00000029u, linkedit_data_command)
+HANDLE_LOAD_COMMAND(LC_SOURCE_VERSION, 0x0000002Au, source_version_command)
+HANDLE_LOAD_COMMAND(LC_DYLIB_CODE_SIGN_DRS, 0x0000002Bu, linkedit_data_command)
+HANDLE_LOAD_COMMAND(LC_ENCRYPTION_INFO_64, 0x0000002Cu,
+ encryption_info_command_64)
+HANDLE_LOAD_COMMAND(LC_LINKER_OPTION, 0x0000002Du, linker_option_command)
+HANDLE_LOAD_COMMAND(LC_LINKER_OPTIMIZATION_HINT, 0x0000002Eu, linkedit_data_command)
+HANDLE_LOAD_COMMAND(LC_VERSION_MIN_TVOS, 0x0000002Fu, version_min_command)
+HANDLE_LOAD_COMMAND(LC_VERSION_MIN_WATCHOS, 0x00000030u, version_min_command)
+
+#endif
+
+#ifdef LOAD_COMMAND_STRUCT
+
+LOAD_COMMAND_STRUCT(dyld_info_command)
+LOAD_COMMAND_STRUCT(dylib_command)
+LOAD_COMMAND_STRUCT(dylinker_command)
+LOAD_COMMAND_STRUCT(dysymtab_command)
+LOAD_COMMAND_STRUCT(encryption_info_command)
+LOAD_COMMAND_STRUCT(encryption_info_command_64)
+LOAD_COMMAND_STRUCT(entry_point_command)
+LOAD_COMMAND_STRUCT(fvmfile_command)
+LOAD_COMMAND_STRUCT(fvmlib_command)
+LOAD_COMMAND_STRUCT(ident_command)
+LOAD_COMMAND_STRUCT(linkedit_data_command)
+LOAD_COMMAND_STRUCT(linker_option_command)
+LOAD_COMMAND_STRUCT(load_command)
+LOAD_COMMAND_STRUCT(prebind_cksum_command)
+LOAD_COMMAND_STRUCT(prebound_dylib_command)
+LOAD_COMMAND_STRUCT(routines_command)
+LOAD_COMMAND_STRUCT(routines_command_64)
+LOAD_COMMAND_STRUCT(rpath_command)
+LOAD_COMMAND_STRUCT(segment_command)
+LOAD_COMMAND_STRUCT(segment_command_64)
+LOAD_COMMAND_STRUCT(source_version_command)
+LOAD_COMMAND_STRUCT(sub_client_command)
+LOAD_COMMAND_STRUCT(sub_framework_command)
+LOAD_COMMAND_STRUCT(sub_library_command)
+LOAD_COMMAND_STRUCT(sub_umbrella_command)
+LOAD_COMMAND_STRUCT(symseg_command)
+LOAD_COMMAND_STRUCT(symtab_command)
+LOAD_COMMAND_STRUCT(thread_command)
+LOAD_COMMAND_STRUCT(twolevel_hints_command)
+LOAD_COMMAND_STRUCT(uuid_command)
+LOAD_COMMAND_STRUCT(version_min_command)
+
+#endif
+
+#undef HANDLE_LOAD_COMMAND
+#undef LOAD_COMMAND_STRUCT
diff --git a/include/llvm/Support/MachO.h b/include/llvm/Support/MachO.h
index 54b8745de1c1..9a03722d250f 100644
--- a/include/llvm/Support/MachO.h
+++ b/include/llvm/Support/MachO.h
@@ -29,7 +29,9 @@ namespace llvm {
MH_MAGIC_64 = 0xFEEDFACFu,
MH_CIGAM_64 = 0xCFFAEDFEu,
FAT_MAGIC = 0xCAFEBABEu,
- FAT_CIGAM = 0xBEBAFECAu
+ FAT_CIGAM = 0xBEBAFECAu,
+ FAT_MAGIC_64 = 0xCAFEBABFu,
+ FAT_CIGAM_64 = 0xBFBAFECAu
};
enum HeaderFileType {
@@ -84,59 +86,15 @@ namespace llvm {
LC_REQ_DYLD = 0x80000000u
};
+#define HANDLE_LOAD_COMMAND(LCName, LCValue, LCStruct) \
+ LCName = LCValue,
+
enum LoadCommandType : uint32_t {
- // Constants for the "cmd" field in llvm::MachO::load_command
- LC_SEGMENT = 0x00000001u,
- LC_SYMTAB = 0x00000002u,
- LC_SYMSEG = 0x00000003u,
- LC_THREAD = 0x00000004u,
- LC_UNIXTHREAD = 0x00000005u,
- LC_LOADFVMLIB = 0x00000006u,
- LC_IDFVMLIB = 0x00000007u,
- LC_IDENT = 0x00000008u,
- LC_FVMFILE = 0x00000009u,
- LC_PREPAGE = 0x0000000Au,
- LC_DYSYMTAB = 0x0000000Bu,
- LC_LOAD_DYLIB = 0x0000000Cu,
- LC_ID_DYLIB = 0x0000000Du,
- LC_LOAD_DYLINKER = 0x0000000Eu,
- LC_ID_DYLINKER = 0x0000000Fu,
- LC_PREBOUND_DYLIB = 0x00000010u,
- LC_ROUTINES = 0x00000011u,
- LC_SUB_FRAMEWORK = 0x00000012u,
- LC_SUB_UMBRELLA = 0x00000013u,
- LC_SUB_CLIENT = 0x00000014u,
- LC_SUB_LIBRARY = 0x00000015u,
- LC_TWOLEVEL_HINTS = 0x00000016u,
- LC_PREBIND_CKSUM = 0x00000017u,
- LC_LOAD_WEAK_DYLIB = 0x80000018u,
- LC_SEGMENT_64 = 0x00000019u,
- LC_ROUTINES_64 = 0x0000001Au,
- LC_UUID = 0x0000001Bu,
- LC_RPATH = 0x8000001Cu,
- LC_CODE_SIGNATURE = 0x0000001Du,
- LC_SEGMENT_SPLIT_INFO = 0x0000001Eu,
- LC_REEXPORT_DYLIB = 0x8000001Fu,
- LC_LAZY_LOAD_DYLIB = 0x00000020u,
- LC_ENCRYPTION_INFO = 0x00000021u,
- LC_DYLD_INFO = 0x00000022u,
- LC_DYLD_INFO_ONLY = 0x80000022u,
- LC_LOAD_UPWARD_DYLIB = 0x80000023u,
- LC_VERSION_MIN_MACOSX = 0x00000024u,
- LC_VERSION_MIN_IPHONEOS = 0x00000025u,
- LC_FUNCTION_STARTS = 0x00000026u,
- LC_DYLD_ENVIRONMENT = 0x00000027u,
- LC_MAIN = 0x80000028u,
- LC_DATA_IN_CODE = 0x00000029u,
- LC_SOURCE_VERSION = 0x0000002Au,
- LC_DYLIB_CODE_SIGN_DRS = 0x0000002Bu,
- LC_ENCRYPTION_INFO_64 = 0x0000002Cu,
- LC_LINKER_OPTION = 0x0000002Du,
- LC_LINKER_OPTIMIZATION_HINT = 0x0000002Eu,
- LC_VERSION_MIN_TVOS = 0x0000002Fu,
- LC_VERSION_MIN_WATCHOS = 0x00000030u,
+ #include "llvm/Support/MachO.def"
};
+#undef HANDLE_LOAD_COMMAND
+
enum : uint32_t {
// Constant bits for the "flags" field in llvm::MachO::segment_command
SG_HIGHVM = 0x1u,
@@ -935,6 +893,15 @@ namespace llvm {
uint32_t align;
};
+ struct fat_arch_64 {
+ uint32_t cputype;
+ uint32_t cpusubtype;
+ uint64_t offset;
+ uint64_t size;
+ uint32_t align;
+ uint32_t reserved;
+ };
+
// Structs from <mach-o/reloc.h>
struct relocation_info {
int32_t r_address;
@@ -993,6 +960,28 @@ namespace llvm {
// Byte order swapping functions for MachO structs
+ inline void swapStruct(fat_header &mh) {
+ sys::swapByteOrder(mh.magic);
+ sys::swapByteOrder(mh.nfat_arch);
+ }
+
+ inline void swapStruct(fat_arch &mh) {
+ sys::swapByteOrder(mh.cputype);
+ sys::swapByteOrder(mh.cpusubtype);
+ sys::swapByteOrder(mh.offset);
+ sys::swapByteOrder(mh.size);
+ sys::swapByteOrder(mh.align);
+ }
+
+ inline void swapStruct(fat_arch_64 &mh) {
+ sys::swapByteOrder(mh.cputype);
+ sys::swapByteOrder(mh.cpusubtype);
+ sys::swapByteOrder(mh.offset);
+ sys::swapByteOrder(mh.size);
+ sys::swapByteOrder(mh.align);
+ sys::swapByteOrder(mh.reserved);
+ }
+
inline void swapStruct(mach_header &mh) {
sys::swapByteOrder(mh.magic);
sys::swapByteOrder(mh.cputype);
@@ -1279,6 +1268,58 @@ namespace llvm {
sys::swapByteOrder(C);
}
+ inline void swapStruct(prebind_cksum_command &C) {
+ sys::swapByteOrder(C.cmd);
+ sys::swapByteOrder(C.cmdsize);
+ sys::swapByteOrder(C.cksum);
+ }
+
+ inline void swapStruct(twolevel_hints_command &C) {
+ sys::swapByteOrder(C.cmd);
+ sys::swapByteOrder(C.cmdsize);
+ sys::swapByteOrder(C.offset);
+ sys::swapByteOrder(C.nhints);
+ }
+
+ inline void swapStruct(prebound_dylib_command &C) {
+ sys::swapByteOrder(C.cmd);
+ sys::swapByteOrder(C.cmdsize);
+ sys::swapByteOrder(C.name);
+ sys::swapByteOrder(C.nmodules);
+ sys::swapByteOrder(C.linked_modules);
+ }
+
+ inline void swapStruct(fvmfile_command &C) {
+ sys::swapByteOrder(C.cmd);
+ sys::swapByteOrder(C.cmdsize);
+ sys::swapByteOrder(C.name);
+ sys::swapByteOrder(C.header_addr);
+ }
+
+ inline void swapStruct(symseg_command &C) {
+ sys::swapByteOrder(C.cmd);
+ sys::swapByteOrder(C.cmdsize);
+ sys::swapByteOrder(C.offset);
+ sys::swapByteOrder(C.size);
+ }
+
+ inline void swapStruct(ident_command &C) {
+ sys::swapByteOrder(C.cmd);
+ sys::swapByteOrder(C.cmdsize);
+ }
+
+ inline void swapStruct(fvmlib &C) {
+ sys::swapByteOrder(C.name);
+ sys::swapByteOrder(C.minor_version);
+ sys::swapByteOrder(C.header_addr);
+ }
+
+ inline void swapStruct(fvmlib_command &C) {
+ sys::swapByteOrder(C.cmd);
+ sys::swapByteOrder(C.cmdsize);
+ swapStruct(C.fvmlib);
+ }
+
// Get/Set functions from <mach-o/nlist.h>
static inline uint16_t GET_LIBRARY_ORDINAL(uint16_t n_desc) {
@@ -1669,6 +1710,13 @@ namespace llvm {
const uint32_t x86_EXCEPTION_STATE_COUNT =
sizeof(x86_exception_state_t) / sizeof(uint32_t);
+ // Define a union of all load command structs
+ #define LOAD_COMMAND_STRUCT(LCStruct) LCStruct LCStruct##_data;
+
+ union macho_load_command {
+ #include "llvm/Support/MachO.def"
+ };
+
} // end namespace MachO
} // end namespace llvm
diff --git a/include/llvm/Support/ManagedStatic.h b/include/llvm/Support/ManagedStatic.h
index 2e131e47177d..ec8154b828e5 100644
--- a/include/llvm/Support/ManagedStatic.h
+++ b/include/llvm/Support/ManagedStatic.h
@@ -14,25 +14,26 @@
#ifndef LLVM_SUPPORT_MANAGEDSTATIC_H
#define LLVM_SUPPORT_MANAGEDSTATIC_H
-#include "llvm/Support/Atomic.h"
#include "llvm/Support/Compiler.h"
-#include "llvm/Support/Threading.h"
+#include <atomic>
+#include <cstddef>
namespace llvm {
/// object_creator - Helper method for ManagedStatic.
template<class C>
-void* object_creator() {
+LLVM_LIBRARY_VISIBILITY void* object_creator() {
return new C();
}
/// object_deleter - Helper method for ManagedStatic.
///
-template<typename T> struct object_deleter {
- static void call(void * Ptr) { delete (T*)Ptr; }
+template <typename T> struct LLVM_LIBRARY_VISIBILITY object_deleter {
+ static void call(void *Ptr) { delete (T *)Ptr; }
};
-template<typename T, size_t N> struct object_deleter<T[N]> {
- static void call(void * Ptr) { delete[] (T*)Ptr; }
+template <typename T, size_t N>
+struct LLVM_LIBRARY_VISIBILITY object_deleter<T[N]> {
+ static void call(void *Ptr) { delete[](T *)Ptr; }
};
/// ManagedStaticBase - Common base class for ManagedStatic instances.
@@ -40,7 +41,7 @@ class ManagedStaticBase {
protected:
// This should only be used as a static variable, which guarantees that this
// will be zero initialized.
- mutable void *Ptr;
+ mutable std::atomic<void *> Ptr;
mutable void (*DeleterFn)(void*);
mutable const ManagedStaticBase *Next;
@@ -60,40 +61,26 @@ public:
template<class C>
class ManagedStatic : public ManagedStaticBase {
public:
-
// Accessors.
C &operator*() {
- void* tmp = Ptr;
- if (llvm_is_multithreaded()) sys::MemoryFence();
- if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
- TsanHappensAfter(this);
+ void *Tmp = Ptr.load(std::memory_order_acquire);
+ if (!Tmp)
+ RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
- return *static_cast<C*>(Ptr);
+ return *static_cast<C *>(Ptr.load(std::memory_order_relaxed));
}
- C *operator->() {
- void* tmp = Ptr;
- if (llvm_is_multithreaded()) sys::MemoryFence();
- if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
- TsanHappensAfter(this);
- return static_cast<C*>(Ptr);
- }
+ C *operator->() { return &**this; }
+
const C &operator*() const {
- void* tmp = Ptr;
- if (llvm_is_multithreaded()) sys::MemoryFence();
- if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
- TsanHappensAfter(this);
+ void *Tmp = Ptr.load(std::memory_order_acquire);
+ if (!Tmp)
+ RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
- return *static_cast<C*>(Ptr);
+ return *static_cast<C *>(Ptr.load(std::memory_order_relaxed));
}
- const C *operator->() const {
- void* tmp = Ptr;
- if (llvm_is_multithreaded()) sys::MemoryFence();
- if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
- TsanHappensAfter(this);
- return static_cast<C*>(Ptr);
- }
+ const C *operator->() const { return &**this; }
};
/// llvm_shutdown - Deallocate and destroy all ManagedStatic variables.
diff --git a/include/llvm/Support/MathExtras.h b/include/llvm/Support/MathExtras.h
index 408ae3c339a2..5c816ac9df92 100644
--- a/include/llvm/Support/MathExtras.h
+++ b/include/llvm/Support/MathExtras.h
@@ -16,9 +16,11 @@
#include "llvm/Support/Compiler.h"
#include "llvm/Support/SwapByteOrder.h"
+#include <algorithm>
#include <cassert>
#include <cstring>
#include <type_traits>
+#include <limits>
#ifdef _MSC_VER
#include <intrin.h>
@@ -281,14 +283,19 @@ inline bool isInt<32>(int64_t x) {
/// left by S.
template<unsigned N, unsigned S>
inline bool isShiftedInt(int64_t x) {
- return isInt<N+S>(x) && (x % (1<<S) == 0);
+ static_assert(
+ N > 0, "isShiftedInt<0> doesn't make sense (refers to a 0-bit number.");
+ static_assert(N + S <= 64, "isShiftedInt<N, S> with N + S > 64 is too wide.");
+ return isInt<N + S>(x) && (x % (UINT64_C(1) << S) == 0);
}
/// isUInt - Checks if an unsigned integer fits into the given bit width.
template<unsigned N>
inline bool isUInt(uint64_t x) {
+ static_assert(N > 0, "isUInt<0> doesn't make sense.");
return N >= 64 || x < (UINT64_C(1)<<(N));
}
+
// Template specializations to get better code for common cases.
template<>
inline bool isUInt<8>(uint64_t x) {
@@ -303,23 +310,55 @@ inline bool isUInt<32>(uint64_t x) {
return static_cast<uint32_t>(x) == x;
}
-/// isShiftedUInt<N,S> - Checks if a unsigned integer is an N bit number shifted
-/// left by S.
+/// Checks if a unsigned integer is an N bit number shifted left by S.
template<unsigned N, unsigned S>
inline bool isShiftedUInt(uint64_t x) {
- return isUInt<N+S>(x) && (x % (1<<S) == 0);
+ static_assert(
+ N > 0, "isShiftedUInt<0> doesn't make sense (refers to a 0-bit number)");
+ static_assert(N + S <= 64,
+ "isShiftedUInt<N, S> with N + S > 64 is too wide.");
+ // Per the two static_asserts above, S must be strictly less than 64. So
+ // 1 << S is not undefined behavior.
+ return isUInt<N + S>(x) && (x % (UINT64_C(1) << S) == 0);
+}
+
+/// Gets the maximum value for a N-bit unsigned integer.
+inline uint64_t maxUIntN(uint64_t N) {
+ assert(N > 0 && N <= 64 && "integer width out of range");
+
+ // uint64_t(1) << 64 is undefined behavior, so we can't do
+ // (uint64_t(1) << N) - 1
+ // without checking first that N != 64. But this works and doesn't have a
+ // branch.
+ return UINT64_MAX >> (64 - N);
+}
+
+/// Gets the minimum value for a N-bit signed integer.
+inline int64_t minIntN(int64_t N) {
+ assert(N > 0 && N <= 64 && "integer width out of range");
+
+ return -(UINT64_C(1)<<(N-1));
+}
+
+/// Gets the maximum value for a N-bit signed integer.
+inline int64_t maxIntN(int64_t N) {
+ assert(N > 0 && N <= 64 && "integer width out of range");
+
+ // This relies on two's complement wraparound when N == 64, so we convert to
+ // int64_t only at the very end to avoid UB.
+ return (UINT64_C(1) << (N - 1)) - 1;
}
/// isUIntN - Checks if an unsigned integer fits into the given (dynamic)
/// bit width.
inline bool isUIntN(unsigned N, uint64_t x) {
- return N >= 64 || x < (UINT64_C(1)<<(N));
+ return N >= 64 || x <= maxUIntN(N);
}
/// isIntN - Checks if an signed integer fits into the given (dynamic)
/// bit width.
inline bool isIntN(unsigned N, int64_t x) {
- return N >= 64 || (-(INT64_C(1)<<(N-1)) <= x && x < (INT64_C(1)<<(N-1)));
+ return N >= 64 || (minIntN(N) <= x && x <= maxIntN(N));
}
/// isMask_32 - This function returns true if the argument is a non-empty
@@ -606,57 +645,78 @@ inline uint64_t PowerOf2Floor(uint64_t A) {
///
/// Examples:
/// \code
-/// RoundUpToAlignment(5, 8) = 8
-/// RoundUpToAlignment(17, 8) = 24
-/// RoundUpToAlignment(~0LL, 8) = 0
-/// RoundUpToAlignment(321, 255) = 510
+/// alignTo(5, 8) = 8
+/// alignTo(17, 8) = 24
+/// alignTo(~0LL, 8) = 0
+/// alignTo(321, 255) = 510
///
-/// RoundUpToAlignment(5, 8, 7) = 7
-/// RoundUpToAlignment(17, 8, 1) = 17
-/// RoundUpToAlignment(~0LL, 8, 3) = 3
-/// RoundUpToAlignment(321, 255, 42) = 552
+/// alignTo(5, 8, 7) = 7
+/// alignTo(17, 8, 1) = 17
+/// alignTo(~0LL, 8, 3) = 3
+/// alignTo(321, 255, 42) = 552
/// \endcode
-inline uint64_t RoundUpToAlignment(uint64_t Value, uint64_t Align,
- uint64_t Skew = 0) {
+inline uint64_t alignTo(uint64_t Value, uint64_t Align, uint64_t Skew = 0) {
Skew %= Align;
return (Value + Align - 1 - Skew) / Align * Align + Skew;
}
+/// Returns the largest uint64_t less than or equal to \p Value and is
+/// \p Skew mod \p Align. \p Align must be non-zero
+inline uint64_t alignDown(uint64_t Value, uint64_t Align, uint64_t Skew = 0) {
+ Skew %= Align;
+ return (Value - Skew) / Align * Align + Skew;
+}
+
/// Returns the offset to the next integer (mod 2**64) that is greater than
/// or equal to \p Value and is a multiple of \p Align. \p Align must be
/// non-zero.
inline uint64_t OffsetToAlignment(uint64_t Value, uint64_t Align) {
- return RoundUpToAlignment(Value, Align) - Value;
+ return alignTo(Value, Align) - Value;
}
-/// SignExtend32 - Sign extend B-bit number x to 32-bit int.
-/// Usage int32_t r = SignExtend32<5>(x);
-template <unsigned B> inline int32_t SignExtend32(uint32_t x) {
- return int32_t(x << (32 - B)) >> (32 - B);
+/// Sign-extend the number in the bottom B bits of X to a 32-bit integer.
+/// Requires 0 < B <= 32.
+template <unsigned B> inline int32_t SignExtend32(uint32_t X) {
+ static_assert(B > 0, "Bit width can't be 0.");
+ static_assert(B <= 32, "Bit width out of range.");
+ return int32_t(X << (32 - B)) >> (32 - B);
}
-/// \brief Sign extend number in the bottom B bits of X to a 32-bit int.
-/// Requires 0 < B <= 32.
+/// Sign-extend the number in the bottom B bits of X to a 32-bit integer.
+/// Requires 0 < B < 32.
inline int32_t SignExtend32(uint32_t X, unsigned B) {
+ assert(B > 0 && "Bit width can't be 0.");
+ assert(B <= 32 && "Bit width out of range.");
return int32_t(X << (32 - B)) >> (32 - B);
}
-/// SignExtend64 - Sign extend B-bit number x to 64-bit int.
-/// Usage int64_t r = SignExtend64<5>(x);
+/// Sign-extend the number in the bottom B bits of X to a 64-bit integer.
+/// Requires 0 < B < 64.
template <unsigned B> inline int64_t SignExtend64(uint64_t x) {
+ static_assert(B > 0, "Bit width can't be 0.");
+ static_assert(B <= 64, "Bit width out of range.");
return int64_t(x << (64 - B)) >> (64 - B);
}
-/// \brief Sign extend number in the bottom B bits of X to a 64-bit int.
-/// Requires 0 < B <= 64.
+/// Sign-extend the number in the bottom B bits of X to a 64-bit integer.
+/// Requires 0 < B < 64.
inline int64_t SignExtend64(uint64_t X, unsigned B) {
+ assert(B > 0 && "Bit width can't be 0.");
+ assert(B <= 64 && "Bit width out of range.");
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.
+/// Subtract two unsigned integers, X and Y, of type T and return the absolute
+/// value of the result.
+template <typename T>
+typename std::enable_if<std::is_unsigned<T>::value, T>::type
+AbsoluteDifference(T X, T Y) {
+ return std::max(X, Y) - std::min(X, Y);
+}
+
+/// 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) {
@@ -671,10 +731,9 @@ SaturatingAdd(T X, T Y, bool *ResultOverflowed = nullptr) {
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.
+/// 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) {
@@ -717,12 +776,10 @@ SaturatingMultiply(T X, T Y, bool *ResultOverflowed = nullptr) {
return Z;
}
-/// \brief Multiply two unsigned integers, X and Y, and add the unsigned
-/// integer, A to the product. Clamp the result to the maximum representable
-/// value of T on overflow. ResultOverflowed indicates if the result is larger
-/// than the maximum representable value of type T.
-/// Note that this is purely a convenience function as there is no distinction
-/// where overflow occurred in a 'fused' multiply-add for unsigned numbers.
+/// Multiply two unsigned integers, X and Y, and add the unsigned integer, A to
+/// the product. Clamp the result to the maximum representable value of T on
+/// overflow. ResultOverflowed indicates if the result is larger than the
+/// maximum representable value of type T.
template <typename T>
typename std::enable_if<std::is_unsigned<T>::value, T>::type
SaturatingMultiplyAdd(T X, T Y, T A, bool *ResultOverflowed = nullptr) {
@@ -736,6 +793,7 @@ SaturatingMultiplyAdd(T X, T Y, T A, bool *ResultOverflowed = nullptr) {
return SaturatingAdd(A, Product, &Overflowed);
}
+/// Use this rather than HUGE_VALF; the latter causes warnings on MSVC.
extern const float huge_valf;
} // End llvm namespace
diff --git a/include/llvm/Support/OnDiskHashTable.h b/include/llvm/Support/OnDiskHashTable.h
index ac978d4c242c..c28fcabe78fc 100644
--- a/include/llvm/Support/OnDiskHashTable.h
+++ b/include/llvm/Support/OnDiskHashTable.h
@@ -152,6 +152,22 @@ public:
using namespace llvm::support;
endian::Writer<little> LE(Out);
+ // Now we're done adding entries, resize the bucket list if it's
+ // significantly too large. (This only happens if the number of
+ // entries is small and we're within our initial allocation of
+ // 64 buckets.) We aim for an occupancy ratio in [3/8, 3/4).
+ //
+ // As a special case, if there are two or fewer entries, just
+ // form a single bucket. A linear scan is fine in that case, and
+ // this is very common in C++ class lookup tables. This also
+ // guarantees we produce at least one bucket for an empty table.
+ //
+ // FIXME: Try computing a perfect hash function at this point.
+ unsigned TargetNumBuckets =
+ NumEntries <= 2 ? 1 : NextPowerOf2(NumEntries * 4 / 3);
+ if (TargetNumBuckets != NumBuckets)
+ resize(TargetNumBuckets);
+
// Emit the payload of the table.
for (offset_type I = 0; I < NumBuckets; ++I) {
Bucket &B = Buckets[I];
@@ -309,7 +325,7 @@ public:
Info *InfoObj;
public:
- iterator() : Data(nullptr), Len(0) {}
+ iterator() : Key(), Data(nullptr), Len(0), InfoObj(nullptr) {}
iterator(const internal_key_type K, const unsigned char *D, offset_type L,
Info *InfoObj)
: Key(K), Data(D), Len(L), InfoObj(InfoObj) {}
diff --git a/include/llvm/Support/Path.h b/include/llvm/Support/Path.h
index 955cc991d9b7..853f0997571c 100644
--- a/include/llvm/Support/Path.h
+++ b/include/llvm/Support/Path.h
@@ -16,7 +16,6 @@
#ifndef LLVM_SUPPORT_PATH_H
#define LLVM_SUPPORT_PATH_H
-#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/DataTypes.h"
#include <iterator>
@@ -88,6 +87,9 @@ public:
reverse_iterator &operator++(); // preincrement
bool operator==(const reverse_iterator &RHS) const;
bool operator!=(const reverse_iterator &RHS) const { return !(*this == RHS); }
+
+ /// @brief Difference in bytes between this and RHS.
+ ptrdiff_t operator-(const reverse_iterator &RHS) const;
};
/// @brief Get begin iterator over \a path.
@@ -140,6 +142,23 @@ void remove_filename(SmallVectorImpl<char> &path);
/// prepended.
void replace_extension(SmallVectorImpl<char> &path, const Twine &extension);
+/// @brief Replace matching path prefix with another path.
+///
+/// @code
+/// /foo, /old, /new => /foo
+/// /old/foo, /old, /new => /new/foo
+/// /foo, <empty>, /new => /new/foo
+/// /old/foo, /old, <empty> => /foo
+/// @endcode
+///
+/// @param Path If \a Path starts with \a OldPrefix modify to instead
+/// start with \a NewPrefix.
+/// @param OldPrefix The path prefix to strip from \a Path.
+/// @param NewPrefix The path prefix to replace \a NewPrefix with.
+void replace_path_prefix(SmallVectorImpl<char> &Path,
+ const StringRef &OldPrefix,
+ const StringRef &NewPrefix);
+
/// @brief Append to path.
///
/// @code
diff --git a/include/llvm/Support/PointerLikeTypeTraits.h b/include/llvm/Support/PointerLikeTypeTraits.h
index c12d237b2796..96cdaed142c2 100644
--- a/include/llvm/Support/PointerLikeTypeTraits.h
+++ b/include/llvm/Support/PointerLikeTypeTraits.h
@@ -37,7 +37,8 @@ template <> struct ConstantLog2<1> : std::integral_constant<size_t, 0> {};
}
// Provide PointerLikeTypeTraits for non-cvr pointers.
-template <typename T> struct PointerLikeTypeTraits<T *> {
+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); }
@@ -46,7 +47,8 @@ template <typename T> struct PointerLikeTypeTraits<T *> {
};
};
-template <> struct PointerLikeTypeTraits<void *> {
+template <> class PointerLikeTypeTraits<void *> {
+public:
static inline void *getAsVoidPointer(void *P) { return P; }
static inline void *getFromVoidPointer(void *P) { return P; }
diff --git a/include/llvm/Support/PrettyStackTrace.h b/include/llvm/Support/PrettyStackTrace.h
index 027f9433969d..62e3bbc0ddbc 100644
--- a/include/llvm/Support/PrettyStackTrace.h
+++ b/include/llvm/Support/PrettyStackTrace.h
@@ -29,9 +29,11 @@ namespace llvm {
/// constructed and destructed, they will add their symbolic frames to a
/// virtual stack trace. This gets dumped out if the program crashes.
class PrettyStackTraceEntry {
- const PrettyStackTraceEntry *NextEntry;
+ friend PrettyStackTraceEntry *ReverseStackTrace(PrettyStackTraceEntry *);
+
+ PrettyStackTraceEntry *NextEntry;
PrettyStackTraceEntry(const PrettyStackTraceEntry &) = delete;
- void operator=(const PrettyStackTraceEntry&) = delete;
+ void operator=(const PrettyStackTraceEntry &) = delete;
public:
PrettyStackTraceEntry();
virtual ~PrettyStackTraceEntry();
@@ -67,7 +69,7 @@ namespace llvm {
};
/// Returns the topmost element of the "pretty" stack state.
- const void* SavePrettyStackState();
+ 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
@@ -76,7 +78,7 @@ namespace llvm {
/// 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);
+ void RestorePrettyStackState(const void *State);
} // end namespace llvm
diff --git a/include/llvm/Support/Printable.h b/include/llvm/Support/Printable.h
index 5c1b8d5070d4..83b8f0998ae6 100644
--- a/include/llvm/Support/Printable.h
+++ b/include/llvm/Support/Printable.h
@@ -38,8 +38,8 @@ class raw_ostream;
class Printable {
public:
std::function<void(raw_ostream &OS)> Print;
- Printable(const std::function<void(raw_ostream &OS)> Print)
- : Print(Print) {}
+ Printable(std::function<void(raw_ostream &OS)> Print)
+ : Print(std::move(Print)) {}
};
static inline raw_ostream &operator<<(raw_ostream &OS, const Printable &P) {
diff --git a/include/llvm/Support/Process.h b/include/llvm/Support/Process.h
index cfdd06c62f33..06fd0af10aa4 100644
--- a/include/llvm/Support/Process.h
+++ b/include/llvm/Support/Process.h
@@ -25,7 +25,6 @@
#ifndef LLVM_SUPPORT_PROCESS_H
#define LLVM_SUPPORT_PROCESS_H
-#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/Optional.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/Support/Allocator.h"
@@ -34,6 +33,7 @@
#include <system_error>
namespace llvm {
+template <typename T> class ArrayRef;
class StringRef;
namespace sys {
@@ -69,6 +69,9 @@ public:
/// @brief Prevent core file generation.
static void PreventCoreFiles();
+ /// \brief true if PreventCoreFiles has been called, false otherwise.
+ static bool AreCoreFilesPrevented();
+
// This function returns the environment variable \arg name's value as a UTF-8
// string. \arg Name is assumed to be in UTF-8 encoding too.
static Optional<std::string> GetEnv(StringRef name);
diff --git a/include/llvm/Support/Program.h b/include/llvm/Support/Program.h
index 727864df2721..055f016d8243 100644
--- a/include/llvm/Support/Program.h
+++ b/include/llvm/Support/Program.h
@@ -44,6 +44,8 @@ struct ProcessInfo {
#error "ProcessInfo is not defined for this platform!"
#endif
+ enum : ProcessId { InvalidPid = 0 };
+
/// The process identifier.
ProcessId Pid;
@@ -88,7 +90,7 @@ struct ProcessInfo {
/// -2 indicates a crash during execution or timeout
int ExecuteAndWait(
StringRef Program, ///< Path of the program to be executed. It is
- /// presumed this is the result of the findProgramByName method.
+ ///< presumed this is the result of the findProgramByName method.
const char **args, ///< A vector of strings that are passed to the
///< program. The first element should be the name of the program.
///< The list *must* be terminated by a null char* entry.
diff --git a/include/llvm/Support/RandomNumberGenerator.h b/include/llvm/Support/RandomNumberGenerator.h
index 7446558f0c88..f146e350fe62 100644
--- a/include/llvm/Support/RandomNumberGenerator.h
+++ b/include/llvm/Support/RandomNumberGenerator.h
@@ -16,12 +16,12 @@
#ifndef LLVM_SUPPORT_RANDOMNUMBERGENERATOR_H_
#define LLVM_SUPPORT_RANDOMNUMBERGENERATOR_H_
-#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataTypes.h" // Needed for uint64_t on Windows.
#include <random>
namespace llvm {
+class StringRef;
/// A random number generator.
///
diff --git a/include/llvm/Support/Registry.h b/include/llvm/Support/Registry.h
index bbea97b289a6..27f025fcd080 100644
--- a/include/llvm/Support/Registry.h
+++ b/include/llvm/Support/Registry.h
@@ -14,9 +14,10 @@
#ifndef LLVM_SUPPORT_REGISTRY_H
#define LLVM_SUPPORT_REGISTRY_H
-#include "llvm/ADT/iterator_range.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/Support/DynamicLibrary.h"
#include <memory>
namespace llvm {
@@ -37,69 +38,45 @@ 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>
- class RegistryTraits {
- RegistryTraits() = delete;
-
- public:
- typedef SimpleRegistryEntry<T> entry;
-
- /// nameof/descof - Accessors for name and description of entries. These are
- // used to generate help for command-line options.
- static const char *nameof(const entry &Entry) { return Entry.getName(); }
- static const char *descof(const entry &Entry) { return Entry.getDesc(); }
- };
-
/// A global registry used in conjunction with static constructors to make
/// pluggable components (like targets or garbage collectors) "just work" when
/// linked with an executable.
- template <typename T, typename U = RegistryTraits<T> >
+ template <typename T>
class Registry {
public:
- typedef U traits;
- typedef typename U::entry entry;
+ typedef SimpleRegistryEntry<T> entry;
class node;
- class listener;
class iterator;
private:
Registry() = delete;
- static void Announce(const entry &E) {
- for (listener *Cur = ListenerHead; Cur; Cur = Cur->Next)
- Cur->registered(E);
- }
-
friend class node;
static node *Head, *Tail;
- friend class listener;
- static listener *ListenerHead, *ListenerTail;
-
public:
/// Node in linked list of entries.
///
class node {
friend class iterator;
+ friend Registry<T>;
node *Next;
const entry& Val;
public:
- node(const entry& V) : Next(nullptr), Val(V) {
- if (Tail)
- Tail->Next = this;
- else
- Head = this;
- Tail = this;
-
- Announce(V);
- }
+ node(const entry &V) : Next(nullptr), Val(V) {}
};
+ static void add_node(node *N) {
+ if (Tail)
+ Tail->Next = N;
+ else
+ Head = N;
+ Tail = N;
+ }
+
/// Iterators for registry entries.
///
class iterator {
@@ -122,60 +99,6 @@ namespace llvm {
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:
- ///
- /// \code
- /// class CollectorPrinter : public Registry<Collector>::listener {
- /// protected:
- /// void registered(const Registry<Collector>::entry &e) {
- /// cerr << "collector now available: " << e->getName() << "\n";
- /// }
- ///
- /// public:
- /// CollectorPrinter() { init(); } // Print those already registered.
- /// };
- ///
- /// CollectorPrinter Printer;
- /// \endcode
- class listener {
- listener *Prev, *Next;
-
- friend void Registry::Announce(const entry &E);
-
- protected:
- /// Called when an entry is added to the registry.
- ///
- virtual void registered(const entry &) = 0;
-
- /// Calls 'registered' for each pre-existing entry.
- ///
- void init() {
- for (iterator I = begin(), E = end(); I != E; ++I)
- registered(*I);
- }
-
- public:
- listener() : Prev(ListenerTail), Next(nullptr) {
- if (Prev)
- Prev->Next = this;
- else
- ListenerHead = this;
- ListenerTail = this;
- }
-
- virtual ~listener() {
- if (Next)
- Next->Prev = Prev;
- else
- ListenerTail = Prev;
- if (Prev)
- Prev->Next = Next;
- else
- ListenerHead = Next;
- }
- };
-
/// A static registration template. Use like such:
///
/// Registry<Collector>::Add<FancyGC>
@@ -184,14 +107,6 @@ namespace llvm {
/// Use of this template requires that:
///
/// 1. The registered subclass has a default constructor.
- //
- /// 2. The registry entry type has a constructor compatible with this
- /// signature:
- ///
- /// entry(const char *Name, const char *ShortDesc, T *(*Ctor)());
- ///
- /// If you have more elaborate requirements, then copy and modify.
- ///
template <typename V>
class Add {
entry Entry;
@@ -201,27 +116,65 @@ namespace llvm {
public:
Add(const char *Name, const char *Desc)
- : Entry(Name, Desc, CtorFn), Node(Entry) {}
+ : Entry(Name, Desc, CtorFn), Node(Entry) {
+ add_node(&Node);
+ }
};
- /// Registry::Parser now lives in llvm/Support/RegistryParser.h.
+ /// A dynamic import facility. This is used on Windows to
+ /// import the entries added in the plugin.
+ static void import(sys::DynamicLibrary &DL, const char *RegistryName) {
+ typedef void *(*GetRegistry)();
+ std::string Name("LLVMGetRegistry_");
+ Name.append(RegistryName);
+ GetRegistry Getter =
+ (GetRegistry)(intptr_t)DL.getAddressOfSymbol(Name.c_str());
+ if (Getter) {
+ // Call the getter function in order to get the full copy of the
+ // registry defined in the plugin DLL, and copy them over to the
+ // current Registry.
+ typedef std::pair<const node *, const node *> Info;
+ Info *I = static_cast<Info *>(Getter());
+ iterator begin(I->first);
+ iterator end(I->second);
+ for (++end; begin != end; ++begin) {
+ // This Node object needs to remain alive for the
+ // duration of the program.
+ add_node(new node(*begin));
+ }
+ }
+ }
+
+ /// Retrieve the data to be passed across DLL boundaries when
+ /// importing registries from another DLL on Windows.
+ static void *exportRegistry() {
+ static std::pair<const node *, const node *> Info(Head, Tail);
+ return &Info;
+ }
};
+
// Since these are defined in a header file, plugins must be sure to export
// these symbols.
+ template <typename T>
+ typename Registry<T>::node *Registry<T>::Head;
- template <typename T, typename U>
- typename Registry<T,U>::node *Registry<T,U>::Head;
-
- template <typename T, typename U>
- typename Registry<T,U>::node *Registry<T,U>::Tail;
-
- template <typename T, typename U>
- typename Registry<T,U>::listener *Registry<T,U>::ListenerHead;
-
- template <typename T, typename U>
- typename Registry<T,U>::listener *Registry<T,U>::ListenerTail;
-
+ template <typename T>
+ typename Registry<T>::node *Registry<T>::Tail;
} // end namespace llvm
+#ifdef LLVM_ON_WIN32
+#define LLVM_EXPORT_REGISTRY(REGISTRY_CLASS) \
+ extern "C" { \
+ __declspec(dllexport) void *__cdecl LLVMGetRegistry_##REGISTRY_CLASS() { \
+ return REGISTRY_CLASS::exportRegistry(); \
+ } \
+ }
+#define LLVM_IMPORT_REGISTRY(REGISTRY_CLASS, DL) \
+ REGISTRY_CLASS::import(DL, #REGISTRY_CLASS)
+#else
+#define LLVM_EXPORT_REGISTRY(REGISTRY_CLASS)
+#define LLVM_IMPORT_REGISTRY(REGISTRY_CLASS, DL)
+#endif
+
#endif // LLVM_SUPPORT_REGISTRY_H
diff --git a/include/llvm/Support/RegistryParser.h b/include/llvm/Support/RegistryParser.h
deleted file mode 100644
index a6997b6fe774..000000000000
--- a/include/llvm/Support/RegistryParser.h
+++ /dev/null
@@ -1,55 +0,0 @@
-//=== RegistryParser.h - Linker-supported plugin registries -----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Defines a command-line parser for a registry.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SUPPORT_REGISTRYPARSER_H
-#define LLVM_SUPPORT_REGISTRYPARSER_H
-
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Registry.h"
-
-namespace llvm {
-
- /// A command-line parser for a registry. Use like such:
- ///
- /// static cl::opt<Registry<Collector>::entry, false,
- /// RegistryParser<Collector> >
- /// GCOpt("gc", cl::desc("Garbage collector to use."),
- /// cl::value_desc());
- ///
- /// To make use of the value:
- ///
- /// Collector *TheCollector = GCOpt->instantiate();
- ///
- template <typename T, typename U = RegistryTraits<T> >
- class RegistryParser :
- public cl::parser<const typename U::entry*>,
- public Registry<T, U>::listener {
- typedef U traits;
- typedef typename U::entry entry;
- typedef typename Registry<T, U>::listener listener;
-
- protected:
- void registered(const entry &E) {
- addLiteralOption(traits::nameof(E), &E, traits::descof(E));
- }
-
- public:
- void initialize(cl::Option &O) {
- listener::init();
- cl::parser<const typename U::entry*>::initialize(O);
- }
- };
-
-}
-
-#endif // LLVM_SUPPORT_REGISTRYPARSER_H
diff --git a/include/llvm/Support/SHA1.h b/include/llvm/Support/SHA1.h
new file mode 100644
index 000000000000..8347a713f272
--- /dev/null
+++ b/include/llvm/Support/SHA1.h
@@ -0,0 +1,82 @@
+//==- SHA1.h - SHA1 implementation for LLVM --*- C++ -*-==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// This code is taken from public domain
+// (http://oauth.googlecode.com/svn/code/c/liboauth/src/sha1.c)
+// and modified by wrapping it in a C++ interface for LLVM,
+// and removing unnecessary code.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_SHA1_H
+#define LLVM_SUPPORT_SHA1_H
+
+#include "llvm/ADT/ArrayRef.h"
+
+#include <cstdint>
+
+namespace llvm {
+template <typename T> class ArrayRef;
+class StringRef;
+
+/// A class that wrap the SHA1 algorithm.
+class SHA1 {
+public:
+ SHA1() { init(); }
+
+ /// Reinitialize the internal state
+ void init();
+
+ /// Digest more data.
+ void update(ArrayRef<uint8_t> Data);
+
+ /// Digest more data.
+ void update(StringRef Str) {
+ update(ArrayRef<uint8_t>((uint8_t *)const_cast<char *>(Str.data()),
+ Str.size()));
+ }
+
+ /// Return a reference to the current raw 160-bits SHA1 for the digested data
+ /// since the last call to init(). This call will add data to the internal
+ /// state and as such is not suited for getting an intermediate result
+ /// (see result()).
+ StringRef final();
+
+ /// Return a reference to the current raw 160-bits SHA1 for the digested data
+ /// since the last call to init(). This is suitable for getting the SHA1 at
+ /// any time without invalidating the internal state so that more calls can be
+ /// made into update.
+ StringRef result();
+
+private:
+ /// Define some constants.
+ /// "static constexpr" would be cleaner but MSVC does not support it yet.
+ enum { BLOCK_LENGTH = 64 };
+ enum { HASH_LENGTH = 20 };
+
+ // Internal State
+ struct {
+ uint32_t Buffer[BLOCK_LENGTH / 4];
+ uint32_t State[HASH_LENGTH / 4];
+ uint32_t ByteCount;
+ uint8_t BufferOffset;
+ } InternalState;
+
+ // Internal copy of the hash, populated and accessed on calls to result()
+ uint32_t HashResult[HASH_LENGTH / 4];
+
+ // Helper
+ void writebyte(uint8_t data);
+ void hashBlock();
+ void addUncounted(uint8_t data);
+ void pad();
+};
+
+} // end llvm namespace
+
+#endif
diff --git a/include/llvm/Support/ScaledNumber.h b/include/llvm/Support/ScaledNumber.h
index c6421efc8b49..910174732994 100644
--- a/include/llvm/Support/ScaledNumber.h
+++ b/include/llvm/Support/ScaledNumber.h
@@ -859,7 +859,6 @@ template <class DigitsT> void ScaledNumber<DigitsT>::shiftLeft(int32_t Shift) {
}
Digits <<= Shift;
- return;
}
template <class DigitsT> void ScaledNumber<DigitsT>::shiftRight(int32_t Shift) {
@@ -886,7 +885,6 @@ template <class DigitsT> void ScaledNumber<DigitsT>::shiftRight(int32_t Shift) {
}
Digits >>= Shift;
- return;
}
template <typename T> struct isPodLike;
@@ -896,4 +894,4 @@ template <typename T> struct isPodLike<ScaledNumber<T>> {
} // end namespace llvm
-#endif
+#endif // LLVM_SUPPORT_SCALEDNUMBER_H
diff --git a/include/llvm/Support/ScopedPrinter.h b/include/llvm/Support/ScopedPrinter.h
new file mode 100644
index 000000000000..a2f2e0985431
--- /dev/null
+++ b/include/llvm/Support/ScopedPrinter.h
@@ -0,0 +1,378 @@
+//===-- ScopedPrinter.h ---------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_SCOPEDPRINTER_H
+#define LLVM_SUPPORT_SCOPEDPRINTER_H
+
+#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+
+namespace llvm {
+
+template <typename T> struct EnumEntry {
+ StringRef Name;
+ // While Name suffices in most of the cases, in certain cases
+ // GNU style and LLVM style of ELFDumper do not
+ // display same string for same enum. The AltName if initialized appropriately
+ // will hold the string that GNU style emits.
+ // Example:
+ // "EM_X86_64" string on LLVM style for Elf_Ehdr->e_machine corresponds to
+ // "Advanced Micro Devices X86-64" on GNU style
+ StringRef AltName;
+ T Value;
+ EnumEntry(StringRef N, StringRef A, T V) : Name(N), AltName(A), Value(V) {}
+ EnumEntry(StringRef N, T V) : Name(N), AltName(N), Value(V) {}
+};
+
+struct HexNumber {
+ // To avoid sign-extension we have to explicitly cast to the appropriate
+ // unsigned type. The overloads are here so that every type that is implicitly
+ // convertible to an integer (including enums and endian helpers) can be used
+ // without requiring type traits or call-site changes.
+ HexNumber(char Value) : Value(static_cast<unsigned char>(Value)) {}
+ HexNumber(signed char Value) : Value(static_cast<unsigned char>(Value)) {}
+ HexNumber(signed short Value) : Value(static_cast<unsigned short>(Value)) {}
+ HexNumber(signed int Value) : Value(static_cast<unsigned int>(Value)) {}
+ HexNumber(signed long Value) : Value(static_cast<unsigned long>(Value)) {}
+ HexNumber(signed long long Value)
+ : Value(static_cast<unsigned long long>(Value)) {}
+ HexNumber(unsigned char Value) : Value(Value) {}
+ HexNumber(unsigned short Value) : Value(Value) {}
+ HexNumber(unsigned int Value) : Value(Value) {}
+ HexNumber(unsigned long Value) : Value(Value) {}
+ HexNumber(unsigned long long Value) : Value(Value) {}
+ uint64_t Value;
+};
+
+raw_ostream &operator<<(raw_ostream &OS, const HexNumber &Value);
+const std::string to_hexString(uint64_t Value, bool UpperCase = true);
+
+template <class T> const std::string to_string(const T &Value) {
+ std::string number;
+ llvm::raw_string_ostream stream(number);
+ stream << Value;
+ return stream.str();
+}
+
+class ScopedPrinter {
+public:
+ ScopedPrinter(raw_ostream &OS) : OS(OS), IndentLevel(0) {}
+
+ void flush() { OS.flush(); }
+
+ void indent(int Levels = 1) { IndentLevel += Levels; }
+
+ void unindent(int Levels = 1) {
+ IndentLevel = std::max(0, IndentLevel - Levels);
+ }
+
+ void resetIndent() { IndentLevel = 0; }
+
+ void setPrefix(StringRef P) { Prefix = P; }
+
+ void printIndent() {
+ OS << Prefix;
+ for (int i = 0; i < IndentLevel; ++i)
+ OS << " ";
+ }
+
+ template <typename T> HexNumber hex(T Value) { return HexNumber(Value); }
+
+ template <typename T, typename TEnum>
+ void printEnum(StringRef Label, T Value,
+ ArrayRef<EnumEntry<TEnum>> EnumValues) {
+ StringRef Name;
+ bool Found = false;
+ for (const auto &EnumItem : EnumValues) {
+ if (EnumItem.Value == Value) {
+ Name = EnumItem.Name;
+ Found = true;
+ break;
+ }
+ }
+
+ if (Found) {
+ startLine() << Label << ": " << Name << " (" << hex(Value) << ")\n";
+ } else {
+ startLine() << Label << ": " << hex(Value) << "\n";
+ }
+ }
+
+ template <typename T, typename TFlag>
+ void printFlags(StringRef Label, T Value, ArrayRef<EnumEntry<TFlag>> Flags,
+ TFlag EnumMask1 = {}, TFlag EnumMask2 = {},
+ TFlag EnumMask3 = {}) {
+ typedef EnumEntry<TFlag> FlagEntry;
+ typedef SmallVector<FlagEntry, 10> FlagVector;
+ FlagVector SetFlags;
+
+ for (const auto &Flag : Flags) {
+ if (Flag.Value == 0)
+ continue;
+
+ TFlag EnumMask{};
+ if (Flag.Value & EnumMask1)
+ EnumMask = EnumMask1;
+ else if (Flag.Value & EnumMask2)
+ EnumMask = EnumMask2;
+ else if (Flag.Value & EnumMask3)
+ EnumMask = EnumMask3;
+ bool IsEnum = (Flag.Value & EnumMask) != 0;
+ if ((!IsEnum && (Value & Flag.Value) == Flag.Value) ||
+ (IsEnum && (Value & EnumMask) == Flag.Value)) {
+ SetFlags.push_back(Flag);
+ }
+ }
+
+ std::sort(SetFlags.begin(), SetFlags.end(), &flagName<TFlag>);
+
+ startLine() << Label << " [ (" << hex(Value) << ")\n";
+ for (const auto &Flag : SetFlags) {
+ startLine() << " " << Flag.Name << " (" << hex(Flag.Value) << ")\n";
+ }
+ startLine() << "]\n";
+ }
+
+ template <typename T> void printFlags(StringRef Label, T Value) {
+ startLine() << Label << " [ (" << hex(Value) << ")\n";
+ uint64_t Flag = 1;
+ uint64_t Curr = Value;
+ while (Curr > 0) {
+ if (Curr & 1)
+ startLine() << " " << hex(Flag) << "\n";
+ Curr >>= 1;
+ Flag <<= 1;
+ }
+ startLine() << "]\n";
+ }
+
+ void printNumber(StringRef Label, uint64_t Value) {
+ startLine() << Label << ": " << Value << "\n";
+ }
+
+ void printNumber(StringRef Label, uint32_t Value) {
+ startLine() << Label << ": " << Value << "\n";
+ }
+
+ void printNumber(StringRef Label, uint16_t Value) {
+ startLine() << Label << ": " << Value << "\n";
+ }
+
+ void printNumber(StringRef Label, uint8_t Value) {
+ startLine() << Label << ": " << unsigned(Value) << "\n";
+ }
+
+ void printNumber(StringRef Label, int64_t Value) {
+ startLine() << Label << ": " << Value << "\n";
+ }
+
+ void printNumber(StringRef Label, int32_t Value) {
+ startLine() << Label << ": " << Value << "\n";
+ }
+
+ void printNumber(StringRef Label, int16_t Value) {
+ startLine() << Label << ": " << Value << "\n";
+ }
+
+ void printNumber(StringRef Label, int8_t Value) {
+ startLine() << Label << ": " << int(Value) << "\n";
+ }
+
+ void printNumber(StringRef Label, const APSInt &Value) {
+ startLine() << Label << ": " << Value << "\n";
+ }
+
+ void printBoolean(StringRef Label, bool Value) {
+ startLine() << Label << ": " << (Value ? "Yes" : "No") << '\n';
+ }
+
+ template <typename... T> void printVersion(StringRef Label, T... Version) {
+ startLine() << Label << ": ";
+ printVersionInternal(Version...);
+ getOStream() << "\n";
+ }
+
+ template <typename T> void printList(StringRef Label, const T &List) {
+ startLine() << Label << ": [";
+ bool Comma = false;
+ for (const auto &Item : List) {
+ if (Comma)
+ OS << ", ";
+ OS << Item;
+ Comma = true;
+ }
+ OS << "]\n";
+ }
+
+ template <typename T, typename U>
+ void printList(StringRef Label, const T &List, const U &Printer) {
+ startLine() << Label << ": [";
+ bool Comma = false;
+ for (const auto &Item : List) {
+ if (Comma)
+ OS << ", ";
+ Printer(OS, Item);
+ Comma = true;
+ }
+ OS << "]\n";
+ }
+
+ template <typename T> void printHexList(StringRef Label, const T &List) {
+ startLine() << Label << ": [";
+ bool Comma = false;
+ for (const auto &Item : List) {
+ if (Comma)
+ OS << ", ";
+ OS << hex(Item);
+ Comma = true;
+ }
+ OS << "]\n";
+ }
+
+ template <typename T> void printHex(StringRef Label, T Value) {
+ startLine() << Label << ": " << hex(Value) << "\n";
+ }
+
+ template <typename T> void printHex(StringRef Label, StringRef Str, T Value) {
+ startLine() << Label << ": " << Str << " (" << hex(Value) << ")\n";
+ }
+
+ template <typename T>
+ void printSymbolOffset(StringRef Label, StringRef Symbol, T Value) {
+ startLine() << Label << ": " << Symbol << '+' << hex(Value) << '\n';
+ }
+
+ void printString(StringRef Value) { startLine() << Value << "\n"; }
+
+ void printString(StringRef Label, StringRef Value) {
+ startLine() << Label << ": " << Value << "\n";
+ }
+
+ void printString(StringRef Label, const std::string &Value) {
+ startLine() << Label << ": " << Value << "\n";
+ }
+
+ template <typename T>
+ void printNumber(StringRef Label, StringRef Str, T Value) {
+ startLine() << Label << ": " << Str << " (" << Value << ")\n";
+ }
+
+ void printBinary(StringRef Label, StringRef Str, ArrayRef<uint8_t> Value) {
+ printBinaryImpl(Label, Str, Value, false);
+ }
+
+ void printBinary(StringRef Label, StringRef Str, ArrayRef<char> Value) {
+ auto V = makeArrayRef(reinterpret_cast<const uint8_t *>(Value.data()),
+ Value.size());
+ printBinaryImpl(Label, Str, V, false);
+ }
+
+ void printBinary(StringRef Label, ArrayRef<uint8_t> Value) {
+ printBinaryImpl(Label, StringRef(), Value, false);
+ }
+
+ void printBinary(StringRef Label, ArrayRef<char> Value) {
+ auto V = makeArrayRef(reinterpret_cast<const uint8_t *>(Value.data()),
+ Value.size());
+ printBinaryImpl(Label, StringRef(), V, false);
+ }
+
+ void printBinary(StringRef Label, StringRef Value) {
+ auto V = makeArrayRef(reinterpret_cast<const uint8_t *>(Value.data()),
+ Value.size());
+ printBinaryImpl(Label, StringRef(), V, false);
+ }
+
+ void printBinaryBlock(StringRef Label, ArrayRef<uint8_t> Value) {
+ printBinaryImpl(Label, StringRef(), Value, true);
+ }
+
+ void printBinaryBlock(StringRef Label, StringRef Value) {
+ auto V = makeArrayRef(reinterpret_cast<const uint8_t *>(Value.data()),
+ Value.size());
+ printBinaryImpl(Label, StringRef(), V, true);
+ }
+
+ template <typename T> void printObject(StringRef Label, const T &Value) {
+ startLine() << Label << ": " << Value << "\n";
+ }
+
+ raw_ostream &startLine() {
+ printIndent();
+ return OS;
+ }
+
+ raw_ostream &getOStream() { return OS; }
+
+private:
+ template <typename T> void printVersionInternal(T Value) {
+ getOStream() << Value;
+ }
+
+ template <typename S, typename T, typename... TArgs>
+ void printVersionInternal(S Value, T Value2, TArgs... Args) {
+ getOStream() << Value << ".";
+ printVersionInternal(Value2, Args...);
+ }
+
+ template <typename T>
+ static bool flagName(const EnumEntry<T> &lhs, const EnumEntry<T> &rhs) {
+ return lhs.Name < rhs.Name;
+ }
+
+ void printBinaryImpl(StringRef Label, StringRef Str, ArrayRef<uint8_t> Value,
+ bool Block);
+
+ raw_ostream &OS;
+ int IndentLevel;
+ StringRef Prefix;
+};
+
+template <>
+inline void
+ScopedPrinter::printHex<support::ulittle16_t>(StringRef Label,
+ support::ulittle16_t Value) {
+ startLine() << Label << ": " << hex(Value) << "\n";
+}
+
+template<char Open, char Close>
+struct DelimitedScope {
+ explicit DelimitedScope(ScopedPrinter &W) : W(W) {
+ W.startLine() << Open << '\n';
+ W.indent();
+ }
+
+ DelimitedScope(ScopedPrinter &W, StringRef N) : W(W) {
+ W.startLine() << N;
+ if (!N.empty())
+ W.getOStream() << ' ';
+ W.getOStream() << Open << '\n';
+ W.indent();
+ }
+
+ ~DelimitedScope() {
+ W.unindent();
+ W.startLine() << Close << '\n';
+ }
+
+ ScopedPrinter &W;
+};
+
+using DictScope = DelimitedScope<'{', '}'>;
+using ListScope = DelimitedScope<'[', ']'>;
+
+} // namespace llvm
+
+#endif
diff --git a/include/llvm/Support/Signals.h b/include/llvm/Support/Signals.h
index 2a4d84bd891a..cbd6f686a778 100644
--- a/include/llvm/Support/Signals.h
+++ b/include/llvm/Support/Signals.h
@@ -38,8 +38,14 @@ namespace sys {
/// When an error signal (such as SIBABRT or SIGSEGV) is delivered to the
/// process, print a stack trace and then exit.
- /// @brief Print a stack trace if a fatal signal occurs.
- void PrintStackTraceOnErrorSignal(bool DisableCrashReporting = false);
+ /// \brief Print a stack trace if a fatal signal occurs.
+ /// \param Argv0 the current binary name, used to find the symbolizer
+ /// relative to the current binary before searching $PATH; can be
+ /// StringRef(), in which case we will only search $PATH.
+ /// \param DisableCrashReporting if \c true, disable the normal crash
+ /// reporting mechanisms on the underlying operating system.
+ void PrintStackTraceOnErrorSignal(StringRef Argv0,
+ bool DisableCrashReporting = false);
/// Disable all system dialog boxes that appear when the process crashes.
void DisableSystemDialogsOnCrash();
diff --git a/include/llvm/Support/StreamingMemoryObject.h b/include/llvm/Support/StreamingMemoryObject.h
index a5980c235946..1ab85372cd20 100644
--- a/include/llvm/Support/StreamingMemoryObject.h
+++ b/include/llvm/Support/StreamingMemoryObject.h
@@ -28,15 +28,7 @@ public:
uint64_t getExtent() const override;
uint64_t readBytes(uint8_t *Buf, uint64_t Size,
uint64_t Address) const override;
- const uint8_t *getPointer(uint64_t address, uint64_t size) const override {
- // FIXME: This could be fixed by ensuring the bytes are fetched and
- // making a copy, requiring that the bitcode size be known, or
- // otherwise ensuring that the memory doesn't go away/get reallocated,
- // but it's not currently necessary. Users that need the pointer (any
- // that need Blobs) don't stream.
- report_fatal_error("getPointer in streaming memory objects not allowed");
- return nullptr;
- }
+ const uint8_t *getPointer(uint64_t Address, uint64_t Size) const override;
bool isValidAddress(uint64_t address) const override;
/// Drop s bytes from the front of the stream, pushing the positions of the
diff --git a/include/llvm/Support/SwapByteOrder.h b/include/llvm/Support/SwapByteOrder.h
index 7761fa1d7e01..91693aceb27d 100644
--- a/include/llvm/Support/SwapByteOrder.h
+++ b/include/llvm/Support/SwapByteOrder.h
@@ -18,7 +18,6 @@
#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataTypes.h"
#include <cstddef>
-#include <limits>
namespace llvm {
namespace sys {
diff --git a/include/llvm/Support/TargetParser.h b/include/llvm/Support/TargetParser.h
index c21019d0c5b8..0e2141f6d46f 100644
--- a/include/llvm/Support/TargetParser.h
+++ b/include/llvm/Support/TargetParser.h
@@ -83,6 +83,7 @@ enum ArchExtKind : unsigned {
AEK_VIRT = 0x200,
AEK_DSP = 0x400,
AEK_FP16 = 0x800,
+ AEK_RAS = 0x1000,
// Unsupported extensions.
AEK_OS = 0x8000000,
AEK_IWMMXT = 0x10000000,
@@ -140,6 +141,61 @@ unsigned parseArchProfile(StringRef Arch);
unsigned parseArchVersion(StringRef Arch);
} // namespace ARM
+
+// FIXME:This should be made into class design,to avoid dupplication.
+namespace AArch64 {
+
+// Arch extension modifiers for CPUs.
+enum ArchExtKind : unsigned {
+ AEK_INVALID = 0x0,
+ AEK_NONE = 0x1,
+ AEK_CRC = 0x2,
+ AEK_CRYPTO = 0x4,
+ AEK_FP = 0x8,
+ AEK_SIMD = 0x10,
+ AEK_FP16 = 0x20,
+ AEK_PROFILE = 0x40,
+ AEK_RAS = 0x80
+};
+
+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 getExtensionFeatures(unsigned Extensions,
+ std::vector<const char*> &Features);
+bool getArchFeatures(unsigned ArchKind, 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);
+unsigned checkArchVersion(StringRef Arch);
+
+// Information by Name
+unsigned getDefaultFPU(StringRef CPU, unsigned ArchKind);
+unsigned getDefaultExtensions(StringRef CPU, unsigned ArchKind);
+StringRef getDefaultCPU(StringRef Arch);
+
+// Parser
+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 AArch64
} // namespace llvm
#endif
diff --git a/include/llvm/Support/TargetRegistry.h b/include/llvm/Support/TargetRegistry.h
index aec181b1d266..076558e4df77 100644
--- a/include/llvm/Support/TargetRegistry.h
+++ b/include/llvm/Support/TargetRegistry.h
@@ -20,6 +20,7 @@
#define LLVM_SUPPORT_TARGETREGISTRY_H
#include "llvm-c/Disassembler.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Support/CodeGen.h"
#include "llvm/Support/FormattedStream.h"
@@ -33,7 +34,6 @@ class MCAsmBackend;
class MCAsmInfo;
class MCAsmParser;
class MCCodeEmitter;
-class MCCodeGenInfo;
class MCContext;
class MCDisassembler;
class MCInstrAnalysis;
@@ -92,10 +92,9 @@ public:
typedef MCAsmInfo *(*MCAsmInfoCtorFnTy)(const MCRegisterInfo &MRI,
const Triple &TT);
- typedef MCCodeGenInfo *(*MCCodeGenInfoCtorFnTy)(const Triple &TT,
- Reloc::Model RM,
- CodeModel::Model CM,
- CodeGenOpt::Level OL);
+ typedef void (*MCAdjustCodeGenOptsFnTy)(const Triple &TT, Reloc::Model RM,
+ CodeModel::Model &CM);
+
typedef MCInstrInfo *(*MCInstrInfoCtorFnTy)(void);
typedef MCInstrAnalysis *(*MCInstrAnalysisCtorFnTy)(const MCInstrInfo *Info);
typedef MCRegisterInfo *(*MCRegInfoCtorFnTy)(const Triple &TT);
@@ -104,8 +103,8 @@ public:
StringRef Features);
typedef TargetMachine *(*TargetMachineCtorTy)(
const Target &T, const Triple &TT, StringRef CPU, StringRef Features,
- const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM,
- CodeGenOpt::Level OL);
+ const TargetOptions &Options, Optional<Reloc::Model> RM,
+ CodeModel::Model CM, CodeGenOpt::Level OL);
// If it weren't for layering issues (this header is in llvm/Support, but
// depends on MC?) this should take the Streamer by value rather than rvalue
// reference.
@@ -177,9 +176,7 @@ private:
/// registered.
MCAsmInfoCtorFnTy MCAsmInfoCtorFn;
- /// MCCodeGenInfoCtorFn - Constructor function for this target's
- /// MCCodeGenInfo, if registered.
- MCCodeGenInfoCtorFnTy MCCodeGenInfoCtorFn;
+ MCAdjustCodeGenOptsFnTy MCAdjustCodeGenOptsFn;
/// MCInstrInfoCtorFn - Constructor function for this target's MCInstrInfo,
/// if registered.
@@ -300,14 +297,10 @@ public:
return MCAsmInfoCtorFn(MRI, Triple(TheTriple));
}
- /// createMCCodeGenInfo - Create a MCCodeGenInfo implementation.
- ///
- MCCodeGenInfo *createMCCodeGenInfo(StringRef TT, Reloc::Model RM,
- CodeModel::Model CM,
- CodeGenOpt::Level OL) const {
- if (!MCCodeGenInfoCtorFn)
- return nullptr;
- return MCCodeGenInfoCtorFn(Triple(TT), RM, CM, OL);
+ void adjustCodeGenOpts(const Triple &TT, Reloc::Model RM,
+ CodeModel::Model &CM) const {
+ if (MCAdjustCodeGenOptsFn)
+ MCAdjustCodeGenOptsFn(TT, RM, CM);
}
/// createMCInstrInfo - Create a MCInstrInfo implementation.
@@ -359,8 +352,7 @@ public:
/// host if that does not exist.
TargetMachine *
createTargetMachine(StringRef TT, StringRef CPU, StringRef Features,
- const TargetOptions &Options,
- Reloc::Model RM = Reloc::Default,
+ const TargetOptions &Options, Optional<Reloc::Model> RM,
CodeModel::Model CM = CodeModel::Default,
CodeGenOpt::Level OL = CodeGenOpt::Default) const {
if (!TargetMachineCtorFn)
@@ -646,18 +638,9 @@ struct TargetRegistry {
T.MCAsmInfoCtorFn = Fn;
}
- /// RegisterMCCodeGenInfo - Register a MCCodeGenInfo implementation for the
- /// given target.
- ///
- /// Clients are responsible for ensuring that registration doesn't occur
- /// while another thread is attempting to access the registry. Typically
- /// this is done by initializing all targets at program startup.
- ///
- /// @param T - The target being registered.
- /// @param Fn - A function to construct a MCCodeGenInfo for the target.
- static void RegisterMCCodeGenInfo(Target &T,
- Target::MCCodeGenInfoCtorFnTy Fn) {
- T.MCCodeGenInfoCtorFn = Fn;
+ static void registerMCAdjustCodeGenOpts(Target &T,
+ Target::MCAdjustCodeGenOptsFnTy Fn) {
+ T.MCAdjustCodeGenOptsFn = Fn;
}
/// RegisterMCInstrInfo - Register a MCInstrInfo implementation for the
@@ -914,39 +897,9 @@ struct RegisterMCAsmInfoFn {
}
};
-/// RegisterMCCodeGenInfo - Helper template for registering a target codegen
-/// info
-/// implementation. This invokes the static "Create" method on the class
-/// to actually do the construction. Usage:
-///
-/// extern "C" void LLVMInitializeFooTarget() {
-/// extern Target TheFooTarget;
-/// RegisterMCCodeGenInfo<FooMCCodeGenInfo> X(TheFooTarget);
-/// }
-template <class MCCodeGenInfoImpl> struct RegisterMCCodeGenInfo {
- RegisterMCCodeGenInfo(Target &T) {
- TargetRegistry::RegisterMCCodeGenInfo(T, &Allocator);
- }
-
-private:
- static MCCodeGenInfo *Allocator(const Triple & /*TT*/, Reloc::Model /*RM*/,
- CodeModel::Model /*CM*/,
- CodeGenOpt::Level /*OL*/) {
- return new MCCodeGenInfoImpl();
- }
-};
-
-/// RegisterMCCodeGenInfoFn - Helper template for registering a target codegen
-/// info implementation. This invokes the specified function to do the
-/// construction. Usage:
-///
-/// extern "C" void LLVMInitializeFooTarget() {
-/// extern Target TheFooTarget;
-/// RegisterMCCodeGenInfoFn X(TheFooTarget, TheFunction);
-/// }
-struct RegisterMCCodeGenInfoFn {
- RegisterMCCodeGenInfoFn(Target &T, Target::MCCodeGenInfoCtorFnTy Fn) {
- TargetRegistry::RegisterMCCodeGenInfo(T, Fn);
+struct RegisterMCAdjustCodeGenOptsFn {
+ RegisterMCAdjustCodeGenOptsFn(Target &T, Target::MCAdjustCodeGenOptsFnTy Fn) {
+ TargetRegistry::registerMCAdjustCodeGenOpts(T, Fn);
}
};
@@ -1097,7 +1050,8 @@ template <class TargetMachineImpl> struct RegisterTargetMachine {
private:
static TargetMachine *Allocator(const Target &T, const Triple &TT,
StringRef CPU, StringRef FS,
- const TargetOptions &Options, Reloc::Model RM,
+ const TargetOptions &Options,
+ Optional<Reloc::Model> RM,
CodeModel::Model CM, CodeGenOpt::Level OL) {
return new TargetMachineImpl(T, TT, CPU, FS, Options, RM, CM, OL);
}
diff --git a/include/llvm/Support/ThreadPool.h b/include/llvm/Support/ThreadPool.h
index 745334db4450..665cec2465bf 100644
--- a/include/llvm/Support/ThreadPool.h
+++ b/include/llvm/Support/ThreadPool.h
@@ -33,6 +33,7 @@
#pragma warning(pop)
#endif
+#include <atomic>
#include <condition_variable>
#include <functional>
#include <memory>
diff --git a/include/llvm/Support/Threading.h b/include/llvm/Support/Threading.h
index 9007c132a99a..09b96dfb4c1c 100644
--- a/include/llvm/Support/Threading.h
+++ b/include/llvm/Support/Threading.h
@@ -15,6 +15,27 @@
#ifndef LLVM_SUPPORT_THREADING_H
#define LLVM_SUPPORT_THREADING_H
+#include "llvm/Config/llvm-config.h" // for LLVM_ON_UNIX
+#include "llvm/Support/Compiler.h"
+#include <ciso646> // So we can check the C++ standard lib macros.
+#include <functional>
+
+// We use std::call_once on all Unix platforms except for NetBSD with
+// libstdc++. That platform has a bug they are working to fix, and they'll
+// remove the NetBSD checks once fixed.
+#if defined(LLVM_ON_UNIX) && \
+ !(defined(__NetBSD__) && !defined(_LIBCPP_VERSION)) && !defined(__ppc__)
+#define LLVM_THREADING_USE_STD_CALL_ONCE 1
+#else
+#define LLVM_THREADING_USE_STD_CALL_ONCE 0
+#endif
+
+#if LLVM_THREADING_USE_STD_CALL_ONCE
+#include <mutex>
+#else
+#include "llvm/Support/Atomic.h"
+#endif
+
namespace llvm {
/// Returns true if LLVM is compiled with support for multi-threading, and
/// false otherwise.
@@ -34,6 +55,66 @@ namespace llvm {
/// the thread stack.
void llvm_execute_on_thread(void (*UserFn)(void*), void *UserData,
unsigned RequestedStackSize = 0);
+
+#if LLVM_THREADING_USE_STD_CALL_ONCE
+
+ typedef std::once_flag once_flag;
+
+ /// This macro is the only way you should define your once flag for LLVM's
+ /// call_once.
+#define LLVM_DEFINE_ONCE_FLAG(flag) static once_flag flag
+
+#else
+
+ enum InitStatus { Uninitialized = 0, Wait = 1, Done = 2 };
+ typedef volatile sys::cas_flag once_flag;
+
+ /// This macro is the only way you should define your once flag for LLVM's
+ /// call_once.
+#define LLVM_DEFINE_ONCE_FLAG(flag) static once_flag flag = Uninitialized
+
+#endif
+
+ /// \brief Execute the function specified as a parameter once.
+ ///
+ /// Typical usage:
+ /// \code
+ /// void foo() {...};
+ /// ...
+ /// LLVM_DEFINE_ONCE_FLAG(flag);
+ /// call_once(flag, foo);
+ /// \endcode
+ ///
+ /// \param flag Flag used for tracking whether or not this has run.
+ /// \param F Function to call once.
+ template <typename Function, typename... Args>
+ void call_once(once_flag &flag, Function &&F, Args &&... ArgList) {
+#if LLVM_THREADING_USE_STD_CALL_ONCE
+ std::call_once(flag, std::forward<Function>(F),
+ std::forward<Args>(ArgList)...);
+#else
+ // For other platforms we use a generic (if brittle) version based on our
+ // atomics.
+ sys::cas_flag old_val = sys::CompareAndSwap(&flag, Wait, Uninitialized);
+ if (old_val == Uninitialized) {
+ std::forward<Function>(F)(std::forward<Args>(ArgList)...);
+ sys::MemoryFence();
+ TsanIgnoreWritesBegin();
+ TsanHappensBefore(&flag);
+ flag = Done;
+ TsanIgnoreWritesEnd();
+ } else {
+ // Wait until any thread doing the call has finished.
+ sys::cas_flag tmp = flag;
+ sys::MemoryFence();
+ while (tmp != Done) {
+ tmp = flag;
+ sys::MemoryFence();
+ }
+ }
+ TsanHappensAfter(&flag);
+#endif
+ }
}
#endif
diff --git a/include/llvm/Support/Timer.h b/include/llvm/Support/Timer.h
index 499fe7b7e70c..f0cb07599b86 100644
--- a/include/llvm/Support/Timer.h
+++ b/include/llvm/Support/Timer.h
@@ -104,6 +104,9 @@ public:
const std::string &getName() const { return Name; }
bool isInitialized() const { return TG != nullptr; }
+ /// Check if the timer is currently running.
+ bool isRunning() const { return Running; }
+
/// Check if startTimer() has ever been called on this timer.
bool hasTriggered() const { return Triggered; }
diff --git a/include/llvm/Support/TrailingObjects.h b/include/llvm/Support/TrailingObjects.h
index 8529746eeccc..5a21cddf9731 100644
--- a/include/llvm/Support/TrailingObjects.h
+++ b/include/llvm/Support/TrailingObjects.h
@@ -197,7 +197,7 @@ struct TrailingObjectsImpl<Align, BaseTy, TopTrailingObj, PrevTy, NextTy,
typename ExtractSecondType<MoreTys, size_t>::type... MoreCounts) {
return additionalSizeToAllocImpl(
(requiresRealignment()
- ? llvm::RoundUpToAlignment(SizeSoFar, llvm::alignOf<NextTy>())
+ ? llvm::alignTo(SizeSoFar, llvm::alignOf<NextTy>())
: SizeSoFar) +
sizeof(NextTy) * Count1,
MoreCounts...);
@@ -290,7 +290,7 @@ class TrailingObjects : private trailing_objects_internal::TrailingObjectsImpl<
}
public:
- // make this (privately inherited) class public.
+ // Make this (privately inherited) member public.
using ParentType::OverloadToken;
/// Returns a pointer to the trailing object array of the given type
@@ -342,6 +342,51 @@ public:
TrailingTys, size_t>::type... Counts) {
return sizeof(BaseTy) + ParentType::additionalSizeToAllocImpl(0, Counts...);
}
+
+ /// A type where its ::with_counts template member has a ::type member
+ /// suitable for use as uninitialized storage for an object with the given
+ /// trailing object counts. The template arguments are similar to those
+ /// of additionalSizeToAlloc.
+ ///
+ /// Use with FixedSizeStorageOwner, e.g.:
+ ///
+ /// \code{.cpp}
+ ///
+ /// MyObj::FixedSizeStorage<void *>::with_counts<1u>::type myStackObjStorage;
+ /// MyObj::FixedSizeStorageOwner
+ /// myStackObjOwner(new ((void *)&myStackObjStorage) MyObj);
+ /// MyObj *const myStackObjPtr = myStackObjOwner.get();
+ ///
+ /// \endcode
+ template <typename... Tys> struct FixedSizeStorage {
+ template <size_t... Counts> struct with_counts {
+ enum { Size = totalSizeToAlloc<Tys...>(Counts...) };
+ typedef llvm::AlignedCharArray<
+ llvm::AlignOf<BaseTy>::Alignment, Size
+ > type;
+ };
+ };
+
+ /// A type that acts as the owner for an object placed into fixed storage.
+ class FixedSizeStorageOwner {
+ public:
+ FixedSizeStorageOwner(BaseTy *p) : p(p) {}
+ ~FixedSizeStorageOwner() {
+ assert(p && "FixedSizeStorageOwner owns null?");
+ p->~BaseTy();
+ }
+
+ BaseTy *get() { return p; }
+ const BaseTy *get() const { return p; }
+
+ private:
+ FixedSizeStorageOwner(const FixedSizeStorageOwner &) = delete;
+ FixedSizeStorageOwner(FixedSizeStorageOwner &&) = delete;
+ FixedSizeStorageOwner &operator=(const FixedSizeStorageOwner &) = delete;
+ FixedSizeStorageOwner &operator=(FixedSizeStorageOwner &&) = delete;
+
+ BaseTy *const p;
+ };
};
} // end namespace llvm
diff --git a/include/llvm/Support/TypeName.h b/include/llvm/Support/TypeName.h
new file mode 100644
index 000000000000..0eb7ead98b21
--- /dev/null
+++ b/include/llvm/Support/TypeName.h
@@ -0,0 +1,65 @@
+//===- TypeName.h -----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_TYPENAME_H
+#define LLVM_SUPPORT_TYPENAME_H
+
+#include "llvm/ADT/StringRef.h"
+
+namespace llvm {
+
+/// We provide a function which tries to compute the (demangled) name of a type
+/// statically.
+///
+/// This routine may fail on some platforms or for particularly unusual types.
+/// Do not use it for anything other than logging and debugging aids. It isn't
+/// portable or dependendable in any real sense.
+///
+/// The returned StringRef will point into a static storage duration string.
+/// However, it may not be null terminated and may be some strangely aligned
+/// inner substring of a larger string.
+template <typename DesiredTypeName>
+inline StringRef getTypeName() {
+#if defined(__clang__) || defined(__GNUC__)
+ StringRef Name = __PRETTY_FUNCTION__;
+
+ StringRef Key = "DesiredTypeName = ";
+ Name = Name.substr(Name.find(Key));
+ assert(!Name.empty() && "Unable to find the template parameter!");
+ Name = Name.drop_front(Key.size());
+
+ assert(Name.endswith("]") && "Name doesn't end in the substitution key!");
+ return Name.drop_back(1);
+#elif defined(_MSC_VER)
+ StringRef Name = __FUNCSIG__;
+
+ StringRef Key = "getTypeName<";
+ Name = Name.substr(Name.find(Key));
+ assert(!Name.empty() && "Unable to find the function name!");
+ Name = Name.drop_front(Key.size());
+
+ for (StringRef Prefix : {"class ", "struct ", "union ", "enum "})
+ if (Name.startswith(Prefix)) {
+ Name = Name.drop_front(Prefix.size());
+ break;
+ }
+
+ auto AnglePos = Name.rfind('>');
+ assert(AnglePos != StringRef::npos && "Unable to find the closing '>'!");
+ return Name.substr(0, AnglePos);
+#else
+ // No known technique for statically extracting a type name on this compiler.
+ // We return a string that is unlikely to look like any type in LLVM.
+ return "UNKNOWN_TYPE";
+#endif
+}
+
+}
+
+#endif
diff --git a/include/llvm/Support/Unicode.h b/include/llvm/Support/Unicode.h
index f668a5bc88df..adedb1ed83a6 100644
--- a/include/llvm/Support/Unicode.h
+++ b/include/llvm/Support/Unicode.h
@@ -15,9 +15,9 @@
#ifndef LLVM_SUPPORT_UNICODE_H
#define LLVM_SUPPORT_UNICODE_H
-#include "llvm/ADT/StringRef.h"
-
namespace llvm {
+class StringRef;
+
namespace sys {
namespace unicode {
diff --git a/include/llvm/Support/Valgrind.h b/include/llvm/Support/Valgrind.h
index 12b0dc961daa..084b901b326c 100644
--- a/include/llvm/Support/Valgrind.h
+++ b/include/llvm/Support/Valgrind.h
@@ -1,4 +1,4 @@
-//===- llvm/Support/Valgrind.h - Communication with Valgrind -----*- C++ -*-===//
+//===- llvm/Support/Valgrind.h - Communication with Valgrind ----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,9 +16,7 @@
#ifndef LLVM_SUPPORT_VALGRIND_H
#define LLVM_SUPPORT_VALGRIND_H
-#include "llvm/Config/llvm-config.h"
-#include "llvm/Support/Compiler.h"
-#include <stddef.h>
+#include <cstddef>
namespace llvm {
namespace sys {
@@ -28,7 +26,7 @@ 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);
-}
-}
+} // namespace sys
+} // end namespace llvm
-#endif
+#endif // LLVM_SUPPORT_VALGRIND_H
diff --git a/include/llvm/Support/YAMLParser.h b/include/llvm/Support/YAMLParser.h
index a5addfa3c7ae..23014fc10a3f 100644
--- a/include/llvm/Support/YAMLParser.h
+++ b/include/llvm/Support/YAMLParser.h
@@ -41,7 +41,6 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/SMLoc.h"
-#include <limits>
#include <map>
#include <utility>
diff --git a/include/llvm/Support/YAMLTraits.h b/include/llvm/Support/YAMLTraits.h
index fb2badfd93ba..bc3fa8ad11da 100644
--- a/include/llvm/Support/YAMLTraits.h
+++ b/include/llvm/Support/YAMLTraits.h
@@ -10,8 +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"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
@@ -19,6 +17,7 @@
#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Endian.h"
#include "llvm/Support/Regex.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/YAMLParser.h"
@@ -512,11 +511,11 @@ public:
template <typename FBT, typename T>
void enumFallback(T &Val) {
- if ( matchEnumFallback() ) {
+ if (matchEnumFallback()) {
// FIXME: Force integral conversion to allow strong typedefs to convert.
- FBT Res = (uint64_t)Val;
+ FBT Res = static_cast<typename FBT::BaseType>(Val);
yamlize(*this, Res, true);
- Val = (uint64_t)Res;
+ Val = static_cast<T>(static_cast<typename FBT::BaseType>(Res));
}
}
@@ -858,6 +857,32 @@ struct ScalarTraits<double> {
static bool mustQuote(StringRef) { return false; }
};
+// For endian types, we just use the existing ScalarTraits for the underlying
+// type. This way endian aware types are supported whenever a ScalarTraits
+// is defined for the underlying type.
+template <typename value_type, support::endianness endian, size_t alignment>
+struct ScalarTraits<support::detail::packed_endian_specific_integral<
+ value_type, endian, alignment>> {
+ typedef support::detail::packed_endian_specific_integral<value_type, endian,
+ alignment>
+ endian_type;
+
+ static void output(const endian_type &E, void *Ctx,
+ llvm::raw_ostream &Stream) {
+ ScalarTraits<value_type>::output(static_cast<value_type>(E), Ctx, Stream);
+ }
+ static StringRef input(StringRef Str, void *Ctx, endian_type &E) {
+ value_type V;
+ auto R = ScalarTraits<value_type>::input(Str, Ctx, V);
+ E = static_cast<endian_type>(V);
+ return R;
+ }
+
+ static bool mustQuote(StringRef Str) {
+ return ScalarTraits<value_type>::mustQuote(Str);
+ }
+};
+
// Utility for use within MappingTraits<>::mapping() method
// to [de]normalize an object for use with YAML conversion.
template <typename TNorm, typename TFinal>
@@ -894,12 +919,16 @@ private:
// to [de]normalize an object for use with YAML conversion.
template <typename TNorm, typename TFinal>
struct MappingNormalizationHeap {
- MappingNormalizationHeap(IO &i_o, TFinal &Obj)
+ MappingNormalizationHeap(IO &i_o, TFinal &Obj,
+ llvm::BumpPtrAllocator *allocator)
: io(i_o), BufPtr(nullptr), Result(Obj) {
if ( io.outputting() ) {
BufPtr = new (&Buffer) TNorm(io, Obj);
}
- else {
+ else if (allocator) {
+ BufPtr = allocator->Allocate<TNorm>();
+ new (BufPtr) TNorm(io);
+ } else {
BufPtr = new TNorm(io);
}
}
@@ -1166,6 +1195,7 @@ private:
bool operator==(const _base &rhs) const { return value == rhs; } \
bool operator<(const _type &rhs) const { return value < rhs.value; } \
_base value; \
+ typedef _base BaseType; \
};
///
diff --git a/include/llvm/Support/raw_sha1_ostream.h b/include/llvm/Support/raw_sha1_ostream.h
new file mode 100644
index 000000000000..329ef9fd069b
--- /dev/null
+++ b/include/llvm/Support/raw_sha1_ostream.h
@@ -0,0 +1,47 @@
+//==- raw_sha1_ostream.h - raw_ostream that compute SHA1 --*- 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 raw_sha1_ostream class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_RAW_SHA1_OSTREAM_H
+#define LLVM_SUPPORT_RAW_SHA1_OSTREAM_H
+
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/SHA1.h"
+#include "llvm/ADT/ArrayRef.h"
+
+namespace llvm {
+
+/// A raw_ostream that hash the content using the sha1 algorithm.
+class raw_sha1_ostream : public raw_ostream {
+ SHA1 State;
+
+ /// See raw_ostream::write_impl.
+ void write_impl(const char *Ptr, size_t Size) override {
+ State.update(ArrayRef<uint8_t>((const uint8_t *)Ptr, Size));
+ }
+
+public:
+ /// Return the current SHA1 hash for the content of the stream
+ StringRef sha1() {
+ flush();
+ return State.result();
+ }
+
+ /// Reset the internal state to start over from scratch.
+ void resetHash() { State.init(); }
+
+ uint64_t current_pos() const override { return 0; }
+};
+
+} // end llvm namespace
+
+#endif
diff --git a/include/llvm/Support/thread.h b/include/llvm/Support/thread.h
index 2d130418a57f..9c45418df55c 100644
--- a/include/llvm/Support/thread.h
+++ b/include/llvm/Support/thread.h
@@ -57,6 +57,7 @@ struct thread {
thread(const thread &) = delete;
void join() {}
+ static unsigned hardware_concurrency() { return 1; };
};
}
diff --git a/include/llvm/Support/type_traits.h b/include/llvm/Support/type_traits.h
index 88385c3fae1e..7706ff527197 100644
--- a/include/llvm/Support/type_traits.h
+++ b/include/llvm/Support/type_traits.h
@@ -17,6 +17,8 @@
#include <type_traits>
#include <utility>
+#include "llvm/Support/Compiler.h"
+
#ifndef __has_feature
#define LLVM_DEFINED_HAS_FEATURE
#define __has_feature(x) 0
@@ -54,11 +56,12 @@ struct isPodLike<std::pair<T, U> > {
};
/// \brief Metafunction that determines whether the given type is either an
-/// integral type or an enumeration type.
+/// integral type or an enumeration type, including enum classes.
///
/// Note that this accepts potentially more integral types than is_integral
-/// because it is based on merely being convertible implicitly to an integral
-/// type.
+/// because it is based on being implicitly convertible to an integral type.
+/// Also note that enum classes aren't implicitly convertible to integral types,
+/// the value may therefore need to be explicitly converted before being used.
template <typename T> class is_integral_or_enum {
typedef typename std::remove_reference<T>::type UnderlyingT;
@@ -67,7 +70,8 @@ public:
!std::is_class<UnderlyingT>::value && // Filter conversion operators.
!std::is_pointer<UnderlyingT>::value &&
!std::is_floating_point<UnderlyingT>::value &&
- std::is_convertible<UnderlyingT, unsigned long long>::value;
+ (std::is_enum<UnderlyingT>::value ||
+ std::is_convertible<UnderlyingT, unsigned long long>::value);
};
/// \brief If T is a pointer, just return it. If it is not, return T&.