aboutsummaryrefslogtreecommitdiffstats
path: root/include/llvm/Support
diff options
context:
space:
mode:
authorStephen Hines <srhines@google.com>2014-07-21 00:45:20 -0700
committerStephen Hines <srhines@google.com>2014-07-21 00:45:20 -0700
commitc6a4f5e819217e1e12c458aed8e7b122e23a3a58 (patch)
tree81b7dd2bb4370a392f31d332a566c903b5744764 /include/llvm/Support
parent19c6fbb3e8aaf74093afa08013134b61fa08f245 (diff)
downloadexternal_llvm-c6a4f5e819217e1e12c458aed8e7b122e23a3a58.zip
external_llvm-c6a4f5e819217e1e12c458aed8e7b122e23a3a58.tar.gz
external_llvm-c6a4f5e819217e1e12c458aed8e7b122e23a3a58.tar.bz2
Update LLVM for rebase to r212749.
Includes a cherry-pick of: r212948 - fixes a small issue with atomic calls Change-Id: Ib97bd980b59f18142a69506400911a6009d9df18
Diffstat (limited to 'include/llvm/Support')
-rw-r--r--include/llvm/Support/ARMBuildAttributes.h15
-rw-r--r--include/llvm/Support/ARMWinEH.h384
-rw-r--r--include/llvm/Support/COFF.h10
-rw-r--r--include/llvm/Support/Compiler.h6
-rw-r--r--include/llvm/Support/ConvertUTF.h14
-rw-r--r--include/llvm/Support/CrashRecoveryContext.h3
-rw-r--r--include/llvm/Support/DataTypes.h.cmake121
-rw-r--r--include/llvm/Support/DataTypes.h.in119
-rw-r--r--include/llvm/Support/Dwarf.h1
-rw-r--r--include/llvm/Support/ELF.h27
-rw-r--r--include/llvm/Support/Endian.h2
-rw-r--r--include/llvm/Support/Errc.h86
-rw-r--r--include/llvm/Support/ErrorHandling.h5
-rw-r--r--include/llvm/Support/ErrorOr.h42
-rw-r--r--include/llvm/Support/FEnv.h56
-rw-r--r--include/llvm/Support/FileOutputBuffer.h10
-rw-r--r--include/llvm/Support/FileSystem.h237
-rw-r--r--include/llvm/Support/Format.h102
-rw-r--r--include/llvm/Support/GenericDomTree.h4
-rw-r--r--include/llvm/Support/GraphWriter.h2
-rw-r--r--include/llvm/Support/LockFileManager.h5
-rw-r--r--include/llvm/Support/MachO.h23
-rw-r--r--include/llvm/Support/ManagedStatic.h3
-rw-r--r--include/llvm/Support/MathExtras.h9
-rw-r--r--include/llvm/Support/Memory.h10
-rw-r--r--include/llvm/Support/MemoryBuffer.h52
-rw-r--r--include/llvm/Support/Process.h11
-rw-r--r--include/llvm/Support/Program.h7
-rw-r--r--include/llvm/Support/RandomNumberGenerator.h57
-rw-r--r--include/llvm/Support/ScaledNumber.h897
-rw-r--r--include/llvm/Support/SourceMgr.h122
-rw-r--r--include/llvm/Support/SpecialCaseList.h96
-rw-r--r--include/llvm/Support/StreamableMemoryObject.h7
-rw-r--r--include/llvm/Support/StringPool.h7
-rw-r--r--include/llvm/Support/SwapByteOrder.h31
-rw-r--r--include/llvm/Support/TargetRegistry.h27
-rw-r--r--include/llvm/Support/Threading.h29
-rw-r--r--include/llvm/Support/WindowsError.h19
-rw-r--r--include/llvm/Support/YAMLTraits.h8
-rw-r--r--include/llvm/Support/system_error.h901
40 files changed, 2016 insertions, 1551 deletions
diff --git a/include/llvm/Support/ARMBuildAttributes.h b/include/llvm/Support/ARMBuildAttributes.h
index 1631200..f63e0a6 100644
--- a/include/llvm/Support/ARMBuildAttributes.h
+++ b/include/llvm/Support/ARMBuildAttributes.h
@@ -159,6 +159,11 @@ enum {
AddressDirect = 1, // Address imported data directly
AddressGOT = 2, // Address imported data indirectly (via GOT)
+ // Tag_ABI_PCS_wchar_t, (=18), uleb128
+ WCharProhibited = 0, // wchar_t is not used
+ WCharWidth2Bytes = 2, // sizeof(wchar_t) == 2
+ WCharWidth4Bytes = 4, // sizeof(wchar_t) == 4
+
// Tag_ABI_FP_denormal, (=20), uleb128
PreserveFPSign = 2, // sign when flushed-to-zero is preserved
@@ -166,6 +171,16 @@ enum {
AllowRTABI = 2, // numbers, infinities, and one quiet NaN (see [RTABI])
AllowIEE754 = 3, // this code to use all the IEEE 754-defined FP encodings
+ // Tag_ABI_enum_size, (=26), uleb128
+ EnumProhibited = 0, // The user prohibited the use of enums when building
+ // this entity.
+ EnumSmallest = 1, // Enum is smallest container big enough to hold all
+ // values.
+ Enum32Bit = 2, // Enum is at least 32 bits.
+ Enum32BitABI = 3, // Every enumeration visible across an ABI-complying
+ // interface contains a value needing 32 bits to encode
+ // it; other enums can be containerized.
+
// Tag_ABI_HardFP_use, (=27), uleb128
HardFPImplied = 0, // FP use should be implied by Tag_FP_arch
HardFPSinglePrecision = 1, // Single-precision only
diff --git a/include/llvm/Support/ARMWinEH.h b/include/llvm/Support/ARMWinEH.h
new file mode 100644
index 0000000..78deb8d
--- /dev/null
+++ b/include/llvm/Support/ARMWinEH.h
@@ -0,0 +1,384 @@
+//===-- llvm/Support/WinARMEH.h - Windows on ARM EH Constants ---*- 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_WINARMEH_H
+#define LLVM_SUPPORT_WINARMEH_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Support/Endian.h"
+
+namespace llvm {
+namespace ARM {
+namespace WinEH {
+enum class RuntimeFunctionFlag {
+ RFF_Unpacked, /// unpacked entry
+ RFF_Packed, /// packed entry
+ RFF_PackedFragment, /// packed entry representing a fragment
+ RFF_Reserved, /// reserved
+};
+
+enum class ReturnType {
+ RT_POP, /// return via pop {pc} (L flag must be set)
+ RT_B, /// 16-bit branch
+ RT_BW, /// 32-bit branch
+ RT_NoEpilogue, /// no epilogue (fragment)
+};
+
+/// RuntimeFunction - An entry in the table of procedure data (.pdata)
+///
+/// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0
+/// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+/// +---------------------------------------------------------------+
+/// | Function Start RVA |
+/// +-------------------+-+-+-+-----+-+---+---------------------+---+
+/// | Stack Adjust |C|L|R| Reg |H|Ret| Function Length |Flg|
+/// +-------------------+-+-+-+-----+-+---+---------------------+---+
+///
+/// Flag : 2-bit field with the following meanings:
+/// - 00 = packed unwind data not used; reamining bits point to .xdata record
+/// - 01 = packed unwind data
+/// - 10 = packed unwind data, function assumed to have no prologue; useful
+/// for function fragments that are discontiguous with the start of the
+/// function
+/// - 11 = reserved
+/// Function Length : 11-bit field providing the length of the entire function
+/// in bytes, divided by 2; if the function is greater than
+/// 4KB, a full .xdata record must be used instead
+/// Ret : 2-bit field indicating how the function returns
+/// - 00 = return via pop {pc} (the L bit must be set)
+/// - 01 = return via 16-bit branch
+/// - 10 = return via 32-bit branch
+/// - 11 = no epilogue; useful for function fragments that may only contain a
+/// prologue but the epilogue is elsewhere
+/// H : 1-bit flag indicating whether the function "homes" the integer parameter
+/// registers (r0-r3), allocating 16-bytes on the stack
+/// Reg : 3-bit field indicating the index of the last saved non-volatile
+/// register. If the R bit is set to 0, then only integer registers are
+/// saved (r4-rN, where N is 4 + Reg). If the R bit is set to 1, then
+/// only floating-point registers are being saved (d8-dN, where N is
+/// 8 + Reg). The special case of the R bit being set to 1 and Reg equal
+/// to 7 indicates that no registers are saved.
+/// R : 1-bit flag indicating whether the non-volatile registers are integer or
+/// floating-point. 0 indicates integer, 1 indicates floating-point. The
+/// special case of the R-flag being set and Reg being set to 7 indicates
+/// that no non-volatile registers are saved.
+/// L : 1-bit flag indicating whether the function saves/restores the link
+/// register (LR)
+/// C : 1-bit flag indicating whether the function includes extra instructions
+/// to setup a frame chain for fast walking. If this flag is set, r11 is
+/// implicitly added to the list of saved non-volatile integer registers.
+/// Stack Adjust : 10-bit field indicating the number of bytes of stack that are
+/// allocated for this function. Only values between 0x000 and
+/// 0x3f3 can be directly encoded. If the value is 0x3f4 or
+/// greater, then the low 4 bits have special meaning as follows:
+/// - Bit 0-1
+/// indicate the number of words' of adjustment (1-4), minus 1
+/// - Bit 2
+/// indicates if the prologue combined adjustment into push
+/// - Bit 3
+/// indicates if the epilogue combined adjustment into pop
+///
+/// RESTRICTIONS:
+/// - IF C is SET:
+/// + L flag must be set since frame chaining requires r11 and lr
+/// + r11 must NOT be included in the set of registers described by Reg
+/// - IF Ret is 0:
+/// + L flag must be set
+
+// NOTE: RuntimeFunction is meant to be a simple class that provides raw access
+// to all fields in the structure. The accessor methods reflect the names of
+// the bitfields that they correspond to. Although some obvious simplifications
+// are possible via merging of methods, it would prevent the use of this class
+// to fully inspect the contents of the data structure which is particularly
+// useful for scenarios such as llvm-readobj to aid in testing.
+
+class RuntimeFunction {
+public:
+ const support::ulittle32_t BeginAddress;
+ const support::ulittle32_t UnwindData;
+
+ RuntimeFunction(const support::ulittle32_t *Data)
+ : BeginAddress(Data[0]), UnwindData(Data[1]) {}
+
+ RuntimeFunction(const support::ulittle32_t BeginAddress,
+ const support::ulittle32_t UnwindData)
+ : BeginAddress(BeginAddress), UnwindData(UnwindData) {}
+
+ RuntimeFunctionFlag Flag() const {
+ return RuntimeFunctionFlag(UnwindData & 0x3);
+ }
+
+ uint32_t ExceptionInformationRVA() const {
+ assert(Flag() == RuntimeFunctionFlag::RFF_Unpacked &&
+ "unpacked form required for this operation");
+ return (UnwindData & ~0x3);
+ }
+
+ uint32_t PackedUnwindData() const {
+ assert((Flag() == RuntimeFunctionFlag::RFF_Packed ||
+ Flag() == RuntimeFunctionFlag::RFF_PackedFragment) &&
+ "packed form required for this operation");
+ return (UnwindData & ~0x3);
+ }
+ uint32_t FunctionLength() const {
+ assert((Flag() == RuntimeFunctionFlag::RFF_Packed ||
+ Flag() == RuntimeFunctionFlag::RFF_PackedFragment) &&
+ "packed form required for this operation");
+ return (((UnwindData & 0x00001ffc) >> 2) << 1);
+ }
+ ReturnType Ret() const {
+ assert((Flag() == RuntimeFunctionFlag::RFF_Packed ||
+ Flag() == RuntimeFunctionFlag::RFF_PackedFragment) &&
+ "packed form required for this operation");
+ assert(((UnwindData & 0x00006000) || L()) && "L must be set to 1");
+ return ReturnType((UnwindData & 0x00006000) >> 13);
+ }
+ bool H() const {
+ assert((Flag() == RuntimeFunctionFlag::RFF_Packed ||
+ Flag() == RuntimeFunctionFlag::RFF_PackedFragment) &&
+ "packed form required for this operation");
+ return ((UnwindData & 0x00008000) >> 15);
+ }
+ uint8_t Reg() const {
+ assert((Flag() == RuntimeFunctionFlag::RFF_Packed ||
+ Flag() == RuntimeFunctionFlag::RFF_PackedFragment) &&
+ "packed form required for this operation");
+ return ((UnwindData & 0x00070000) >> 16);
+ }
+ bool R() const {
+ assert((Flag() == RuntimeFunctionFlag::RFF_Packed ||
+ Flag() == RuntimeFunctionFlag::RFF_PackedFragment) &&
+ "packed form required for this operation");
+ return ((UnwindData & 0x00080000) >> 19);
+ }
+ bool L() const {
+ assert((Flag() == RuntimeFunctionFlag::RFF_Packed ||
+ Flag() == RuntimeFunctionFlag::RFF_PackedFragment) &&
+ "packed form required for this operation");
+ return ((UnwindData & 0x00100000) >> 20);
+ }
+ bool C() const {
+ assert((Flag() == RuntimeFunctionFlag::RFF_Packed ||
+ Flag() == RuntimeFunctionFlag::RFF_PackedFragment) &&
+ "packed form required for this operation");
+ assert(((~UnwindData & 0x00200000) || L()) &&
+ "L flag must be set, chaining requires r11 and LR");
+ assert(((~UnwindData & 0x00200000) || (Reg() < 7) || R()) &&
+ "r11 must not be included in Reg; C implies r11");
+ return ((UnwindData & 0x00200000) >> 21);
+ }
+ uint16_t StackAdjust() const {
+ assert((Flag() == RuntimeFunctionFlag::RFF_Packed ||
+ Flag() == RuntimeFunctionFlag::RFF_PackedFragment) &&
+ "packed form required for this operation");
+ return ((UnwindData & 0xffc00000) >> 22);
+ }
+};
+
+/// PrologueFolding - pseudo-flag derived from Stack Adjust indicating that the
+/// prologue has stack adjustment combined into the push
+inline bool PrologueFolding(const RuntimeFunction &RF) {
+ return RF.StackAdjust() >= 0x3f4 && (RF.StackAdjust() & 0x4);
+}
+/// Epilogue - pseudo-flag derived from Stack Adjust indicating that the
+/// epilogue has stack adjustment combined into the pop
+inline bool EpilogueFolding(const RuntimeFunction &RF) {
+ return RF.StackAdjust() >= 0x3f4 && (RF.StackAdjust() & 0x8);
+}
+/// StackAdjustment - calculated stack adjustment in words. The stack
+/// adjustment should be determined via this function to account for the special
+/// handling the special encoding when the value is >= 0x3f4.
+inline uint16_t StackAdjustment(const RuntimeFunction &RF) {
+ uint16_t Adjustment = RF.StackAdjust();
+ if (Adjustment >= 0x3f4)
+ return (Adjustment & 0x3) ? ((Adjustment & 0x3) << 2) - 1 : 0;
+ return Adjustment;
+}
+
+/// SavedRegisterMask - Utility function to calculate the set of saved general
+/// purpose (r0-r15) and VFP (d0-d31) registers.
+std::pair<uint16_t, uint32_t> SavedRegisterMask(const RuntimeFunction &RF);
+
+/// ExceptionDataRecord - An entry in the table of exception data (.xdata)
+///
+/// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0
+/// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+/// +-------+---------+-+-+-+---+-----------------------------------+
+/// | C Wrd | Epi Cnt |F|E|X|Ver| Function Length |
+/// +-------+--------+'-'-'-'---'---+-------------------------------+
+/// | Reserved |Ex. Code Words| (Extended Epilogue Count) |
+/// +-------+--------+--------------+-------------------------------+
+///
+/// Function Length : 18-bit field indicating the total length of the function
+/// in bytes divided by 2. If a function is larger than
+/// 512KB, then multiple pdata and xdata records must be used.
+/// Vers : 2-bit field describing the version of the remaining structure. Only
+/// version 0 is currently defined (values 1-3 are not permitted).
+/// X : 1-bit field indicating the presence of exception data
+/// E : 1-bit field indicating that the single epilogue is packed into the
+/// header
+/// F : 1-bit field indicating that the record describes a function fragment
+/// (implies that no prologue is present, and prologue processing should be
+/// skipped)
+/// Epilogue Count : 5-bit field that differs in meaning based on the E field.
+///
+/// If E is set, then this field specifies the index of the
+/// first unwind code describing the (only) epilogue.
+///
+/// Otherwise, this field indicates the number of exception
+/// scopes. If more than 31 scopes exist, then this field and
+/// the Code Words field must both be set to 0 to indicate that
+/// an extension word is required.
+/// Code Words : 4-bit field that species the number of 32-bit words needed to
+/// contain all the unwind codes. If more than 15 words (63 code
+/// bytes) are required, then this field and the Epilogue Count
+/// field must both be set to 0 to indicate that an extension word
+/// is required.
+/// Extended Epilogue Count, Extended Code Words :
+/// Valid only if Epilog Count and Code Words are both
+/// set to 0. Provides an 8-bit extended code word
+/// count and 16-bits for epilogue count
+///
+/// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0
+/// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+/// +----------------+------+---+---+-------------------------------+
+/// | Ep Start Idx | Cond |Res| Epilogue Start Offset |
+/// +----------------+------+---+-----------------------------------+
+///
+/// If the E bit is unset in the header, the header is followed by a series of
+/// epilogue scopes, which are sorted by their offset.
+///
+/// Epilogue Start Offset: 18-bit field encoding the offset of epilogue relative
+/// to the start of the function in bytes divided by two
+/// Res : 2-bit field reserved for future expansion (must be set to 0)
+/// Condition : 4-bit field providing the condition under which the epilogue is
+/// executed. Unconditional epilogues should set this field to 0xe.
+/// Epilogues must be entirely conditional or unconditional, and in
+/// Thumb-2 mode. The epilogue beings with the first instruction
+/// after the IT opcode.
+/// Epilogue Start Index : 8-bit field indicating the byte index of the first
+/// unwind code describing the epilogue
+///
+/// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0
+/// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+/// +---------------+---------------+---------------+---------------+
+/// | Unwind Code 3 | Unwind Code 2 | Unwind Code 1 | Unwind Code 0 |
+/// +---------------+---------------+---------------+---------------+
+///
+/// Following the epilogue scopes, the byte code describing the unwinding
+/// follows. This is padded to align up to word alignment. Bytes are stored in
+/// little endian.
+///
+/// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0
+/// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+/// +---------------------------------------------------------------+
+/// | Exception Handler RVA (requires X = 1) |
+/// +---------------------------------------------------------------+
+/// | (possibly followed by data required for exception handler) |
+/// +---------------------------------------------------------------+
+///
+/// If the X bit is set in the header, the unwind byte code is followed by the
+/// exception handler information. This constants of one Exception Handler RVA
+/// which is the address to the exception handler, followed immediately by the
+/// variable length data associated with the exception handler.
+///
+
+struct EpilogueScope {
+ const support::ulittle32_t ES;
+
+ EpilogueScope(const support::ulittle32_t Data) : ES(Data) {}
+ uint32_t EpilogueStartOffset() const {
+ return (ES & 0x0003ffff);
+ }
+ uint8_t Res() const {
+ return ((ES & 0x000c0000) >> 18);
+ }
+ uint8_t Condition() const {
+ return ((ES & 0x00f00000) >> 20);
+ }
+ uint8_t EpilogueStartIndex() const {
+ return ((ES & 0xff000000) >> 24);
+ }
+};
+
+struct ExceptionDataRecord;
+inline size_t HeaderWords(const ExceptionDataRecord &XR);
+
+struct ExceptionDataRecord {
+ const support::ulittle32_t *Data;
+
+ ExceptionDataRecord(const support::ulittle32_t *Data) : Data(Data) {}
+
+ uint32_t FunctionLength() const {
+ return (Data[0] & 0x0003ffff);
+ }
+
+ uint8_t Vers() const {
+ return (Data[0] & 0x000C0000) >> 18;
+ }
+
+ bool X() const {
+ return ((Data[0] & 0x00100000) >> 20);
+ }
+
+ bool E() const {
+ return ((Data[0] & 0x00200000) >> 21);
+ }
+
+ bool F() const {
+ return ((Data[0] & 0x00400000) >> 22);
+ }
+
+ uint8_t EpilogueCount() const {
+ if (HeaderWords(*this) == 1)
+ return (Data[0] & 0x0f800000) >> 23;
+ return Data[1] & 0x0000ffff;
+ }
+
+ uint8_t CodeWords() const {
+ if (HeaderWords(*this) == 1)
+ return (Data[0] & 0xf0000000) >> 28;
+ return (Data[1] & 0x00ff0000) >> 16;
+ }
+
+ ArrayRef<support::ulittle32_t> EpilogueScopes() const {
+ assert(E() == 0 && "epilogue scopes are only present when the E bit is 0");
+ size_t Offset = HeaderWords(*this);
+ return ArrayRef<support::ulittle32_t>(&Data[Offset], EpilogueCount());
+ }
+
+ ArrayRef<support::ulittle8_t> UnwindByteCode() const {
+ const size_t Offset = HeaderWords(*this)
+ + (E() ? 0 : EpilogueCount());
+ const support::ulittle8_t *ByteCode =
+ reinterpret_cast<const support::ulittle8_t *>(&Data[Offset]);
+ return ArrayRef<support::ulittle8_t>(ByteCode,
+ CodeWords() * sizeof(uint32_t));
+ }
+
+ uint32_t ExceptionHandlerRVA() const {
+ assert(X() && "Exception Handler RVA is only valid if the X bit is set");
+ return Data[HeaderWords(*this) + EpilogueCount() + CodeWords()];
+ }
+
+ uint32_t ExceptionHandlerParameter() const {
+ assert(X() && "Exception Handler RVA is only valid if the X bit is set");
+ return Data[HeaderWords(*this) + EpilogueCount() + CodeWords() + 1];
+ }
+};
+
+inline size_t HeaderWords(const ExceptionDataRecord &XR) {
+ return (XR.Data[0] & 0xff800000) ? 1 : 2;
+}
+}
+}
+}
+
+#endif
+
diff --git a/include/llvm/Support/COFF.h b/include/llvm/Support/COFF.h
index f0e5c7d..e09ef07 100644
--- a/include/llvm/Support/COFF.h
+++ b/include/llvm/Support/COFF.h
@@ -553,7 +553,8 @@ namespace COFF {
IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE = 0x0040,
/// Code integrity checks are enforced.
IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY = 0x0080,
- IMAGE_DLL_CHARACTERISTICS_NX_COMPAT = 0x0100, ///< Image is NX compatible.
+ ///< Image is NX compatible.
+ IMAGE_DLL_CHARACTERISTICS_NX_COMPAT = 0x0100,
/// Isolation aware, but do not isolate the image.
IMAGE_DLL_CHARACTERISTICS_NO_ISOLATION = 0x0200,
/// Does not use structured exception handling (SEH). No SEH handler may be
@@ -561,7 +562,12 @@ namespace COFF {
IMAGE_DLL_CHARACTERISTICS_NO_SEH = 0x0400,
/// Do not bind the image.
IMAGE_DLL_CHARACTERISTICS_NO_BIND = 0x0800,
- IMAGE_DLL_CHARACTERISTICS_WDM_DRIVER = 0x2000, ///< A WDM driver.
+ ///< Image should execute in an AppContainer.
+ IMAGE_DLL_CHARACTERISTICS_APPCONTAINER = 0x1000,
+ ///< A WDM driver.
+ IMAGE_DLL_CHARACTERISTICS_WDM_DRIVER = 0x2000,
+ ///< Image supports Control Flow Guard.
+ IMAGE_DLL_CHARACTERISTICS_GUARD_CF = 0x4000,
/// Terminal Server aware.
IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE = 0x8000
};
diff --git a/include/llvm/Support/Compiler.h b/include/llvm/Support/Compiler.h
index 1edcd45..25bf32a 100644
--- a/include/llvm/Support/Compiler.h
+++ b/include/llvm/Support/Compiler.h
@@ -61,6 +61,12 @@
#define LLVM_MSC_PREREQ(version) 0
#endif
+#ifndef _MSC_VER
+#define LLVM_NOEXCEPT noexcept
+#else
+#define LLVM_NOEXCEPT
+#endif
+
/// \brief Does the compiler support r-value reference *this?
///
/// Sadly, this is separate from just r-value reference support because GCC
diff --git a/include/llvm/Support/ConvertUTF.h b/include/llvm/Support/ConvertUTF.h
index 2820366..a184d0d 100644
--- a/include/llvm/Support/ConvertUTF.h
+++ b/include/llvm/Support/ConvertUTF.h
@@ -136,7 +136,19 @@ ConversionResult ConvertUTF8toUTF16 (
const UTF8** sourceStart, const UTF8* sourceEnd,
UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags);
-ConversionResult ConvertUTF8toUTF32 (
+/**
+ * Convert a partial UTF8 sequence to UTF32. If the sequence ends in an
+ * incomplete code unit sequence, returns \c sourceExhausted.
+ */
+ConversionResult ConvertUTF8toUTF32Partial(
+ const UTF8** sourceStart, const UTF8* sourceEnd,
+ UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags);
+
+/**
+ * Convert a partial UTF8 sequence to UTF32. If the sequence ends in an
+ * incomplete code unit sequence, returns \c sourceIllegal.
+ */
+ConversionResult ConvertUTF8toUTF32(
const UTF8** sourceStart, const UTF8* sourceEnd,
UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags);
diff --git a/include/llvm/Support/CrashRecoveryContext.h b/include/llvm/Support/CrashRecoveryContext.h
index c132373..3869ebd 100644
--- a/include/llvm/Support/CrashRecoveryContext.h
+++ b/include/llvm/Support/CrashRecoveryContext.h
@@ -87,6 +87,9 @@ public:
/// requested stack size).
///
/// See RunSafely() and llvm_execute_on_thread().
+ ///
+ /// On Darwin, if PRIO_DARWIN_BG is set on the calling thread, it will be
+ /// propagated to the new thread as well.
bool RunSafelyOnThread(function_ref<void()>, unsigned RequestedStackSize = 0);
bool RunSafelyOnThread(void (*Fn)(void*), void *UserData,
unsigned RequestedStackSize = 0) {
diff --git a/include/llvm/Support/DataTypes.h.cmake b/include/llvm/Support/DataTypes.h.cmake
index a26070c..1f0c8eb 100644
--- a/include/llvm/Support/DataTypes.h.cmake
+++ b/include/llvm/Support/DataTypes.h.cmake
@@ -37,6 +37,16 @@
#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
@@ -55,14 +65,6 @@
/* Note that <inttypes.h> includes <stdint.h>, if this is a C99 system. */
#include <sys/types.h>
-#ifdef HAVE_INTTYPES_H
-#include <inttypes.h>
-#endif
-
-#ifdef HAVE_STDINT_H
-#include <stdint.h>
-#endif
-
#ifdef _AIX
#include "llvm/Support/AIXDataTypesFix.h"
#endif
@@ -77,11 +79,6 @@ typedef u_int64_t uint64_t;
#endif
#else /* _MSC_VER */
-/* Visual C++ doesn't provide standard integer headers, but it does provide
- built-in data types. */
-#ifdef HAVE_STDINT_H
-#include <stdint.h>
-#endif
#include <stdlib.h>
#include <stddef.h>
#include <sys/types.h>
@@ -90,93 +87,21 @@ typedef u_int64_t uint64_t;
#else
#include <math.h>
#endif
-typedef __int64 int64_t;
-typedef unsigned __int64 uint64_t;
-typedef signed int int32_t;
-typedef unsigned int uint32_t;
-typedef short int16_t;
-typedef unsigned short uint16_t;
-typedef signed char int8_t;
-typedef unsigned char uint8_t;
+
#if defined(_WIN64)
- typedef signed __int64 ssize_t;
+typedef signed __int64 ssize_t;
#else
- typedef signed int ssize_t;
-#endif
-#ifndef INT8_MAX
-# define INT8_MAX 127
-#endif
-#ifndef INT8_MIN
-# define INT8_MIN -128
-#endif
-#ifndef UINT8_MAX
-# define UINT8_MAX 255
-#endif
-#ifndef INT16_MAX
-# define INT16_MAX 32767
-#endif
-#ifndef INT16_MIN
-# define INT16_MIN -32768
-#endif
-#ifndef UINT16_MAX
-# define UINT16_MAX 65535
-#endif
-#ifndef INT32_MAX
-# define INT32_MAX 2147483647
-#endif
-#ifndef INT32_MIN
-/* MSC treats -2147483648 as -(2147483648U). */
-# define INT32_MIN (-INT32_MAX - 1)
-#endif
-#ifndef UINT32_MAX
-# define UINT32_MAX 4294967295U
-#endif
-/* Certain compatibility updates to VC++ introduce the `cstdint'
- * header, which defines the INT*_C macros. On default installs they
- * are absent. */
-#ifndef INT8_C
-# define INT8_C(C) C##i8
-#endif
-#ifndef UINT8_C
-# define UINT8_C(C) C##ui8
-#endif
-#ifndef INT16_C
-# define INT16_C(C) C##i16
-#endif
-#ifndef UINT16_C
-# define UINT16_C(C) C##ui16
-#endif
-#ifndef INT32_C
-# define INT32_C(C) C##i32
-#endif
-#ifndef UINT32_C
-# define UINT32_C(C) C##ui32
-#endif
-#ifndef INT64_C
-# define INT64_C(C) C##i64
-#endif
-#ifndef UINT64_C
-# define UINT64_C(C) C##ui64
-#endif
-
-#ifndef PRId64
-# define PRId64 "I64d"
-#endif
-#ifndef PRIi64
-# define PRIi64 "I64i"
-#endif
-#ifndef PRIo64
-# define PRIo64 "I64o"
-#endif
-#ifndef PRIu64
-# define PRIu64 "I64u"
-#endif
-#ifndef PRIx64
-# define PRIx64 "I64x"
-#endif
-#ifndef PRIX64
-# define PRIX64 "I64X"
-#endif
+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 */
diff --git a/include/llvm/Support/DataTypes.h.in b/include/llvm/Support/DataTypes.h.in
index 7fc9b72..09cfcdf 100644
--- a/include/llvm/Support/DataTypes.h.in
+++ b/include/llvm/Support/DataTypes.h.in
@@ -37,6 +37,16 @@
#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
@@ -55,14 +65,6 @@
/* Note that <inttypes.h> includes <stdint.h>, if this is a C99 system. */
#include <sys/types.h>
-#ifdef HAVE_INTTYPES_H
-#include <inttypes.h>
-#endif
-
-#ifdef HAVE_STDINT_H
-#include <stdint.h>
-#endif
-
#ifdef _AIX
#include "llvm/Support/AIXDataTypesFix.h"
#endif
@@ -77,8 +79,6 @@ typedef u_int64_t uint64_t;
#endif
#else /* _MSC_VER */
-/* Visual C++ doesn't provide standard integer headers, but it does provide
- built-in data types. */
#include <stdlib.h>
#include <stddef.h>
#include <sys/types.h>
@@ -87,94 +87,21 @@ typedef u_int64_t uint64_t;
#else
#include <math.h>
#endif
-typedef __int64 int64_t;
-typedef unsigned __int64 uint64_t;
-typedef signed int int32_t;
-typedef unsigned int uint32_t;
-typedef short int16_t;
-typedef unsigned short uint16_t;
-typedef signed char int8_t;
-typedef unsigned char uint8_t;
+
#if defined(_WIN64)
- typedef signed __int64 ssize_t;
+typedef signed __int64 ssize_t;
#else
- typedef signed int ssize_t;
-#endif
-
-#ifndef INT8_MAX
-# define INT8_MAX 127
-#endif
-#ifndef INT8_MIN
-# define INT8_MIN -128
-#endif
-#ifndef UINT8_MAX
-# define UINT8_MAX 255
-#endif
-#ifndef INT16_MAX
-# define INT16_MAX 32767
-#endif
-#ifndef INT16_MIN
-# define INT16_MIN -32768
-#endif
-#ifndef UINT16_MAX
-# define UINT16_MAX 65535
-#endif
-#ifndef INT32_MAX
-# define INT32_MAX 2147483647
-#endif
-#ifndef INT32_MIN
-/* MSC treats -2147483648 as -(2147483648U). */
-# define INT32_MIN (-INT32_MAX - 1)
-#endif
-#ifndef UINT32_MAX
-# define UINT32_MAX 4294967295U
-#endif
-/* Certain compatibility updates to VC++ introduce the `cstdint'
- * header, which defines the INT*_C macros. On default installs they
- * are absent. */
-#ifndef INT8_C
-# define INT8_C(C) C##i8
-#endif
-#ifndef UINT8_C
-# define UINT8_C(C) C##ui8
-#endif
-#ifndef INT16_C
-# define INT16_C(C) C##i16
-#endif
-#ifndef UINT16_C
-# define UINT16_C(C) C##ui16
-#endif
-#ifndef INT32_C
-# define INT32_C(C) C##i32
-#endif
-#ifndef UINT32_C
-# define UINT32_C(C) C##ui32
-#endif
-#ifndef INT64_C
-# define INT64_C(C) C##i64
-#endif
-#ifndef UINT64_C
-# define UINT64_C(C) C##ui64
-#endif
-
-#ifndef PRId64
-# define PRId64 "I64d"
-#endif
-#ifndef PRIi64
-# define PRIi64 "I64i"
-#endif
-#ifndef PRIo64
-# define PRIo64 "I64o"
-#endif
-#ifndef PRIu64
-# define PRIu64 "I64u"
-#endif
-#ifndef PRIx64
-# define PRIx64 "I64x"
-#endif
-#ifndef PRIX64
-# define PRIX64 "I64X"
-#endif
+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 */
diff --git a/include/llvm/Support/Dwarf.h b/include/llvm/Support/Dwarf.h
index ca31644..cd9f756 100644
--- a/include/llvm/Support/Dwarf.h
+++ b/include/llvm/Support/Dwarf.h
@@ -57,7 +57,6 @@ enum LLVMConstants : uint32_t {
DW_TAG_user_base = 0x1000, // Recommended base for user tags.
DWARF_VERSION = 4, // Default dwarf version we output.
- DW_CIE_VERSION = 1, // Common frame information version.
DW_PUBTYPES_VERSION = 2, // Section version number for .debug_pubtypes.
DW_PUBNAMES_VERSION = 2, // Section version number for .debug_pubnames.
DW_ARANGES_VERSION = 2 // Section version number for .debug_aranges.
diff --git a/include/llvm/Support/ELF.h b/include/llvm/Support/ELF.h
index 0b3e55b..67cc651 100644
--- a/include/llvm/Support/ELF.h
+++ b/include/llvm/Support/ELF.h
@@ -124,6 +124,8 @@ enum {
};
// Machine architectures
+// See current registered ELF machine architectures at:
+// http://www.uxsglobal.com/developers/gabi/latest/ch4.eheader.html
enum {
EM_NONE = 0, // No machine
EM_M32 = 1, // AT&T WE 32100
@@ -287,7 +289,26 @@ enum {
EM_RL78 = 197, // Renesas RL78 family
EM_VIDEOCORE5 = 198, // Broadcom VideoCore V processor
EM_78KOR = 199, // Renesas 78KOR family
- EM_56800EX = 200 // Freescale 56800EX Digital Signal Controller (DSC)
+ EM_56800EX = 200, // Freescale 56800EX Digital Signal Controller (DSC)
+ EM_BA1 = 201, // Beyond BA1 CPU architecture
+ EM_BA2 = 202, // Beyond BA2 CPU architecture
+ EM_XCORE = 203, // XMOS xCORE processor family
+ EM_MCHP_PIC = 204, // Microchip 8-bit PIC(r) family
+ EM_INTEL205 = 205, // Reserved by Intel
+ EM_INTEL206 = 206, // Reserved by Intel
+ EM_INTEL207 = 207, // Reserved by Intel
+ EM_INTEL208 = 208, // Reserved by Intel
+ EM_INTEL209 = 209, // Reserved by Intel
+ EM_KM32 = 210, // KM211 KM32 32-bit processor
+ EM_KMX32 = 211, // KM211 KMX32 32-bit processor
+ EM_KMX16 = 212, // KM211 KMX16 16-bit processor
+ EM_KMX8 = 213, // KM211 KMX8 8-bit processor
+ EM_KVARC = 214, // KM211 KVARC processor
+ EM_CDP = 215, // Paneve CDP architecture family
+ EM_COGE = 216, // Cognitive Smart Memory Processor
+ EM_COOL = 217, // iCelero CoolEngine
+ EM_NORC = 218, // Nanoradio Optimized RISC
+ EM_CSR_KALIMBA = 219 // CSR Kalimba architecture family
};
// Object file classes.
@@ -1278,6 +1299,7 @@ enum : unsigned {
SHT_MIPS_REGINFO = 0x70000006, // Register usage information
SHT_MIPS_OPTIONS = 0x7000000d, // General options
+ SHT_MIPS_ABIFLAGS = 0x7000002a, // ABI information.
SHT_HIPROC = 0x7fffffff, // Highest processor arch-specific type.
SHT_LOUSER = 0x80000000, // Lowest type reserved for applications.
@@ -1595,7 +1617,8 @@ enum {
// MIPS program header types.
PT_MIPS_REGINFO = 0x70000000, // Register usage information.
PT_MIPS_RTPROC = 0x70000001, // Runtime procedure table.
- PT_MIPS_OPTIONS = 0x70000002 // Options segment.
+ PT_MIPS_OPTIONS = 0x70000002, // Options segment.
+ PT_MIPS_ABIFLAGS = 0x70000003 // Abiflags segment.
};
// Segment flag bits.
diff --git a/include/llvm/Support/Endian.h b/include/llvm/Support/Endian.h
index 2c5ab74..455d0fc 100644
--- a/include/llvm/Support/Endian.h
+++ b/include/llvm/Support/Endian.h
@@ -38,7 +38,7 @@ namespace endian {
template<typename value_type, endianness endian>
inline value_type byte_swap(value_type value) {
if (endian != native && sys::IsBigEndianHost != (endian == big))
- return sys::SwapByteOrder(value);
+ sys::swapByteOrder(value);
return value;
}
diff --git a/include/llvm/Support/Errc.h b/include/llvm/Support/Errc.h
new file mode 100644
index 0000000..80bfe2a
--- /dev/null
+++ b/include/llvm/Support/Errc.h
@@ -0,0 +1,86 @@
+//===- llvm/Support/Errc.h - Defines the llvm::errc enum --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// While std::error_code works OK on all platforms we use, there are some
+// some problems with std::errc that can be avoided by using our own
+// enumeration:
+//
+// * std::errc is a namespace in some implementations. That meas that ADL
+// doesn't work and it is sometimes necessary to write std::make_error_code
+// or in templates:
+// using std::make_error_code;
+// make_error_code(...);
+//
+// with this enum it is safe to always just use make_error_code.
+//
+// * Some implementations define fewer names than others. This header has
+// the intersection of all the ones we support.
+//
+// * std::errc is just marked with is_error_condition_enum. This means that
+// common patters like AnErrorCode == errc::no_such_file_or_directory take
+// 4 virtual calls instead of two comparisons.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_ERRC_H
+#define LLVM_SUPPORT_ERRC_H
+
+#include <system_error>
+
+namespace llvm {
+enum class errc {
+ argument_list_too_long = int(std::errc::argument_list_too_long),
+ argument_out_of_domain = int(std::errc::argument_out_of_domain),
+ bad_address = int(std::errc::bad_address),
+ bad_file_descriptor = int(std::errc::bad_file_descriptor),
+ broken_pipe = int(std::errc::broken_pipe),
+ device_or_resource_busy = int(std::errc::device_or_resource_busy),
+ directory_not_empty = int(std::errc::directory_not_empty),
+ executable_format_error = int(std::errc::executable_format_error),
+ file_exists = int(std::errc::file_exists),
+ file_too_large = int(std::errc::file_too_large),
+ filename_too_long = int(std::errc::filename_too_long),
+ function_not_supported = int(std::errc::function_not_supported),
+ illegal_byte_sequence = int(std::errc::illegal_byte_sequence),
+ inappropriate_io_control_operation =
+ int(std::errc::inappropriate_io_control_operation),
+ interrupted = int(std::errc::interrupted),
+ invalid_argument = int(std::errc::invalid_argument),
+ invalid_seek = int(std::errc::invalid_seek),
+ io_error = int(std::errc::io_error),
+ is_a_directory = int(std::errc::is_a_directory),
+ no_child_process = int(std::errc::no_child_process),
+ no_lock_available = int(std::errc::no_lock_available),
+ no_space_on_device = int(std::errc::no_space_on_device),
+ no_such_device_or_address = int(std::errc::no_such_device_or_address),
+ no_such_device = int(std::errc::no_such_device),
+ no_such_file_or_directory = int(std::errc::no_such_file_or_directory),
+ no_such_process = int(std::errc::no_such_process),
+ not_a_directory = int(std::errc::not_a_directory),
+ not_enough_memory = int(std::errc::not_enough_memory),
+ operation_not_permitted = int(std::errc::operation_not_permitted),
+ permission_denied = int(std::errc::permission_denied),
+ read_only_file_system = int(std::errc::read_only_file_system),
+ resource_deadlock_would_occur = int(std::errc::resource_deadlock_would_occur),
+ resource_unavailable_try_again =
+ int(std::errc::resource_unavailable_try_again),
+ result_out_of_range = int(std::errc::result_out_of_range),
+ too_many_files_open_in_system = int(std::errc::too_many_files_open_in_system),
+ too_many_files_open = int(std::errc::too_many_files_open),
+ too_many_links = int(std::errc::too_many_links)
+};
+
+inline std::error_code make_error_code(errc E) {
+ return std::error_code(static_cast<int>(E), std::generic_category());
+}
+}
+
+namespace std {
+template <> struct is_error_code_enum<llvm::errc> : std::true_type {};
+}
+#endif
diff --git a/include/llvm/Support/ErrorHandling.h b/include/llvm/Support/ErrorHandling.h
index ac3a4d8..9afd52d 100644
--- a/include/llvm/Support/ErrorHandling.h
+++ b/include/llvm/Support/ErrorHandling.h
@@ -30,9 +30,6 @@ namespace llvm {
/// install_fatal_error_handler - Installs a new error handler to be used
/// whenever a serious (non-recoverable) error is encountered by LLVM.
///
- /// If you are using llvm_start_multithreaded, you should register the handler
- /// before doing that.
- ///
/// If no error handler is installed the default is to print the error message
/// to stderr, and call exit(1). If an error handler is installed then it is
/// the handler's responsibility to log the message, it will no longer be
@@ -50,8 +47,6 @@ namespace llvm {
void *user_data = nullptr);
/// Restores default error handling behaviour.
- /// This must not be called between llvm_start_multithreaded() and
- /// llvm_stop_multithreaded().
void remove_fatal_error_handler();
/// ScopedFatalErrorHandler - This is a simple helper class which just
diff --git a/include/llvm/Support/ErrorOr.h b/include/llvm/Support/ErrorOr.h
index becd957..0742a2d 100644
--- a/include/llvm/Support/ErrorOr.h
+++ b/include/llvm/Support/ErrorOr.h
@@ -18,8 +18,8 @@
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/Support/AlignOf.h"
-#include "llvm/Support/system_error.h"
#include <cassert>
+#include <system_error>
#include <type_traits>
namespace llvm {
@@ -94,15 +94,16 @@ private:
public:
template <class E>
- ErrorOr(E ErrorCode, typename std::enable_if<is_error_code_enum<E>::value ||
- is_error_condition_enum<E>::value,
- void *>::type = 0)
+ ErrorOr(E ErrorCode,
+ typename std::enable_if<std::is_error_code_enum<E>::value ||
+ std::is_error_condition_enum<E>::value,
+ void *>::type = 0)
: HasError(true) {
- new (getErrorStorage()) error_code(make_error_code(ErrorCode));
+ new (getErrorStorage()) std::error_code(make_error_code(ErrorCode));
}
- ErrorOr(llvm::error_code EC) : HasError(true) {
- new (getErrorStorage()) error_code(EC);
+ ErrorOr(std::error_code EC) : HasError(true) {
+ new (getErrorStorage()) std::error_code(EC);
}
ErrorOr(T Val) : HasError(false) {
@@ -162,8 +163,8 @@ public:
reference get() { return *getStorage(); }
const_reference get() const { return const_cast<ErrorOr<T> >(this)->get(); }
- error_code getError() const {
- return HasError ? *getErrorStorage() : error_code::success();
+ std::error_code getError() const {
+ return HasError ? *getErrorStorage() : std::error_code();
}
pointer operator ->() {
@@ -184,7 +185,7 @@ private:
} else {
// Get other's error.
HasError = true;
- new (getErrorStorage()) error_code(Other.getError());
+ new (getErrorStorage()) std::error_code(Other.getError());
}
}
@@ -216,7 +217,7 @@ private:
} else {
// Get other's error.
HasError = true;
- new (getErrorStorage()) error_code(Other.getError());
+ new (getErrorStorage()) std::error_code(Other.getError());
}
}
@@ -247,28 +248,29 @@ private:
return reinterpret_cast<const storage_type*>(TStorage.buffer);
}
- error_code *getErrorStorage() {
+ std::error_code *getErrorStorage() {
assert(HasError && "Cannot get error when a value exists!");
- return reinterpret_cast<error_code*>(ErrorStorage.buffer);
+ return reinterpret_cast<std::error_code *>(ErrorStorage.buffer);
}
- const error_code *getErrorStorage() const {
+ const std::error_code *getErrorStorage() const {
return const_cast<ErrorOr<T> *>(this)->getErrorStorage();
}
union {
AlignedCharArrayUnion<storage_type> TStorage;
- AlignedCharArrayUnion<error_code> ErrorStorage;
+ AlignedCharArrayUnion<std::error_code> ErrorStorage;
};
bool HasError : 1;
};
-template<class T, class E>
-typename std::enable_if<is_error_code_enum<E>::value ||
- is_error_condition_enum<E>::value, bool>::type
-operator ==(ErrorOr<T> &Err, E Code) {
- return error_code(Err) == Code;
+template <class T, class E>
+typename std::enable_if<std::is_error_code_enum<E>::value ||
+ std::is_error_condition_enum<E>::value,
+ bool>::type
+operator==(ErrorOr<T> &Err, E Code) {
+ return std::error_code(Err) == Code;
}
} // end namespace llvm
diff --git a/include/llvm/Support/FEnv.h b/include/llvm/Support/FEnv.h
deleted file mode 100644
index 8560ee0..0000000
--- a/include/llvm/Support/FEnv.h
+++ /dev/null
@@ -1,56 +0,0 @@
-//===- llvm/Support/FEnv.h - Host floating-point exceptions ------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file provides an operating system independent interface to
-// floating-point exception interfaces.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SUPPORT_FENV_H
-#define LLVM_SUPPORT_FENV_H
-
-#include "llvm/Config/config.h"
-#include <cerrno>
-#ifdef HAVE_FENV_H
-#include <fenv.h>
-#endif
-
-// FIXME: Clang's #include handling apparently doesn't work for libstdc++'s
-// fenv.h; see PR6907 for details.
-#if defined(__clang__) && defined(_GLIBCXX_FENV_H)
-#undef HAVE_FENV_H
-#endif
-
-namespace llvm {
-namespace sys {
-
-/// llvm_fenv_clearexcept - Clear the floating-point exception state.
-static inline void llvm_fenv_clearexcept() {
-#if defined(HAVE_FENV_H) && HAVE_DECL_FE_ALL_EXCEPT
- feclearexcept(FE_ALL_EXCEPT);
-#endif
- errno = 0;
-}
-
-/// llvm_fenv_testexcept - Test if a floating-point exception was raised.
-static inline bool llvm_fenv_testexcept() {
- int errno_val = errno;
- if (errno_val == ERANGE || errno_val == EDOM)
- return true;
-#if defined(HAVE_FENV_H) && HAVE_DECL_FE_ALL_EXCEPT && HAVE_DECL_FE_INEXACT
- if (fetestexcept(FE_ALL_EXCEPT & ~FE_INEXACT))
- return true;
-#endif
- return false;
-}
-
-} // End sys namespace
-} // End llvm namespace
-
-#endif
diff --git a/include/llvm/Support/FileOutputBuffer.h b/include/llvm/Support/FileOutputBuffer.h
index a8a48fa..0a9a979 100644
--- a/include/llvm/Support/FileOutputBuffer.h
+++ b/include/llvm/Support/FileOutputBuffer.h
@@ -20,8 +20,6 @@
#include "llvm/Support/FileSystem.h"
namespace llvm {
-class error_code;
-
/// FileOutputBuffer - This interface provides simple way to create an in-memory
/// buffer which will be written to a file. During the lifetime of these
/// objects, the content or existence of the specified file is undefined. That
@@ -39,9 +37,9 @@ public:
/// Factory method to create an OutputBuffer object which manages a read/write
/// buffer of the specified size. When committed, the buffer will be written
/// to the file at the specified path.
- static error_code create(StringRef FilePath, size_t Size,
- std::unique_ptr<FileOutputBuffer> &Result,
- unsigned Flags = 0);
+ static std::error_code create(StringRef FilePath, size_t Size,
+ std::unique_ptr<FileOutputBuffer> &Result,
+ unsigned Flags = 0);
/// Returns a pointer to the start of the buffer.
uint8_t *getBufferStart() {
@@ -68,7 +66,7 @@ public:
/// is called, the file is deleted in the destructor. The optional parameter
/// is used if it turns out you want the file size to be smaller than
/// initially requested.
- error_code commit(int64_t NewSmallerSize = -1);
+ std::error_code commit(int64_t NewSmallerSize = -1);
/// If this object was previously committed, the destructor just deletes
/// this object. If this object was not committed, the destructor
diff --git a/include/llvm/Support/FileSystem.h b/include/llvm/Support/FileSystem.h
index 806a3e3..556701c 100644
--- a/include/llvm/Support/FileSystem.h
+++ b/include/llvm/Support/FileSystem.h
@@ -33,11 +33,11 @@
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/TimeValue.h"
-#include "llvm/Support/system_error.h"
#include <ctime>
#include <iterator>
#include <stack>
#include <string>
+#include <system_error>
#include <tuple>
#include <vector>
@@ -49,26 +49,18 @@ namespace llvm {
namespace sys {
namespace fs {
-/// An "enum class" enumeration for the file system's view of the type.
-struct file_type {
- enum Impl {
- status_error,
- file_not_found,
- regular_file,
- directory_file,
- symlink_file,
- block_file,
- character_file,
- fifo_file,
- socket_file,
- type_unknown
- };
-
- file_type(Impl V) : V(V) {}
- operator Impl() const { return V; }
-
-private:
- Impl V;
+/// An enumeration for the file system's view of the type.
+enum class file_type {
+ status_error,
+ file_not_found,
+ regular_file,
+ directory_file,
+ symlink_file,
+ block_file,
+ character_file,
+ fifo_file,
+ socket_file,
+ type_unknown
};
/// space_info - Self explanatory.
@@ -142,7 +134,7 @@ public:
};
/// file_status - Represents the result of a call to stat and friends. It has
-/// a platform specific member to store the result.
+/// a platform-specific member to store the result.
class file_status
{
#if defined(LLVM_ON_UNIX)
@@ -281,8 +273,8 @@ private:
///
/// @param path A path that is modified to be an absolute path.
/// @returns errc::success if \a path has been made absolute, otherwise a
-/// platform specific error_code.
-error_code make_absolute(SmallVectorImpl<char> &path);
+/// platform-specific error_code.
+std::error_code make_absolute(SmallVectorImpl<char> &path);
/// @brief Normalize path separators in \a Path
///
@@ -290,7 +282,7 @@ error_code make_absolute(SmallVectorImpl<char> &path);
/// This is particularly useful when cross-compiling Windows on Linux, but is
/// safe to invoke on Windows, which accepts both characters as a path
/// separator.
-error_code normalize_separators(SmallVectorImpl<char> &Path);
+std::error_code normalize_separators(SmallVectorImpl<char> &Path);
/// @brief Create all the non-existent directories in path.
///
@@ -298,7 +290,8 @@ error_code normalize_separators(SmallVectorImpl<char> &Path);
/// @returns errc::success if is_directory(path), otherwise a platform
/// specific error_code. If IgnoreExisting is false, also returns
/// error if the directory already existed.
-error_code create_directories(const Twine &path, bool IgnoreExisting = true);
+std::error_code create_directories(const Twine &path,
+ bool IgnoreExisting = true);
/// @brief Create the directory in path.
///
@@ -306,7 +299,7 @@ error_code create_directories(const Twine &path, bool IgnoreExisting = true);
/// @returns errc::success if is_directory(path), otherwise a platform
/// specific error_code. If IgnoreExisting is false, also returns
/// error if the directory already existed.
-error_code create_directory(const Twine &path, bool IgnoreExisting = true);
+std::error_code create_directory(const Twine &path, bool IgnoreExisting = true);
/// @brief Create a link from \a from to \a to.
///
@@ -319,36 +312,42 @@ error_code create_directory(const Twine &path, bool IgnoreExisting = true);
/// @param from The path to hard link from. This is created.
/// @returns errc::success if the link was created, otherwise a platform
/// specific error_code.
-error_code create_link(const Twine &to, const Twine &from);
+std::error_code create_link(const Twine &to, const Twine &from);
/// @brief Get the current path.
///
/// @param result Holds the current path on return.
/// @returns errc::success if the current path has been stored in result,
-/// otherwise a platform specific error_code.
-error_code current_path(SmallVectorImpl<char> &result);
+/// otherwise a platform-specific error_code.
+std::error_code current_path(SmallVectorImpl<char> &result);
/// @brief Remove path. Equivalent to POSIX remove().
///
/// @param path Input path.
/// @returns errc::success if path has been removed or didn't exist, otherwise a
-/// platform specific error code. If IgnoreNonExisting is false, also
+/// platform-specific error code. If IgnoreNonExisting is false, also
/// returns error if the file didn't exist.
-error_code remove(const Twine &path, bool IgnoreNonExisting = true);
+std::error_code remove(const Twine &path, bool IgnoreNonExisting = true);
/// @brief Rename \a from to \a to. Files are renamed as if by POSIX rename().
///
/// @param from The path to rename from.
/// @param to The path to rename to. This is created.
-error_code rename(const Twine &from, const Twine &to);
+std::error_code rename(const Twine &from, const Twine &to);
+
+/// @brief Copy the contents of \a From to \a To.
+///
+/// @param From The path to copy from.
+/// @param To The path to copy to. This is created.
+std::error_code copy_file(const Twine &From, const Twine &To);
/// @brief Resize path to size. File is resized as if by POSIX truncate().
///
/// @param path Input path.
/// @param size Size to resize to.
/// @returns errc::success if \a path has been resized to \a size, otherwise a
-/// platform specific error_code.
-error_code resize_file(const Twine &path, uint64_t size);
+/// platform-specific error_code.
+std::error_code resize_file(const Twine &path, uint64_t size);
/// @}
/// @name Physical Observers
@@ -367,8 +366,8 @@ bool exists(file_status status);
/// @param result Set to true if the file represented by status exists, false if
/// it does not. Undefined otherwise.
/// @returns errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code exists(const Twine &path, bool &result);
+/// platform-specific error_code.
+std::error_code exists(const Twine &path, bool &result);
/// @brief Simpler version of exists for clients that don't need to
/// differentiate between an error and false.
@@ -409,8 +408,8 @@ bool equivalent(file_status A, file_status B);
/// @param result Set to true if stat(A) and stat(B) have the same device and
/// inode (or equivalent).
/// @returns errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code equivalent(const Twine &A, const Twine &B, bool &result);
+/// platform-specific error_code.
+std::error_code equivalent(const Twine &A, const Twine &B, bool &result);
/// @brief Simpler version of equivalent for clients that don't need to
/// differentiate between an error and false.
@@ -431,8 +430,8 @@ bool is_directory(file_status status);
/// @param result Set to true if \a path is a directory, false if it is not.
/// Undefined otherwise.
/// @returns errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code is_directory(const Twine &path, bool &result);
+/// platform-specific error_code.
+std::error_code is_directory(const Twine &path, bool &result);
/// @brief Simpler version of is_directory for clients that don't need to
/// differentiate between an error and false.
@@ -453,8 +452,8 @@ bool is_regular_file(file_status status);
/// @param result Set to true if \a path is a regular file, false if it is not.
/// Undefined otherwise.
/// @returns errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code is_regular_file(const Twine &path, bool &result);
+/// platform-specific error_code.
+std::error_code is_regular_file(const Twine &path, bool &result);
/// @brief Simpler version of is_regular_file for clients that don't need to
/// differentiate between an error and false.
@@ -479,41 +478,41 @@ bool is_other(file_status status);
/// @param result Set to true if \a path exists, but is not a directory, regular
/// file, or a symlink, false if it does not. Undefined otherwise.
/// @returns errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code is_other(const Twine &path, bool &result);
+/// platform-specific error_code.
+std::error_code is_other(const Twine &path, bool &result);
/// @brief Get file status as if by POSIX stat().
///
/// @param path Input path.
/// @param result Set to the file status.
/// @returns errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code status(const Twine &path, file_status &result);
+/// platform-specific error_code.
+std::error_code status(const Twine &path, file_status &result);
/// @brief A version for when a file descriptor is already available.
-error_code status(int FD, file_status &Result);
+std::error_code status(int FD, file_status &Result);
/// @brief Get file size.
///
/// @param Path Input path.
/// @param Result Set to the size of the file in \a Path.
/// @returns errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-inline error_code file_size(const Twine &Path, uint64_t &Result) {
+/// platform-specific error_code.
+inline std::error_code file_size(const Twine &Path, uint64_t &Result) {
file_status Status;
- error_code EC = status(Path, Status);
+ std::error_code EC = status(Path, Status);
if (EC)
return EC;
Result = Status.getSize();
- return error_code::success();
+ return std::error_code();
}
/// @brief Set the file modification and access time.
///
/// @returns errc::success if the file times were successfully set, otherwise a
-/// platform specific error_code or errc::not_supported on platforms
-/// where the functionality isn't available.
-error_code setLastModificationAndAccessTime(int FD, TimeValue Time);
+/// platform-specific error_code or errc::function_not_supported on
+/// platforms where the functionality isn't available.
+std::error_code setLastModificationAndAccessTime(int FD, TimeValue Time);
/// @brief Is status available?
///
@@ -526,8 +525,8 @@ bool status_known(file_status s);
/// @param path Input path.
/// @param result Set to true if status() != status_error.
/// @returns errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code status_known(const Twine &path, bool &result);
+/// platform-specific error_code.
+std::error_code status_known(const Twine &path, bool &result);
/// @brief Create a uniquely named file.
///
@@ -549,14 +548,14 @@ error_code status_known(const Twine &path, bool &result);
/// @param ResultFD Set to the opened file's file descriptor.
/// @param ResultPath Set to the opened file's absolute path.
/// @returns errc::success if Result{FD,Path} have been successfully set,
-/// otherwise a platform specific error_code.
-error_code createUniqueFile(const Twine &Model, int &ResultFD,
- SmallVectorImpl<char> &ResultPath,
- unsigned Mode = all_read | all_write);
+/// otherwise a platform-specific error_code.
+std::error_code createUniqueFile(const Twine &Model, int &ResultFD,
+ SmallVectorImpl<char> &ResultPath,
+ unsigned Mode = all_read | all_write);
/// @brief Simpler version for clients that don't want an open file.
-error_code createUniqueFile(const Twine &Model,
- SmallVectorImpl<char> &ResultPath);
+std::error_code createUniqueFile(const Twine &Model,
+ SmallVectorImpl<char> &ResultPath);
/// @brief Create a file in the system temporary directory.
///
@@ -566,16 +565,16 @@ error_code createUniqueFile(const Twine &Model,
///
/// This should be used for things like a temporary .s that is removed after
/// running the assembler.
-error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix,
- int &ResultFD,
- SmallVectorImpl<char> &ResultPath);
+std::error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix,
+ int &ResultFD,
+ SmallVectorImpl<char> &ResultPath);
/// @brief Simpler version for clients that don't want an open file.
-error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix,
- SmallVectorImpl<char> &ResultPath);
+std::error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix,
+ SmallVectorImpl<char> &ResultPath);
-error_code createUniqueDirectory(const Twine &Prefix,
- SmallVectorImpl<char> &ResultPath);
+std::error_code createUniqueDirectory(const Twine &Prefix,
+ SmallVectorImpl<char> &ResultPath);
enum OpenFlags : unsigned {
F_None = 0,
@@ -606,31 +605,10 @@ inline OpenFlags &operator|=(OpenFlags &A, OpenFlags B) {
return A;
}
-error_code openFileForWrite(const Twine &Name, int &ResultFD, OpenFlags Flags,
- unsigned Mode = 0666);
+std::error_code openFileForWrite(const Twine &Name, int &ResultFD,
+ OpenFlags Flags, unsigned Mode = 0666);
-error_code openFileForRead(const Twine &Name, int &ResultFD);
-
-/// @brief Are \a path's first bytes \a magic?
-///
-/// @param path Input path.
-/// @param magic Byte sequence to compare \a path's first len(magic) bytes to.
-/// @returns errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code has_magic(const Twine &path, const Twine &magic, bool &result);
-
-/// @brief Get \a path's first \a len bytes.
-///
-/// @param path Input path.
-/// @param len Number of magic bytes to get.
-/// @param result Set to the first \a len bytes in the file pointed to by
-/// \a path. Or the entire file if file_size(path) < len, in which
-/// case result.size() returns the size of the file.
-/// @returns errc::success if result has been successfully set,
-/// errc::value_too_large if len is larger then the file pointed to by
-/// \a path, otherwise a platform specific error_code.
-error_code get_magic(const Twine &path, uint32_t len,
- SmallVectorImpl<char> &result);
+std::error_code openFileForRead(const Twine &Name, int &ResultFD);
/// @brief Identify the type of a binary file based on how magical it is.
file_magic identify_magic(StringRef magic);
@@ -640,10 +618,10 @@ file_magic identify_magic(StringRef magic);
/// @param path Input path.
/// @param result Set to the type of file, or file_magic::unknown.
/// @returns errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code identify_magic(const Twine &path, file_magic &result);
+/// platform-specific error_code.
+std::error_code identify_magic(const Twine &path, file_magic &result);
-error_code getUniqueID(const Twine Path, UniqueID &Result);
+std::error_code getUniqueID(const Twine Path, UniqueID &Result);
/// This class represents a memory mapped file. It is based on
/// boost::iostreams::mapped_file.
@@ -660,7 +638,7 @@ public:
};
private:
- /// Platform specific mapping state.
+ /// Platform-specific mapping state.
mapmode Mode;
uint64_t Size;
void *Mapping;
@@ -670,7 +648,7 @@ private:
void *FileMappingHandle;
#endif
- error_code init(int FD, bool CloseFD, uint64_t Offset);
+ std::error_code init(int FD, bool CloseFD, uint64_t Offset);
public:
typedef char char_type;
@@ -692,21 +670,14 @@ public:
/// mapped_file_region::alignment().
/// \param ec This is set to errc::success if the map was constructed
/// successfully. Otherwise it is set to a platform dependent error.
- mapped_file_region(const Twine &path,
- mapmode mode,
- uint64_t length,
- uint64_t offset,
- error_code &ec);
+ mapped_file_region(const Twine &path, mapmode mode, uint64_t length,
+ uint64_t offset, std::error_code &ec);
/// \param fd An open file descriptor to map. mapped_file_region takes
/// ownership if closefd is true. It must have been opended in the correct
/// mode.
- mapped_file_region(int fd,
- bool closefd,
- mapmode mode,
- uint64_t length,
- uint64_t offset,
- error_code &ec);
+ mapped_file_region(int fd, bool closefd, mapmode mode, uint64_t length,
+ uint64_t offset, std::error_code &ec);
~mapped_file_region();
@@ -722,30 +693,6 @@ public:
static int alignment();
};
-/// @brief Memory maps the contents of a file
-///
-/// @param path Path to file to map.
-/// @param file_offset Byte offset in file where mapping should begin.
-/// @param size Byte length of range of the file to map.
-/// @param map_writable If true, the file will be mapped in r/w such
-/// that changes to the mapped buffer will be flushed back
-/// to the file. If false, the file will be mapped read-only
-/// and the buffer will be read-only.
-/// @param result Set to the start address of the mapped buffer.
-/// @returns errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code map_file_pages(const Twine &path, off_t file_offset, size_t size,
- bool map_writable, void *&result);
-
-
-/// @brief Memory unmaps the contents of a file
-///
-/// @param base Pointer to the start of the buffer.
-/// @param size Byte length of the range to unmmap.
-/// @returns errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code unmap_file_pages(void *base, size_t size);
-
/// Return the path to the main executable, given the value of argv[0] from
/// program startup and the address of main itself. In extremis, this function
/// may fail and return an empty path.
@@ -777,7 +724,7 @@ public:
void replace_filename(const Twine &filename, file_status st = file_status());
const std::string &path() const { return Path; }
- error_code status(file_status &result) const;
+ std::error_code status(file_status &result) const;
bool operator==(const directory_entry& rhs) const { return Path == rhs.Path; }
bool operator!=(const directory_entry& rhs) const { return !(*this == rhs); }
@@ -790,9 +737,9 @@ public:
namespace detail {
struct DirIterState;
- error_code directory_iterator_construct(DirIterState&, StringRef);
- error_code directory_iterator_increment(DirIterState&);
- error_code directory_iterator_destruct(DirIterState&);
+ std::error_code directory_iterator_construct(DirIterState &, StringRef);
+ std::error_code directory_iterator_increment(DirIterState &);
+ std::error_code directory_iterator_destruct(DirIterState &);
/// DirIterState - Keeps state for the directory_iterator. It is reference
/// counted in order to preserve InputIterator semantics on copy.
@@ -816,14 +763,14 @@ class directory_iterator {
IntrusiveRefCntPtr<detail::DirIterState> State;
public:
- explicit directory_iterator(const Twine &path, error_code &ec) {
+ explicit directory_iterator(const Twine &path, std::error_code &ec) {
State = new detail::DirIterState;
SmallString<128> path_storage;
ec = detail::directory_iterator_construct(*State,
path.toStringRef(path_storage));
}
- explicit directory_iterator(const directory_entry &de, error_code &ec) {
+ explicit directory_iterator(const directory_entry &de, std::error_code &ec) {
State = new detail::DirIterState;
ec = detail::directory_iterator_construct(*State, de.path());
}
@@ -832,7 +779,7 @@ public:
directory_iterator() : State(nullptr) {}
// No operator++ because we need error_code.
- directory_iterator &increment(error_code &ec) {
+ directory_iterator &increment(std::error_code &ec) {
ec = directory_iterator_increment(*State);
return *this;
}
@@ -878,14 +825,14 @@ class recursive_directory_iterator {
public:
recursive_directory_iterator() {}
- explicit recursive_directory_iterator(const Twine &path, error_code &ec)
- : State(new detail::RecDirIterState) {
+ explicit recursive_directory_iterator(const Twine &path, std::error_code &ec)
+ : State(new detail::RecDirIterState) {
State->Stack.push(directory_iterator(path, ec));
if (State->Stack.top() == directory_iterator())
State.reset();
}
// No operator++ because we need error_code.
- recursive_directory_iterator &increment(error_code &ec) {
+ recursive_directory_iterator &increment(std::error_code &ec) {
const directory_iterator end_itr;
if (State->HasNoPushRequest)
@@ -934,7 +881,7 @@ public:
assert(State->Level > 0 && "Cannot pop an iterator with level < 1");
const directory_iterator end_itr;
- error_code ec;
+ std::error_code ec;
do {
if (ec)
report_fatal_error("Error incrementing directory iterator.");
diff --git a/include/llvm/Support/Format.h b/include/llvm/Support/Format.h
index a62801f..b713cc7 100644
--- a/include/llvm/Support/Format.h
+++ b/include/llvm/Support/Format.h
@@ -36,23 +36,23 @@
namespace llvm {
-/// format_object_base - This is a helper class used for handling formatted
-/// output. It is the abstract base class of a templated derived class.
+/// This is a helper class used for handling formatted output. It is the
+/// abstract base class of a templated derived class.
class format_object_base {
protected:
const char *Fmt;
virtual void home(); // Out of line virtual method.
- /// snprint - Call snprintf() for this object, on the given buffer and size.
+ /// Call snprintf() for this object, on the given buffer and size.
virtual int snprint(char *Buffer, unsigned BufferSize) const = 0;
public:
format_object_base(const char *fmt) : Fmt(fmt) {}
virtual ~format_object_base() {}
- /// print - Format the object into the specified buffer. On success, this
- /// returns the length of the formatted string. If the buffer is too small,
- /// this returns a length to retry with, which will be larger than BufferSize.
+ /// Format the object into the specified buffer. On success, this returns
+ /// the length of the formatted string. If the buffer is too small, this
+ /// returns a length to retry with, which will be larger than BufferSize.
unsigned print(char *Buffer, unsigned BufferSize) const {
assert(BufferSize && "Invalid buffer size!");
@@ -61,21 +61,23 @@ public:
// VC++ and old GlibC return negative on overflow, just double the size.
if (N < 0)
- return BufferSize*2;
+ return BufferSize * 2;
- // Other impls yield number of bytes needed, not including the final '\0'.
+ // Other implementations yield number of bytes needed, not including the
+ // final '\0'.
if (unsigned(N) >= BufferSize)
- return N+1;
+ return N + 1;
// Otherwise N is the length of output (not including the final '\0').
return N;
}
};
-/// format_object1 - This is a templated helper class used by the format
-/// function that captures the object to be formated and the format string. When
-/// actually printed, this synthesizes the string into a temporary buffer
-/// provided and returns whether or not it is big enough.
+/// These are templated helper classes used by the format function that
+/// capture the object to be formated and the format string. When actually
+/// printed, this synthesizes the string into a temporary buffer provided and
+/// returns whether or not it is big enough.
+
template <typename T>
class format_object1 : public format_object_base {
T Val;
@@ -89,10 +91,6 @@ public:
}
};
-/// format_object2 - This is a templated helper class used by the format
-/// function that captures the object to be formated and the format string. When
-/// actually printed, this synthesizes the string into a temporary buffer
-/// provided and returns whether or not it is big enough.
template <typename T1, typename T2>
class format_object2 : public format_object_base {
T1 Val1;
@@ -107,10 +105,6 @@ public:
}
};
-/// format_object3 - This is a templated helper class used by the format
-/// function that captures the object to be formated and the format string. When
-/// actually printed, this synthesizes the string into a temporary buffer
-/// provided and returns whether or not it is big enough.
template <typename T1, typename T2, typename T3>
class format_object3 : public format_object_base {
T1 Val1;
@@ -126,10 +120,6 @@ public:
}
};
-/// format_object4 - This is a templated helper class used by the format
-/// function that captures the object to be formated and the format string. When
-/// actually printed, this synthesizes the string into a temporary buffer
-/// provided and returns whether or not it is big enough.
template <typename T1, typename T2, typename T3, typename T4>
class format_object4 : public format_object_base {
T1 Val1;
@@ -147,10 +137,6 @@ public:
}
};
-/// format_object5 - This is a templated helper class used by the format
-/// function that captures the object to be formated and the format string. When
-/// actually printed, this synthesizes the string into a temporary buffer
-/// provided and returns whether or not it is big enough.
template <typename T1, typename T2, typename T3, typename T4, typename T5>
class format_object5 : public format_object_base {
T1 Val1;
@@ -170,47 +156,52 @@ public:
}
};
-/// This is a helper function that is used to produce formatted output.
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6>
+class format_object6 : public format_object_base {
+ T1 Val1;
+ T2 Val2;
+ T3 Val3;
+ T4 Val4;
+ T5 Val5;
+ T6 Val6;
+public:
+ format_object6(const char *Fmt, const T1 &Val1, const T2 &Val2,
+ const T3 &Val3, const T4 &Val4, const T5 &Val5, const T6 &Val6)
+ : format_object_base(Fmt), Val1(Val1), Val2(Val2), Val3(Val3), Val4(Val4),
+ Val5(Val5), Val6(Val6) { }
+
+ int snprint(char *Buffer, unsigned BufferSize) const override {
+ return snprintf(Buffer, BufferSize, Fmt, Val1, Val2, Val3, Val4, Val5, Val6);
+ }
+};
+
+/// These are helper functions used to produce formatted output. They use
+/// template type deduction to construct the appropriate instance of the
+/// format_object class to simplify their construction.
///
/// This is typically used like:
/// \code
/// OS << format("%0.4f", myfloat) << '\n';
/// \endcode
+
template <typename T>
inline format_object1<T> format(const char *Fmt, const T &Val) {
return format_object1<T>(Fmt, Val);
}
-/// This is a helper function that is used to produce formatted output.
-///
-/// This is typically used like:
-/// \code
-/// OS << format("%0.4f", myfloat) << '\n';
-/// \endcode
template <typename T1, typename T2>
inline format_object2<T1, T2> format(const char *Fmt, const T1 &Val1,
const T2 &Val2) {
return format_object2<T1, T2>(Fmt, Val1, Val2);
}
-/// This is a helper function that is used to produce formatted output.
-///
-/// This is typically used like:
-/// \code
-/// OS << format("%0.4f", myfloat) << '\n';
-/// \endcode
template <typename T1, typename T2, typename T3>
inline format_object3<T1, T2, T3> format(const char *Fmt, const T1 &Val1,
const T2 &Val2, const T3 &Val3) {
return format_object3<T1, T2, T3>(Fmt, Val1, Val2, Val3);
}
-/// This is a helper function that is used to produce formatted output.
-///
-/// This is typically used like:
-/// \code
-/// OS << format("%0.4f", myfloat) << '\n';
-/// \endcode
template <typename T1, typename T2, typename T3, typename T4>
inline format_object4<T1, T2, T3, T4> format(const char *Fmt, const T1 &Val1,
const T2 &Val2, const T3 &Val3,
@@ -218,12 +209,6 @@ inline format_object4<T1, T2, T3, T4> format(const char *Fmt, const T1 &Val1,
return format_object4<T1, T2, T3, T4>(Fmt, Val1, Val2, Val3, Val4);
}
-/// This is a helper function that is used to produce formatted output.
-///
-/// This is typically used like:
-/// \code
-/// OS << format("%0.4f", myfloat) << '\n';
-/// \endcode
template <typename T1, typename T2, typename T3, typename T4, typename T5>
inline format_object5<T1, T2, T3, T4, T5> format(const char *Fmt,const T1 &Val1,
const T2 &Val2, const T3 &Val3,
@@ -231,6 +216,15 @@ inline format_object5<T1, T2, T3, T4, T5> format(const char *Fmt,const T1 &Val1,
return format_object5<T1, T2, T3, T4, T5>(Fmt, Val1, Val2, Val3, Val4, Val5);
}
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6>
+inline format_object6<T1, T2, T3, T4, T5, T6>
+format(const char *Fmt, const T1 &Val1, const T2 &Val2, const T3 &Val3,
+ const T4 &Val4, const T5 &Val5, const T6 &Val6) {
+ return format_object6<T1, T2, T3, T4, T5, T6>(Fmt, Val1, Val2, Val3, Val4,
+ Val5, Val6);
+}
+
} // end namespace llvm
#endif
diff --git a/include/llvm/Support/GenericDomTree.h b/include/llvm/Support/GenericDomTree.h
index e344220..876ab6e 100644
--- a/include/llvm/Support/GenericDomTree.h
+++ b/include/llvm/Support/GenericDomTree.h
@@ -330,6 +330,10 @@ public:
return DomTreeNodes.lookup(BB);
}
+ inline DomTreeNodeBase<NodeT> *operator[](NodeT *BB) const {
+ return getNode(BB);
+ }
+
/// getRootNode - This returns the entry node for the CFG of the function. If
/// this tree represents the post-dominance relations for a function, however,
/// this root may be a node with the block == NULL. This is the case when
diff --git a/include/llvm/Support/GraphWriter.h b/include/llvm/Support/GraphWriter.h
index 539673a..2f02aa7 100644
--- a/include/llvm/Support/GraphWriter.h
+++ b/include/llvm/Support/GraphWriter.h
@@ -50,7 +50,7 @@ namespace GraphProgram {
};
}
-void DisplayGraph(StringRef Filename, bool wait = true,
+bool DisplayGraph(StringRef Filename, bool wait = true,
GraphProgram::Name program = GraphProgram::DOT);
template<typename GraphType>
diff --git a/include/llvm/Support/LockFileManager.h b/include/llvm/Support/LockFileManager.h
index 523a781..61c65da 100644
--- a/include/llvm/Support/LockFileManager.h
+++ b/include/llvm/Support/LockFileManager.h
@@ -12,11 +12,10 @@
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/system_error.h"
+#include <system_error>
#include <utility> // for std::pair
namespace llvm {
-
/// \brief Class that manages the creation of a lock file to aid
/// implicit coordination between different processes.
///
@@ -56,7 +55,7 @@ private:
SmallString<128> UniqueLockFileName;
Optional<std::pair<std::string, int> > Owner;
- Optional<error_code> Error;
+ Optional<std::error_code> Error;
LockFileManager(const LockFileManager &) LLVM_DELETED_FUNCTION;
LockFileManager &operator=(const LockFileManager &) LLVM_DELETED_FUNCTION;
diff --git a/include/llvm/Support/MachO.h b/include/llvm/Support/MachO.h
index 2a0fc7b..bd4dc2f 100644
--- a/include/llvm/Support/MachO.h
+++ b/include/llvm/Support/MachO.h
@@ -360,11 +360,28 @@ namespace llvm {
enum {
// Constant masks for the "n_desc" field in llvm::MachO::nlist and
// llvm::MachO::nlist_64
+ // The low 3 bits are the for the REFERENCE_TYPE.
+ REFERENCE_TYPE = 0x7,
+ REFERENCE_FLAG_UNDEFINED_NON_LAZY = 0,
+ REFERENCE_FLAG_UNDEFINED_LAZY = 1,
+ REFERENCE_FLAG_DEFINED = 2,
+ REFERENCE_FLAG_PRIVATE_DEFINED = 3,
+ REFERENCE_FLAG_PRIVATE_UNDEFINED_NON_LAZY = 4,
+ REFERENCE_FLAG_PRIVATE_UNDEFINED_LAZY = 5,
+ // Flag bits (some overlap with the library ordinal bits).
N_ARM_THUMB_DEF = 0x0008u,
+ REFERENCED_DYNAMICALLY = 0x0010u,
N_NO_DEAD_STRIP = 0x0020u,
N_WEAK_REF = 0x0040u,
N_WEAK_DEF = 0x0080u,
- N_SYMBOL_RESOLVER = 0x0100u
+ N_SYMBOL_RESOLVER = 0x0100u,
+ N_ALT_ENTRY = 0x0200u,
+ // For undefined symbols coming from libraries, see GET_LIBRARY_ORDINAL()
+ // as these are in the top 8 bits.
+ SELF_LIBRARY_ORDINAL = 0x0,
+ MAX_LIBRARY_ORDINAL = 0xfd,
+ DYNAMIC_LOOKUP_ORDINAL = 0xfe,
+ EXECUTABLE_ORDINAL = 0xff
};
enum StabType {
@@ -998,8 +1015,8 @@ namespace llvm {
enum : uint32_t {
// Capability bits used in the definition of cpusubtype.
- CPU_SUB_TYPE_MASK = 0xff000000, // Mask for architecture bits
- CPU_SUB_TYPE_LIB64 = 0x80000000, // 64 bit libraries
+ CPU_SUBTYPE_MASK = 0xff000000, // Mask for architecture bits
+ CPU_SUBTYPE_LIB64 = 0x80000000, // 64 bit libraries
// Special CPU subtype constants.
CPU_SUBTYPE_MULTIPLE = ~0u
diff --git a/include/llvm/Support/ManagedStatic.h b/include/llvm/Support/ManagedStatic.h
index 1bb8cea..d8fbfeb 100644
--- a/include/llvm/Support/ManagedStatic.h
+++ b/include/llvm/Support/ManagedStatic.h
@@ -103,9 +103,6 @@ void llvm_shutdown();
/// llvm_shutdown() when it is destroyed.
struct llvm_shutdown_obj {
llvm_shutdown_obj() { }
- explicit llvm_shutdown_obj(bool multithreaded) {
- if (multithreaded) llvm_start_multithreaded();
- }
~llvm_shutdown_obj() { llvm_shutdown(); }
};
diff --git a/include/llvm/Support/MathExtras.h b/include/llvm/Support/MathExtras.h
index f1f7b4f..0abba62 100644
--- a/include/llvm/Support/MathExtras.h
+++ b/include/llvm/Support/MathExtras.h
@@ -230,6 +230,9 @@ static const unsigned char BitReverseTable256[256] = {
#define R4(n) R2(n), R2(n + 2 * 16), R2(n + 1 * 16), R2(n + 3 * 16)
#define R6(n) R4(n), R4(n + 2 * 4), R4(n + 1 * 4), R4(n + 3 * 4)
R6(0), R6(2), R6(1), R6(3)
+#undef R2
+#undef R4
+#undef R6
};
/// \brief Reverse the bits in \p Val.
@@ -258,6 +261,12 @@ inline uint32_t Lo_32(uint64_t Value) {
return static_cast<uint32_t>(Value);
}
+/// Make_64 - This functions makes a 64-bit integer from a high / low pair of
+/// 32-bit integers.
+inline uint64_t Make_64(uint32_t High, uint32_t Low) {
+ return ((uint64_t)High << 32) | (uint64_t)Low;
+}
+
/// isInt - Checks if an integer fits into the given bit width.
template<unsigned N>
inline bool isInt(int64_t x) {
diff --git a/include/llvm/Support/Memory.h b/include/llvm/Support/Memory.h
index 0996adb..b4305cb 100644
--- a/include/llvm/Support/Memory.h
+++ b/include/llvm/Support/Memory.h
@@ -15,8 +15,8 @@
#define LLVM_SUPPORT_MEMORY_H
#include "llvm/Support/DataTypes.h"
-#include "llvm/Support/system_error.h"
#include <string>
+#include <system_error>
namespace llvm {
namespace sys {
@@ -77,7 +77,7 @@ namespace sys {
static MemoryBlock allocateMappedMemory(size_t NumBytes,
const MemoryBlock *const NearBlock,
unsigned Flags,
- error_code &EC);
+ std::error_code &EC);
/// This method releases a block of memory that was allocated with the
/// allocateMappedMemory method. It should not be used to release any
@@ -88,7 +88,7 @@ namespace sys {
/// describing the failure if an error occurred.
///
/// @brief Release mapped memory.
- static error_code releaseMappedMemory(MemoryBlock &Block);
+ static std::error_code releaseMappedMemory(MemoryBlock &Block);
/// This method sets the protection flags for a block of memory to the
/// state specified by /p Flags. The behavior is not specified if the
@@ -105,8 +105,8 @@ namespace sys {
/// describing the failure if an error occurred.
///
/// @brief Set memory protection state.
- static error_code protectMappedMemory(const MemoryBlock &Block,
- unsigned Flags);
+ static std::error_code protectMappedMemory(const MemoryBlock &Block,
+ unsigned Flags);
/// This method allocates a block of Read/Write/Execute memory that is
/// suitable for executing dynamically generated code (e.g. JIT). An
diff --git a/include/llvm/Support/MemoryBuffer.h b/include/llvm/Support/MemoryBuffer.h
index 5810c47..147be47 100644
--- a/include/llvm/Support/MemoryBuffer.h
+++ b/include/llvm/Support/MemoryBuffer.h
@@ -19,12 +19,11 @@
#include "llvm/Support/CBindingWrapping.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/ErrorOr.h"
#include <memory>
+#include <system_error>
namespace llvm {
-
-class error_code;
-
/// MemoryBuffer - This interface provides simple read-only access to a block
/// of memory, and provides simple methods for reading files and standard input
/// into a memory buffer. In addition to basic access to the characters in the
@@ -62,19 +61,17 @@ public:
return "Unknown buffer";
}
- /// getFile - Open the specified file as a MemoryBuffer, returning a new
- /// MemoryBuffer if successful, otherwise returning null. If FileSize is
- /// specified, this means that the client knows that the file exists and that
- /// it has the specified size.
+ /// Open the specified file as a MemoryBuffer, returning a new MemoryBuffer
+ /// if successful, otherwise returning null. If FileSize is specified, this
+ /// means that the client knows that the file exists and that it has the
+ /// specified size.
///
/// \param IsVolatileSize Set to true to indicate that the file size may be
/// changing, e.g. when libclang tries to parse while the user is
/// editing/updating the file.
- static error_code getFile(Twine Filename,
- std::unique_ptr<MemoryBuffer> &Result,
- int64_t FileSize = -1,
- bool RequiresNullTerminator = true,
- bool IsVolatileSize = false);
+ static ErrorOr<std::unique_ptr<MemoryBuffer>>
+ getFile(Twine Filename, int64_t FileSize = -1,
+ bool RequiresNullTerminator = true, bool IsVolatileSize = false);
/// Given an already-open file descriptor, map some slice of it into a
/// MemoryBuffer. The slice is specified by an \p Offset and \p MapSize.
@@ -83,10 +80,9 @@ public:
/// \param IsVolatileSize Set to true to indicate that the file size may be
/// changing, e.g. when libclang tries to parse while the user is
/// editing/updating the file.
- static error_code getOpenFileSlice(int FD, const char *Filename,
- std::unique_ptr<MemoryBuffer> &Result,
- uint64_t MapSize, int64_t Offset,
- bool IsVolatileSize = false);
+ static ErrorOr<std::unique_ptr<MemoryBuffer>>
+ getOpenFileSlice(int FD, const char *Filename, uint64_t MapSize,
+ int64_t Offset, bool IsVolatileSize = false);
/// Given an already-open file descriptor, read the file and return a
/// MemoryBuffer.
@@ -94,11 +90,9 @@ public:
/// \param IsVolatileSize Set to true to indicate that the file size may be
/// changing, e.g. when libclang tries to parse while the user is
/// editing/updating the file.
- static error_code getOpenFile(int FD, const char *Filename,
- std::unique_ptr<MemoryBuffer> &Result,
- uint64_t FileSize,
- bool RequiresNullTerminator = true,
- bool IsVolatileSize = false);
+ static ErrorOr<std::unique_ptr<MemoryBuffer>>
+ getOpenFile(int FD, const char *Filename, uint64_t FileSize,
+ bool RequiresNullTerminator = true, bool IsVolatileSize = false);
/// getMemBuffer - Open the specified memory range as a MemoryBuffer. Note
/// that InputData must be null terminated if RequiresNullTerminator is true.
@@ -125,17 +119,13 @@ public:
static MemoryBuffer *getNewUninitMemBuffer(size_t Size,
StringRef BufferName = "");
- /// getSTDIN - Read all of stdin into a file buffer, and return it.
- /// If an error occurs, this returns null and sets ec.
- static error_code getSTDIN(std::unique_ptr<MemoryBuffer> &Result);
-
+ /// Read all of stdin into a file buffer, and return it.
+ static ErrorOr<std::unique_ptr<MemoryBuffer>> getSTDIN();
- /// getFileOrSTDIN - Open the specified file as a MemoryBuffer, or open stdin
- /// if the Filename is "-". If an error occurs, this returns null and sets
- /// ec.
- static error_code getFileOrSTDIN(StringRef Filename,
- std::unique_ptr<MemoryBuffer> &Result,
- int64_t FileSize = -1);
+ /// Open the specified file as a MemoryBuffer, or open stdin if the Filename
+ /// is "-".
+ static ErrorOr<std::unique_ptr<MemoryBuffer>>
+ getFileOrSTDIN(StringRef Filename, int64_t FileSize = -1);
//===--------------------------------------------------------------------===//
// Provided for performance analysis.
diff --git a/include/llvm/Support/Process.h b/include/llvm/Support/Process.h
index 7f6441e..30973de 100644
--- a/include/llvm/Support/Process.h
+++ b/include/llvm/Support/Process.h
@@ -31,7 +31,7 @@
#include "llvm/Support/Allocator.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/TimeValue.h"
-#include "llvm/Support/system_error.h"
+#include <system_error>
namespace llvm {
class StringRef;
@@ -171,10 +171,17 @@ public:
// string. \arg Name is assumed to be in UTF-8 encoding too.
static Optional<std::string> GetEnv(StringRef name);
+ /// This function searches for an existing file in the list of directories
+ /// in a PATH like environment variable, and returns the first file found,
+ /// according to the order of the entries in the PATH like environment
+ /// variable.
+ static Optional<std::string> FindInEnvPath(const std::string& EnvName,
+ const std::string& FileName);
+
/// This function returns a SmallVector containing the arguments passed from
/// the operating system to the program. This function expects to be handed
/// the vector passed in from main.
- static error_code
+ static std::error_code
GetArgumentVector(SmallVectorImpl<const char *> &Args,
ArrayRef<const char *> ArgsFromMain,
SpecificBumpPtrAllocator<char> &ArgAllocator);
diff --git a/include/llvm/Support/Program.h b/include/llvm/Support/Program.h
index 9160b7d..51279a9 100644
--- a/include/llvm/Support/Program.h
+++ b/include/llvm/Support/Program.h
@@ -16,10 +16,9 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/Path.h"
-#include "llvm/Support/system_error.h"
+#include <system_error>
namespace llvm {
-class error_code;
namespace sys {
/// This is the OS-specific separator for PATH like environment variables:
@@ -67,8 +66,8 @@ struct ProcessInfo {
// These functions change the specified standard stream (stdin or stdout) to
// binary mode. They return errc::success if the specified stream
// was changed. Otherwise a platform dependent error is returned.
- error_code ChangeStdinToBinary();
- error_code ChangeStdoutToBinary();
+ std::error_code ChangeStdinToBinary();
+ std::error_code ChangeStdoutToBinary();
/// This function executes the program using the arguments provided. The
/// invoked program will inherit the stdin, stdout, and stderr file
diff --git a/include/llvm/Support/RandomNumberGenerator.h b/include/llvm/Support/RandomNumberGenerator.h
new file mode 100644
index 0000000..cadc713
--- /dev/null
+++ b/include/llvm/Support/RandomNumberGenerator.h
@@ -0,0 +1,57 @@
+//==- llvm/Support/RandomNumberGenerator.h - RNG for diversity ---*- 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 abstraction for random number generation (RNG).
+// Note that the current implementation is not cryptographically secure
+// as it uses the C++11 <random> facilities.
+//
+//===----------------------------------------------------------------------===//
+
+#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 {
+
+/// A random number generator.
+/// Instances of this class should not be shared across threads.
+class RandomNumberGenerator {
+public:
+ /// Seeds and salts the underlying RNG engine. The salt of type StringRef
+ /// is passed into the constructor. The seed can be set on the command
+ /// line via -rng-seed=<uint64>.
+ /// The reason for the salt is to ensure different random streams even if
+ /// the same seed is used for multiple invocations of the compiler.
+ /// A good salt value should add additional entropy and be constant across
+ /// different machines (i.e., no paths) to allow for reproducible builds.
+ /// An instance of this class can be retrieved from the current Module.
+ /// \see Module::getRNG
+ RandomNumberGenerator(StringRef Salt);
+
+ /// Returns a random number in the range [0, Max).
+ uint64_t next(uint64_t Max);
+
+private:
+ // 64-bit Mersenne Twister by Matsumoto and Nishimura, 2000
+ // http://en.cppreference.com/w/cpp/numeric/random/mersenne_twister_engine
+ std::mt19937_64 Generator;
+
+ // Noncopyable.
+ RandomNumberGenerator(const RandomNumberGenerator &other)
+ LLVM_DELETED_FUNCTION;
+ RandomNumberGenerator &
+ operator=(const RandomNumberGenerator &other) LLVM_DELETED_FUNCTION;
+};
+}
+
+#endif
diff --git a/include/llvm/Support/ScaledNumber.h b/include/llvm/Support/ScaledNumber.h
new file mode 100644
index 0000000..2bd7e74
--- /dev/null
+++ b/include/llvm/Support/ScaledNumber.h
@@ -0,0 +1,897 @@
+//===- llvm/Support/ScaledNumber.h - Support for scaled numbers -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains functions (and a class) useful for working with scaled
+// numbers -- in particular, pairs of integers where one represents digits and
+// another represents a scale. The functions are helpers and live in the
+// namespace ScaledNumbers. The class ScaledNumber is useful for modelling
+// certain cost metrics that need simple, integer-like semantics that are easy
+// to reason about.
+//
+// These might remind you of soft-floats. If you want one of those, you're in
+// the wrong place. Look at include/llvm/ADT/APFloat.h instead.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_SCALEDNUMBER_H
+#define LLVM_SUPPORT_SCALEDNUMBER_H
+
+#include "llvm/Support/MathExtras.h"
+
+#include <algorithm>
+#include <cstdint>
+#include <limits>
+#include <string>
+#include <tuple>
+#include <utility>
+
+namespace llvm {
+namespace ScaledNumbers {
+
+/// \brief Maximum scale; same as APFloat for easy debug printing.
+const int32_t MaxScale = 16383;
+
+/// \brief Maximum scale; same as APFloat for easy debug printing.
+const int32_t MinScale = -16382;
+
+/// \brief Get the width of a number.
+template <class DigitsT> inline int getWidth() { return sizeof(DigitsT) * 8; }
+
+/// \brief Conditionally round up a scaled number.
+///
+/// Given \c Digits and \c Scale, round up iff \c ShouldRound is \c true.
+/// Always returns \c Scale unless there's an overflow, in which case it
+/// returns \c 1+Scale.
+///
+/// \pre adding 1 to \c Scale will not overflow INT16_MAX.
+template <class DigitsT>
+inline std::pair<DigitsT, int16_t> getRounded(DigitsT Digits, int16_t Scale,
+ bool ShouldRound) {
+ static_assert(!std::numeric_limits<DigitsT>::is_signed, "expected unsigned");
+
+ if (ShouldRound)
+ if (!++Digits)
+ // Overflow.
+ return std::make_pair(DigitsT(1) << (getWidth<DigitsT>() - 1), Scale + 1);
+ return std::make_pair(Digits, Scale);
+}
+
+/// \brief Convenience helper for 32-bit rounding.
+inline std::pair<uint32_t, int16_t> getRounded32(uint32_t Digits, int16_t Scale,
+ bool ShouldRound) {
+ return getRounded(Digits, Scale, ShouldRound);
+}
+
+/// \brief Convenience helper for 64-bit rounding.
+inline std::pair<uint64_t, int16_t> getRounded64(uint64_t Digits, int16_t Scale,
+ bool ShouldRound) {
+ return getRounded(Digits, Scale, ShouldRound);
+}
+
+/// \brief Adjust a 64-bit scaled number down to the appropriate width.
+///
+/// \pre Adding 64 to \c Scale will not overflow INT16_MAX.
+template <class DigitsT>
+inline std::pair<DigitsT, int16_t> getAdjusted(uint64_t Digits,
+ int16_t Scale = 0) {
+ static_assert(!std::numeric_limits<DigitsT>::is_signed, "expected unsigned");
+
+ const int Width = getWidth<DigitsT>();
+ if (Width == 64 || Digits <= std::numeric_limits<DigitsT>::max())
+ return std::make_pair(Digits, Scale);
+
+ // Shift right and round.
+ int Shift = 64 - Width - countLeadingZeros(Digits);
+ return getRounded<DigitsT>(Digits >> Shift, Scale + Shift,
+ Digits & (UINT64_C(1) << (Shift - 1)));
+}
+
+/// \brief Convenience helper for adjusting to 32 bits.
+inline std::pair<uint32_t, int16_t> getAdjusted32(uint64_t Digits,
+ int16_t Scale = 0) {
+ return getAdjusted<uint32_t>(Digits, Scale);
+}
+
+/// \brief Convenience helper for adjusting to 64 bits.
+inline std::pair<uint64_t, int16_t> getAdjusted64(uint64_t Digits,
+ int16_t Scale = 0) {
+ return getAdjusted<uint64_t>(Digits, Scale);
+}
+
+/// \brief Multiply two 64-bit integers to create a 64-bit scaled number.
+///
+/// Implemented with four 64-bit integer multiplies.
+std::pair<uint64_t, int16_t> multiply64(uint64_t LHS, uint64_t RHS);
+
+/// \brief Multiply two 32-bit integers to create a 32-bit scaled number.
+///
+/// Implemented with one 64-bit integer multiply.
+template <class DigitsT>
+inline std::pair<DigitsT, int16_t> getProduct(DigitsT LHS, DigitsT RHS) {
+ static_assert(!std::numeric_limits<DigitsT>::is_signed, "expected unsigned");
+
+ if (getWidth<DigitsT>() <= 32 || (LHS <= UINT32_MAX && RHS <= UINT32_MAX))
+ return getAdjusted<DigitsT>(uint64_t(LHS) * RHS);
+
+ return multiply64(LHS, RHS);
+}
+
+/// \brief Convenience helper for 32-bit product.
+inline std::pair<uint32_t, int16_t> getProduct32(uint32_t LHS, uint32_t RHS) {
+ return getProduct(LHS, RHS);
+}
+
+/// \brief Convenience helper for 64-bit product.
+inline std::pair<uint64_t, int16_t> getProduct64(uint64_t LHS, uint64_t RHS) {
+ return getProduct(LHS, RHS);
+}
+
+/// \brief Divide two 64-bit integers to create a 64-bit scaled number.
+///
+/// Implemented with long division.
+///
+/// \pre \c Dividend and \c Divisor are non-zero.
+std::pair<uint64_t, int16_t> divide64(uint64_t Dividend, uint64_t Divisor);
+
+/// \brief Divide two 32-bit integers to create a 32-bit scaled number.
+///
+/// Implemented with one 64-bit integer divide/remainder pair.
+///
+/// \pre \c Dividend and \c Divisor are non-zero.
+std::pair<uint32_t, int16_t> divide32(uint32_t Dividend, uint32_t Divisor);
+
+/// \brief Divide two 32-bit numbers to create a 32-bit scaled number.
+///
+/// Implemented with one 64-bit integer divide/remainder pair.
+///
+/// Returns \c (DigitsT_MAX, MaxScale) for divide-by-zero (0 for 0/0).
+template <class DigitsT>
+std::pair<DigitsT, int16_t> getQuotient(DigitsT Dividend, DigitsT Divisor) {
+ static_assert(!std::numeric_limits<DigitsT>::is_signed, "expected unsigned");
+ static_assert(sizeof(DigitsT) == 4 || sizeof(DigitsT) == 8,
+ "expected 32-bit or 64-bit digits");
+
+ // Check for zero.
+ if (!Dividend)
+ return std::make_pair(0, 0);
+ if (!Divisor)
+ return std::make_pair(std::numeric_limits<DigitsT>::max(), MaxScale);
+
+ if (getWidth<DigitsT>() == 64)
+ return divide64(Dividend, Divisor);
+ return divide32(Dividend, Divisor);
+}
+
+/// \brief Convenience helper for 32-bit quotient.
+inline std::pair<uint32_t, int16_t> getQuotient32(uint32_t Dividend,
+ uint32_t Divisor) {
+ return getQuotient(Dividend, Divisor);
+}
+
+/// \brief Convenience helper for 64-bit quotient.
+inline std::pair<uint64_t, int16_t> getQuotient64(uint64_t Dividend,
+ uint64_t Divisor) {
+ return getQuotient(Dividend, Divisor);
+}
+
+/// \brief Implementation of getLg() and friends.
+///
+/// Returns the rounded lg of \c Digits*2^Scale and an int specifying whether
+/// this was rounded up (1), down (-1), or exact (0).
+///
+/// Returns \c INT32_MIN when \c Digits is zero.
+template <class DigitsT>
+inline std::pair<int32_t, int> getLgImpl(DigitsT Digits, int16_t Scale) {
+ static_assert(!std::numeric_limits<DigitsT>::is_signed, "expected unsigned");
+
+ if (!Digits)
+ return std::make_pair(INT32_MIN, 0);
+
+ // Get the floor of the lg of Digits.
+ int32_t LocalFloor = sizeof(Digits) * 8 - countLeadingZeros(Digits) - 1;
+
+ // Get the actual floor.
+ int32_t Floor = Scale + LocalFloor;
+ if (Digits == UINT64_C(1) << LocalFloor)
+ return std::make_pair(Floor, 0);
+
+ // Round based on the next digit.
+ assert(LocalFloor >= 1);
+ bool Round = Digits & UINT64_C(1) << (LocalFloor - 1);
+ return std::make_pair(Floor + Round, Round ? 1 : -1);
+}
+
+/// \brief Get the lg (rounded) of a scaled number.
+///
+/// Get the lg of \c Digits*2^Scale.
+///
+/// Returns \c INT32_MIN when \c Digits is zero.
+template <class DigitsT> int32_t getLg(DigitsT Digits, int16_t Scale) {
+ return getLgImpl(Digits, Scale).first;
+}
+
+/// \brief Get the lg floor of a scaled number.
+///
+/// Get the floor of the lg of \c Digits*2^Scale.
+///
+/// Returns \c INT32_MIN when \c Digits is zero.
+template <class DigitsT> int32_t getLgFloor(DigitsT Digits, int16_t Scale) {
+ auto Lg = getLgImpl(Digits, Scale);
+ return Lg.first - (Lg.second > 0);
+}
+
+/// \brief Get the lg ceiling of a scaled number.
+///
+/// Get the ceiling of the lg of \c Digits*2^Scale.
+///
+/// Returns \c INT32_MIN when \c Digits is zero.
+template <class DigitsT> int32_t getLgCeiling(DigitsT Digits, int16_t Scale) {
+ auto Lg = getLgImpl(Digits, Scale);
+ return Lg.first + (Lg.second < 0);
+}
+
+/// \brief Implementation for comparing scaled numbers.
+///
+/// Compare two 64-bit numbers with different scales. Given that the scale of
+/// \c L is higher than that of \c R by \c ScaleDiff, compare them. Return -1,
+/// 1, and 0 for less than, greater than, and equal, respectively.
+///
+/// \pre 0 <= ScaleDiff < 64.
+int compareImpl(uint64_t L, uint64_t R, int ScaleDiff);
+
+/// \brief Compare two scaled numbers.
+///
+/// Compare two scaled numbers. Returns 0 for equal, -1 for less than, and 1
+/// for greater than.
+template <class DigitsT>
+int compare(DigitsT LDigits, int16_t LScale, DigitsT RDigits, int16_t RScale) {
+ static_assert(!std::numeric_limits<DigitsT>::is_signed, "expected unsigned");
+
+ // Check for zero.
+ if (!LDigits)
+ return RDigits ? -1 : 0;
+ if (!RDigits)
+ return 1;
+
+ // Check for the scale. Use getLgFloor to be sure that the scale difference
+ // is always lower than 64.
+ int32_t lgL = getLgFloor(LDigits, LScale), lgR = getLgFloor(RDigits, RScale);
+ if (lgL != lgR)
+ return lgL < lgR ? -1 : 1;
+
+ // Compare digits.
+ if (LScale < RScale)
+ return compareImpl(LDigits, RDigits, RScale - LScale);
+
+ return -compareImpl(RDigits, LDigits, LScale - RScale);
+}
+
+/// \brief Match scales of two numbers.
+///
+/// Given two scaled numbers, match up their scales. Change the digits and
+/// scales in place. Shift the digits as necessary to form equivalent numbers,
+/// losing precision only when necessary.
+///
+/// If the output value of \c LDigits (\c RDigits) is \c 0, the output value of
+/// \c LScale (\c RScale) is unspecified.
+///
+/// As a convenience, returns the matching scale. If the output value of one
+/// number is zero, returns the scale of the other. If both are zero, which
+/// scale is returned is unspecifed.
+template <class DigitsT>
+int16_t matchScales(DigitsT &LDigits, int16_t &LScale, DigitsT &RDigits,
+ int16_t &RScale) {
+ static_assert(!std::numeric_limits<DigitsT>::is_signed, "expected unsigned");
+
+ if (LScale < RScale)
+ // Swap arguments.
+ return matchScales(RDigits, RScale, LDigits, LScale);
+ if (!LDigits)
+ return RScale;
+ if (!RDigits || LScale == RScale)
+ return LScale;
+
+ // Now LScale > RScale. Get the difference.
+ int32_t ScaleDiff = int32_t(LScale) - RScale;
+ if (ScaleDiff >= 2 * getWidth<DigitsT>()) {
+ // Don't bother shifting. RDigits will get zero-ed out anyway.
+ RDigits = 0;
+ return LScale;
+ }
+
+ // Shift LDigits left as much as possible, then shift RDigits right.
+ int32_t ShiftL = std::min<int32_t>(countLeadingZeros(LDigits), ScaleDiff);
+ assert(ShiftL < getWidth<DigitsT>() && "can't shift more than width");
+
+ int32_t ShiftR = ScaleDiff - ShiftL;
+ if (ShiftR >= getWidth<DigitsT>()) {
+ // Don't bother shifting. RDigits will get zero-ed out anyway.
+ RDigits = 0;
+ return LScale;
+ }
+
+ LDigits <<= ShiftL;
+ RDigits >>= ShiftR;
+
+ LScale -= ShiftL;
+ RScale += ShiftR;
+ assert(LScale == RScale && "scales should match");
+ return LScale;
+}
+
+/// \brief Get the sum of two scaled numbers.
+///
+/// Get the sum of two scaled numbers with as much precision as possible.
+///
+/// \pre Adding 1 to \c LScale (or \c RScale) will not overflow INT16_MAX.
+template <class DigitsT>
+std::pair<DigitsT, int16_t> getSum(DigitsT LDigits, int16_t LScale,
+ DigitsT RDigits, int16_t RScale) {
+ static_assert(!std::numeric_limits<DigitsT>::is_signed, "expected unsigned");
+
+ // Check inputs up front. This is only relevent if addition overflows, but
+ // testing here should catch more bugs.
+ assert(LScale < INT16_MAX && "scale too large");
+ assert(RScale < INT16_MAX && "scale too large");
+
+ // Normalize digits to match scales.
+ int16_t Scale = matchScales(LDigits, LScale, RDigits, RScale);
+
+ // Compute sum.
+ DigitsT Sum = LDigits + RDigits;
+ if (Sum >= RDigits)
+ return std::make_pair(Sum, Scale);
+
+ // Adjust sum after arithmetic overflow.
+ DigitsT HighBit = DigitsT(1) << (getWidth<DigitsT>() - 1);
+ return std::make_pair(HighBit | Sum >> 1, Scale + 1);
+}
+
+/// \brief Convenience helper for 32-bit sum.
+inline std::pair<uint32_t, int16_t> getSum32(uint32_t LDigits, int16_t LScale,
+ uint32_t RDigits, int16_t RScale) {
+ return getSum(LDigits, LScale, RDigits, RScale);
+}
+
+/// \brief Convenience helper for 64-bit sum.
+inline std::pair<uint64_t, int16_t> getSum64(uint64_t LDigits, int16_t LScale,
+ uint64_t RDigits, int16_t RScale) {
+ return getSum(LDigits, LScale, RDigits, RScale);
+}
+
+/// \brief Get the difference of two scaled numbers.
+///
+/// Get LHS minus RHS with as much precision as possible.
+///
+/// Returns \c (0, 0) if the RHS is larger than the LHS.
+template <class DigitsT>
+std::pair<DigitsT, int16_t> getDifference(DigitsT LDigits, int16_t LScale,
+ DigitsT RDigits, int16_t RScale) {
+ static_assert(!std::numeric_limits<DigitsT>::is_signed, "expected unsigned");
+
+ // Normalize digits to match scales.
+ const DigitsT SavedRDigits = RDigits;
+ const int16_t SavedRScale = RScale;
+ matchScales(LDigits, LScale, RDigits, RScale);
+
+ // Compute difference.
+ if (LDigits <= RDigits)
+ return std::make_pair(0, 0);
+ if (RDigits || !SavedRDigits)
+ return std::make_pair(LDigits - RDigits, LScale);
+
+ // Check if RDigits just barely lost its last bit. E.g., for 32-bit:
+ //
+ // 1*2^32 - 1*2^0 == 0xffffffff != 1*2^32
+ const auto RLgFloor = getLgFloor(SavedRDigits, SavedRScale);
+ if (!compare(LDigits, LScale, DigitsT(1), RLgFloor + getWidth<DigitsT>()))
+ return std::make_pair(std::numeric_limits<DigitsT>::max(), RLgFloor);
+
+ return std::make_pair(LDigits, LScale);
+}
+
+/// \brief Convenience helper for 32-bit difference.
+inline std::pair<uint32_t, int16_t> getDifference32(uint32_t LDigits,
+ int16_t LScale,
+ uint32_t RDigits,
+ int16_t RScale) {
+ return getDifference(LDigits, LScale, RDigits, RScale);
+}
+
+/// \brief Convenience helper for 64-bit difference.
+inline std::pair<uint64_t, int16_t> getDifference64(uint64_t LDigits,
+ int16_t LScale,
+ uint64_t RDigits,
+ int16_t RScale) {
+ return getDifference(LDigits, LScale, RDigits, RScale);
+}
+
+} // end namespace ScaledNumbers
+} // end namespace llvm
+
+namespace llvm {
+
+class raw_ostream;
+class ScaledNumberBase {
+public:
+ static const int DefaultPrecision = 10;
+
+ static void dump(uint64_t D, int16_t E, int Width);
+ static raw_ostream &print(raw_ostream &OS, uint64_t D, int16_t E, int Width,
+ unsigned Precision);
+ static std::string toString(uint64_t D, int16_t E, int Width,
+ unsigned Precision);
+ static int countLeadingZeros32(uint32_t N) { return countLeadingZeros(N); }
+ static int countLeadingZeros64(uint64_t N) { return countLeadingZeros(N); }
+ static uint64_t getHalf(uint64_t N) { return (N >> 1) + (N & 1); }
+
+ static std::pair<uint64_t, bool> splitSigned(int64_t N) {
+ if (N >= 0)
+ return std::make_pair(N, false);
+ uint64_t Unsigned = N == INT64_MIN ? UINT64_C(1) << 63 : uint64_t(-N);
+ return std::make_pair(Unsigned, true);
+ }
+ static int64_t joinSigned(uint64_t U, bool IsNeg) {
+ if (U > uint64_t(INT64_MAX))
+ return IsNeg ? INT64_MIN : INT64_MAX;
+ return IsNeg ? -int64_t(U) : int64_t(U);
+ }
+};
+
+/// \brief Simple representation of a scaled number.
+///
+/// ScaledNumber is a number represented by digits and a scale. It uses simple
+/// saturation arithmetic and every operation is well-defined for every value.
+/// It's somewhat similar in behaviour to a soft-float, but is *not* a
+/// replacement for one. If you're doing numerics, look at \a APFloat instead.
+/// Nevertheless, we've found these semantics useful for modelling certain cost
+/// metrics.
+///
+/// The number is split into a signed scale and unsigned digits. The number
+/// represented is \c getDigits()*2^getScale(). In this way, the digits are
+/// much like the mantissa in the x87 long double, but there is no canonical
+/// form so the same number can be represented by many bit representations.
+///
+/// ScaledNumber is templated on the underlying integer type for digits, which
+/// is expected to be unsigned.
+///
+/// Unlike APFloat, ScaledNumber does not model architecture floating point
+/// behaviour -- while this might make it a little faster and easier to reason
+/// about, it certainly makes it more dangerous for general numerics.
+///
+/// ScaledNumber is totally ordered. However, there is no canonical form, so
+/// there are multiple representations of most scalars. E.g.:
+///
+/// ScaledNumber(8u, 0) == ScaledNumber(4u, 1)
+/// ScaledNumber(4u, 1) == ScaledNumber(2u, 2)
+/// ScaledNumber(2u, 2) == ScaledNumber(1u, 3)
+///
+/// ScaledNumber implements most arithmetic operations. Precision is kept
+/// where possible. Uses simple saturation arithmetic, so that operations
+/// saturate to 0.0 or getLargest() rather than under or overflowing. It has
+/// some extra arithmetic for unit inversion. 0.0/0.0 is defined to be 0.0.
+/// Any other division by 0.0 is defined to be getLargest().
+///
+/// As a convenience for modifying the exponent, left and right shifting are
+/// both implemented, and both interpret negative shifts as positive shifts in
+/// the opposite direction.
+///
+/// Scales are limited to the range accepted by x87 long double. This makes
+/// it trivial to add functionality to convert to APFloat (this is already
+/// relied on for the implementation of printing).
+///
+/// Possible (and conflicting) future directions:
+///
+/// 1. Turn this into a wrapper around \a APFloat.
+/// 2. Share the algorithm implementations with \a APFloat.
+/// 3. Allow \a ScaledNumber to represent a signed number.
+template <class DigitsT> class ScaledNumber : ScaledNumberBase {
+public:
+ static_assert(!std::numeric_limits<DigitsT>::is_signed,
+ "only unsigned floats supported");
+
+ typedef DigitsT DigitsType;
+
+private:
+ typedef std::numeric_limits<DigitsType> DigitsLimits;
+
+ static const int Width = sizeof(DigitsType) * 8;
+ static_assert(Width <= 64, "invalid integer width for digits");
+
+private:
+ DigitsType Digits;
+ int16_t Scale;
+
+public:
+ ScaledNumber() : Digits(0), Scale(0) {}
+
+ ScaledNumber(DigitsType Digits, int16_t Scale)
+ : Digits(Digits), Scale(Scale) {}
+
+private:
+ ScaledNumber(const std::pair<uint64_t, int16_t> &X)
+ : Digits(X.first), Scale(X.second) {}
+
+public:
+ static ScaledNumber getZero() { return ScaledNumber(0, 0); }
+ static ScaledNumber getOne() { return ScaledNumber(1, 0); }
+ static ScaledNumber getLargest() {
+ return ScaledNumber(DigitsLimits::max(), ScaledNumbers::MaxScale);
+ }
+ static ScaledNumber get(uint64_t N) { return adjustToWidth(N, 0); }
+ static ScaledNumber getInverse(uint64_t N) {
+ return get(N).invert();
+ }
+ static ScaledNumber getFraction(DigitsType N, DigitsType D) {
+ return getQuotient(N, D);
+ }
+
+ int16_t getScale() const { return Scale; }
+ DigitsType getDigits() const { return Digits; }
+
+ /// \brief Convert to the given integer type.
+ ///
+ /// Convert to \c IntT using simple saturating arithmetic, truncating if
+ /// necessary.
+ template <class IntT> IntT toInt() const;
+
+ bool isZero() const { return !Digits; }
+ bool isLargest() const { return *this == getLargest(); }
+ bool isOne() const {
+ if (Scale > 0 || Scale <= -Width)
+ return false;
+ return Digits == DigitsType(1) << -Scale;
+ }
+
+ /// \brief The log base 2, rounded.
+ ///
+ /// Get the lg of the scalar. lg 0 is defined to be INT32_MIN.
+ int32_t lg() const { return ScaledNumbers::getLg(Digits, Scale); }
+
+ /// \brief The log base 2, rounded towards INT32_MIN.
+ ///
+ /// Get the lg floor. lg 0 is defined to be INT32_MIN.
+ int32_t lgFloor() const { return ScaledNumbers::getLgFloor(Digits, Scale); }
+
+ /// \brief The log base 2, rounded towards INT32_MAX.
+ ///
+ /// Get the lg ceiling. lg 0 is defined to be INT32_MIN.
+ int32_t lgCeiling() const {
+ return ScaledNumbers::getLgCeiling(Digits, Scale);
+ }
+
+ bool operator==(const ScaledNumber &X) const { return compare(X) == 0; }
+ bool operator<(const ScaledNumber &X) const { return compare(X) < 0; }
+ bool operator!=(const ScaledNumber &X) const { return compare(X) != 0; }
+ bool operator>(const ScaledNumber &X) const { return compare(X) > 0; }
+ bool operator<=(const ScaledNumber &X) const { return compare(X) <= 0; }
+ bool operator>=(const ScaledNumber &X) const { return compare(X) >= 0; }
+
+ bool operator!() const { return isZero(); }
+
+ /// \brief Convert to a decimal representation in a string.
+ ///
+ /// Convert to a string. Uses scientific notation for very large/small
+ /// numbers. Scientific notation is used roughly for numbers outside of the
+ /// range 2^-64 through 2^64.
+ ///
+ /// \c Precision indicates the number of decimal digits of precision to use;
+ /// 0 requests the maximum available.
+ ///
+ /// As a special case to make debugging easier, if the number is small enough
+ /// to convert without scientific notation and has more than \c Precision
+ /// digits before the decimal place, it's printed accurately to the first
+ /// digit past zero. E.g., assuming 10 digits of precision:
+ ///
+ /// 98765432198.7654... => 98765432198.8
+ /// 8765432198.7654... => 8765432198.8
+ /// 765432198.7654... => 765432198.8
+ /// 65432198.7654... => 65432198.77
+ /// 5432198.7654... => 5432198.765
+ std::string toString(unsigned Precision = DefaultPrecision) {
+ return ScaledNumberBase::toString(Digits, Scale, Width, Precision);
+ }
+
+ /// \brief Print a decimal representation.
+ ///
+ /// Print a string. See toString for documentation.
+ raw_ostream &print(raw_ostream &OS,
+ unsigned Precision = DefaultPrecision) const {
+ return ScaledNumberBase::print(OS, Digits, Scale, Width, Precision);
+ }
+ void dump() const { return ScaledNumberBase::dump(Digits, Scale, Width); }
+
+ ScaledNumber &operator+=(const ScaledNumber &X) {
+ std::tie(Digits, Scale) =
+ ScaledNumbers::getSum(Digits, Scale, X.Digits, X.Scale);
+ // Check for exponent past MaxScale.
+ if (Scale > ScaledNumbers::MaxScale)
+ *this = getLargest();
+ return *this;
+ }
+ ScaledNumber &operator-=(const ScaledNumber &X) {
+ std::tie(Digits, Scale) =
+ ScaledNumbers::getDifference(Digits, Scale, X.Digits, X.Scale);
+ return *this;
+ }
+ ScaledNumber &operator*=(const ScaledNumber &X);
+ ScaledNumber &operator/=(const ScaledNumber &X);
+ ScaledNumber &operator<<=(int16_t Shift) {
+ shiftLeft(Shift);
+ return *this;
+ }
+ ScaledNumber &operator>>=(int16_t Shift) {
+ shiftRight(Shift);
+ return *this;
+ }
+
+private:
+ void shiftLeft(int32_t Shift);
+ void shiftRight(int32_t Shift);
+
+ /// \brief Adjust two floats to have matching exponents.
+ ///
+ /// Adjust \c this and \c X to have matching exponents. Returns the new \c X
+ /// by value. Does nothing if \a isZero() for either.
+ ///
+ /// The value that compares smaller will lose precision, and possibly become
+ /// \a isZero().
+ ScaledNumber matchScales(ScaledNumber X) {
+ ScaledNumbers::matchScales(Digits, Scale, X.Digits, X.Scale);
+ return X;
+ }
+
+public:
+ /// \brief Scale a large number accurately.
+ ///
+ /// Scale N (multiply it by this). Uses full precision multiplication, even
+ /// if Width is smaller than 64, so information is not lost.
+ uint64_t scale(uint64_t N) const;
+ uint64_t scaleByInverse(uint64_t N) const {
+ // TODO: implement directly, rather than relying on inverse. Inverse is
+ // expensive.
+ return inverse().scale(N);
+ }
+ int64_t scale(int64_t N) const {
+ std::pair<uint64_t, bool> Unsigned = splitSigned(N);
+ return joinSigned(scale(Unsigned.first), Unsigned.second);
+ }
+ int64_t scaleByInverse(int64_t N) const {
+ std::pair<uint64_t, bool> Unsigned = splitSigned(N);
+ return joinSigned(scaleByInverse(Unsigned.first), Unsigned.second);
+ }
+
+ int compare(const ScaledNumber &X) const {
+ return ScaledNumbers::compare(Digits, Scale, X.Digits, X.Scale);
+ }
+ int compareTo(uint64_t N) const {
+ ScaledNumber Scaled = get(N);
+ int Compare = compare(Scaled);
+ if (Width == 64 || Compare != 0)
+ return Compare;
+
+ // Check for precision loss. We know *this == RoundTrip.
+ uint64_t RoundTrip = Scaled.template toInt<uint64_t>();
+ return N == RoundTrip ? 0 : RoundTrip < N ? -1 : 1;
+ }
+ int compareTo(int64_t N) const { return N < 0 ? 1 : compareTo(uint64_t(N)); }
+
+ ScaledNumber &invert() { return *this = ScaledNumber::get(1) / *this; }
+ ScaledNumber inverse() const { return ScaledNumber(*this).invert(); }
+
+private:
+ static ScaledNumber getProduct(DigitsType LHS, DigitsType RHS) {
+ return ScaledNumbers::getProduct(LHS, RHS);
+ }
+ static ScaledNumber getQuotient(DigitsType Dividend, DigitsType Divisor) {
+ return ScaledNumbers::getQuotient(Dividend, Divisor);
+ }
+
+ static int countLeadingZerosWidth(DigitsType Digits) {
+ if (Width == 64)
+ return countLeadingZeros64(Digits);
+ if (Width == 32)
+ return countLeadingZeros32(Digits);
+ return countLeadingZeros32(Digits) + Width - 32;
+ }
+
+ /// \brief Adjust a number to width, rounding up if necessary.
+ ///
+ /// Should only be called for \c Shift close to zero.
+ ///
+ /// \pre Shift >= MinScale && Shift + 64 <= MaxScale.
+ static ScaledNumber adjustToWidth(uint64_t N, int32_t Shift) {
+ assert(Shift >= ScaledNumbers::MinScale && "Shift should be close to 0");
+ assert(Shift <= ScaledNumbers::MaxScale - 64 &&
+ "Shift should be close to 0");
+ auto Adjusted = ScaledNumbers::getAdjusted<DigitsT>(N, Shift);
+ return Adjusted;
+ }
+
+ static ScaledNumber getRounded(ScaledNumber P, bool Round) {
+ // Saturate.
+ if (P.isLargest())
+ return P;
+
+ return ScaledNumbers::getRounded(P.Digits, P.Scale, Round);
+ }
+};
+
+#define SCALED_NUMBER_BOP(op, base) \
+ template <class DigitsT> \
+ ScaledNumber<DigitsT> operator op(const ScaledNumber<DigitsT> &L, \
+ const ScaledNumber<DigitsT> &R) { \
+ return ScaledNumber<DigitsT>(L) base R; \
+ }
+SCALED_NUMBER_BOP(+, += )
+SCALED_NUMBER_BOP(-, -= )
+SCALED_NUMBER_BOP(*, *= )
+SCALED_NUMBER_BOP(/, /= )
+SCALED_NUMBER_BOP(<<, <<= )
+SCALED_NUMBER_BOP(>>, >>= )
+#undef SCALED_NUMBER_BOP
+
+template <class DigitsT>
+raw_ostream &operator<<(raw_ostream &OS, const ScaledNumber<DigitsT> &X) {
+ return X.print(OS, 10);
+}
+
+#define SCALED_NUMBER_COMPARE_TO_TYPE(op, T1, T2) \
+ template <class DigitsT> \
+ bool operator op(const ScaledNumber<DigitsT> &L, T1 R) { \
+ return L.compareTo(T2(R)) op 0; \
+ } \
+ template <class DigitsT> \
+ bool operator op(T1 L, const ScaledNumber<DigitsT> &R) { \
+ return 0 op R.compareTo(T2(L)); \
+ }
+#define SCALED_NUMBER_COMPARE_TO(op) \
+ SCALED_NUMBER_COMPARE_TO_TYPE(op, uint64_t, uint64_t) \
+ SCALED_NUMBER_COMPARE_TO_TYPE(op, uint32_t, uint64_t) \
+ SCALED_NUMBER_COMPARE_TO_TYPE(op, int64_t, int64_t) \
+ SCALED_NUMBER_COMPARE_TO_TYPE(op, int32_t, int64_t)
+SCALED_NUMBER_COMPARE_TO(< )
+SCALED_NUMBER_COMPARE_TO(> )
+SCALED_NUMBER_COMPARE_TO(== )
+SCALED_NUMBER_COMPARE_TO(!= )
+SCALED_NUMBER_COMPARE_TO(<= )
+SCALED_NUMBER_COMPARE_TO(>= )
+#undef SCALED_NUMBER_COMPARE_TO
+#undef SCALED_NUMBER_COMPARE_TO_TYPE
+
+template <class DigitsT>
+uint64_t ScaledNumber<DigitsT>::scale(uint64_t N) const {
+ if (Width == 64 || N <= DigitsLimits::max())
+ return (get(N) * *this).template toInt<uint64_t>();
+
+ // Defer to the 64-bit version.
+ return ScaledNumber<uint64_t>(Digits, Scale).scale(N);
+}
+
+template <class DigitsT>
+template <class IntT>
+IntT ScaledNumber<DigitsT>::toInt() const {
+ typedef std::numeric_limits<IntT> Limits;
+ if (*this < 1)
+ return 0;
+ if (*this >= Limits::max())
+ return Limits::max();
+
+ IntT N = Digits;
+ if (Scale > 0) {
+ assert(size_t(Scale) < sizeof(IntT) * 8);
+ return N << Scale;
+ }
+ if (Scale < 0) {
+ assert(size_t(-Scale) < sizeof(IntT) * 8);
+ return N >> -Scale;
+ }
+ return N;
+}
+
+template <class DigitsT>
+ScaledNumber<DigitsT> &ScaledNumber<DigitsT>::
+operator*=(const ScaledNumber &X) {
+ if (isZero())
+ return *this;
+ if (X.isZero())
+ return *this = X;
+
+ // Save the exponents.
+ int32_t Scales = int32_t(Scale) + int32_t(X.Scale);
+
+ // Get the raw product.
+ *this = getProduct(Digits, X.Digits);
+
+ // Combine with exponents.
+ return *this <<= Scales;
+}
+template <class DigitsT>
+ScaledNumber<DigitsT> &ScaledNumber<DigitsT>::
+operator/=(const ScaledNumber &X) {
+ if (isZero())
+ return *this;
+ if (X.isZero())
+ return *this = getLargest();
+
+ // Save the exponents.
+ int32_t Scales = int32_t(Scale) - int32_t(X.Scale);
+
+ // Get the raw quotient.
+ *this = getQuotient(Digits, X.Digits);
+
+ // Combine with exponents.
+ return *this <<= Scales;
+}
+template <class DigitsT> void ScaledNumber<DigitsT>::shiftLeft(int32_t Shift) {
+ if (!Shift || isZero())
+ return;
+ assert(Shift != INT32_MIN);
+ if (Shift < 0) {
+ shiftRight(-Shift);
+ return;
+ }
+
+ // Shift as much as we can in the exponent.
+ int32_t ScaleShift = std::min(Shift, ScaledNumbers::MaxScale - Scale);
+ Scale += ScaleShift;
+ if (ScaleShift == Shift)
+ return;
+
+ // Check this late, since it's rare.
+ if (isLargest())
+ return;
+
+ // Shift the digits themselves.
+ Shift -= ScaleShift;
+ if (Shift > countLeadingZerosWidth(Digits)) {
+ // Saturate.
+ *this = getLargest();
+ return;
+ }
+
+ Digits <<= Shift;
+ return;
+}
+
+template <class DigitsT> void ScaledNumber<DigitsT>::shiftRight(int32_t Shift) {
+ if (!Shift || isZero())
+ return;
+ assert(Shift != INT32_MIN);
+ if (Shift < 0) {
+ shiftLeft(-Shift);
+ return;
+ }
+
+ // Shift as much as we can in the exponent.
+ int32_t ScaleShift = std::min(Shift, Scale - ScaledNumbers::MinScale);
+ Scale -= ScaleShift;
+ if (ScaleShift == Shift)
+ return;
+
+ // Shift the digits themselves.
+ Shift -= ScaleShift;
+ if (Shift >= Width) {
+ // Saturate.
+ *this = getZero();
+ return;
+ }
+
+ Digits >>= Shift;
+ return;
+}
+
+template <typename T> struct isPodLike;
+template <typename T> struct isPodLike<ScaledNumber<T>> {
+ static const bool value = true;
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Support/SourceMgr.h b/include/llvm/Support/SourceMgr.h
index 39f896d..4717553 100644
--- a/include/llvm/Support/SourceMgr.h
+++ b/include/llvm/Support/SourceMgr.h
@@ -30,7 +30,7 @@ namespace llvm {
class Twine;
class raw_ostream;
-/// SourceMgr - This owns the files read by a parser, handles include stacks,
+/// This owns the files read by a parser, handles include stacks,
/// and handles diagnostic wrangling.
class SourceMgr {
public:
@@ -40,34 +40,34 @@ public:
DK_Note
};
- /// DiagHandlerTy - Clients that want to handle their own diagnostics in a
- /// custom way can register a function pointer+context as a diagnostic
- /// handler. It gets called each time PrintMessage is invoked.
+ /// Clients that want to handle their own diagnostics in a custom way can
+ /// register a function pointer+context as a diagnostic handler.
+ /// It gets called each time PrintMessage is invoked.
typedef void (*DiagHandlerTy)(const SMDiagnostic &, void *Context);
private:
struct SrcBuffer {
- /// Buffer - The memory buffer for the file.
+ /// The memory buffer for the file.
MemoryBuffer *Buffer;
- /// IncludeLoc - This is the location of the parent include, or null if at
- /// the top level.
+ /// This is the location of the parent include, or null if at the top level.
SMLoc IncludeLoc;
};
- /// Buffers - This is all of the buffers that we are reading from.
+ /// This is all of the buffers that we are reading from.
std::vector<SrcBuffer> Buffers;
- // IncludeDirectories - This is the list of directories we should search for
- // include files in.
+ // This is the list of directories we should search for include files in.
std::vector<std::string> IncludeDirectories;
- /// LineNoCache - This is a cache for line number queries, its implementation
- /// is really private to SourceMgr.cpp.
+ /// This is a cache for line number queries, its implementation is really
+ /// private to SourceMgr.cpp.
mutable void *LineNoCache;
DiagHandlerTy DiagHandler;
void *DiagContext;
+ bool isValidBufferID(unsigned i) const { return i && i <= Buffers.size(); }
+
SourceMgr(const SourceMgr&) LLVM_DELETED_FUNCTION;
void operator=(const SourceMgr&) LLVM_DELETED_FUNCTION;
public:
@@ -79,8 +79,8 @@ public:
IncludeDirectories = Dirs;
}
- /// setDiagHandler - Specify a diagnostic handler to be invoked every time
- /// PrintMessage is called. Ctx is passed into the handler when it is invoked.
+ /// Specify a diagnostic handler to be invoked every time PrintMessage is
+ /// called. \p Ctx is passed into the handler when it is invoked.
void setDiagHandler(DiagHandlerTy DH, void *Ctx = nullptr) {
DiagHandler = DH;
DiagContext = Ctx;
@@ -90,60 +90,67 @@ public:
void *getDiagContext() const { return DiagContext; }
const SrcBuffer &getBufferInfo(unsigned i) const {
- assert(i < Buffers.size() && "Invalid Buffer ID!");
- return Buffers[i];
+ assert(isValidBufferID(i));
+ return Buffers[i - 1];
}
const MemoryBuffer *getMemoryBuffer(unsigned i) const {
- assert(i < Buffers.size() && "Invalid Buffer ID!");
- return Buffers[i].Buffer;
+ assert(isValidBufferID(i));
+ return Buffers[i - 1].Buffer;
}
- size_t getNumBuffers() const {
+ unsigned getNumBuffers() const {
return Buffers.size();
}
+ unsigned getMainFileID() const {
+ assert(getNumBuffers());
+ return 1;
+ }
+
SMLoc getParentIncludeLoc(unsigned i) const {
- assert(i < Buffers.size() && "Invalid Buffer ID!");
- return Buffers[i].IncludeLoc;
+ assert(isValidBufferID(i));
+ return Buffers[i - 1].IncludeLoc;
}
- /// AddNewSourceBuffer - Add a new source buffer to this source manager. This
- /// takes ownership of the memory buffer.
- size_t AddNewSourceBuffer(MemoryBuffer *F, SMLoc IncludeLoc) {
+ /// Add a new source buffer to this source manager. This takes ownership of
+ /// the memory buffer.
+ unsigned AddNewSourceBuffer(MemoryBuffer *F, SMLoc IncludeLoc) {
SrcBuffer NB;
NB.Buffer = F;
NB.IncludeLoc = IncludeLoc;
Buffers.push_back(NB);
- return Buffers.size() - 1;
+ return Buffers.size();
}
- /// AddIncludeFile - Search for a file with the specified name in the current
- /// directory or in one of the IncludeDirs. If no file is found, this returns
- /// ~0, otherwise it returns the buffer ID of the stacked file.
- /// The full path to the included file can be found in IncludedFile.
- size_t AddIncludeFile(const std::string &Filename, SMLoc IncludeLoc,
- std::string &IncludedFile);
+ /// Search for a file with the specified name in the current directory or in
+ /// one of the IncludeDirs.
+ ///
+ /// If no file is found, this returns 0, otherwise it returns the buffer ID
+ /// of the stacked file. The full path to the included file can be found in
+ /// \p IncludedFile.
+ unsigned AddIncludeFile(const std::string &Filename, SMLoc IncludeLoc,
+ std::string &IncludedFile);
- /// FindBufferContainingLoc - Return the ID of the buffer containing the
- /// specified location, returning -1 if not found.
- int FindBufferContainingLoc(SMLoc Loc) const;
+ /// Return the ID of the buffer containing the specified location.
+ ///
+ /// 0 is returned if the buffer is not found.
+ unsigned FindBufferContainingLoc(SMLoc Loc) const;
- /// FindLineNumber - Find the line number for the specified location in the
- /// specified file. This is not a fast method.
- unsigned FindLineNumber(SMLoc Loc, int BufferID = -1) const {
+ /// Find the line number for the specified location in the specified file.
+ /// This is not a fast method.
+ unsigned FindLineNumber(SMLoc Loc, unsigned BufferID = 0) const {
return getLineAndColumn(Loc, BufferID).first;
}
- /// getLineAndColumn - Find the line and column number for the specified
- /// location in the specified file. This is not a fast method.
- std::pair<unsigned, unsigned>
- getLineAndColumn(SMLoc Loc, int BufferID = -1) const;
+ /// Find the line and column number for the specified location in the
+ /// specified file. This is not a fast method.
+ std::pair<unsigned, unsigned> getLineAndColumn(SMLoc Loc,
+ unsigned BufferID = 0) const;
- /// PrintMessage - Emit a message about the specified location with the
- /// specified string.
+ /// Emit a message about the specified location with the specified string.
///
- /// @param ShowColors - Display colored messages if output is a terminal and
+ /// \param ShowColors Display colored messages if output is a terminal and
/// the default error handler is used.
void PrintMessage(raw_ostream &OS, SMLoc Loc, DiagKind Kind,
const Twine &Msg,
@@ -157,21 +164,28 @@ public:
ArrayRef<SMFixIt> FixIts = None,
bool ShowColors = true) const;
- /// GetMessage - Return an SMDiagnostic at the specified location with the
- /// specified string.
+ /// Emits a manually-constructed diagnostic to the given output stream.
+ ///
+ /// \param ShowColors Display colored messages if output is a terminal and
+ /// the default error handler is used.
+ void PrintMessage(raw_ostream &OS, const SMDiagnostic &Diagnostic,
+ bool ShowColors = true) const;
+
+ /// Return an SMDiagnostic at the specified location with the specified
+ /// string.
///
- /// @param Msg If non-null, the kind of message (e.g., "error") which is
+ /// \param Msg If non-null, the kind of message (e.g., "error") which is
/// prefixed to the message.
SMDiagnostic GetMessage(SMLoc Loc, DiagKind Kind, const Twine &Msg,
ArrayRef<SMRange> Ranges = None,
ArrayRef<SMFixIt> FixIts = None) const;
- /// PrintIncludeStack - Prints the names of included files and the line of the
- /// file they were included from. A diagnostic handler can use this before
- /// printing its custom formatted message.
+ /// Prints the names of included files and the line of the file they were
+ /// included from. A diagnostic handler can use this before printing its
+ /// custom formatted message.
///
- /// @param IncludeLoc - The line of the include.
- /// @param OS the raw_ostream to print on.
+ /// \param IncludeLoc The location of the include.
+ /// \param OS the raw_ostream to print on.
void PrintIncludeStack(SMLoc IncludeLoc, raw_ostream &OS) const;
};
@@ -208,8 +222,8 @@ public:
};
-/// SMDiagnostic - Instances of this class encapsulate one diagnostic report,
-/// allowing printing to a raw_ostream as a caret diagnostic.
+/// Instances of this class encapsulate one diagnostic report, allowing
+/// printing to a raw_ostream as a caret diagnostic.
class SMDiagnostic {
const SourceMgr *SM;
SMLoc Loc;
diff --git a/include/llvm/Support/SpecialCaseList.h b/include/llvm/Support/SpecialCaseList.h
new file mode 100644
index 0000000..098b9c7
--- /dev/null
+++ b/include/llvm/Support/SpecialCaseList.h
@@ -0,0 +1,96 @@
+//===-- SpecialCaseList.h - special case list for sanitizers ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//===----------------------------------------------------------------------===//
+//
+// This is a utility class used to parse user-provided text files with
+// "special case lists" for code sanitizers. Such files are used to
+// define "ABI list" for DataFlowSanitizer and blacklists for another sanitizers
+// like AddressSanitizer or UndefinedBehaviorSanitizer.
+//
+// Empty lines and lines starting with "#" are ignored. All the rest lines
+// should have the form:
+// section:wildcard_expression[=category]
+// If category is not specified, it is assumed to be empty string.
+// Definitions of "section" and "category" are sanitizer-specific. For example,
+// sanitizer blacklists support sections "src", "fun" and "global".
+// Wildcard expressions define, respectively, source files, functions or
+// globals which shouldn't be instrumented.
+// Examples of categories:
+// "functional": used in DFSan to list functions with pure functional
+// semantics.
+// "init": used in ASan blacklist to disable initialization-order bugs
+// detection for certain globals or source files.
+// Full special case list file example:
+// ---
+// # Blacklisted items:
+// fun:*_ZN4base6subtle*
+// global:*global_with_bad_access_or_initialization*
+// global:*global_with_initialization_issues*=init
+// type:*Namespace::ClassName*=init
+// src:file_with_tricky_code.cc
+// src:ignore-global-initializers-issues.cc=init
+//
+// # Functions with pure functional semantics:
+// fun:cos=functional
+// fun:sin=functional
+// ---
+// Note that the wild card is in fact an llvm::Regex, but * is automatically
+// replaced with .*
+// This is similar to the "ignore" feature of ThreadSanitizer.
+// http://code.google.com/p/data-race-test/wiki/ThreadSanitizerIgnores
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_SPECIALCASELIST_H
+#define LLVM_SUPPORT_SPECIALCASELIST_H
+
+#include "llvm/ADT/StringMap.h"
+
+namespace llvm {
+class MemoryBuffer;
+class Regex;
+class StringRef;
+
+class SpecialCaseList {
+ public:
+ /// Parses the special case list from a file. If Path is empty, returns
+ /// an empty special case list. On failure, returns 0 and writes an error
+ /// message to string.
+ static SpecialCaseList *create(const StringRef Path, std::string &Error);
+ /// Parses the special case list from a memory buffer. On failure, returns
+ /// 0 and writes an error message to string.
+ static SpecialCaseList *create(const MemoryBuffer *MB, std::string &Error);
+ /// Parses the special case list from a file. On failure, reports a fatal
+ /// error.
+ static SpecialCaseList *createOrDie(const StringRef Path);
+
+ ~SpecialCaseList();
+
+ /// Returns true, if special case list contains a line
+ /// \code
+ /// @Section:<E>=@Category
+ /// \endcode
+ /// and @Query satisfies a wildcard expression <E>.
+ bool inSection(const StringRef Section, const StringRef Query,
+ const StringRef Category = StringRef()) const;
+
+ private:
+ SpecialCaseList(SpecialCaseList const &) LLVM_DELETED_FUNCTION;
+ SpecialCaseList &operator=(SpecialCaseList const &) LLVM_DELETED_FUNCTION;
+
+ struct Entry;
+ StringMap<StringMap<Entry> > Entries;
+
+ SpecialCaseList();
+ /// Parses just-constructed SpecialCaseList entries from a memory buffer.
+ bool parse(const MemoryBuffer *MB, std::string &Error);
+};
+
+} // namespace llvm
+
+#endif // LLVM_SUPPORT_SPECIALCASELIST_H
+
diff --git a/include/llvm/Support/StreamableMemoryObject.h b/include/llvm/Support/StreamableMemoryObject.h
index 9c9e55c..6e71ad4 100644
--- a/include/llvm/Support/StreamableMemoryObject.h
+++ b/include/llvm/Support/StreamableMemoryObject.h
@@ -13,6 +13,7 @@
#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataStream.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MemoryObject.h"
#include <cassert>
#include <memory>
@@ -115,7 +116,7 @@ public:
// requiring that the bitcode size be known, or otherwise ensuring that
// the memory doesn't go away/get reallocated, but it's
// not currently necessary. Users that need the pointer don't stream.
- assert(0 && "getPointer in streaming memory objects not allowed");
+ llvm_unreachable("getPointer in streaming memory objects not allowed");
return nullptr;
}
bool isValidAddress(uint64_t address) const override;
@@ -154,8 +155,8 @@ private:
kChunkSize);
BytesRead += bytes;
if (bytes < kChunkSize) {
- if (ObjectSize && BytesRead < Pos)
- assert(0 && "Unexpected short read fetching bitcode");
+ assert((!ObjectSize || BytesRead >= Pos) &&
+ "Unexpected short read fetching bitcode");
if (BytesRead <= Pos) { // reached EOF/ran out of bytes
ObjectSize = BytesRead;
EOFReached = true;
diff --git a/include/llvm/Support/StringPool.h b/include/llvm/Support/StringPool.h
index 7e1394c..3e04653 100644
--- a/include/llvm/Support/StringPool.h
+++ b/include/llvm/Support/StringPool.h
@@ -29,6 +29,7 @@
#ifndef LLVM_SUPPORT_STRINGPOOL_H
#define LLVM_SUPPORT_STRINGPOOL_H
+#include "llvm/Support/Compiler.h"
#include "llvm/ADT/StringMap.h"
#include <cassert>
#include <new>
@@ -128,10 +129,10 @@ namespace llvm {
}
inline const char *operator*() const { return begin(); }
- inline operator bool() const { return S != nullptr; }
+ inline LLVM_EXPLICIT operator bool() const { return S != nullptr; }
- inline bool operator==(const PooledStringPtr &That) { return S == That.S; }
- inline bool operator!=(const PooledStringPtr &That) { return S != That.S; }
+ inline bool operator==(const PooledStringPtr &That) const { return S == That.S; }
+ inline bool operator!=(const PooledStringPtr &That) const { return S != That.S; }
};
} // End llvm namespace
diff --git a/include/llvm/Support/SwapByteOrder.h b/include/llvm/Support/SwapByteOrder.h
index e65f9cc..340954f 100644
--- a/include/llvm/Support/SwapByteOrder.h
+++ b/include/llvm/Support/SwapByteOrder.h
@@ -68,33 +68,38 @@ inline uint64_t SwapByteOrder_64(uint64_t value) {
#endif
}
-inline unsigned char SwapByteOrder(unsigned char C) { return C; }
-inline signed char SwapByteOrder(signed char C) { return C; }
-inline char SwapByteOrder(char C) { return C; }
+inline unsigned char getSwappedBytes(unsigned char C) { return C; }
+inline signed char getSwappedBytes(signed char C) { return C; }
+inline char getSwappedBytes(char C) { return C; }
-inline unsigned short SwapByteOrder(unsigned short C) { return SwapByteOrder_16(C); }
-inline signed short SwapByteOrder( signed short C) { return SwapByteOrder_16(C); }
+inline unsigned short getSwappedBytes(unsigned short C) { return SwapByteOrder_16(C); }
+inline signed short getSwappedBytes( signed short C) { return SwapByteOrder_16(C); }
-inline unsigned int SwapByteOrder(unsigned int C) { return SwapByteOrder_32(C); }
-inline signed int SwapByteOrder( signed int C) { return SwapByteOrder_32(C); }
+inline unsigned int getSwappedBytes(unsigned int C) { return SwapByteOrder_32(C); }
+inline signed int getSwappedBytes( signed int C) { return SwapByteOrder_32(C); }
#if __LONG_MAX__ == __INT_MAX__
-inline unsigned long SwapByteOrder(unsigned long C) { return SwapByteOrder_32(C); }
-inline signed long SwapByteOrder( signed long C) { return SwapByteOrder_32(C); }
+inline unsigned long getSwappedBytes(unsigned long C) { return SwapByteOrder_32(C); }
+inline signed long getSwappedBytes( signed long C) { return SwapByteOrder_32(C); }
#elif __LONG_MAX__ == __LONG_LONG_MAX__
-inline unsigned long SwapByteOrder(unsigned long C) { return SwapByteOrder_64(C); }
-inline signed long SwapByteOrder( signed long C) { return SwapByteOrder_64(C); }
+inline unsigned long getSwappedBytes(unsigned long C) { return SwapByteOrder_64(C); }
+inline signed long getSwappedBytes( signed long C) { return SwapByteOrder_64(C); }
#else
#error "Unknown long size!"
#endif
-inline unsigned long long SwapByteOrder(unsigned long long C) {
+inline unsigned long long getSwappedBytes(unsigned long long C) {
return SwapByteOrder_64(C);
}
-inline signed long long SwapByteOrder(signed long long C) {
+inline signed long long getSwappedBytes(signed long long C) {
return SwapByteOrder_64(C);
}
+template<typename T>
+inline void swapByteOrder(T &Value) {
+ Value = getSwappedBytes(Value);
+}
+
} // end namespace sys
} // end namespace llvm
diff --git a/include/llvm/Support/TargetRegistry.h b/include/llvm/Support/TargetRegistry.h
index fcdc604..5d5b86a 100644
--- a/include/llvm/Support/TargetRegistry.h
+++ b/include/llvm/Support/TargetRegistry.h
@@ -51,6 +51,7 @@ namespace llvm {
class raw_ostream;
class formatted_raw_ostream;
+ MCStreamer *createNullStreamer(MCContext &Ctx);
MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
bool isVerboseAsm, bool useDwarfDirectory,
MCInstPrinter *InstPrint, MCCodeEmitter *CE,
@@ -139,6 +140,7 @@ namespace llvm {
MCCodeEmitter *CE,
MCAsmBackend *TAB,
bool ShowInst);
+ typedef MCStreamer *(*NullStreamerCtorTy)(MCContext &Ctx);
typedef MCRelocationInfo *(*MCRelocationInfoCtorTy)(StringRef TT,
MCContext &Ctx);
typedef MCSymbolizer *(*MCSymbolizerCtorTy)(StringRef TT,
@@ -225,6 +227,10 @@ namespace llvm {
/// AsmStreamer, if registered (default = llvm::createAsmStreamer).
AsmStreamerCtorTy AsmStreamerCtorFn;
+ /// Construction function for this target's NullStreamer, if registered
+ /// (default = llvm::createNullStreamer).
+ NullStreamerCtorTy NullStreamerCtorFn;
+
/// MCRelocationInfoCtorFn - Construction function for this target's
/// MCRelocationInfo, if registered (default = llvm::createMCRelocationInfo)
MCRelocationInfoCtorTy MCRelocationInfoCtorFn;
@@ -235,8 +241,8 @@ namespace llvm {
public:
Target()
- : AsmStreamerCtorFn(nullptr), MCRelocationInfoCtorFn(nullptr),
- MCSymbolizerCtorFn(nullptr) {}
+ : AsmStreamerCtorFn(nullptr), NullStreamerCtorFn(nullptr),
+ MCRelocationInfoCtorFn(nullptr), MCSymbolizerCtorFn(nullptr) {}
/// @name Target Information
/// @{
@@ -447,6 +453,12 @@ namespace llvm {
InstPrint, CE, TAB, ShowInst);
}
+ MCStreamer *createNullStreamer(MCContext &Ctx) const {
+ if (NullStreamerCtorFn)
+ return NullStreamerCtorFn(Ctx);
+ return llvm::createNullStreamer(Ctx);
+ }
+
/// createMCRelocationInfo - Create a target specific MCRelocationInfo.
///
/// \param TT The target triple.
@@ -553,13 +565,6 @@ namespace llvm {
Triple &TheTriple,
std::string &Error);
- /// getClosestTargetForJIT - Pick the best target that is compatible with
- /// the current host. If no close target can be found, this returns null
- /// and sets the Error string to a reason.
- ///
- /// Maintained for compatibility through 2.6.
- static const Target *getClosestTargetForJIT(std::string &Error);
-
/// @}
/// @name Target Registration
/// @{
@@ -780,6 +785,10 @@ namespace llvm {
T.AsmStreamerCtorFn = Fn;
}
+ static void RegisterNullStreamer(Target &T, Target::NullStreamerCtorTy Fn) {
+ T.NullStreamerCtorFn = Fn;
+ }
+
/// RegisterMCRelocationInfo - Register an MCRelocationInfo
/// implementation for the given target.
///
diff --git a/include/llvm/Support/Threading.h b/include/llvm/Support/Threading.h
index a7e8774..7e87584 100644
--- a/include/llvm/Support/Threading.h
+++ b/include/llvm/Support/Threading.h
@@ -7,7 +7,8 @@
//
//===----------------------------------------------------------------------===//
//
-// TThis file defines llvm_start_multithreaded() and friends.
+// This file declares helper functions for running LLVM in a multi-threaded
+// environment.
//
//===----------------------------------------------------------------------===//
@@ -15,32 +16,10 @@
#define LLVM_SUPPORT_THREADING_H
namespace llvm {
- /// llvm_start_multithreaded - Allocate and initialize structures needed to
- /// make LLVM safe for multithreading. The return value indicates whether
- /// multithreaded initialization succeeded. LLVM will still be operational
- /// on "failed" return, and will still be safe for hosting threading
- /// applications in the JIT, but will not be safe for concurrent calls to the
- /// LLVM APIs.
- /// THIS MUST EXECUTE IN ISOLATION FROM ALL OTHER LLVM API CALLS.
- bool llvm_start_multithreaded();
-
- /// llvm_stop_multithreaded - Deallocate structures necessary to make LLVM
- /// safe for multithreading.
- /// THIS MUST EXECUTE IN ISOLATION FROM ALL OTHER LLVM API CALLS.
- void llvm_stop_multithreaded();
-
- /// llvm_is_multithreaded - Check whether LLVM is executing in thread-safe
- /// mode or not.
+ /// Returns true if LLVM is compiled with support for multi-threading, and
+ /// false otherwise.
bool llvm_is_multithreaded();
- /// acquire_global_lock - Acquire the global lock. This is a no-op if called
- /// before llvm_start_multithreaded().
- void llvm_acquire_global_lock();
-
- /// release_global_lock - Release the global lock. This is a no-op if called
- /// before llvm_start_multithreaded().
- void llvm_release_global_lock();
-
/// llvm_execute_on_thread - Execute the given \p UserFn on a separate
/// thread, passing it the provided \p UserData.
///
diff --git a/include/llvm/Support/WindowsError.h b/include/llvm/Support/WindowsError.h
new file mode 100644
index 0000000..0e909a0
--- /dev/null
+++ b/include/llvm/Support/WindowsError.h
@@ -0,0 +1,19 @@
+//===-- WindowsError.h - Support for mapping windows errors to posix-------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_WINDOWS_ERROR_H
+#define LLVM_SUPPORT_WINDOWS_ERROR_H
+
+#include <system_error>
+
+namespace llvm {
+std::error_code mapWindowsError(unsigned EV);
+}
+
+#endif
diff --git a/include/llvm/Support/YAMLTraits.h b/include/llvm/Support/YAMLTraits.h
index 4ee05ed..a23faf6 100644
--- a/include/llvm/Support/YAMLTraits.h
+++ b/include/llvm/Support/YAMLTraits.h
@@ -24,7 +24,7 @@
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/YAMLParser.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/system_error.h"
+#include <system_error>
namespace llvm {
namespace yaml {
@@ -880,7 +880,7 @@ public:
~Input();
// Check if there was an syntax or semantic error during parsing.
- llvm::error_code error();
+ std::error_code error();
private:
bool outputting() override;
@@ -982,13 +982,13 @@ public:
// These are only used by operator>>. They could be private
// if those templated things could be made friends.
bool setCurrentDocument();
- void nextDocument();
+ bool nextDocument();
private:
llvm::SourceMgr SrcMgr; // must be before Strm
std::unique_ptr<llvm::yaml::Stream> Strm;
std::unique_ptr<HNode> TopNode;
- llvm::error_code EC;
+ std::error_code EC;
llvm::BumpPtrAllocator StringAllocator;
llvm::yaml::document_iterator DocIterator;
std::vector<bool> BitValuesUsed;
diff --git a/include/llvm/Support/system_error.h b/include/llvm/Support/system_error.h
deleted file mode 100644
index aa5e9f7..0000000
--- a/include/llvm/Support/system_error.h
+++ /dev/null
@@ -1,901 +0,0 @@
-//===---------------------------- system_error ------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This was lifted from libc++ and modified for C++03. This is called
-// system_error even though it does not define that class because that's what
-// it's called in C++0x. We don't define system_error because it is only used
-// for exception handling, which we don't use in LLVM.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SUPPORT_SYSTEM_ERROR_H
-#define LLVM_SUPPORT_SYSTEM_ERROR_H
-
-#include "llvm/Support/Compiler.h"
-
-/*
- system_error synopsis
-
-namespace std
-{
-
-class error_category
-{
-public:
- virtual ~error_category();
-
- error_category(const error_category&) = delete;
- error_category& operator=(const error_category&) = delete;
-
- virtual const char* name() const = 0;
- virtual error_condition default_error_condition(int ev) const;
- virtual bool equivalent(int code, const error_condition& condition) const;
- virtual bool equivalent(const error_code& code, int condition) const;
- virtual std::string message(int ev) const = 0;
-
- bool operator==(const error_category& rhs) const;
- bool operator!=(const error_category& rhs) const;
- bool operator<(const error_category& rhs) const;
-};
-
-const error_category& generic_category();
-const error_category& system_category();
-
-template <class T> struct is_error_code_enum
- : public std::false_type {};
-
-template <class T> struct is_error_condition_enum
- : public std::false_type {};
-
-class error_code
-{
-public:
- // constructors:
- error_code();
- error_code(int val, const error_category& cat);
- template <class ErrorCodeEnum>
- error_code(ErrorCodeEnum e);
-
- // modifiers:
- void assign(int val, const error_category& cat);
- template <class ErrorCodeEnum>
- error_code& operator=(ErrorCodeEnum e);
- void clear();
-
- // observers:
- int value() const;
- const error_category& category() const;
- error_condition default_error_condition() const;
- std::string message() const;
- explicit operator bool() const;
-};
-
-// non-member functions:
-bool operator<(const error_code& lhs, const error_code& rhs);
-template <class charT, class traits>
- basic_ostream<charT,traits>&
- operator<<(basic_ostream<charT,traits>& os, const error_code& ec);
-
-class error_condition
-{
-public:
- // constructors:
- error_condition();
- error_condition(int val, const error_category& cat);
- template <class ErrorConditionEnum>
- error_condition(ErrorConditionEnum e);
-
- // modifiers:
- void assign(int val, const error_category& cat);
- template <class ErrorConditionEnum>
- error_condition& operator=(ErrorConditionEnum e);
- void clear();
-
- // observers:
- int value() const;
- const error_category& category() const;
- std::string message() const;
- explicit operator bool() const;
-};
-
-bool operator<(const error_condition& lhs, const error_condition& rhs);
-
-class system_error
- : public runtime_error
-{
-public:
- system_error(error_code ec, const std::string& what_arg);
- system_error(error_code ec, const char* what_arg);
- system_error(error_code ec);
- system_error(int ev, const error_category& ecat, const std::string& what_arg);
- system_error(int ev, const error_category& ecat, const char* what_arg);
- system_error(int ev, const error_category& ecat);
-
- const error_code& code() const throw();
- const char* what() const throw();
-};
-
-enum class errc
-{
- address_family_not_supported, // EAFNOSUPPORT
- address_in_use, // EADDRINUSE
- address_not_available, // EADDRNOTAVAIL
- already_connected, // EISCONN
- argument_list_too_long, // E2BIG
- argument_out_of_domain, // EDOM
- bad_address, // EFAULT
- bad_file_descriptor, // EBADF
- bad_message, // EBADMSG
- broken_pipe, // EPIPE
- connection_aborted, // ECONNABORTED
- connection_already_in_progress, // EALREADY
- connection_refused, // ECONNREFUSED
- connection_reset, // ECONNRESET
- cross_device_link, // EXDEV
- destination_address_required, // EDESTADDRREQ
- device_or_resource_busy, // EBUSY
- directory_not_empty, // ENOTEMPTY
- executable_format_error, // ENOEXEC
- file_exists, // EEXIST
- file_too_large, // EFBIG
- filename_too_long, // ENAMETOOLONG
- function_not_supported, // ENOSYS
- host_unreachable, // EHOSTUNREACH
- identifier_removed, // EIDRM
- illegal_byte_sequence, // EILSEQ
- inappropriate_io_control_operation, // ENOTTY
- interrupted, // EINTR
- invalid_argument, // EINVAL
- invalid_seek, // ESPIPE
- io_error, // EIO
- is_a_directory, // EISDIR
- message_size, // EMSGSIZE
- network_down, // ENETDOWN
- network_reset, // ENETRESET
- network_unreachable, // ENETUNREACH
- no_buffer_space, // ENOBUFS
- no_child_process, // ECHILD
- no_link, // ENOLINK
- no_lock_available, // ENOLCK
- no_message_available, // ENODATA
- no_message, // ENOMSG
- no_protocol_option, // ENOPROTOOPT
- no_space_on_device, // ENOSPC
- no_stream_resources, // ENOSR
- no_such_device_or_address, // ENXIO
- no_such_device, // ENODEV
- no_such_file_or_directory, // ENOENT
- no_such_process, // ESRCH
- not_a_directory, // ENOTDIR
- not_a_socket, // ENOTSOCK
- not_a_stream, // ENOSTR
- not_connected, // ENOTCONN
- not_enough_memory, // ENOMEM
- not_supported, // ENOTSUP
- operation_canceled, // ECANCELED
- operation_in_progress, // EINPROGRESS
- operation_not_permitted, // EPERM
- operation_not_supported, // EOPNOTSUPP
- operation_would_block, // EWOULDBLOCK
- owner_dead, // EOWNERDEAD
- permission_denied, // EACCES
- protocol_error, // EPROTO
- protocol_not_supported, // EPROTONOSUPPORT
- read_only_file_system, // EROFS
- resource_deadlock_would_occur, // EDEADLK
- resource_unavailable_try_again, // EAGAIN
- result_out_of_range, // ERANGE
- state_not_recoverable, // ENOTRECOVERABLE
- stream_timeout, // ETIME
- text_file_busy, // ETXTBSY
- timed_out, // ETIMEDOUT
- too_many_files_open_in_system, // ENFILE
- too_many_files_open, // EMFILE
- too_many_links, // EMLINK
- too_many_symbolic_link_levels, // ELOOP
- value_too_large, // EOVERFLOW
- wrong_protocol_type // EPROTOTYPE
-};
-
-template <> struct is_error_condition_enum<errc> : std::true_type { }
-
-error_code make_error_code(errc e);
-error_condition make_error_condition(errc e);
-
-// Comparison operators:
-bool operator==(const error_code& lhs, const error_code& rhs);
-bool operator==(const error_code& lhs, const error_condition& rhs);
-bool operator==(const error_condition& lhs, const error_code& rhs);
-bool operator==(const error_condition& lhs, const error_condition& rhs);
-bool operator!=(const error_code& lhs, const error_code& rhs);
-bool operator!=(const error_code& lhs, const error_condition& rhs);
-bool operator!=(const error_condition& lhs, const error_code& rhs);
-bool operator!=(const error_condition& lhs, const error_condition& rhs);
-
-template <> struct hash<std::error_code>;
-
-} // std
-
-*/
-
-#include "llvm/Config/llvm-config.h"
-#include <cerrno>
-#include <string>
-
-// This must be here instead of a .inc file because it is used in the definition
-// of the enum values below.
-#ifdef LLVM_ON_WIN32
-
- // The following numbers were taken from VS2010.
-# ifndef EAFNOSUPPORT
-# define EAFNOSUPPORT 102
-# endif
-# ifndef EADDRINUSE
-# define EADDRINUSE 100
-# endif
-# ifndef EADDRNOTAVAIL
-# define EADDRNOTAVAIL 101
-# endif
-# ifndef EISCONN
-# define EISCONN 113
-# endif
-# ifndef E2BIG
-# define E2BIG 7
-# endif
-# ifndef EDOM
-# define EDOM 33
-# endif
-# ifndef EFAULT
-# define EFAULT 14
-# endif
-# ifndef EBADF
-# define EBADF 9
-# endif
-# ifndef EBADMSG
-# define EBADMSG 104
-# endif
-# ifndef EPIPE
-# define EPIPE 32
-# endif
-# ifndef ECONNABORTED
-# define ECONNABORTED 106
-# endif
-# ifndef EALREADY
-# define EALREADY 103
-# endif
-# ifndef ECONNREFUSED
-# define ECONNREFUSED 107
-# endif
-# ifndef ECONNRESET
-# define ECONNRESET 108
-# endif
-# ifndef EXDEV
-# define EXDEV 18
-# endif
-# ifndef EDESTADDRREQ
-# define EDESTADDRREQ 109
-# endif
-# ifndef EBUSY
-# define EBUSY 16
-# endif
-# ifndef ENOTEMPTY
-# define ENOTEMPTY 41
-# endif
-# ifndef ENOEXEC
-# define ENOEXEC 8
-# endif
-# ifndef EEXIST
-# define EEXIST 17
-# endif
-# ifndef EFBIG
-# define EFBIG 27
-# endif
-# ifndef ENAMETOOLONG
-# define ENAMETOOLONG 38
-# endif
-# ifndef ENOSYS
-# define ENOSYS 40
-# endif
-# ifndef EHOSTUNREACH
-# define EHOSTUNREACH 110
-# endif
-# ifndef EIDRM
-# define EIDRM 111
-# endif
-# ifndef EILSEQ
-# define EILSEQ 42
-# endif
-# ifndef ENOTTY
-# define ENOTTY 25
-# endif
-# ifndef EINTR
-# define EINTR 4
-# endif
-# ifndef EINVAL
-# define EINVAL 22
-# endif
-# ifndef ESPIPE
-# define ESPIPE 29
-# endif
-# ifndef EIO
-# define EIO 5
-# endif
-# ifndef EISDIR
-# define EISDIR 21
-# endif
-# ifndef EMSGSIZE
-# define EMSGSIZE 115
-# endif
-# ifndef ENETDOWN
-# define ENETDOWN 116
-# endif
-# ifndef ENETRESET
-# define ENETRESET 117
-# endif
-# ifndef ENETUNREACH
-# define ENETUNREACH 118
-# endif
-# ifndef ENOBUFS
-# define ENOBUFS 119
-# endif
-# ifndef ECHILD
-# define ECHILD 10
-# endif
-# ifndef ENOLINK
-# define ENOLINK 121
-# endif
-# ifndef ENOLCK
-# define ENOLCK 39
-# endif
-# ifndef ENODATA
-# define ENODATA 120
-# endif
-# ifndef ENOMSG
-# define ENOMSG 122
-# endif
-# ifndef ENOPROTOOPT
-# define ENOPROTOOPT 123
-# endif
-# ifndef ENOSPC
-# define ENOSPC 28
-# endif
-# ifndef ENOSR
-# define ENOSR 124
-# endif
-# ifndef ENXIO
-# define ENXIO 6
-# endif
-# ifndef ENODEV
-# define ENODEV 19
-# endif
-# ifndef ENOENT
-# define ENOENT 2
-# endif
-# ifndef ESRCH
-# define ESRCH 3
-# endif
-# ifndef ENOTDIR
-# define ENOTDIR 20
-# endif
-# ifndef ENOTSOCK
-# define ENOTSOCK 128
-# endif
-# ifndef ENOSTR
-# define ENOSTR 125
-# endif
-# ifndef ENOTCONN
-# define ENOTCONN 126
-# endif
-# ifndef ENOMEM
-# define ENOMEM 12
-# endif
-# ifndef ENOTSUP
-# define ENOTSUP 129
-# endif
-# ifndef ECANCELED
-# define ECANCELED 105
-# endif
-# ifndef EINPROGRESS
-# define EINPROGRESS 112
-# endif
-# ifndef EPERM
-# define EPERM 1
-# endif
-# ifndef EOPNOTSUPP
-# define EOPNOTSUPP 130
-# endif
-# ifndef EWOULDBLOCK
-# define EWOULDBLOCK 140
-# endif
-# ifndef EOWNERDEAD
-# define EOWNERDEAD 133
-# endif
-# ifndef EACCES
-# define EACCES 13
-# endif
-# ifndef EPROTO
-# define EPROTO 134
-# endif
-# ifndef EPROTONOSUPPORT
-# define EPROTONOSUPPORT 135
-# endif
-# ifndef EROFS
-# define EROFS 30
-# endif
-# ifndef EDEADLK
-# define EDEADLK 36
-# endif
-# ifndef EAGAIN
-# define EAGAIN 11
-# endif
-# ifndef ERANGE
-# define ERANGE 34
-# endif
-# ifndef ENOTRECOVERABLE
-# define ENOTRECOVERABLE 127
-# endif
-# ifndef ETIME
-# define ETIME 137
-# endif
-# ifndef ETXTBSY
-# define ETXTBSY 139
-# endif
-# ifndef ETIMEDOUT
-# define ETIMEDOUT 138
-# endif
-# ifndef ENFILE
-# define ENFILE 23
-# endif
-# ifndef EMFILE
-# define EMFILE 24
-# endif
-# ifndef EMLINK
-# define EMLINK 31
-# endif
-# ifndef ELOOP
-# define ELOOP 114
-# endif
-# ifndef EOVERFLOW
-# define EOVERFLOW 132
-# endif
-# ifndef EPROTOTYPE
-# define EPROTOTYPE 136
-# endif
-#endif
-
-namespace llvm {
-
-// is_error_code_enum
-
-template <class Tp> struct is_error_code_enum : public std::false_type {};
-
-// is_error_condition_enum
-
-template <class Tp> struct is_error_condition_enum : public std::false_type {};
-
-// Some error codes are not present on all platforms, so we provide equivalents
-// for them:
-
-//enum class errc
-struct errc {
-enum _ {
- success = 0,
- address_family_not_supported = EAFNOSUPPORT,
- address_in_use = EADDRINUSE,
- address_not_available = EADDRNOTAVAIL,
- already_connected = EISCONN,
- argument_list_too_long = E2BIG,
- argument_out_of_domain = EDOM,
- bad_address = EFAULT,
- bad_file_descriptor = EBADF,
-#ifdef EBADMSG
- bad_message = EBADMSG,
-#else
- bad_message = EINVAL,
-#endif
- broken_pipe = EPIPE,
- connection_aborted = ECONNABORTED,
- connection_already_in_progress = EALREADY,
- connection_refused = ECONNREFUSED,
- connection_reset = ECONNRESET,
- cross_device_link = EXDEV,
- destination_address_required = EDESTADDRREQ,
- device_or_resource_busy = EBUSY,
- directory_not_empty = ENOTEMPTY,
- executable_format_error = ENOEXEC,
- file_exists = EEXIST,
- file_too_large = EFBIG,
- filename_too_long = ENAMETOOLONG,
- function_not_supported = ENOSYS,
- host_unreachable = EHOSTUNREACH,
- identifier_removed = EIDRM,
- illegal_byte_sequence = EILSEQ,
- inappropriate_io_control_operation = ENOTTY,
- interrupted = EINTR,
- invalid_argument = EINVAL,
- invalid_seek = ESPIPE,
- io_error = EIO,
- is_a_directory = EISDIR,
- message_size = EMSGSIZE,
- network_down = ENETDOWN,
- network_reset = ENETRESET,
- network_unreachable = ENETUNREACH,
- no_buffer_space = ENOBUFS,
- no_child_process = ECHILD,
-#ifdef ENOLINK
- no_link = ENOLINK,
-#else
- no_link = EINVAL,
-#endif
- no_lock_available = ENOLCK,
-#ifdef ENODATA
- no_message_available = ENODATA,
-#else
- no_message_available = ENOMSG,
-#endif
- no_message = ENOMSG,
- no_protocol_option = ENOPROTOOPT,
- no_space_on_device = ENOSPC,
-#ifdef ENOSR
- no_stream_resources = ENOSR,
-#else
- no_stream_resources = ENOMEM,
-#endif
- no_such_device_or_address = ENXIO,
- no_such_device = ENODEV,
- no_such_file_or_directory = ENOENT,
- no_such_process = ESRCH,
- not_a_directory = ENOTDIR,
- not_a_socket = ENOTSOCK,
-#ifdef ENOSTR
- not_a_stream = ENOSTR,
-#else
- not_a_stream = EINVAL,
-#endif
- not_connected = ENOTCONN,
- not_enough_memory = ENOMEM,
- not_supported = ENOTSUP,
-#ifdef ECANCELED
- operation_canceled = ECANCELED,
-#else
- operation_canceled = EINVAL,
-#endif
- operation_in_progress = EINPROGRESS,
- operation_not_permitted = EPERM,
- operation_not_supported = EOPNOTSUPP,
- operation_would_block = EWOULDBLOCK,
-#ifdef EOWNERDEAD
- owner_dead = EOWNERDEAD,
-#else
- owner_dead = EINVAL,
-#endif
- permission_denied = EACCES,
-#ifdef EPROTO
- protocol_error = EPROTO,
-#else
- protocol_error = EINVAL,
-#endif
- protocol_not_supported = EPROTONOSUPPORT,
- read_only_file_system = EROFS,
- resource_deadlock_would_occur = EDEADLK,
- resource_unavailable_try_again = EAGAIN,
- result_out_of_range = ERANGE,
-#ifdef ENOTRECOVERABLE
- state_not_recoverable = ENOTRECOVERABLE,
-#else
- state_not_recoverable = EINVAL,
-#endif
-#ifdef ETIME
- stream_timeout = ETIME,
-#else
- stream_timeout = ETIMEDOUT,
-#endif
- text_file_busy = ETXTBSY,
- timed_out = ETIMEDOUT,
- too_many_files_open_in_system = ENFILE,
- too_many_files_open = EMFILE,
- too_many_links = EMLINK,
- too_many_symbolic_link_levels = ELOOP,
- value_too_large = EOVERFLOW,
- wrong_protocol_type = EPROTOTYPE
-};
-
- _ v_;
-
- errc(_ v) : v_(v) {}
- operator int() const {return v_;}
-};
-
-template <> struct is_error_condition_enum<errc> : std::true_type { };
-
-template <> struct is_error_condition_enum<errc::_> : std::true_type { };
-
-class error_condition;
-class error_code;
-
-// class error_category
-
-class _do_message;
-
-class error_category
-{
-public:
- virtual ~error_category();
-
- error_category();
-private:
- error_category(const error_category&) LLVM_DELETED_FUNCTION;
- error_category& operator=(const error_category&) LLVM_DELETED_FUNCTION;
-
-public:
- virtual const char* name() const = 0;
- virtual error_condition default_error_condition(int _ev) const;
- virtual bool equivalent(int _code, const error_condition& _condition) const;
- virtual bool equivalent(const error_code& _code, int _condition) const;
- virtual std::string message(int _ev) const = 0;
-
- bool operator==(const error_category& _rhs) const {return this == &_rhs;}
-
- bool operator!=(const error_category& _rhs) const {return !(*this == _rhs);}
-
- bool operator< (const error_category& _rhs) const {return this < &_rhs;}
-
- friend class _do_message;
-};
-
-class _do_message : public error_category
-{
-public:
- std::string message(int ev) const override;
-};
-
-const error_category& generic_category();
-const error_category& system_category();
-
-/// Get the error_category used for errno values from POSIX functions. This is
-/// the same as the system_category on POSIX systems, but is the same as the
-/// generic_category on Windows.
-const error_category& posix_category();
-
-class error_condition
-{
- int _val_;
- const error_category* _cat_;
-public:
- error_condition() : _val_(0), _cat_(&generic_category()) {}
-
- error_condition(int _val, const error_category& _cat)
- : _val_(_val), _cat_(&_cat) {}
-
- template <class E>
- error_condition(E _e, typename std::enable_if<
- is_error_condition_enum<E>::value
- >::type* = 0)
- {*this = make_error_condition(_e);}
-
- void assign(int _val, const error_category& _cat) {
- _val_ = _val;
- _cat_ = &_cat;
- }
-
- template <class E>
- typename std::enable_if<is_error_condition_enum<E>::value,
- error_condition &>::type
- operator=(E _e) {
- *this = make_error_condition(_e);
- return *this;
- }
-
- void clear() {
- _val_ = 0;
- _cat_ = &generic_category();
- }
-
- int value() const {return _val_;}
-
- const error_category& category() const {return *_cat_;}
- std::string message() const;
-
- typedef void (*unspecified_bool_type)();
- static void unspecified_bool_true() {}
-
- operator unspecified_bool_type() const { // true if error
- return _val_ == 0 ? nullptr : unspecified_bool_true;
- }
-};
-
-inline error_condition make_error_condition(errc _e) {
- return error_condition(static_cast<int>(_e), generic_category());
-}
-
-inline bool operator<(const error_condition& _x, const error_condition& _y) {
- return _x.category() < _y.category()
- || (_x.category() == _y.category() && _x.value() < _y.value());
-}
-
-// error_code
-
-class error_code {
- int _val_;
- const error_category* _cat_;
-public:
- error_code() : _val_(0), _cat_(&system_category()) {}
-
- static error_code success() {
- return error_code();
- }
-
- error_code(int _val, const error_category& _cat)
- : _val_(_val), _cat_(&_cat) {}
-
- template <class E>
- error_code(E _e, typename std::enable_if<
- is_error_code_enum<E>::value
- >::type* = 0) {
- *this = make_error_code(_e);
- }
-
- void assign(int _val, const error_category& _cat) {
- _val_ = _val;
- _cat_ = &_cat;
- }
-
- template <class E>
- typename std::enable_if<is_error_code_enum<E>::value, error_code &>::type
- operator=(E _e) {
- *this = make_error_code(_e);
- return *this;
- }
-
- void clear() {
- _val_ = 0;
- _cat_ = &system_category();
- }
-
- int value() const {return _val_;}
-
- const error_category& category() const {return *_cat_;}
-
- error_condition default_error_condition() const
- {return _cat_->default_error_condition(_val_);}
-
- std::string message() const;
-
- typedef void (*unspecified_bool_type)();
- static void unspecified_bool_true() {}
-
- operator unspecified_bool_type() const { // true if error
- return _val_ == 0 ? nullptr : unspecified_bool_true;
- }
-};
-
-inline error_code make_error_code(errc _e) {
- return error_code(static_cast<int>(_e), generic_category());
-}
-
-inline bool operator<(const error_code& _x, const error_code& _y) {
- return _x.category() < _y.category()
- || (_x.category() == _y.category() && _x.value() < _y.value());
-}
-
-inline bool operator==(const error_code& _x, const error_code& _y) {
- return _x.category() == _y.category() && _x.value() == _y.value();
-}
-
-inline bool operator==(const error_code& _x, const error_condition& _y) {
- return _x.category().equivalent(_x.value(), _y)
- || _y.category().equivalent(_x, _y.value());
-}
-
-inline bool operator==(const error_condition& _x, const error_code& _y) {
- return _y == _x;
-}
-
-inline bool operator==(const error_condition& _x, const error_condition& _y) {
- return _x.category() == _y.category() && _x.value() == _y.value();
-}
-
-inline bool operator!=(const error_code& _x, const error_code& _y) {
- return !(_x == _y);
-}
-
-inline bool operator!=(const error_code& _x, const error_condition& _y) {
- return !(_x == _y);
-}
-
-inline bool operator!=(const error_condition& _x, const error_code& _y) {
- return !(_x == _y);
-}
-
-inline bool operator!=(const error_condition& _x, const error_condition& _y) {
- return !(_x == _y);
-}
-
-// Windows errors.
-
-// To construct an error_code after an API error:
-//
-// error_code( ::GetLastError(), system_category() )
-struct windows_error {
-enum _ {
- success = 0,
- // These names and values are based on Windows WinError.h
- // This is not a complete list. Add to this list if you need to explicitly
- // check for it.
- invalid_function = 1, // ERROR_INVALID_FUNCTION,
- file_not_found = 2, // ERROR_FILE_NOT_FOUND,
- path_not_found = 3, // ERROR_PATH_NOT_FOUND,
- too_many_open_files = 4, // ERROR_TOO_MANY_OPEN_FILES,
- access_denied = 5, // ERROR_ACCESS_DENIED,
- invalid_handle = 6, // ERROR_INVALID_HANDLE,
- arena_trashed = 7, // ERROR_ARENA_TRASHED,
- not_enough_memory = 8, // ERROR_NOT_ENOUGH_MEMORY,
- invalid_block = 9, // ERROR_INVALID_BLOCK,
- bad_environment = 10, // ERROR_BAD_ENVIRONMENT,
- bad_format = 11, // ERROR_BAD_FORMAT,
- invalid_access = 12, // ERROR_INVALID_ACCESS,
- outofmemory = 14, // ERROR_OUTOFMEMORY,
- invalid_drive = 15, // ERROR_INVALID_DRIVE,
- current_directory = 16, // ERROR_CURRENT_DIRECTORY,
- not_same_device = 17, // ERROR_NOT_SAME_DEVICE,
- no_more_files = 18, // ERROR_NO_MORE_FILES,
- write_protect = 19, // ERROR_WRITE_PROTECT,
- bad_unit = 20, // ERROR_BAD_UNIT,
- not_ready = 21, // ERROR_NOT_READY,
- bad_command = 22, // ERROR_BAD_COMMAND,
- crc = 23, // ERROR_CRC,
- bad_length = 24, // ERROR_BAD_LENGTH,
- seek = 25, // ERROR_SEEK,
- not_dos_disk = 26, // ERROR_NOT_DOS_DISK,
- sector_not_found = 27, // ERROR_SECTOR_NOT_FOUND,
- out_of_paper = 28, // ERROR_OUT_OF_PAPER,
- write_fault = 29, // ERROR_WRITE_FAULT,
- read_fault = 30, // ERROR_READ_FAULT,
- gen_failure = 31, // ERROR_GEN_FAILURE,
- sharing_violation = 32, // ERROR_SHARING_VIOLATION,
- lock_violation = 33, // ERROR_LOCK_VIOLATION,
- wrong_disk = 34, // ERROR_WRONG_DISK,
- sharing_buffer_exceeded = 36, // ERROR_SHARING_BUFFER_EXCEEDED,
- handle_eof = 38, // ERROR_HANDLE_EOF,
- handle_disk_full = 39, // ERROR_HANDLE_DISK_FULL,
- rem_not_list = 51, // ERROR_REM_NOT_LIST,
- dup_name = 52, // ERROR_DUP_NAME,
- bad_net_path = 53, // ERROR_BAD_NETPATH,
- network_busy = 54, // ERROR_NETWORK_BUSY,
- file_exists = 80, // ERROR_FILE_EXISTS,
- cannot_make = 82, // ERROR_CANNOT_MAKE,
- broken_pipe = 109, // ERROR_BROKEN_PIPE,
- open_failed = 110, // ERROR_OPEN_FAILED,
- buffer_overflow = 111, // ERROR_BUFFER_OVERFLOW,
- disk_full = 112, // ERROR_DISK_FULL,
- insufficient_buffer = 122, // ERROR_INSUFFICIENT_BUFFER,
- lock_failed = 167, // ERROR_LOCK_FAILED,
- busy = 170, // ERROR_BUSY,
- cancel_violation = 173, // ERROR_CANCEL_VIOLATION,
- already_exists = 183 // ERROR_ALREADY_EXISTS
-};
- _ v_;
-
- windows_error(_ v) : v_(v) {}
- explicit windows_error(int v) : v_(_(v)) {}
- operator int() const {return v_;}
-};
-
-
-template <> struct is_error_code_enum<windows_error> : std::true_type { };
-
-template <> struct is_error_code_enum<windows_error::_> : std::true_type { };
-
-inline error_code make_error_code(windows_error e) {
- return error_code(static_cast<int>(e), system_category());
-}
-
-} // end namespace llvm
-
-#endif