summaryrefslogtreecommitdiffstats
path: root/include/llvm/Support
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/Support')
-rw-r--r--include/llvm/Support/Allocator.h15
-rw-r--r--include/llvm/Support/BlockFrequency.h10
-rw-r--r--include/llvm/Support/COFF.h7
-rw-r--r--include/llvm/Support/CommandLine.h4
-rw-r--r--include/llvm/Support/Compiler.h26
-rw-r--r--include/llvm/Support/Compression.h2
-rw-r--r--include/llvm/Support/Debug.h4
-rw-r--r--include/llvm/Support/DebugLoc.h4
-rw-r--r--include/llvm/Support/Dwarf.h250
-rw-r--r--include/llvm/Support/ELF.h63
-rw-r--r--include/llvm/Support/ErrorOr.h266
-rw-r--r--include/llvm/Support/FileSystem.h31
-rw-r--r--include/llvm/Support/FormattedStream.h21
-rw-r--r--include/llvm/Support/GCOV.h105
-rw-r--r--include/llvm/Support/IntegersSubset.h540
-rw-r--r--include/llvm/Support/IntegersSubsetMapping.h588
-rw-r--r--include/llvm/Support/MachO.h823
-rw-r--r--include/llvm/Support/ManagedStatic.h1
-rw-r--r--include/llvm/Support/MathExtras.h10
-rw-r--r--include/llvm/Support/MemoryBuffer.h8
-rw-r--r--include/llvm/Support/PassNameParser.h7
-rw-r--r--include/llvm/Support/Path.h7
-rw-r--r--include/llvm/Support/PatternMatch.h12
-rw-r--r--include/llvm/Support/PrettyStackTrace.h10
-rw-r--r--include/llvm/Support/Process.h34
-rw-r--r--include/llvm/Support/Program.h62
-rw-r--r--include/llvm/Support/RecyclingAllocator.h3
-rw-r--r--include/llvm/Support/SourceMgr.h8
-rw-r--r--include/llvm/Support/TargetRegistry.h144
-rw-r--r--include/llvm/Support/Unicode.h62
-rw-r--r--include/llvm/Support/UnicodeCharRanges.h120
-rw-r--r--include/llvm/Support/Valgrind.h4
-rw-r--r--include/llvm/Support/ValueHandle.h5
-rw-r--r--include/llvm/Support/YAMLParser.h80
-rw-r--r--include/llvm/Support/YAMLTraits.h44
35 files changed, 1380 insertions, 2000 deletions
diff --git a/include/llvm/Support/Allocator.h b/include/llvm/Support/Allocator.h
index 3243fd9..397f50f 100644
--- a/include/llvm/Support/Allocator.h
+++ b/include/llvm/Support/Allocator.h
@@ -99,6 +99,9 @@ class BumpPtrAllocator {
/// allocate a separate slab.
size_t SizeThreshold;
+ /// \brief the default allocator used if one is not provided
+ MallocSlabAllocator DefaultSlabAllocator;
+
/// Allocator - The underlying allocator we use to get slabs of memory. This
/// defaults to MallocSlabAllocator, which wraps malloc, but it could be
/// changed to use a custom allocator.
@@ -133,12 +136,10 @@ class BumpPtrAllocator {
/// one.
void DeallocateSlabs(MemSlab *Slab);
- static MallocSlabAllocator DefaultSlabAllocator;
-
template<typename T> friend class SpecificBumpPtrAllocator;
public:
- BumpPtrAllocator(size_t size = 4096, size_t threshold = 4096,
- SlabAllocator &allocator = DefaultSlabAllocator);
+ BumpPtrAllocator(size_t size = 4096, size_t threshold = 4096);
+ BumpPtrAllocator(size_t size, size_t threshold, SlabAllocator &allocator);
~BumpPtrAllocator();
/// Reset - Deallocate all but the current slab and reset the current pointer
@@ -189,8 +190,10 @@ template <typename T>
class SpecificBumpPtrAllocator {
BumpPtrAllocator Allocator;
public:
- SpecificBumpPtrAllocator(size_t size = 4096, size_t threshold = 4096,
- SlabAllocator &allocator = BumpPtrAllocator::DefaultSlabAllocator)
+ SpecificBumpPtrAllocator(size_t size = 4096, size_t threshold = 4096)
+ : Allocator(size, threshold) {}
+ SpecificBumpPtrAllocator(size_t size, size_t threshold,
+ SlabAllocator &allocator)
: Allocator(size, threshold, allocator) {}
~SpecificBumpPtrAllocator() {
diff --git a/include/llvm/Support/BlockFrequency.h b/include/llvm/Support/BlockFrequency.h
index 666b3c8..21879e7 100644
--- a/include/llvm/Support/BlockFrequency.h
+++ b/include/llvm/Support/BlockFrequency.h
@@ -27,8 +27,10 @@ class BlockFrequency {
uint64_t Frequency;
static const int64_t ENTRY_FREQ = 1 << 14;
- // Scale frequency by N/D, saturating on overflow.
- void scale(uint32_t N, uint32_t D);
+ /// \brief Scale the given BlockFrequency by N/D. Return the remainder from
+ /// the division by D. Upon overflow, the routine will saturate and
+ /// additionally will return the remainder set to D.
+ uint32_t scale(uint32_t N, uint32_t D);
public:
BlockFrequency(uint64_t Freq = 0) : Frequency(Freq) { }
@@ -57,6 +59,10 @@ public:
BlockFrequency &operator+=(const BlockFrequency &Freq);
const BlockFrequency operator+(const BlockFrequency &Freq) const;
+ /// \brief Scale the given BlockFrequency by N/D. Return the remainder from
+ /// the division by D. Upon overflow, the routine will saturate.
+ uint32_t scale(const BranchProbability &Prob);
+
bool operator<(const BlockFrequency &RHS) const {
return Frequency < RHS.Frequency;
}
diff --git a/include/llvm/Support/COFF.h b/include/llvm/Support/COFF.h
index a39a3f9..9cc3989 100644
--- a/include/llvm/Support/COFF.h
+++ b/include/llvm/Support/COFF.h
@@ -222,7 +222,7 @@ namespace COFF {
uint32_t Characteristics;
};
- enum SectionCharacteristics {
+ enum SectionCharacteristics LLVM_ENUM_INT_TYPE(uint32_t) {
SC_Invalid = 0xffffffff,
IMAGE_SCN_TYPE_NO_PAD = 0x00000008,
@@ -511,7 +511,9 @@ namespace COFF {
IMAGE_SUBSYSTEM_NATIVE = 1, ///< Device drivers and native Windows processes
IMAGE_SUBSYSTEM_WINDOWS_GUI = 2, ///< The Windows GUI subsystem.
IMAGE_SUBSYSTEM_WINDOWS_CUI = 3, ///< The Windows character subsystem.
+ IMAGE_SUBSYSTEM_OS2_CUI = 5, ///< The OS/2 character subsytem.
IMAGE_SUBSYSTEM_POSIX_CUI = 7, ///< The POSIX character subsystem.
+ IMAGE_SUBSYSTEM_NATIVE_WINDOWS = 8, ///< Native Windows 9x driver.
IMAGE_SUBSYSTEM_WINDOWS_CE_GUI = 9, ///< Windows CE.
IMAGE_SUBSYSTEM_EFI_APPLICATION = 10, ///< An EFI application.
IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER = 11, ///< An EFI driver with boot
@@ -519,7 +521,8 @@ namespace COFF {
IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER = 12, ///< An EFI driver with run-time
/// services.
IMAGE_SUBSYSTEM_EFI_ROM = 13, ///< An EFI ROM image.
- IMAGE_SUBSYSTEM_XBOX = 14 ///< XBOX.
+ IMAGE_SUBSYSTEM_XBOX = 14, ///< XBOX.
+ IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION = 16 ///< A BCD application.
};
enum DLLCharacteristics {
diff --git a/include/llvm/Support/CommandLine.h b/include/llvm/Support/CommandLine.h
index c0bfbae..4efb6a6 100644
--- a/include/llvm/Support/CommandLine.h
+++ b/include/llvm/Support/CommandLine.h
@@ -350,6 +350,9 @@ struct cat {
struct GenericOptionValue {
virtual ~GenericOptionValue() {}
virtual bool compare(const GenericOptionValue &V) const = 0;
+
+private:
+ virtual void anchor();
};
template<class DataType> struct OptionValue;
@@ -1752,6 +1755,7 @@ void getRegisteredOptions(StringMap<Option*> &Map);
/// \brief Saves strings in the inheritor's stable storage and returns a stable
/// raw character pointer.
class StringSaver {
+ virtual void anchor();
public:
virtual const char *SaveString(const char *Str) = 0;
virtual ~StringSaver() {}; // Pacify -Wnon-virtual-dtor.
diff --git a/include/llvm/Support/Compiler.h b/include/llvm/Support/Compiler.h
index feac934..860f43e 100644
--- a/include/llvm/Support/Compiler.h
+++ b/include/llvm/Support/Compiler.h
@@ -179,6 +179,12 @@
#define LLVM_ATTRIBUTE_USED
#endif
+#if __has_attribute(warn_unused_result) || __GNUC_PREREQ(3, 4)
+#define LLVM_ATTRIBUTE_UNUSED_RESULT __attribute__((__warn_unused_result__))
+#else
+#define LLVM_ATTRIBUTE_UNUSED_RESULT
+#endif
+
// Some compilers warn about unused functions. When a function is sometimes
// used or not depending on build settings (e.g. a function only called from
// within "assert"), this attribute can be used to suppress such warnings.
@@ -385,4 +391,24 @@
# define LLVM_STATIC_ASSERT(expr, msg)
#endif
+/// \macro LLVM_ENUM_INT_TYPE
+/// \brief Expands to colon followed by the given integral type on compilers
+/// which support C++11 strong enums. This can be used to make enums unsigned
+/// with MSVC.
+#if __has_feature(cxx_strong_enums)
+# define LLVM_ENUM_INT_TYPE(intty) : intty
+#elif defined(_MSC_VER) && _MSC_VER >= 1600 // Added in MSVC 2010.
+# define LLVM_ENUM_INT_TYPE(intty) : intty
+#else
+# define LLVM_ENUM_INT_TYPE(intty)
+#endif
+
+/// \brief Does the compiler support generalized initializers (using braced
+/// lists and std::initializer_list).
+#if __has_feature(cxx_generalized_initializers)
+#define LLVM_HAS_INITIALIZER_LISTS 1
+#else
+#define LLVM_HAS_INITIALIZER_LISTS 0
+#endif
+
#endif
diff --git a/include/llvm/Support/Compression.h b/include/llvm/Support/Compression.h
index 9b1142d..bef9146 100644
--- a/include/llvm/Support/Compression.h
+++ b/include/llvm/Support/Compression.h
@@ -50,6 +50,8 @@ Status uncompress(StringRef InputBuffer,
OwningPtr<MemoryBuffer> &UncompressedBuffer,
size_t UncompressedSize);
+uint32_t crc32(StringRef Buffer);
+
} // End of namespace zlib
} // End of namespace llvm
diff --git a/include/llvm/Support/Debug.h b/include/llvm/Support/Debug.h
index 896fe84..2702408 100644
--- a/include/llvm/Support/Debug.h
+++ b/include/llvm/Support/Debug.h
@@ -26,9 +26,9 @@
#ifndef LLVM_SUPPORT_DEBUG_H
#define LLVM_SUPPORT_DEBUG_H
-namespace llvm {
+#include "llvm/Support/raw_ostream.h"
-class raw_ostream;
+namespace llvm {
/// DEBUG_TYPE macro - Files can specify a DEBUG_TYPE as a string, which causes
/// all of their DEBUG statements to be activatable with -debug-only=thatstring.
diff --git a/include/llvm/Support/DebugLoc.h b/include/llvm/Support/DebugLoc.h
index f35d407..05f31d7 100644
--- a/include/llvm/Support/DebugLoc.h
+++ b/include/llvm/Support/DebugLoc.h
@@ -15,6 +15,8 @@
#ifndef LLVM_SUPPORT_DEBUGLOC_H
#define LLVM_SUPPORT_DEBUGLOC_H
+#include "llvm/Support/DataTypes.h"
+
namespace llvm {
template <typename T> struct DenseMapInfo;
class MDNode;
@@ -45,7 +47,7 @@ namespace llvm {
/// LineCol - This 32-bit value encodes the line and column number for the
/// location, encoded as 24-bits for line and 8 bits for col. A value of 0
/// for either means unknown.
- unsigned LineCol;
+ uint32_t LineCol;
/// ScopeIdx - This is an opaque ID# for Scope/InlinedAt information,
/// decoded by LLVMContext. 0 is unknown.
diff --git a/include/llvm/Support/Dwarf.h b/include/llvm/Support/Dwarf.h
index d0e2322..23bbd1c 100644
--- a/include/llvm/Support/Dwarf.h
+++ b/include/llvm/Support/Dwarf.h
@@ -16,60 +16,59 @@
#ifndef LLVM_SUPPORT_DWARF_H
#define LLVM_SUPPORT_DWARF_H
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataTypes.h"
-
namespace llvm {
//===----------------------------------------------------------------------===//
// Debug info constants.
-enum {
- LLVMDebugVersion = (12 << 16), // Current version of debug information.
- LLVMDebugVersion11 = (11 << 16), // Constant for version 11.
- LLVMDebugVersion10 = (10 << 16), // Constant for version 10.
- LLVMDebugVersion9 = (9 << 16), // Constant for version 9.
- LLVMDebugVersion8 = (8 << 16), // Constant for version 8.
- LLVMDebugVersion7 = (7 << 16), // Constant for version 7.
- LLVMDebugVersion6 = (6 << 16), // Constant for version 6.
- LLVMDebugVersion5 = (5 << 16), // Constant for version 5.
- LLVMDebugVersion4 = (4 << 16), // Constant for version 4.
- LLVMDebugVersionMask = 0xffff0000 // Mask for version number.
+enum LLVM_ENUM_INT_TYPE(uint32_t) {
+ LLVMDebugVersion = (12 << 16), // Current version of debug information.
+ LLVMDebugVersion11 = (11 << 16), // Constant for version 11.
+ LLVMDebugVersion10 = (10 << 16), // Constant for version 10.
+ LLVMDebugVersion9 = (9 << 16), // Constant for version 9.
+ LLVMDebugVersion8 = (8 << 16), // Constant for version 8.
+ LLVMDebugVersion7 = (7 << 16), // Constant for version 7.
+ LLVMDebugVersion6 = (6 << 16), // Constant for version 6.
+ LLVMDebugVersion5 = (5 << 16), // Constant for version 5.
+ LLVMDebugVersion4 = (4 << 16), // Constant for version 4.
+ LLVMDebugVersionMask = 0xffff0000 // Mask for version number.
};
namespace dwarf {
//===----------------------------------------------------------------------===//
// Dwarf constants as gleaned from the DWARF Debugging Information Format V.4
-// reference manual http://dwarf.freestandards.org .
+// reference manual http://dwarf.freestandards.org.
//
// Do not mix the following two enumerations sets. DW_TAG_invalid changes the
// enumeration base type.
-enum llvm_dwarf_constants {
+enum LLVMConstants LLVM_ENUM_INT_TYPE(uint32_t) {
// llvm mock tags
- DW_TAG_invalid = ~0U, // Tag for invalid results.
+ DW_TAG_invalid = ~0U, // Tag for invalid results.
- DW_TAG_auto_variable = 0x100, // Tag for local (auto) variables.
- DW_TAG_arg_variable = 0x101, // Tag for argument variables.
+ DW_TAG_auto_variable = 0x100, // Tag for local (auto) variables.
+ DW_TAG_arg_variable = 0x101, // Tag for argument variables.
- DW_TAG_user_base = 0x1000, // Recommended base for user tags.
+ DW_TAG_user_base = 0x1000, // Recommended base for user tags.
- DW_CIE_VERSION = 1 // Common frame information version.
+ 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.
};
-
// Special ID values that distinguish a CIE from a FDE in DWARF CFI.
// Not inside an enum because a 64-bit value is needed.
const uint32_t DW_CIE_ID = UINT32_MAX;
const uint64_t DW64_CIE_ID = UINT64_MAX;
-
-enum dwarf_constants {
- DWARF_VERSION = 2,
-
- // Tags
+enum Tag LLVM_ENUM_INT_TYPE(uint16_t) {
DW_TAG_array_type = 0x01,
DW_TAG_class_type = 0x02,
DW_TAG_entry_point = 0x03,
@@ -139,12 +138,38 @@ enum dwarf_constants {
DW_TAG_GNU_formal_parameter_pack = 0x4108,
DW_TAG_lo_user = 0x4080,
DW_TAG_APPLE_property = 0x4200,
- DW_TAG_hi_user = 0xffff,
-
- // Children flag
- DW_CHILDREN_no = 0x00,
- DW_CHILDREN_yes = 0x01,
+ DW_TAG_hi_user = 0xffff
+};
+inline bool isType(Tag T) {
+ switch (T) {
+ case DW_TAG_array_type:
+ case DW_TAG_class_type:
+ case DW_TAG_interface_type:
+ case DW_TAG_enumeration_type:
+ case DW_TAG_pointer_type:
+ case DW_TAG_reference_type:
+ case DW_TAG_rvalue_reference_type:
+ case DW_TAG_string_type:
+ case DW_TAG_structure_type:
+ case DW_TAG_subroutine_type:
+ case DW_TAG_union_type:
+ case DW_TAG_ptr_to_member_type:
+ case DW_TAG_set_type:
+ case DW_TAG_subrange_type:
+ case DW_TAG_base_type:
+ case DW_TAG_const_type:
+ case DW_TAG_file_type:
+ case DW_TAG_packed_type:
+ case DW_TAG_volatile_type:
+ case DW_TAG_typedef:
+ return true;
+ default:
+ return false;
+ }
+}
+
+enum Attribute LLVM_ENUM_INT_TYPE(uint16_t) {
// Attributes
DW_AT_sibling = 0x01,
DW_AT_location = 0x02,
@@ -295,8 +320,10 @@ enum dwarf_constants {
DW_AT_APPLE_property_setter = 0x3fea,
DW_AT_APPLE_property_attribute = 0x3feb,
DW_AT_APPLE_objc_complete_type = 0x3fec,
- DW_AT_APPLE_property = 0x3fed,
+ DW_AT_APPLE_property = 0x3fed
+};
+enum Form LLVM_ENUM_INT_TYPE(uint16_t) {
// Attribute form encodings
DW_FORM_addr = 0x01,
DW_FORM_block2 = 0x03,
@@ -326,8 +353,10 @@ enum dwarf_constants {
// Extensions for Fission proposal
DW_FORM_GNU_addr_index = 0x1f01,
- DW_FORM_GNU_str_index = 0x1f02,
+ DW_FORM_GNU_str_index = 0x1f02
+};
+enum LocationAtom {
// Operation encodings
DW_OP_addr = 0x03,
DW_OP_deref = 0x06,
@@ -486,10 +515,15 @@ enum dwarf_constants {
DW_OP_lo_user = 0xe0,
DW_OP_hi_user = 0xff,
+ // Extensions for GNU-style thread-local storage.
+ DW_OP_GNU_push_tls_address = 0xe0,
+
// Extensions for Fission proposal.
DW_OP_GNU_addr_index = 0xfb,
- DW_OP_GNU_const_index = 0xfc,
+ DW_OP_GNU_const_index = 0xfc
+};
+enum TypeKind {
// Encoding attribute values
DW_ATE_address = 0x01,
DW_ATE_boolean = 0x02,
@@ -508,37 +542,49 @@ enum dwarf_constants {
DW_ATE_decimal_float = 0x0f,
DW_ATE_UTF = 0x10,
DW_ATE_lo_user = 0x80,
- DW_ATE_hi_user = 0xff,
+ DW_ATE_hi_user = 0xff
+};
+enum DecimalSignEncoding {
// Decimal sign attribute values
DW_DS_unsigned = 0x01,
DW_DS_leading_overpunch = 0x02,
DW_DS_trailing_overpunch = 0x03,
DW_DS_leading_separate = 0x04,
- DW_DS_trailing_separate = 0x05,
+ DW_DS_trailing_separate = 0x05
+};
+enum EndianityEncoding {
// Endianity attribute values
DW_END_default = 0x00,
DW_END_big = 0x01,
DW_END_little = 0x02,
DW_END_lo_user = 0x40,
- DW_END_hi_user = 0xff,
+ DW_END_hi_user = 0xff
+};
+enum AccessAttribute {
// Accessibility codes
DW_ACCESS_public = 0x01,
DW_ACCESS_protected = 0x02,
- DW_ACCESS_private = 0x03,
+ DW_ACCESS_private = 0x03
+};
+enum VisibilityAttribute {
// Visibility codes
DW_VIS_local = 0x01,
DW_VIS_exported = 0x02,
- DW_VIS_qualified = 0x03,
+ DW_VIS_qualified = 0x03
+};
+enum VirtualityAttribute {
// Virtuality codes
DW_VIRTUALITY_none = 0x00,
DW_VIRTUALITY_virtual = 0x01,
- DW_VIRTUALITY_pure_virtual = 0x02,
+ DW_VIRTUALITY_pure_virtual = 0x02
+};
+enum SourceLanguage {
// Language names
DW_LANG_C89 = 0x0001,
DW_LANG_C = 0x0002,
@@ -562,35 +608,47 @@ enum dwarf_constants {
DW_LANG_Python = 0x0014,
DW_LANG_lo_user = 0x8000,
DW_LANG_Mips_Assembler = 0x8001,
- DW_LANG_hi_user = 0xffff,
+ DW_LANG_hi_user = 0xffff
+};
+enum CaseSensitivity {
// Identifier case codes
DW_ID_case_sensitive = 0x00,
DW_ID_up_case = 0x01,
DW_ID_down_case = 0x02,
- DW_ID_case_insensitive = 0x03,
+ DW_ID_case_insensitive = 0x03
+};
+enum CallingConvention {
// Calling convention codes
DW_CC_normal = 0x01,
DW_CC_program = 0x02,
DW_CC_nocall = 0x03,
DW_CC_lo_user = 0x40,
- DW_CC_hi_user = 0xff,
+ DW_CC_hi_user = 0xff
+};
+enum InlineAttribute {
// Inline codes
DW_INL_not_inlined = 0x00,
DW_INL_inlined = 0x01,
DW_INL_declared_not_inlined = 0x02,
- DW_INL_declared_inlined = 0x03,
+ DW_INL_declared_inlined = 0x03
+};
+enum ArrayDimensionOrdering {
// Array ordering
DW_ORD_row_major = 0x00,
- DW_ORD_col_major = 0x01,
+ DW_ORD_col_major = 0x01
+};
+enum DiscriminantList {
// Discriminant descriptor values
DW_DSC_label = 0x00,
- DW_DSC_range = 0x01,
+ DW_DSC_range = 0x01
+};
+enum LineNumberOps {
// Line Number Standard Opcode Encodings
DW_LNS_extended_op = 0x00,
DW_LNS_copy = 0x01,
@@ -604,23 +662,29 @@ enum dwarf_constants {
DW_LNS_fixed_advance_pc = 0x09,
DW_LNS_set_prologue_end = 0x0a,
DW_LNS_set_epilogue_begin = 0x0b,
- DW_LNS_set_isa = 0x0c,
+ DW_LNS_set_isa = 0x0c
+};
+enum LineNumberExtendedOps {
// Line Number Extended Opcode Encodings
DW_LNE_end_sequence = 0x01,
DW_LNE_set_address = 0x02,
DW_LNE_define_file = 0x03,
DW_LNE_set_discriminator = 0x04,
DW_LNE_lo_user = 0x80,
- DW_LNE_hi_user = 0xff,
+ DW_LNE_hi_user = 0xff
+};
+enum MacinfoRecordType {
// Macinfo Type Encodings
DW_MACINFO_define = 0x01,
DW_MACINFO_undef = 0x02,
DW_MACINFO_start_file = 0x03,
DW_MACINFO_end_file = 0x04,
- DW_MACINFO_vendor_ext = 0xff,
+ DW_MACINFO_vendor_ext = 0xff
+};
+enum CallFrameInfo {
// Call frame instruction encodings
DW_CFA_extended = 0x00,
DW_CFA_nop = 0x00,
@@ -653,7 +717,13 @@ enum dwarf_constants {
DW_CFA_GNU_window_save = 0x2d,
DW_CFA_GNU_args_size = 0x2e,
DW_CFA_lo_user = 0x1c,
- DW_CFA_hi_user = 0x3f,
+ DW_CFA_hi_user = 0x3f
+};
+
+enum Constants {
+ // Children flag
+ DW_CHILDREN_no = 0x00,
+ DW_CHILDREN_yes = 0x01,
DW_EH_PE_absptr = 0x00,
DW_EH_PE_omit = 0xff,
@@ -671,8 +741,10 @@ enum dwarf_constants {
DW_EH_PE_datarel = 0x30,
DW_EH_PE_funcrel = 0x40,
DW_EH_PE_aligned = 0x50,
- DW_EH_PE_indirect = 0x80,
+ DW_EH_PE_indirect = 0x80
+};
+enum ApplePropertyAttributes {
// Apple Objective-C Property Attributes
DW_APPLE_PROPERTY_readonly = 0x01,
DW_APPLE_PROPERTY_readwrite = 0x02,
@@ -765,6 +837,84 @@ const char *MacinfoString(unsigned Encoding);
/// CallFrameString - Return the string for the specified call frame instruction
/// encodings.
const char *CallFrameString(unsigned Encoding);
+
+// Constants for the DWARF5 Accelerator Table Proposal
+enum AcceleratorTable {
+ // Data layout descriptors.
+ DW_ATOM_null = 0u, // Marker as the end of a list of atoms.
+ DW_ATOM_die_offset = 1u, // DIE offset in the debug_info section.
+ DW_ATOM_cu_offset = 2u, // Offset of the compile unit header that contains the
+ // item in question.
+ DW_ATOM_die_tag = 3u, // A tag entry.
+ DW_ATOM_type_flags = 4u, // Set of flags for a type.
+
+ // DW_ATOM_type_flags values.
+
+ // Always set for C++, only set for ObjC if this is the @implementation for a
+ // class.
+ DW_FLAG_type_implementation = 2u,
+
+ // Hash functions.
+
+ // Daniel J. Bernstein hash.
+ DW_hash_function_djb = 0u
+};
+
+/// AtomTypeString - Return the string for the specified Atom type.
+const char *AtomTypeString(unsigned Atom);
+
+// Constants for the GNU pubnames/pubtypes extensions supporting gdb index.
+enum GDBIndexEntryKind {
+ GIEK_NONE,
+ GIEK_TYPE,
+ GIEK_VARIABLE,
+ GIEK_FUNCTION,
+ GIEK_OTHER,
+ GIEK_UNUSED5,
+ GIEK_UNUSED6,
+ GIEK_UNUSED7
+};
+
+const char *GDBIndexEntryKindString(GDBIndexEntryKind Kind);
+
+enum GDBIndexEntryLinkage {
+ GIEL_EXTERNAL,
+ GIEL_STATIC
+};
+
+const char *GDBIndexEntryLinkageString(GDBIndexEntryLinkage Linkage);
+
+/// The gnu_pub* kind looks like:
+///
+/// 0-3 reserved
+/// 4-6 symbol kind
+/// 7 0 == global, 1 == static
+///
+/// A gdb_index descriptor includes the above kind, shifted 24 bits up with the
+/// offset of the cu within the debug_info section stored in those 24 bits.
+struct PubIndexEntryDescriptor {
+ GDBIndexEntryKind Kind;
+ GDBIndexEntryLinkage Linkage;
+ PubIndexEntryDescriptor(GDBIndexEntryKind Kind, GDBIndexEntryLinkage Linkage)
+ : Kind(Kind), Linkage(Linkage) {}
+ /* implicit */ PubIndexEntryDescriptor(GDBIndexEntryKind Kind)
+ : Kind(Kind), Linkage(GIEL_EXTERNAL) {}
+ explicit PubIndexEntryDescriptor(uint8_t Value)
+ : Kind(static_cast<GDBIndexEntryKind>((Value & KIND_MASK) >>
+ KIND_OFFSET)),
+ Linkage(static_cast<GDBIndexEntryLinkage>((Value & LINKAGE_MASK) >>
+ LINKAGE_OFFSET)) {}
+ uint8_t toBits() { return Kind << KIND_OFFSET | Linkage << LINKAGE_OFFSET; }
+
+private:
+ enum {
+ KIND_OFFSET = 4,
+ KIND_MASK = 7 << KIND_OFFSET,
+ LINKAGE_OFFSET = 7,
+ LINKAGE_MASK = 1 << LINKAGE_OFFSET
+ };
+};
+
} // End of namespace dwarf
} // End of namespace llvm
diff --git a/include/llvm/Support/ELF.h b/include/llvm/Support/ELF.h
index 54da31c..2868f35 100644
--- a/include/llvm/Support/ELF.h
+++ b/include/llvm/Support/ELF.h
@@ -20,6 +20,7 @@
#ifndef LLVM_SUPPORT_ELF_H
#define LLVM_SUPPORT_ELF_H
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataTypes.h"
#include <cstring>
@@ -650,7 +651,7 @@ enum {
};
// ARM Specific e_flags
-enum {
+enum LLVM_ENUM_INT_TYPE(unsigned) {
EF_ARM_SOFT_FLOAT = 0x00000200U,
EF_ARM_VFP_FLOAT = 0x00000400U,
EF_ARM_EABI_UNKNOWN = 0x00000000U,
@@ -800,7 +801,7 @@ enum {
};
// Mips Specific e_flags
-enum {
+enum LLVM_ENUM_INT_TYPE(unsigned) {
EF_MIPS_NOREORDER = 0x00000001, // Don't reorder instructions
EF_MIPS_PIC = 0x00000002, // Position independent code
EF_MIPS_CPIC = 0x00000004, // Call object with Position independent code
@@ -880,6 +881,19 @@ enum {
R_MIPS_GLOB_DAT = 51,
R_MIPS_COPY = 126,
R_MIPS_JUMP_SLOT = 127,
+ R_MICROMIPS_26_S1 = 133,
+ R_MICROMIPS_HI16 = 134,
+ R_MICROMIPS_LO16 = 135,
+ R_MICROMIPS_GOT16 = 138,
+ R_MICROMIPS_PC16_S1 = 141,
+ R_MICROMIPS_CALL16 = 142,
+ R_MICROMIPS_GOT_DISP = 145,
+ R_MICROMIPS_GOT_PAGE = 146,
+ R_MICROMIPS_GOT_OFST = 147,
+ R_MICROMIPS_TLS_DTPREL_HI16 = 164,
+ R_MICROMIPS_TLS_DTPREL_LO16 = 165,
+ R_MICROMIPS_TLS_TPREL_HI16 = 169,
+ R_MICROMIPS_TLS_TPREL_LO16 = 170,
R_MIPS_NUM = 218
};
@@ -1116,7 +1130,7 @@ enum {
};
// Section types.
-enum {
+enum LLVM_ENUM_INT_TYPE(unsigned) {
SHT_NULL = 0, // No associated section (inactive entry).
SHT_PROGBITS = 1, // Program-defined contents.
SHT_SYMTAB = 2, // Symbol table.
@@ -1164,7 +1178,7 @@ enum {
};
// Section flags.
-enum {
+enum LLVM_ENUM_INT_TYPE(unsigned) {
// Section data should be writable during execution.
SHF_WRITE = 0x1,
@@ -1196,6 +1210,9 @@ enum {
// This section holds Thread-Local Storage.
SHF_TLS = 0x400U,
+ // This section is excluded from the final executable or shared library.
+ SHF_EXCLUDE = 0x80000000U,
+
// Start of target-specific flags.
/// XCORE_SHF_CP_SECTION - All sections with the "c" flag are grouped
@@ -1226,12 +1243,34 @@ enum {
// for faster accesses
SHF_HEX_GPREL = 0x10000000,
- // Do not strip this section. FIXME: We need target specific SHF_ enums.
- SHF_MIPS_NOSTRIP = 0x8000000
+ // Section contains text/data which may be replicated in other sections.
+ // Linker must retain only one copy.
+ SHF_MIPS_NODUPES = 0x01000000,
+
+ // Linker must generate implicit hidden weak names.
+ SHF_MIPS_NAMES = 0x02000000,
+
+ // Section data local to process.
+ SHF_MIPS_LOCAL = 0x04000000,
+
+ // Do not strip this section.
+ SHF_MIPS_NOSTRIP = 0x08000000,
+
+ // Section must be part of global data area.
+ SHF_MIPS_GPREL = 0x10000000,
+
+ // This section should be merged.
+ SHF_MIPS_MERGE = 0x20000000,
+
+ // Address size to be inferred from section entry size.
+ SHF_MIPS_ADDR = 0x40000000,
+
+ // Section data is string data by default.
+ SHF_MIPS_STRING = 0x80000000
};
// Section Group Flags
-enum {
+enum LLVM_ENUM_INT_TYPE(unsigned) {
GRP_COMDAT = 0x1,
GRP_MASKOS = 0x0ff00000,
GRP_MASKPROC = 0xf0000000
@@ -1444,11 +1483,16 @@ enum {
PT_ARM_ARCHEXT = 0x70000000, // Platform architecture compatibility info
// These all contain stack unwind tables.
PT_ARM_EXIDX = 0x70000001,
- PT_ARM_UNWIND = 0x70000001
+ PT_ARM_UNWIND = 0x70000001,
+
+ // MIPS program header types.
+ PT_MIPS_REGINFO = 0x70000000, // Register usage information.
+ PT_MIPS_RTPROC = 0x70000001, // Runtime procedure table.
+ PT_MIPS_OPTIONS = 0x70000002 // Options segment.
};
// Segment flag bits.
-enum {
+enum LLVM_ENUM_INT_TYPE(unsigned) {
PF_X = 1, // Execute
PF_W = 2, // Write
PF_R = 4, // Read
@@ -1526,6 +1570,7 @@ enum {
DT_RELCOUNT = 0x6FFFFFFA, // ELF32_Rel count.
DT_FLAGS_1 = 0X6FFFFFFB, // Flags_1.
+ DT_VERSYM = 0x6FFFFFF0, // The address of .gnu.version section.
DT_VERDEF = 0X6FFFFFFC, // The address of the version definition table.
DT_VERDEFNUM = 0X6FFFFFFD, // The number of entries in DT_VERDEF.
DT_VERNEED = 0X6FFFFFFE, // The address of the version Dependency table.
diff --git a/include/llvm/Support/ErrorOr.h b/include/llvm/Support/ErrorOr.h
index f3ac305..d5b11cb 100644
--- a/include/llvm/Support/ErrorOr.h
+++ b/include/llvm/Support/ErrorOr.h
@@ -27,38 +27,6 @@
#endif
namespace llvm {
-struct ErrorHolderBase {
- error_code Error;
- uint16_t RefCount;
- bool HasUserData;
-
- ErrorHolderBase() : RefCount(1) {}
-
- void aquire() {
- ++RefCount;
- }
-
- void release() {
- if (--RefCount == 0)
- delete this;
- }
-
-protected:
- virtual ~ErrorHolderBase() {}
-};
-
-template<class T>
-struct ErrorHolder : ErrorHolderBase {
-#if LLVM_HAS_RVALUE_REFERENCES
- ErrorHolder(T &&UD) : UserData(llvm_move(UD)) {}
-#else
- ErrorHolder(T &UD) : UserData(UD) {}
-#endif
- T UserData;
-};
-
-template<class Tp> struct ErrorOrUserDataTraits : llvm::false_type {};
-
#if LLVM_HAS_CXX11_TYPETRAITS && LLVM_HAS_RVALUE_REFERENCES
template<class T, class V>
typename std::enable_if< std::is_constructible<T, V>::value
@@ -111,44 +79,6 @@ public:
/// buffer->write("adena");
/// \endcode
///
-/// ErrorOr<T> also supports user defined data for specific error_codes. To use
-/// this feature you must first add a template specialization of
-/// ErrorOrUserDataTraits derived from std::true_type for your type in the lld
-/// namespace. This specialization must have a static error_code error()
-/// function that returns the error_code this data is used with.
-///
-/// getError<UserData>() may be called to get either the stored user data, or
-/// a default constructed UserData if none was stored.
-///
-/// Example:
-/// \code
-/// struct InvalidArgError {
-/// InvalidArgError() {}
-/// InvalidArgError(std::string S) : ArgName(S) {}
-/// std::string ArgName;
-/// };
-///
-/// namespace llvm {
-/// template<>
-/// struct ErrorOrUserDataTraits<InvalidArgError> : std::true_type {
-/// static error_code error() {
-/// return make_error_code(errc::invalid_argument);
-/// }
-/// };
-/// } // end namespace llvm
-///
-/// using namespace llvm;
-///
-/// ErrorOr<int> foo() {
-/// return InvalidArgError("adena");
-/// }
-///
-/// int main() {
-/// auto a = foo();
-/// if (!a && error_code(a) == errc::invalid_argument)
-/// llvm::errs() << a.getError<InvalidArgError>().ArgName << "\n";
-/// }
-/// \endcode
///
/// An implicit conversion to bool provides a way to check if there was an
/// error. The unary * and -> operators provide pointer like access to the
@@ -178,43 +108,28 @@ private:
typedef typename remove_reference<T>::type *pointer;
public:
- ErrorOr() : IsValid(false) {}
-
template <class E>
ErrorOr(E ErrorCode, typename enable_if_c<is_error_code_enum<E>::value ||
is_error_condition_enum<E>::value,
void *>::type = 0)
- : HasError(true), IsValid(true) {
- Error = new ErrorHolderBase;
- Error->Error = make_error_code(ErrorCode);
- Error->HasUserData = false;
- }
-
- ErrorOr(llvm::error_code EC) : HasError(true), IsValid(true) {
- Error = new ErrorHolderBase;
- Error->Error = EC;
- Error->HasUserData = false;
+ : HasError(true) {
+ new (getError()) error_code(make_error_code(ErrorCode));
}
- template<class UserDataT>
- ErrorOr(UserDataT UD, typename
- enable_if_c<ErrorOrUserDataTraits<UserDataT>::value>::type* = 0)
- : HasError(true), IsValid(true) {
- Error = new ErrorHolder<UserDataT>(llvm_move(UD));
- Error->Error = ErrorOrUserDataTraits<UserDataT>::error();
- Error->HasUserData = true;
+ ErrorOr(llvm::error_code EC) : HasError(true) {
+ new (getError()) error_code(EC);
}
- ErrorOr(T Val) : HasError(false), IsValid(true) {
+ ErrorOr(T Val) : HasError(false) {
new (get()) storage_type(moveIfMoveConstructible<storage_type>(Val));
}
- ErrorOr(const ErrorOr &Other) : IsValid(false) {
+ ErrorOr(const ErrorOr &Other) {
copyConstruct(Other);
}
template <class OtherT>
- ErrorOr(const ErrorOr<OtherT> &Other) : IsValid(false) {
+ ErrorOr(const ErrorOr<OtherT> &Other) {
copyConstruct(Other);
}
@@ -230,12 +145,12 @@ public:
}
#if LLVM_HAS_RVALUE_REFERENCES
- ErrorOr(ErrorOr &&Other) : IsValid(false) {
+ ErrorOr(ErrorOr &&Other) {
moveConstruct(std::move(Other));
}
template <class OtherT>
- ErrorOr(ErrorOr<OtherT> &&Other) : IsValid(false) {
+ ErrorOr(ErrorOr<OtherT> &&Other) {
moveConstruct(std::move(Other));
}
@@ -252,37 +167,20 @@ public:
#endif
~ErrorOr() {
- if (!IsValid)
- return;
- if (HasError)
- Error->release();
- else
+ if (!HasError)
get()->~storage_type();
}
- template<class ET>
- ET getError() const {
- assert(IsValid && "Cannot get the error of a default constructed ErrorOr!");
- assert(HasError && "Cannot get an error if none exists!");
- assert(ErrorOrUserDataTraits<ET>::error() == Error->Error &&
- "Incorrect user error data type for error!");
- if (!Error->HasUserData)
- return ET();
- return reinterpret_cast<const ErrorHolder<ET>*>(Error)->UserData;
- }
-
typedef void (*unspecified_bool_type)();
static void unspecified_bool_true() {}
/// \brief Return false if there is an error.
operator unspecified_bool_type() const {
- assert(IsValid && "Can't do anything on a default constructed ErrorOr!");
return HasError ? 0 : unspecified_bool_true;
}
operator llvm::error_code() const {
- assert(IsValid && "Can't do anything on a default constructed ErrorOr!");
- return HasError ? Error->Error : llvm::error_code::success();
+ return HasError ? *getError() : llvm::error_code::success();
}
pointer operator ->() {
@@ -296,19 +194,14 @@ public:
private:
template <class OtherT>
void copyConstruct(const ErrorOr<OtherT> &Other) {
- // Construct an invalid ErrorOr if other is invalid.
- if (!Other.IsValid)
- return;
- IsValid = true;
if (!Other.HasError) {
// Get the other value.
HasError = false;
new (get()) storage_type(*Other.get());
} else {
// Get other's error.
- Error = Other.Error;
HasError = true;
- Error->aquire();
+ new (getError()) error_code(Other);
}
}
@@ -334,22 +227,14 @@ private:
#if LLVM_HAS_RVALUE_REFERENCES
template <class OtherT>
void moveConstruct(ErrorOr<OtherT> &&Other) {
- // Construct an invalid ErrorOr if other is invalid.
- if (!Other.IsValid)
- return;
- IsValid = true;
if (!Other.HasError) {
// Get the other value.
HasError = false;
new (get()) storage_type(std::move(*Other.get()));
- // Tell other not to do any destruction.
- Other.IsValid = false;
} else {
// Get other's error.
- Error = Other.Error;
HasError = true;
- // Tell other not to do any destruction.
- Other.IsValid = false;
+ new (getError()) error_code(Other);
}
}
@@ -372,135 +257,30 @@ private:
}
storage_type *get() {
- assert(IsValid && "Can't do anything on a default constructed ErrorOr!");
assert(!HasError && "Cannot get value when an error exists!");
return reinterpret_cast<storage_type*>(TStorage.buffer);
}
const storage_type *get() const {
- assert(IsValid && "Can't do anything on a default constructed ErrorOr!");
assert(!HasError && "Cannot get value when an error exists!");
return reinterpret_cast<const storage_type*>(TStorage.buffer);
}
- union {
- AlignedCharArrayUnion<storage_type> TStorage;
- ErrorHolderBase *Error;
- };
- bool HasError : 1;
- bool IsValid : 1;
-};
-
-// ErrorOr specialization for void.
-template <>
-class ErrorOr<void> {
-public:
- ErrorOr() : Error(0, 0) {}
-
- template <class E>
- ErrorOr(E ErrorCode, typename enable_if_c<is_error_code_enum<E>::value ||
- is_error_condition_enum<E>::value,
- void *> ::type = 0)
- : Error(0, 0) {
- error_code EC = make_error_code(ErrorCode);
- if (EC == errc::success) {
- Error.setInt(1);
- return;
- }
- ErrorHolderBase *EHB = new ErrorHolderBase;
- EHB->Error = EC;
- EHB->HasUserData = false;
- Error.setPointer(EHB);
- }
-
- ErrorOr(llvm::error_code EC) : Error(0, 0) {
- if (EC == errc::success) {
- Error.setInt(1);
- return;
- }
- ErrorHolderBase *E = new ErrorHolderBase;
- E->Error = EC;
- E->HasUserData = false;
- Error.setPointer(E);
- }
-
- template<class UserDataT>
- ErrorOr(UserDataT UD, typename
- enable_if_c<ErrorOrUserDataTraits<UserDataT>::value>::type* = 0)
- : Error(0, 0) {
- ErrorHolderBase *E = new ErrorHolder<UserDataT>(llvm_move(UD));
- E->Error = ErrorOrUserDataTraits<UserDataT>::error();
- E->HasUserData = true;
- Error.setPointer(E);
+ error_code *getError() {
+ assert(HasError && "Cannot get error when a value exists!");
+ return reinterpret_cast<error_code*>(ErrorStorage.buffer);
}
- ErrorOr(const ErrorOr &Other) : Error(0, 0) {
- Error = Other.Error;
- if (Other.Error.getPointer()->Error) {
- Error.getPointer()->aquire();
- }
+ const error_code *getError() const {
+ return const_cast<ErrorOr<T> *>(this)->getError();
}
- ErrorOr &operator =(const ErrorOr &Other) {
- if (this == &Other)
- return *this;
-
- this->~ErrorOr();
- new (this) ErrorOr(Other);
- return *this;
- }
-
-#if LLVM_HAS_RVALUE_REFERENCES
- ErrorOr(ErrorOr &&Other) : Error(0) {
- // Get other's error.
- Error = Other.Error;
- // Tell other not to do any destruction.
- Other.Error.setPointer(0);
- }
-
- ErrorOr &operator =(ErrorOr &&Other) {
- if (this == &Other)
- return *this;
-
- this->~ErrorOr();
- new (this) ErrorOr(std::move(Other));
-
- return *this;
- }
-#endif
-
- ~ErrorOr() {
- if (Error.getPointer())
- Error.getPointer()->release();
- }
-
- template<class ET>
- ET getError() const {
- assert(ErrorOrUserDataTraits<ET>::error() == *this &&
- "Incorrect user error data type for error!");
- if (!Error.getPointer()->HasUserData)
- return ET();
- return reinterpret_cast<const ErrorHolder<ET> *>(
- Error.getPointer())->UserData;
- }
-
- typedef void (*unspecified_bool_type)();
- static void unspecified_bool_true() {}
-
- /// \brief Return false if there is an error.
- operator unspecified_bool_type() const {
- return Error.getInt() ? unspecified_bool_true : 0;
- }
-
- operator llvm::error_code() const {
- return Error.getInt() ? make_error_code(errc::success)
- : Error.getPointer()->Error;
- }
-
-private:
- // If the bit is 1, the error is success.
- llvm::PointerIntPair<ErrorHolderBase *, 1> Error;
+ union {
+ AlignedCharArrayUnion<storage_type> TStorage;
+ AlignedCharArrayUnion<error_code> ErrorStorage;
+ };
+ bool HasError : 1;
};
template<class T, class E>
diff --git a/include/llvm/Support/FileSystem.h b/include/llvm/Support/FileSystem.h
index c130b47..d301f84 100644
--- a/include/llvm/Support/FileSystem.h
+++ b/include/llvm/Support/FileSystem.h
@@ -238,7 +238,9 @@ struct file_magic {
macho_dsym_companion, ///< Mach-O dSYM companion file
macho_universal_binary, ///< Mach-O universal binary
coff_object, ///< COFF object file
- pecoff_executable ///< PECOFF executable file
+ coff_import_library, ///< COFF import library
+ pecoff_executable, ///< PECOFF executable file
+ windows_resource ///< Windows compiled resource file (.rc)
};
bool is_object() const {
@@ -638,17 +640,6 @@ error_code openFileForWrite(const Twine &Name, int &ResultFD, OpenFlags Flags,
error_code openFileForRead(const Twine &Name, int &ResultFD);
-/// @brief Canonicalize path.
-///
-/// Sets result to the file system's idea of what path is. The result is always
-/// absolute and has the same capitalization as the file system.
-///
-/// @param path Input path.
-/// @param result Set to the canonicalized version of \a path.
-/// @returns errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code canonicalize(const Twine &path, SmallVectorImpl<char> &result);
-
/// @brief Are \a path's first bytes \a magic?
///
/// @param path Input path.
@@ -731,7 +722,7 @@ public:
/// should begin. Must be a multiple of
/// mapped_file_region::alignment().
/// \param ec This is set to errc::success if the map was constructed
- /// sucessfully. Otherwise it is set to a platform dependent error.
+ /// successfully. Otherwise it is set to a platform dependent error.
mapped_file_region(const Twine &path,
mapmode mode,
uint64_t length,
@@ -869,7 +860,7 @@ public:
}
/// Construct end iterator.
- directory_iterator() : State(new detail::DirIterState) {}
+ directory_iterator() : State(0) {}
// No operator++ because we need error_code.
directory_iterator &increment(error_code &ec) {
@@ -881,6 +872,12 @@ public:
const directory_entry *operator->() const { return &State->CurrentEntry; }
bool operator==(const directory_iterator &RHS) const {
+ if (State == RHS.State)
+ return true;
+ if (RHS.State == 0)
+ return State->CurrentEntry == directory_entry();
+ if (State == 0)
+ return RHS.State->CurrentEntry == directory_entry();
return State->CurrentEntry == RHS.State->CurrentEntry;
}
@@ -920,7 +917,7 @@ public:
}
// No operator++ because we need error_code.
recursive_directory_iterator &increment(error_code &ec) {
- static const directory_iterator end_itr;
+ const directory_iterator end_itr;
if (State->HasNoPushRequest)
State->HasNoPushRequest = false;
@@ -964,10 +961,10 @@ public:
// modifiers
/// Goes up one level if Level > 0.
void pop() {
- assert(State && "Cannot pop and end itertor!");
+ assert(State && "Cannot pop an end iterator!");
assert(State->Level > 0 && "Cannot pop an iterator with level < 1");
- static const directory_iterator end_itr;
+ const directory_iterator end_itr;
error_code ec;
do {
if (ec)
diff --git a/include/llvm/Support/FormattedStream.h b/include/llvm/Support/FormattedStream.h
index 18ee048..df1f218 100644
--- a/include/llvm/Support/FormattedStream.h
+++ b/include/llvm/Support/FormattedStream.h
@@ -129,6 +129,27 @@ public:
/// getLine - Return the line number
unsigned getLine() { return Position.second; }
+
+ raw_ostream &resetColor() {
+ TheStream->resetColor();
+ return *this;
+ }
+
+ raw_ostream &reverseColor() {
+ TheStream->reverseColor();
+ return *this;
+ }
+
+ raw_ostream &changeColor(enum Colors Color,
+ bool Bold,
+ bool BG) {
+ TheStream->changeColor(Color, Bold, BG);
+ return *this;
+ }
+
+ bool is_displayed() const {
+ return TheStream->is_displayed();
+ }
private:
void releaseStream() {
diff --git a/include/llvm/Support/GCOV.h b/include/llvm/Support/GCOV.h
index f1040f5..0aa716a 100644
--- a/include/llvm/Support/GCOV.h
+++ b/include/llvm/Support/GCOV.h
@@ -15,6 +15,7 @@
#ifndef LLVM_SUPPORT_GCOV_H
#define LLVM_SUPPORT_GCOV_H
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Support/MemoryBuffer.h"
@@ -24,7 +25,6 @@ namespace llvm {
class GCOVFunction;
class GCOVBlock;
-class GCOVLines;
class FileInfo;
namespace GCOV {
@@ -125,30 +125,65 @@ public:
return true;
}
- uint32_t readInt() {
- uint32_t Result;
+ /// readObjectTag - If cursor points to an object summary tag then increment
+ /// the cursor and return true otherwise return false.
+ bool readObjectTag() {
+ StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4);
+ if (Tag.empty() ||
+ Tag[0] != '\0' || Tag[1] != '\0' ||
+ Tag[2] != '\0' || Tag[3] != '\xa1') {
+ return false;
+ }
+ Cursor += 4;
+ return true;
+ }
+
+ /// readProgramTag - If cursor points to a program summary tag then increment
+ /// the cursor and return true otherwise return false.
+ bool readProgramTag() {
+ StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4);
+ if (Tag.empty() ||
+ Tag[0] != '\0' || Tag[1] != '\0' ||
+ Tag[2] != '\0' || Tag[3] != '\xa3') {
+ return false;
+ }
+ Cursor += 4;
+ return true;
+ }
+
+ bool readInt(uint32_t &Val) {
+ if (Buffer->getBuffer().size() < Cursor+4) {
+ errs() << "Unexpected end of memory buffer: " << Cursor+4 << ".\n";
+ return false;
+ }
StringRef Str = Buffer->getBuffer().slice(Cursor, Cursor+4);
- assert (Str.empty() == false && "Unexpected memory buffer end!");
Cursor += 4;
- Result = *(const uint32_t *)(Str.data());
- return Result;
+ Val = *(const uint32_t *)(Str.data());
+ return true;
}
- uint64_t readInt64() {
- uint64_t Lo = readInt();
- uint64_t Hi = readInt();
- uint64_t Result = Lo | (Hi << 32);
- return Result;
+ bool readInt64(uint64_t &Val) {
+ uint32_t Lo, Hi;
+ if (!readInt(Lo) || !readInt(Hi)) return false;
+ Val = ((uint64_t)Hi << 32) | Lo;
+ return true;
}
- StringRef readString() {
- uint32_t Len = readInt() * 4;
- StringRef Str = Buffer->getBuffer().slice(Cursor, Cursor+Len);
+ bool readString(StringRef &Str) {
+ uint32_t Len;
+ if (!readInt(Len)) return false;
+ Len *= 4;
+ if (Buffer->getBuffer().size() < Cursor+Len) {
+ errs() << "Unexpected end of memory buffer: " << Cursor+Len << ".\n";
+ return false;
+ }
+ Str = Buffer->getBuffer().slice(Cursor, Cursor+Len).split('\0').first;
Cursor += Len;
- return Str;
+ return true;
}
uint64_t getCursor() const { return Cursor; }
+ void advanceCursor(uint32_t n) { Cursor += n*4; }
private:
MemoryBuffer *Buffer;
uint64_t Cursor;
@@ -158,13 +193,15 @@ private:
/// (.gcno and .gcda).
class GCOVFile {
public:
- GCOVFile() {}
+ GCOVFile() : Functions(), RunCount(0), ProgramCount(0) {}
~GCOVFile();
bool read(GCOVBuffer &Buffer);
void dump();
void collectLineCounts(FileInfo &FI);
private:
SmallVector<GCOVFunction *, 16> Functions;
+ uint32_t RunCount;
+ uint32_t ProgramCount;
};
/// GCOVFunction - Collects function information.
@@ -173,6 +210,7 @@ public:
GCOVFunction() : Ident(0), LineNumber(0) {}
~GCOVFunction();
bool read(GCOVBuffer &Buffer, GCOV::GCOVFormat Format);
+ StringRef getFilename() const { return Filename; }
void dump();
void collectLineCounts(FileInfo &FI);
private:
@@ -186,39 +224,36 @@ private:
/// GCOVBlock - Collects block information.
class GCOVBlock {
public:
- GCOVBlock(uint32_t N) : Number(N), Counter(0) {}
+ GCOVBlock(GCOVFunction &P, uint32_t N) :
+ Parent(P), Number(N), Counter(0), Edges(), Lines() {}
~GCOVBlock();
void addEdge(uint32_t N) { Edges.push_back(N); }
- void addLine(StringRef Filename, uint32_t LineNo);
- void addCount(uint64_t N) { Counter = N; }
+ void addLine(uint32_t N) { Lines.push_back(N); }
+ void addCount(uint64_t N) { Counter += N; }
+ size_t getNumEdges() { return Edges.size(); }
void dump();
void collectLineCounts(FileInfo &FI);
private:
+ GCOVFunction &Parent;
uint32_t Number;
uint64_t Counter;
SmallVector<uint32_t, 16> Edges;
- StringMap<GCOVLines *> Lines;
+ SmallVector<uint32_t, 16> Lines;
};
-/// GCOVLines - A wrapper around a vector of int to keep track of line nos.
-class GCOVLines {
-public:
- ~GCOVLines() { Lines.clear(); }
- void add(uint32_t N) { Lines.push_back(N); }
- void collectLineCounts(FileInfo &FI, StringRef Filename, uint32_t Count);
- void dump();
-
-private:
- SmallVector<uint32_t, 4> Lines;
-};
-
-typedef SmallVector<uint32_t, 16> LineCounts;
+typedef DenseMap<uint32_t, uint64_t> LineCounts;
class FileInfo {
public:
- void addLineCount(StringRef Filename, uint32_t Line, uint32_t Count);
- void print();
+ void addLineCount(StringRef Filename, uint32_t Line, uint64_t Count) {
+ LineInfo[Filename][Line-1] += Count;
+ }
+ void setRunCount(uint32_t Runs) { RunCount = Runs; }
+ void setProgramCount(uint32_t Programs) { ProgramCount = Programs; }
+ void print(raw_fd_ostream &OS, StringRef gcnoFile, StringRef gcdaFile);
private:
StringMap<LineCounts> LineInfo;
+ uint32_t RunCount;
+ uint32_t ProgramCount;
};
}
diff --git a/include/llvm/Support/IntegersSubset.h b/include/llvm/Support/IntegersSubset.h
deleted file mode 100644
index 64b79ee..0000000
--- a/include/llvm/Support/IntegersSubset.h
+++ /dev/null
@@ -1,540 +0,0 @@
-//===-- llvm/IntegersSubset.h - The subset of integers ----------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-/// @file
-/// This file contains class that implements constant set of ranges:
-/// [<Low0,High0>,...,<LowN,HighN>]. Initially, this class was created for
-/// SwitchInst and was used for case value representation that may contain
-/// multiple ranges for a single successor.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SUPPORT_INTEGERSSUBSET_H
-#define LLVM_SUPPORT_INTEGERSSUBSET_H
-
-#include "llvm/IR/Constants.h"
-#include "llvm/IR/DerivedTypes.h"
-#include "llvm/IR/LLVMContext.h"
-#include <list>
-
-namespace llvm {
-
- // The IntItem is a wrapper for APInt.
- // 1. It determines sign of integer, it allows to use
- // comparison operators >,<,>=,<=, and as result we got shorter and cleaner
- // constructions.
- // 2. It helps to implement PR1255 (case ranges) as a series of small patches.
- // 3. Currently we can interpret IntItem both as ConstantInt and as APInt.
- // It allows to provide SwitchInst methods that works with ConstantInt for
- // non-updated passes. And it allows to use APInt interface for new methods.
- // 4. IntItem can be easily replaced with APInt.
-
- // The set of macros that allows to propagate APInt operators to the IntItem.
-
-#define INT_ITEM_DEFINE_COMPARISON(op,func) \
- bool operator op (const APInt& RHS) const { \
- return getAPIntValue().func(RHS); \
- }
-
-#define INT_ITEM_DEFINE_UNARY_OP(op) \
- IntItem operator op () const { \
- APInt res = op(getAPIntValue()); \
- Constant *NewVal = ConstantInt::get(ConstantIntVal->getContext(), res); \
- return IntItem(cast<ConstantInt>(NewVal)); \
- }
-
-#define INT_ITEM_DEFINE_BINARY_OP(op) \
- IntItem operator op (const APInt& RHS) const { \
- APInt res = getAPIntValue() op RHS; \
- Constant *NewVal = ConstantInt::get(ConstantIntVal->getContext(), res); \
- return IntItem(cast<ConstantInt>(NewVal)); \
- }
-
-#define INT_ITEM_DEFINE_ASSIGNMENT_BY_OP(op) \
- IntItem& operator op (const APInt& RHS) {\
- APInt res = getAPIntValue();\
- res op RHS; \
- Constant *NewVal = ConstantInt::get(ConstantIntVal->getContext(), res); \
- ConstantIntVal = cast<ConstantInt>(NewVal); \
- return *this; \
- }
-
-#define INT_ITEM_DEFINE_PREINCDEC(op) \
- IntItem& operator op () { \
- APInt res = getAPIntValue(); \
- op(res); \
- Constant *NewVal = ConstantInt::get(ConstantIntVal->getContext(), res); \
- ConstantIntVal = cast<ConstantInt>(NewVal); \
- return *this; \
- }
-
-#define INT_ITEM_DEFINE_POSTINCDEC(op) \
- IntItem& operator op (int) { \
- APInt res = getAPIntValue();\
- op(res); \
- Constant *NewVal = ConstantInt::get(ConstantIntVal->getContext(), res); \
- OldConstantIntVal = ConstantIntVal; \
- ConstantIntVal = cast<ConstantInt>(NewVal); \
- return IntItem(OldConstantIntVal); \
- }
-
-#define INT_ITEM_DEFINE_OP_STANDARD_INT(RetTy, op, IntTy) \
- RetTy operator op (IntTy RHS) const { \
- return (*this) op APInt(getAPIntValue().getBitWidth(), RHS); \
- }
-
-class IntItem {
- ConstantInt *ConstantIntVal;
- const APInt* APIntVal;
- IntItem(const ConstantInt *V) :
- ConstantIntVal(const_cast<ConstantInt*>(V)),
- APIntVal(&ConstantIntVal->getValue()){}
- const APInt& getAPIntValue() const {
- return *APIntVal;
- }
-public:
-
- IntItem() {}
-
- operator const APInt&() const {
- return getAPIntValue();
- }
-
- // Propagate APInt operators.
- // Note, that
- // /,/=,>>,>>= are not implemented in APInt.
- // <<= is implemented for unsigned RHS, but not implemented for APInt RHS.
-
- INT_ITEM_DEFINE_COMPARISON(<, ult)
- INT_ITEM_DEFINE_COMPARISON(>, ugt)
- INT_ITEM_DEFINE_COMPARISON(<=, ule)
- INT_ITEM_DEFINE_COMPARISON(>=, uge)
-
- INT_ITEM_DEFINE_COMPARISON(==, eq)
- INT_ITEM_DEFINE_OP_STANDARD_INT(bool,==,uint64_t)
-
- INT_ITEM_DEFINE_COMPARISON(!=, ne)
- INT_ITEM_DEFINE_OP_STANDARD_INT(bool,!=,uint64_t)
-
- INT_ITEM_DEFINE_BINARY_OP(*)
- INT_ITEM_DEFINE_BINARY_OP(+)
- INT_ITEM_DEFINE_OP_STANDARD_INT(IntItem,+,uint64_t)
- INT_ITEM_DEFINE_BINARY_OP(-)
- INT_ITEM_DEFINE_OP_STANDARD_INT(IntItem,-,uint64_t)
- INT_ITEM_DEFINE_BINARY_OP(<<)
- INT_ITEM_DEFINE_OP_STANDARD_INT(IntItem,<<,unsigned)
- INT_ITEM_DEFINE_BINARY_OP(&)
- INT_ITEM_DEFINE_BINARY_OP(^)
- INT_ITEM_DEFINE_BINARY_OP(|)
-
- INT_ITEM_DEFINE_ASSIGNMENT_BY_OP(*=)
- INT_ITEM_DEFINE_ASSIGNMENT_BY_OP(+=)
- INT_ITEM_DEFINE_ASSIGNMENT_BY_OP(-=)
- INT_ITEM_DEFINE_ASSIGNMENT_BY_OP(&=)
- INT_ITEM_DEFINE_ASSIGNMENT_BY_OP(^=)
- INT_ITEM_DEFINE_ASSIGNMENT_BY_OP(|=)
-
- // Special case for <<=
- IntItem& operator <<= (unsigned RHS) {
- APInt res = getAPIntValue();
- res <<= RHS;
- Constant *NewVal = ConstantInt::get(ConstantIntVal->getContext(), res);
- ConstantIntVal = cast<ConstantInt>(NewVal);
- return *this;
- }
-
- INT_ITEM_DEFINE_UNARY_OP(-)
- INT_ITEM_DEFINE_UNARY_OP(~)
-
- INT_ITEM_DEFINE_PREINCDEC(++)
- INT_ITEM_DEFINE_PREINCDEC(--)
-
- // The set of workarounds, since currently we use ConstantInt implemented
- // integer.
-
- static IntItem fromConstantInt(const ConstantInt *V) {
- return IntItem(V);
- }
- static IntItem fromType(Type* Ty, const APInt& V) {
- ConstantInt *C = cast<ConstantInt>(ConstantInt::get(Ty, V));
- return fromConstantInt(C);
- }
- static IntItem withImplLikeThis(const IntItem& LikeThis, const APInt& V) {
- ConstantInt *C = cast<ConstantInt>(ConstantInt::get(
- LikeThis.ConstantIntVal->getContext(), V));
- return fromConstantInt(C);
- }
- ConstantInt *toConstantInt() const {
- return ConstantIntVal;
- }
-};
-
-template<class IntType>
-class IntRange {
-protected:
- IntType Low;
- IntType High;
- bool IsEmpty : 1;
- bool IsSingleNumber : 1;
-
-public:
- typedef IntRange<IntType> self;
- typedef std::pair<self, self> SubRes;
-
- IntRange() : IsEmpty(true) {}
- IntRange(const self &RHS) :
- Low(RHS.Low), High(RHS.High),
- IsEmpty(RHS.IsEmpty), IsSingleNumber(RHS.IsSingleNumber) {}
- IntRange(const IntType &C) :
- Low(C), High(C), IsEmpty(false), IsSingleNumber(true) {}
-
- IntRange(const IntType &L, const IntType &H) : Low(L), High(H),
- IsEmpty(false), IsSingleNumber(Low == High) {}
-
- bool isEmpty() const { return IsEmpty; }
- bool isSingleNumber() const { return IsSingleNumber; }
-
- const IntType& getLow() const {
- assert(!IsEmpty && "Range is empty.");
- return Low;
- }
- const IntType& getHigh() const {
- assert(!IsEmpty && "Range is empty.");
- return High;
- }
-
- bool operator<(const self &RHS) const {
- assert(!IsEmpty && "Left range is empty.");
- assert(!RHS.IsEmpty && "Right range is empty.");
- if (Low == RHS.Low) {
- if (High > RHS.High)
- return true;
- return false;
- }
- if (Low < RHS.Low)
- return true;
- return false;
- }
-
- bool operator==(const self &RHS) const {
- assert(!IsEmpty && "Left range is empty.");
- assert(!RHS.IsEmpty && "Right range is empty.");
- return Low == RHS.Low && High == RHS.High;
- }
-
- bool operator!=(const self &RHS) const {
- return !operator ==(RHS);
- }
-
- static bool LessBySize(const self &LHS, const self &RHS) {
- return (LHS.High - LHS.Low) < (RHS.High - RHS.Low);
- }
-
- bool isInRange(const IntType &IntVal) const {
- assert(!IsEmpty && "Range is empty.");
- return IntVal >= Low && IntVal <= High;
- }
-
- SubRes sub(const self &RHS) const {
- SubRes Res;
-
- // RHS is either more global and includes this range or
- // if it doesn't intersected with this range.
- if (!isInRange(RHS.Low) && !isInRange(RHS.High)) {
-
- // If RHS more global (it is enough to check
- // only one border in this case.
- if (RHS.isInRange(Low))
- return std::make_pair(self(Low, High), self());
-
- return Res;
- }
-
- if (Low < RHS.Low) {
- Res.first.Low = Low;
- IntType NewHigh = RHS.Low;
- --NewHigh;
- Res.first.High = NewHigh;
- }
- if (High > RHS.High) {
- IntType NewLow = RHS.High;
- ++NewLow;
- Res.second.Low = NewLow;
- Res.second.High = High;
- }
- return Res;
- }
- };
-
-//===----------------------------------------------------------------------===//
-/// IntegersSubsetGeneric - class that implements the subset of integers. It
-/// consists from ranges and single numbers.
-template <class IntTy>
-class IntegersSubsetGeneric {
-public:
- // Use Chris Lattner idea, that was initially described here:
- // http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20120213/136954.html
- // In short, for more compact memory consumption we can store flat
- // numbers collection, and define range as pair of indices.
- // In that case we can safe some memory on 32 bit machines.
- typedef std::vector<IntTy> FlatCollectionTy;
- typedef std::pair<IntTy*, IntTy*> RangeLinkTy;
- typedef std::vector<RangeLinkTy> RangeLinksTy;
- typedef typename RangeLinksTy::const_iterator RangeLinksConstIt;
-
- typedef IntegersSubsetGeneric<IntTy> self;
-
-protected:
-
- FlatCollectionTy FlatCollection;
- RangeLinksTy RangeLinks;
-
- bool IsSingleNumber;
- bool IsSingleNumbersOnly;
-
-public:
-
- template<class RangesCollectionTy>
- explicit IntegersSubsetGeneric(const RangesCollectionTy& Links) {
- assert(Links.size() && "Empty ranges are not allowed.");
-
- // In case of big set of single numbers consumes additional RAM space,
- // but allows to avoid additional reallocation.
- FlatCollection.reserve(Links.size() * 2);
- RangeLinks.reserve(Links.size());
- IsSingleNumbersOnly = true;
- for (typename RangesCollectionTy::const_iterator i = Links.begin(),
- e = Links.end(); i != e; ++i) {
- RangeLinkTy RangeLink;
- FlatCollection.push_back(i->getLow());
- RangeLink.first = &FlatCollection.back();
- if (i->getLow() != i->getHigh()) {
- FlatCollection.push_back(i->getHigh());
- IsSingleNumbersOnly = false;
- }
- RangeLink.second = &FlatCollection.back();
- RangeLinks.push_back(RangeLink);
- }
- IsSingleNumber = IsSingleNumbersOnly && RangeLinks.size() == 1;
- }
-
- IntegersSubsetGeneric(const self& RHS) {
- *this = RHS;
- }
-
- self& operator=(const self& RHS) {
- FlatCollection.clear();
- RangeLinks.clear();
- FlatCollection.reserve(RHS.RangeLinks.size() * 2);
- RangeLinks.reserve(RHS.RangeLinks.size());
- for (RangeLinksConstIt i = RHS.RangeLinks.begin(), e = RHS.RangeLinks.end();
- i != e; ++i) {
- RangeLinkTy RangeLink;
- FlatCollection.push_back(*(i->first));
- RangeLink.first = &FlatCollection.back();
- if (i->first != i->second)
- FlatCollection.push_back(*(i->second));
- RangeLink.second = &FlatCollection.back();
- RangeLinks.push_back(RangeLink);
- }
- IsSingleNumber = RHS.IsSingleNumber;
- IsSingleNumbersOnly = RHS.IsSingleNumbersOnly;
- return *this;
- }
-
- typedef IntRange<IntTy> Range;
-
- /// Checks is the given constant satisfies this case. Returns
- /// true if it equals to one of contained values or belongs to the one of
- /// contained ranges.
- bool isSatisfies(const IntTy &CheckingVal) const {
- if (IsSingleNumber)
- return FlatCollection.front() == CheckingVal;
- if (IsSingleNumbersOnly)
- return std::find(FlatCollection.begin(),
- FlatCollection.end(),
- CheckingVal) != FlatCollection.end();
-
- for (size_t i = 0, e = getNumItems(); i < e; ++i) {
- if (RangeLinks[i].first == RangeLinks[i].second) {
- if (*RangeLinks[i].first == CheckingVal)
- return true;
- } else if (*RangeLinks[i].first <= CheckingVal &&
- *RangeLinks[i].second >= CheckingVal)
- return true;
- }
- return false;
- }
-
- /// Returns set's item with given index.
- Range getItem(unsigned idx) const {
- const RangeLinkTy &Link = RangeLinks[idx];
- if (Link.first != Link.second)
- return Range(*Link.first, *Link.second);
- else
- return Range(*Link.first);
- }
-
- /// Return number of items (ranges) stored in set.
- size_t getNumItems() const {
- return RangeLinks.size();
- }
-
- /// Returns true if whole subset contains single element.
- bool isSingleNumber() const {
- return IsSingleNumber;
- }
-
- /// Returns true if whole subset contains only single numbers, no ranges.
- bool isSingleNumbersOnly() const {
- return IsSingleNumbersOnly;
- }
-
- /// Does the same like getItem(idx).isSingleNumber(), but
- /// works faster, since we avoid creation of temporary range object.
- bool isSingleNumber(unsigned idx) const {
- return RangeLinks[idx].first == RangeLinks[idx].second;
- }
-
- /// Returns set the size, that equals number of all values + sizes of all
- /// ranges.
- /// Ranges set is considered as flat numbers collection.
- /// E.g.: for range [<0>, <1>, <4,8>] the size will 7;
- /// for range [<0>, <1>, <5>] the size will 3
- unsigned getSize() const {
- APInt sz(((const APInt&)getItem(0).getLow()).getBitWidth(), 0);
- for (size_t i = 0, e = getNumItems(); i != e; ++i) {
- const APInt Low = getItem(i).getLow();
- const APInt High = getItem(i).getHigh();
- APInt S = High - Low + 1;
- sz += S;
- }
- return sz.getZExtValue();
- }
-
- /// Allows to access single value even if it belongs to some range.
- /// Ranges set is considered as flat numbers collection.
- /// [<1>, <4,8>] is considered as [1,4,5,6,7,8]
- /// For range [<1>, <4,8>] getSingleValue(3) returns 6.
- APInt getSingleValue(unsigned idx) const {
- APInt sz(((const APInt&)getItem(0).getLow()).getBitWidth(), 0);
- for (unsigned i = 0, e = getNumItems(); i != e; ++i) {
- const APInt Low = getItem(i).getLow();
- const APInt High = getItem(i).getHigh();
- APInt S = High - Low + 1;
- APInt oldSz = sz;
- sz += S;
- if (sz.ugt(idx)) {
- APInt Res = Low;
- APInt Offset(oldSz.getBitWidth(), idx);
- Offset -= oldSz;
- Res += Offset;
- return Res;
- }
- }
- assert(0 && "Index exceeds high border.");
- return sz;
- }
-
- /// Does the same as getSingleValue, but works only if subset contains
- /// single numbers only.
- const IntTy& getSingleNumber(unsigned idx) const {
- assert(IsSingleNumbersOnly && "This method works properly if subset "
- "contains single numbers only.");
- return FlatCollection[idx];
- }
-};
-
-//===----------------------------------------------------------------------===//
-/// IntegersSubset - currently is extension of IntegersSubsetGeneric
-/// that also supports conversion to/from Constant* object.
-class IntegersSubset : public IntegersSubsetGeneric<IntItem> {
-
- typedef IntegersSubsetGeneric<IntItem> ParentTy;
-
- Constant *Holder;
-
- static unsigned getNumItemsFromConstant(Constant *C) {
- return cast<ArrayType>(C->getType())->getNumElements();
- }
-
- static Range getItemFromConstant(Constant *C, unsigned idx) {
- const Constant *CV = C->getAggregateElement(idx);
-
- unsigned NumEls = cast<VectorType>(CV->getType())->getNumElements();
- switch (NumEls) {
- case 1:
- return Range(IntItem::fromConstantInt(
- cast<ConstantInt>(CV->getAggregateElement(0U))),
- IntItem::fromConstantInt(cast<ConstantInt>(
- cast<ConstantInt>(CV->getAggregateElement(0U)))));
- case 2:
- return Range(IntItem::fromConstantInt(
- cast<ConstantInt>(CV->getAggregateElement(0U))),
- IntItem::fromConstantInt(
- cast<ConstantInt>(CV->getAggregateElement(1))));
- default:
- assert(0 && "Only pairs and single numbers are allowed here.");
- return Range();
- }
- }
-
- std::vector<Range> rangesFromConstant(Constant *C) {
- unsigned NumItems = getNumItemsFromConstant(C);
- std::vector<Range> r;
- r.reserve(NumItems);
- for (unsigned i = 0, e = NumItems; i != e; ++i)
- r.push_back(getItemFromConstant(C, i));
- return r;
- }
-
-public:
-
- explicit IntegersSubset(Constant *C) : ParentTy(rangesFromConstant(C)),
- Holder(C) {}
-
- IntegersSubset(const IntegersSubset& RHS) :
- ParentTy(*(const ParentTy *)&RHS), // FIXME: tweak for msvc.
- Holder(RHS.Holder) {}
-
- template<class RangesCollectionTy>
- explicit IntegersSubset(const RangesCollectionTy& Src) : ParentTy(Src) {
- std::vector<Constant*> Elts;
- Elts.reserve(Src.size());
- for (typename RangesCollectionTy::const_iterator i = Src.begin(),
- e = Src.end(); i != e; ++i) {
- const Range &R = *i;
- std::vector<Constant*> r;
- if (R.isSingleNumber()) {
- r.reserve(2);
- // FIXME: Since currently we have ConstantInt based numbers
- // use hack-conversion of IntItem to ConstantInt
- r.push_back(R.getLow().toConstantInt());
- r.push_back(R.getHigh().toConstantInt());
- } else {
- r.reserve(1);
- r.push_back(R.getLow().toConstantInt());
- }
- Constant *CV = ConstantVector::get(r);
- Elts.push_back(CV);
- }
- ArrayType *ArrTy =
- ArrayType::get(Elts.front()->getType(), (uint64_t)Elts.size());
- Holder = ConstantArray::get(ArrTy, Elts);
- }
-
- operator Constant*() { return Holder; }
- operator const Constant*() const { return Holder; }
- Constant *operator->() { return Holder; }
- const Constant *operator->() const { return Holder; }
-};
-
-}
-
-#endif /* CLLVM_SUPPORT_INTEGERSSUBSET_H */
diff --git a/include/llvm/Support/IntegersSubsetMapping.h b/include/llvm/Support/IntegersSubsetMapping.h
deleted file mode 100644
index 641ce78..0000000
--- a/include/llvm/Support/IntegersSubsetMapping.h
+++ /dev/null
@@ -1,588 +0,0 @@
-//===- IntegersSubsetMapping.h - Mapping subset ==> Successor ---*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-/// @file
-/// IntegersSubsetMapping is mapping from A to B, where
-/// Items in A is subsets of integers,
-/// Items in B some pointers (Successors).
-/// If user which to add another subset for successor that is already
-/// exists in mapping, IntegersSubsetMapping merges existing subset with
-/// added one.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SUPPORT_INTEGERSSUBSETMAPPING_H
-#define LLVM_SUPPORT_INTEGERSSUBSETMAPPING_H
-
-#include "llvm/Support/IntegersSubset.h"
-#include <list>
-#include <map>
-#include <vector>
-
-namespace llvm {
-
-template <class SuccessorClass,
- class IntegersSubsetTy = IntegersSubset,
- class IntTy = IntItem>
-class IntegersSubsetMapping {
- // FIXME: To much similar iterators typedefs, similar names.
- // - Rename RangeIterator to the cluster iterator.
- // - Remove unused "add" methods.
- // - Class contents needs cleaning.
-public:
-
- typedef IntRange<IntTy> RangeTy;
-
- struct RangeEx : public RangeTy {
- RangeEx() : Weight(1) {}
- RangeEx(const RangeTy &R) : RangeTy(R), Weight(1) {}
- RangeEx(const RangeTy &R, unsigned W) : RangeTy(R), Weight(W) {}
- RangeEx(const IntTy &C) : RangeTy(C), Weight(1) {}
- RangeEx(const IntTy &L, const IntTy &H) : RangeTy(L, H), Weight(1) {}
- RangeEx(const IntTy &L, const IntTy &H, unsigned W) :
- RangeTy(L, H), Weight(W) {}
- unsigned Weight;
- };
-
- typedef std::pair<RangeEx, SuccessorClass*> Cluster;
-
- typedef std::list<RangeTy> RangesCollection;
- typedef typename RangesCollection::iterator RangesCollectionIt;
- typedef typename RangesCollection::const_iterator RangesCollectionConstIt;
- typedef IntegersSubsetMapping<SuccessorClass, IntegersSubsetTy, IntTy> self;
-
-protected:
-
- typedef std::list<Cluster> CaseItems;
- typedef typename CaseItems::iterator CaseItemIt;
- typedef typename CaseItems::const_iterator CaseItemConstIt;
-
- // TODO: Change unclean CRS prefixes to SubsetMap for example.
- typedef std::map<SuccessorClass*, RangesCollection > CRSMap;
- typedef typename CRSMap::iterator CRSMapIt;
-
- struct ClustersCmp {
- bool operator()(const Cluster &C1, const Cluster &C2) {
- return C1.first < C2.first;
- }
- };
-
- CaseItems Items;
- bool Sorted;
-
- bool isIntersected(CaseItemIt& LItem, CaseItemIt& RItem) {
- return LItem->first.getHigh() >= RItem->first.getLow();
- }
-
- bool isJoinable(CaseItemIt& LItem, CaseItemIt& RItem) {
- if (LItem->second != RItem->second) {
- assert(!isIntersected(LItem, RItem) &&
- "Intersected items with different successors!");
- return false;
- }
- APInt RLow = RItem->first.getLow();
- if (RLow != APInt::getNullValue(RLow.getBitWidth()))
- --RLow;
- return LItem->first.getHigh() >= RLow;
- }
-
- void sort() {
- if (!Sorted) {
- std::vector<Cluster> clustersVector;
- clustersVector.reserve(Items.size());
- clustersVector.insert(clustersVector.begin(), Items.begin(), Items.end());
- std::sort(clustersVector.begin(), clustersVector.end(), ClustersCmp());
- Items.clear();
- Items.insert(Items.begin(), clustersVector.begin(), clustersVector.end());
- Sorted = true;
- }
- }
-
- enum DiffProcessState {
- L_OPENED,
- INTERSECT_OPENED,
- R_OPENED,
- ALL_IS_CLOSED
- };
-
- class DiffStateMachine {
-
- DiffProcessState State;
- IntTy OpenPt;
- SuccessorClass *CurrentLSuccessor;
- SuccessorClass *CurrentRSuccessor;
-
- self *LeftMapping;
- self *IntersectionMapping;
- self *RightMapping;
-
- public:
-
- typedef
- IntegersSubsetMapping<SuccessorClass, IntegersSubsetTy, IntTy> MappingTy;
-
- DiffStateMachine(MappingTy *L,
- MappingTy *Intersection,
- MappingTy *R) :
- State(ALL_IS_CLOSED),
- LeftMapping(L),
- IntersectionMapping(Intersection),
- RightMapping(R)
- {}
-
- void onLOpen(const IntTy &Pt, SuccessorClass *S) {
- switch (State) {
- case R_OPENED:
- if (Pt > OpenPt/*Don't add empty ranges.*/ && RightMapping)
- RightMapping->add(OpenPt, Pt-1, CurrentRSuccessor);
- State = INTERSECT_OPENED;
- break;
- case ALL_IS_CLOSED:
- State = L_OPENED;
- break;
- default:
- assert(0 && "Got unexpected point.");
- break;
- }
- CurrentLSuccessor = S;
- OpenPt = Pt;
- }
-
- void onLClose(const IntTy &Pt) {
- switch (State) {
- case L_OPENED:
- assert(Pt >= OpenPt &&
- "Subset is not sorted or contains overlapped ranges");
- if (LeftMapping)
- LeftMapping->add(OpenPt, Pt, CurrentLSuccessor);
- State = ALL_IS_CLOSED;
- break;
- case INTERSECT_OPENED:
- if (IntersectionMapping)
- IntersectionMapping->add(OpenPt, Pt, CurrentLSuccessor);
- OpenPt = Pt + 1;
- State = R_OPENED;
- break;
- default:
- assert(0 && "Got unexpected point.");
- break;
- }
- }
-
- void onROpen(const IntTy &Pt, SuccessorClass *S) {
- switch (State) {
- case L_OPENED:
- if (Pt > OpenPt && LeftMapping)
- LeftMapping->add(OpenPt, Pt-1, CurrentLSuccessor);
- State = INTERSECT_OPENED;
- break;
- case ALL_IS_CLOSED:
- State = R_OPENED;
- break;
- default:
- assert(0 && "Got unexpected point.");
- break;
- }
- CurrentRSuccessor = S;
- OpenPt = Pt;
- }
-
- void onRClose(const IntTy &Pt) {
- switch (State) {
- case R_OPENED:
- assert(Pt >= OpenPt &&
- "Subset is not sorted or contains overlapped ranges");
- if (RightMapping)
- RightMapping->add(OpenPt, Pt, CurrentRSuccessor);
- State = ALL_IS_CLOSED;
- break;
- case INTERSECT_OPENED:
- if (IntersectionMapping)
- IntersectionMapping->add(OpenPt, Pt, CurrentLSuccessor);
- OpenPt = Pt + 1;
- State = L_OPENED;
- break;
- default:
- assert(0 && "Got unexpected point.");
- break;
- }
- }
-
- void onLROpen(const IntTy &Pt,
- SuccessorClass *LS,
- SuccessorClass *RS) {
- switch (State) {
- case ALL_IS_CLOSED:
- State = INTERSECT_OPENED;
- break;
- default:
- assert(0 && "Got unexpected point.");
- break;
- }
- CurrentLSuccessor = LS;
- CurrentRSuccessor = RS;
- OpenPt = Pt;
- }
-
- void onLRClose(const IntTy &Pt) {
- switch (State) {
- case INTERSECT_OPENED:
- if (IntersectionMapping)
- IntersectionMapping->add(OpenPt, Pt, CurrentLSuccessor);
- State = ALL_IS_CLOSED;
- break;
- default:
- assert(0 && "Got unexpected point.");
- break;
- }
- }
-
- bool isLOpened() { return State == L_OPENED; }
- bool isROpened() { return State == R_OPENED; }
- };
-
-public:
-
- // Don't public CaseItems itself. Don't allow edit the Items directly.
- // Just present the user way to iterate over the internal collection
- // sharing iterator, begin() and end(). Editing should be controlled by
- // factory.
- typedef CaseItemIt RangeIterator;
-
- typedef std::pair<SuccessorClass*, IntegersSubsetTy> Case;
- typedef std::list<Case> Cases;
- typedef typename Cases::iterator CasesIt;
-
- IntegersSubsetMapping() {
- Sorted = false;
- }
-
- bool verify() {
- RangeIterator DummyErrItem;
- return verify(DummyErrItem);
- }
-
- bool verify(RangeIterator& errItem) {
- if (Items.empty())
- return true;
- sort();
- for (CaseItemIt j = Items.begin(), i = j++, e = Items.end();
- j != e; i = j++) {
- if (isIntersected(i, j) && i->second != j->second) {
- errItem = j;
- return false;
- }
- }
- return true;
- }
-
- bool isOverlapped(self &RHS) {
- if (Items.empty() || RHS.empty())
- return true;
-
- for (CaseItemIt L = Items.begin(), R = RHS.Items.begin(),
- el = Items.end(), er = RHS.Items.end(); L != el && R != er;) {
-
- const RangeTy &LRange = L->first;
- const RangeTy &RRange = R->first;
-
- if (LRange.getLow() > RRange.getLow()) {
- if (RRange.isSingleNumber() || LRange.getLow() > RRange.getHigh())
- ++R;
- else
- return true;
- } else if (LRange.getLow() < RRange.getLow()) {
- if (LRange.isSingleNumber() || LRange.getHigh() < RRange.getLow())
- ++L;
- else
- return true;
- } else // iRange.getLow() == jRange.getLow()
- return true;
- }
- return false;
- }
-
-
- void optimize() {
- if (Items.size() < 2)
- return;
- sort();
- CaseItems OldItems = Items;
- Items.clear();
- const IntTy *Low = &OldItems.begin()->first.getLow();
- const IntTy *High = &OldItems.begin()->first.getHigh();
- unsigned Weight = OldItems.begin()->first.Weight;
- SuccessorClass *Successor = OldItems.begin()->second;
- for (CaseItemIt j = OldItems.begin(), i = j++, e = OldItems.end();
- j != e; i = j++) {
- if (isJoinable(i, j)) {
- const IntTy *CurHigh = &j->first.getHigh();
- Weight += j->first.Weight;
- if (*CurHigh > *High)
- High = CurHigh;
- } else {
- RangeEx R(*Low, *High, Weight);
- add(R, Successor);
- Low = &j->first.getLow();
- High = &j->first.getHigh();
- Weight = j->first.Weight;
- Successor = j->second;
- }
- }
- RangeEx R(*Low, *High, Weight);
- add(R, Successor);
- // We recollected the Items, but we kept it sorted.
- Sorted = true;
- }
-
- /// Adds a constant value.
- void add(const IntTy &C, SuccessorClass *S = 0) {
- RangeTy R(C);
- add(R, S);
- }
-
- /// Adds a range.
- void add(const IntTy &Low, const IntTy &High, SuccessorClass *S = 0) {
- RangeTy R(Low, High);
- add(R, S);
- }
- void add(const RangeTy &R, SuccessorClass *S = 0) {
- RangeEx REx = R;
- add(REx, S);
- }
- void add(const RangeEx &R, SuccessorClass *S = 0) {
- Items.push_back(std::make_pair(R, S));
- Sorted = false;
- }
-
- /// Adds all ranges and values from given ranges set to the current
- /// mapping.
- void add(const IntegersSubsetTy &CRS, SuccessorClass *S = 0,
- unsigned Weight = 0) {
- unsigned ItemWeight = 1;
- if (Weight)
- // Weight is associated with CRS, for now we perform a division to
- // get the weight for each item.
- ItemWeight = Weight / CRS.getNumItems();
- for (unsigned i = 0, e = CRS.getNumItems(); i < e; ++i) {
- RangeTy R = CRS.getItem(i);
- RangeEx REx(R, ItemWeight);
- add(REx, S);
- }
- }
-
- void add(self& RHS) {
- Items.insert(Items.end(), RHS.Items.begin(), RHS.Items.end());
- }
-
- void add(self& RHS, SuccessorClass *S) {
- for (CaseItemIt i = RHS.Items.begin(), e = RHS.Items.end(); i != e; ++i)
- add(i->first, S);
- }
-
- void add(const RangesCollection& RHS, SuccessorClass *S = 0) {
- for (RangesCollectionConstIt i = RHS.begin(), e = RHS.end(); i != e; ++i)
- add(*i, S);
- }
-
- /// Removes items from set.
- void removeItem(RangeIterator i) { Items.erase(i); }
-
- /// Moves whole case from current mapping to the NewMapping object.
- void detachCase(self& NewMapping, SuccessorClass *Succ) {
- for (CaseItemIt i = Items.begin(); i != Items.end();)
- if (i->second == Succ) {
- NewMapping.add(i->first, i->second);
- Items.erase(i++);
- } else
- ++i;
- }
-
- /// Removes all clusters for given successor.
- void removeCase(SuccessorClass *Succ) {
- for (CaseItemIt i = Items.begin(); i != Items.end();)
- if (i->second == Succ) {
- Items.erase(i++);
- } else
- ++i;
- }
-
- /// Find successor that satisfies given value.
- SuccessorClass *findSuccessor(const IntTy& Val) {
- for (CaseItemIt i = Items.begin(); i != Items.end(); ++i) {
- if (i->first.isInRange(Val))
- return i->second;
- }
- return 0;
- }
-
- /// Calculates the difference between this mapping and RHS.
- /// THIS without RHS is placed into LExclude,
- /// RHS without THIS is placed into RExclude,
- /// THIS intersect RHS is placed into Intersection.
- void diff(self *LExclude, self *Intersection, self *RExclude,
- const self& RHS) {
-
- DiffStateMachine Machine(LExclude, Intersection, RExclude);
-
- CaseItemConstIt L = Items.begin(), R = RHS.Items.begin();
- while (L != Items.end() && R != RHS.Items.end()) {
- const Cluster &LCluster = *L;
- const RangeEx &LRange = LCluster.first;
- const Cluster &RCluster = *R;
- const RangeEx &RRange = RCluster.first;
-
- if (LRange.getHigh() < RRange.getLow()) {
- Machine.onLOpen(LRange.getLow(), LCluster.second);
- Machine.onLClose(LRange.getHigh());
- ++L;
- continue;
- }
-
- if (LRange.getLow() > RRange.getHigh()) {
- Machine.onROpen(RRange.getLow(), RCluster.second);
- Machine.onRClose(RRange.getHigh());
- ++R;
- continue;
- }
-
- if (LRange.getLow() < RRange.getLow()) {
- // May be opened in previous iteration.
- if (!Machine.isLOpened())
- Machine.onLOpen(LRange.getLow(), LCluster.second);
- Machine.onROpen(RRange.getLow(), RCluster.second);
- }
- else if (RRange.getLow() < LRange.getLow()) {
- if (!Machine.isROpened())
- Machine.onROpen(RRange.getLow(), RCluster.second);
- Machine.onLOpen(LRange.getLow(), LCluster.second);
- }
- else
- Machine.onLROpen(LRange.getLow(), LCluster.second, RCluster.second);
-
- if (LRange.getHigh() < RRange.getHigh()) {
- Machine.onLClose(LRange.getHigh());
- ++L;
- while(L != Items.end() && L->first.getHigh() < RRange.getHigh()) {
- Machine.onLOpen(L->first.getLow(), L->second);
- Machine.onLClose(L->first.getHigh());
- ++L;
- }
- }
- else if (RRange.getHigh() < LRange.getHigh()) {
- Machine.onRClose(RRange.getHigh());
- ++R;
- while(R != RHS.Items.end() && R->first.getHigh() < LRange.getHigh()) {
- Machine.onROpen(R->first.getLow(), R->second);
- Machine.onRClose(R->first.getHigh());
- ++R;
- }
- }
- else {
- Machine.onLRClose(LRange.getHigh());
- ++L;
- ++R;
- }
- }
-
- if (L != Items.end()) {
- if (Machine.isLOpened()) {
- Machine.onLClose(L->first.getHigh());
- ++L;
- }
- if (LExclude)
- while (L != Items.end()) {
- LExclude->add(L->first, L->second);
- ++L;
- }
- } else if (R != RHS.Items.end()) {
- if (Machine.isROpened()) {
- Machine.onRClose(R->first.getHigh());
- ++R;
- }
- if (RExclude)
- while (R != RHS.Items.end()) {
- RExclude->add(R->first, R->second);
- ++R;
- }
- }
- }
-
- /// Builds the finalized case objects.
- void getCases(Cases& TheCases, bool PreventMerging = false) {
- //FIXME: PreventMerging is a temporary parameter.
- //Currently a set of passes is still knows nothing about
- //switches with case ranges, and if these passes meet switch
- //with complex case that crashs the application.
- if (PreventMerging) {
- for (RangeIterator i = this->begin(); i != this->end(); ++i) {
- RangesCollection SingleRange;
- SingleRange.push_back(i->first);
- TheCases.push_back(std::make_pair(i->second,
- IntegersSubsetTy(SingleRange)));
- }
- return;
- }
- CRSMap TheCRSMap;
- for (RangeIterator i = this->begin(); i != this->end(); ++i)
- TheCRSMap[i->second].push_back(i->first);
- for (CRSMapIt i = TheCRSMap.begin(), e = TheCRSMap.end(); i != e; ++i)
- TheCases.push_back(std::make_pair(i->first, IntegersSubsetTy(i->second)));
- }
-
- /// Builds the finalized case objects ignoring successor values, as though
- /// all ranges belongs to the same successor.
- IntegersSubsetTy getCase() {
- RangesCollection Ranges;
- for (RangeIterator i = this->begin(); i != this->end(); ++i)
- Ranges.push_back(i->first);
- return IntegersSubsetTy(Ranges);
- }
-
- /// Returns pointer to value of case if it is single-numbered or 0
- /// in another case.
- const IntTy* getCaseSingleNumber(SuccessorClass *Succ) {
- const IntTy* Res = 0;
- for (CaseItemIt i = Items.begin(); i != Items.end(); ++i)
- if (i->second == Succ) {
- if (!i->first.isSingleNumber())
- return 0;
- if (Res)
- return 0;
- else
- Res = &(i->first.getLow());
- }
- return Res;
- }
-
- /// Returns true if there is no ranges and values inside.
- bool empty() const { return Items.empty(); }
-
- void clear() {
- Items.clear();
- // Don't reset Sorted flag:
- // 1. For empty mapping it matters nothing.
- // 2. After first item will added Sorted flag will cleared.
- }
-
- // Returns number of clusters
- unsigned size() const {
- return Items.size();
- }
-
- RangeIterator begin() { return Items.begin(); }
- RangeIterator end() { return Items.end(); }
-};
-
-class BasicBlock;
-typedef IntegersSubsetMapping<BasicBlock> IntegersSubsetToBB;
-
-}
-
-#endif /* LLVM_SUPPORT_INTEGERSSUBSETMAPPING_CRSBUILDER_H */
diff --git a/include/llvm/Support/MachO.h b/include/llvm/Support/MachO.h
index 7f28c3f..897a611 100644
--- a/include/llvm/Support/MachO.h
+++ b/include/llvm/Support/MachO.h
@@ -14,273 +14,419 @@
#ifndef LLVM_SUPPORT_MACHO_H
#define LLVM_SUPPORT_MACHO_H
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/Host.h"
-// NOTE: The enums in this file are intentially named to be different than those
-// in the headers in /usr/include/mach (on darwin systems) to avoid conflicts
-// with those macros.
namespace llvm {
namespace MachO {
// Enums from <mach-o/loader.h>
- enum {
+ enum LLVM_ENUM_INT_TYPE(uint32_t) {
// Constants for the "magic" field in llvm::MachO::mach_header and
// llvm::MachO::mach_header_64
- HeaderMagic32 = 0xFEEDFACEu, // MH_MAGIC
- HeaderMagic32Swapped = 0xCEFAEDFEu, // MH_CIGAM
- HeaderMagic64 = 0xFEEDFACFu, // MH_MAGIC_64
- HeaderMagic64Swapped = 0xCFFAEDFEu, // MH_CIGAM_64
- UniversalMagic = 0xCAFEBABEu, // FAT_MAGIC
- UniversalMagicSwapped = 0xBEBAFECAu, // FAT_CIGAM
+ MH_MAGIC = 0xFEEDFACEu,
+ MH_CIGAM = 0xCEFAEDFEu,
+ MH_MAGIC_64 = 0xFEEDFACFu,
+ MH_CIGAM_64 = 0xCFFAEDFEu,
+ FAT_MAGIC = 0xCAFEBABEu,
+ FAT_CIGAM = 0xBEBAFECAu
+ };
+ enum HeaderFileType {
// Constants for the "filetype" field in llvm::MachO::mach_header and
// llvm::MachO::mach_header_64
- HeaderFileTypeObject = 0x1u, // MH_OBJECT
- HeaderFileTypeExecutable = 0x2u, // MH_EXECUTE
- HeaderFileTypeFixedVMShlib = 0x3u, // MH_FVMLIB
- HeaderFileTypeCore = 0x4u, // MH_CORE
- HeaderFileTypePreloadedExecutable = 0x5u, // MH_PRELOAD
- HeaderFileTypeDynamicShlib = 0x6u, // MH_DYLIB
- HeaderFileTypeDynamicLinkEditor = 0x7u, // MH_DYLINKER
- HeaderFileTypeBundle = 0x8u, // MH_BUNDLE
- HeaderFileTypeDynamicShlibStub = 0x9u, // MH_DYLIB_STUB
- HeaderFileTypeDSYM = 0xAu, // MH_DSYM
- HeaderFileTypeKextBundle = 0xBu, // MH_KEXT_BUNDLE
+ MH_OBJECT = 0x1u,
+ MH_EXECUTE = 0x2u,
+ MH_FVMLIB = 0x3u,
+ MH_CORE = 0x4u,
+ MH_PRELOAD = 0x5u,
+ MH_DYLIB = 0x6u,
+ MH_DYLINKER = 0x7u,
+ MH_BUNDLE = 0x8u,
+ MH_DYLIB_STUB = 0x9u,
+ MH_DSYM = 0xAu,
+ MH_KEXT_BUNDLE = 0xBu
+ };
+ enum {
// Constant bits for the "flags" field in llvm::MachO::mach_header and
// llvm::MachO::mach_header_64
- HeaderFlagBitNoUndefinedSymbols = 0x00000001u, // MH_NOUNDEFS
- HeaderFlagBitIsIncrementalLinkObject= 0x00000002u, // MH_INCRLINK
- HeaderFlagBitIsDynamicLinkObject = 0x00000004u, // MH_DYLDLINK
- HeaderFlagBitBindAtLoad = 0x00000008u, // MH_BINDATLOAD
- HeaderFlagBitPrebound = 0x00000010u, // MH_PREBOUND
- HeaderFlagBitSplitSegments = 0x00000020u, // MH_SPLIT_SEGS
- HeaderFlagBitLazyInit = 0x00000040u, // MH_LAZY_INIT
- HeaderFlagBitTwoLevelNamespace = 0x00000080u, // MH_TWOLEVEL
- HeaderFlagBitForceFlatNamespace = 0x00000100u, // MH_FORCE_FLAT
- HeaderFlagBitNoMultipleDefintions = 0x00000200u, // MH_NOMULTIDEFS
- HeaderFlagBitNoFixPrebinding = 0x00000400u, // MH_NOFIXPREBINDING
- HeaderFlagBitPrebindable = 0x00000800u, // MH_PREBINDABLE
- HeaderFlagBitAllModulesBound = 0x00001000u, // MH_ALLMODSBOUND
- HeaderFlagBitSubsectionsViaSymbols = 0x00002000u, // MH_SUBSECTIONS_VIA_SYMBOLS
- HeaderFlagBitCanonical = 0x00004000u, // MH_CANONICAL
- HeaderFlagBitWeakDefines = 0x00008000u, // MH_WEAK_DEFINES
- HeaderFlagBitBindsToWeak = 0x00010000u, // MH_BINDS_TO_WEAK
- HeaderFlagBitAllowStackExecution = 0x00020000u, // MH_ALLOW_STACK_EXECUTION
- HeaderFlagBitRootSafe = 0x00040000u, // MH_ROOT_SAFE
- HeaderFlagBitSetUIDSafe = 0x00080000u, // MH_SETUID_SAFE
- HeaderFlagBitNoReexportedDylibs = 0x00100000u, // MH_NO_REEXPORTED_DYLIBS
- HeaderFlagBitPIE = 0x00200000u, // MH_PIE
- HeaderFlagBitDeadStrippableDylib = 0x00400000u, // MH_DEAD_STRIPPABLE_DYLIB
-
+ MH_NOUNDEFS = 0x00000001u,
+ MH_INCRLINK = 0x00000002u,
+ MH_DYLDLINK = 0x00000004u,
+ MH_BINDATLOAD = 0x00000008u,
+ MH_PREBOUND = 0x00000010u,
+ MH_SPLIT_SEGS = 0x00000020u,
+ MH_LAZY_INIT = 0x00000040u,
+ MH_TWOLEVEL = 0x00000080u,
+ MH_FORCE_FLAT = 0x00000100u,
+ MH_NOMULTIDEFS = 0x00000200u,
+ MH_NOFIXPREBINDING = 0x00000400u,
+ MH_PREBINDABLE = 0x00000800u,
+ MH_ALLMODSBOUND = 0x00001000u,
+ MH_SUBSECTIONS_VIA_SYMBOLS = 0x00002000u,
+ MH_CANONICAL = 0x00004000u,
+ MH_WEAK_DEFINES = 0x00008000u,
+ MH_BINDS_TO_WEAK = 0x00010000u,
+ MH_ALLOW_STACK_EXECUTION = 0x00020000u,
+ MH_ROOT_SAFE = 0x00040000u,
+ MH_SETUID_SAFE = 0x00080000u,
+ MH_NO_REEXPORTED_DYLIBS = 0x00100000u,
+ MH_PIE = 0x00200000u,
+ MH_DEAD_STRIPPABLE_DYLIB = 0x00400000u
+ };
+
+ enum LLVM_ENUM_INT_TYPE(uint32_t) {
+ // Flags for the "cmd" field in llvm::MachO::load_command
+ LC_REQ_DYLD = 0x80000000u
+ };
+
+ enum LoadCommandType LLVM_ENUM_INT_TYPE(uint32_t) {
// Constants for the "cmd" field in llvm::MachO::load_command
- LoadCommandDynamicLinkerRequired = 0x80000000u, // LC_REQ_DYLD
- LoadCommandSegment32 = 0x00000001u, // LC_SEGMENT
- LoadCommandSymtab = 0x00000002u, // LC_SYMTAB
- LoadCommandSymSeg = 0x00000003u, // LC_SYMSEG
- LoadCommandThread = 0x00000004u, // LC_THREAD
- LoadCommandUnixThread = 0x00000005u, // LC_UNIXTHREAD
- LoadCommandFixedVMShlibLoad = 0x00000006u, // LC_LOADFVMLIB
- LoadCommandFixedVMShlibIdent = 0x00000007u, // LC_IDFVMLIB
- LoadCommandIdent = 0x00000008u, // LC_IDENT
- LoadCommandFixedVMFileInclusion = 0x00000009u, // LC_FVMFILE
- LoadCommandPrePage = 0x0000000Au, // LC_PREPAGE
- LoadCommandDynamicSymtabInfo = 0x0000000Bu, // LC_DYSYMTAB
- LoadCommandDylibLoad = 0x0000000Cu, // LC_LOAD_DYLIB
- LoadCommandDylibIdent = 0x0000000Du, // LC_ID_DYLIB
- LoadCommandDynamicLinkerLoad = 0x0000000Eu, // LC_LOAD_DYLINKER
- LoadCommandDynamicLinkerIdent = 0x0000000Fu, // LC_ID_DYLINKER
- LoadCommandDylibPrebound = 0x00000010u, // LC_PREBOUND_DYLIB
- LoadCommandRoutines32 = 0x00000011u, // LC_ROUTINES
- LoadCommandSubFramework = 0x00000012u, // LC_SUB_FRAMEWORK
- LoadCommandSubUmbrella = 0x00000013u, // LC_SUB_UMBRELLA
- LoadCommandSubClient = 0x00000014u, // LC_SUB_CLIENT
- LoadCommandSubLibrary = 0x00000015u, // LC_SUB_LIBRARY
- LoadCommandTwoLevelHints = 0x00000016u, // LC_TWOLEVEL_HINTS
- LoadCommandPreBindChecksum = 0x00000017u, // LC_PREBIND_CKSUM
- LoadCommandDylibLoadWeak = 0x80000018u, // LC_LOAD_WEAK_DYLIB
- LoadCommandSegment64 = 0x00000019u, // LC_SEGMENT_64
- LoadCommandRoutines64 = 0x0000001Au, // LC_ROUTINES_64
- LoadCommandUUID = 0x0000001Bu, // LC_UUID
- LoadCommandRunpath = 0x8000001Cu, // LC_RPATH
- LoadCommandCodeSignature = 0x0000001Du, // LC_CODE_SIGNATURE
- LoadCommandSegmentSplitInfo = 0x0000001Eu, // LC_SEGMENT_SPLIT_INFO
- LoadCommandDylibReexport = 0x8000001Fu, // LC_REEXPORT_DYLIB
- LoadCommandDylibLazyLoad = 0x00000020u, // LC_LAZY_LOAD_DYLIB
- LoadCommandEncryptionInfo = 0x00000021u, // LC_ENCRYPTION_INFO
- LoadCommandDynamicLinkerInfo = 0x00000022u, // LC_DYLD_INFO
- LoadCommandDynamicLinkerInfoOnly = 0x80000022u, // LC_DYLD_INFO_ONLY
- LoadCommandDylibLoadUpward = 0x80000023u, // LC_LOAD_UPWARD_DYLIB
- LoadCommandVersionMinMacOSX = 0x00000024u, // LC_VERSION_MIN_MACOSX
- LoadCommandVersionMinIPhoneOS = 0x00000025u, // LC_VERSION_MIN_IPHONEOS
- LoadCommandFunctionStarts = 0x00000026u, // LC_FUNCTION_STARTS
- LoadCommandDyldEnvironment = 0x00000027u, // LC_DYLD_ENVIRONMENT
- LoadCommandMain = 0x80000028u, // LC_MAIN
- LoadCommandDataInCode = 0x00000029u, // LC_DATA_IN_CODE
- LoadCommandSourceVersion = 0x0000002Au, // LC_SOURCE_VERSION
- LoadCommandCodeSignDRs = 0x0000002Bu, // LC_DYLIB_CODE_SIGN_DRS
-
+ LC_SEGMENT = 0x00000001u,
+ LC_SYMTAB = 0x00000002u,
+ LC_SYMSEG = 0x00000003u,
+ LC_THREAD = 0x00000004u,
+ LC_UNIXTHREAD = 0x00000005u,
+ LC_LOADFVMLIB = 0x00000006u,
+ LC_IDFVMLIB = 0x00000007u,
+ LC_IDENT = 0x00000008u,
+ LC_FVMFILE = 0x00000009u,
+ LC_PREPAGE = 0x0000000Au,
+ LC_DYSYMTAB = 0x0000000Bu,
+ LC_LOAD_DYLIB = 0x0000000Cu,
+ LC_ID_DYLIB = 0x0000000Du,
+ LC_LOAD_DYLINKER = 0x0000000Eu,
+ LC_ID_DYLINKER = 0x0000000Fu,
+ LC_PREBOUND_DYLIB = 0x00000010u,
+ LC_ROUTINES = 0x00000011u,
+ LC_SUB_FRAMEWORK = 0x00000012u,
+ LC_SUB_UMBRELLA = 0x00000013u,
+ LC_SUB_CLIENT = 0x00000014u,
+ LC_SUB_LIBRARY = 0x00000015u,
+ LC_TWOLEVEL_HINTS = 0x00000016u,
+ LC_PREBIND_CKSUM = 0x00000017u,
+ LC_LOAD_WEAK_DYLIB = 0x80000018u,
+ LC_SEGMENT_64 = 0x00000019u,
+ LC_ROUTINES_64 = 0x0000001Au,
+ LC_UUID = 0x0000001Bu,
+ LC_RPATH = 0x8000001Cu,
+ LC_CODE_SIGNATURE = 0x0000001Du,
+ LC_SEGMENT_SPLIT_INFO = 0x0000001Eu,
+ LC_REEXPORT_DYLIB = 0x8000001Fu,
+ LC_LAZY_LOAD_DYLIB = 0x00000020u,
+ LC_ENCRYPTION_INFO = 0x00000021u,
+ LC_DYLD_INFO = 0x00000022u,
+ LC_DYLD_INFO_ONLY = 0x80000022u,
+ LC_LOAD_UPWARD_DYLIB = 0x80000023u,
+ LC_VERSION_MIN_MACOSX = 0x00000024u,
+ LC_VERSION_MIN_IPHONEOS = 0x00000025u,
+ LC_FUNCTION_STARTS = 0x00000026u,
+ LC_DYLD_ENVIRONMENT = 0x00000027u,
+ LC_MAIN = 0x80000028u,
+ LC_DATA_IN_CODE = 0x00000029u,
+ LC_SOURCE_VERSION = 0x0000002Au,
+ LC_DYLIB_CODE_SIGN_DRS = 0x0000002Bu,
+ // 0x0000002Cu,
+ LC_LINKER_OPTIONS = 0x0000002Du
+ };
+
+ enum LLVM_ENUM_INT_TYPE(uint32_t) {
// Constant bits for the "flags" field in llvm::MachO::segment_command
- SegmentCommandFlagBitHighVM = 0x1u, // SG_HIGHVM
- SegmentCommandFlagBitFixedVMLibrary = 0x2u, // SG_FVMLIB
- SegmentCommandFlagBitNoRelocations = 0x4u, // SG_NORELOC
- SegmentCommandFlagBitProtectedVersion1 = 0x8u, // SG_PROTECTED_VERSION_1
+ SG_HIGHVM = 0x1u,
+ SG_FVMLIB = 0x2u,
+ SG_NORELOC = 0x4u,
+ SG_PROTECTED_VERSION_1 = 0x8u,
// Constant masks for the "flags" field in llvm::MachO::section and
// llvm::MachO::section_64
- SectionFlagMaskSectionType = 0x000000ffu, // SECTION_TYPE
- SectionFlagMaskAllAttributes = 0xffffff00u, // SECTION_ATTRIBUTES
- SectionFlagMaskUserAttributes = 0xff000000u, // SECTION_ATTRIBUTES_USR
- SectionFlagMaskSystemAttributes = 0x00ffff00u, // SECTION_ATTRIBUTES_SYS
+ SECTION_TYPE = 0x000000ffu, // SECTION_TYPE
+ SECTION_ATTRIBUTES = 0xffffff00u, // SECTION_ATTRIBUTES
+ SECTION_ATTRIBUTES_USR = 0xff000000u, // SECTION_ATTRIBUTES_USR
+ SECTION_ATTRIBUTES_SYS = 0x00ffff00u // SECTION_ATTRIBUTES_SYS
+ };
+ enum SectionType {
// Constant masks for the "flags[7:0]" field in llvm::MachO::section and
// llvm::MachO::section_64 (mask "flags" with SECTION_TYPE)
- SectionTypeRegular = 0x00u, // S_REGULAR
- SectionTypeZeroFill = 0x01u, // S_ZEROFILL
- SectionTypeCStringLiterals = 0x02u, // S_CSTRING_LITERALS
- SectionType4ByteLiterals = 0x03u, // S_4BYTE_LITERALS
- SectionType8ByteLiterals = 0x04u, // S_8BYTE_LITERALS
- SectionTypeLiteralPointers = 0x05u, // S_LITERAL_POINTERS
- SectionTypeNonLazySymbolPointers = 0x06u, // S_NON_LAZY_SYMBOL_POINTERS
- SectionTypeLazySymbolPointers = 0x07u, // S_LAZY_SYMBOL_POINTERS
- SectionTypeSymbolStubs = 0x08u, // S_SYMBOL_STUBS
- SectionTypeModuleInitFunctionPointers = 0x09u, // S_MOD_INIT_FUNC_POINTERS
- SectionTypeModuleTermFunctionPointers = 0x0au, // S_MOD_TERM_FUNC_POINTERS
- SectionTypeCoalesced = 0x0bu, // S_COALESCED
- SectionTypeZeroFillLarge = 0x0cu, // S_GB_ZEROFILL
- SectionTypeInterposing = 0x0du, // S_INTERPOSING
- SectionType16ByteLiterals = 0x0eu, // S_16BYTE_LITERALS
- SectionTypeDTraceObjectFormat = 0x0fu, // S_DTRACE_DOF
- SectionTypeLazyDylibSymbolPointers = 0x10u, // S_LAZY_DYLIB_SYMBOL_POINTERS
-
+ S_REGULAR = 0x00u,
+ S_ZEROFILL = 0x01u,
+ S_CSTRING_LITERALS = 0x02u,
+ S_4BYTE_LITERALS = 0x03u,
+ S_8BYTE_LITERALS = 0x04u,
+ S_LITERAL_POINTERS = 0x05u,
+ S_NON_LAZY_SYMBOL_POINTERS = 0x06u,
+ S_LAZY_SYMBOL_POINTERS = 0x07u,
+ S_SYMBOL_STUBS = 0x08u,
+ S_MOD_INIT_FUNC_POINTERS = 0x09u,
+ S_MOD_TERM_FUNC_POINTERS = 0x0au,
+ S_COALESCED = 0x0bu,
+ S_GB_ZEROFILL = 0x0cu,
+ S_INTERPOSING = 0x0du,
+ S_16BYTE_LITERALS = 0x0eu,
+ S_DTRACE_DOF = 0x0fu,
+ S_LAZY_DYLIB_SYMBOL_POINTERS = 0x10u,
+ S_THREAD_LOCAL_REGULAR = 0x11u,
+ S_THREAD_LOCAL_ZEROFILL = 0x12u,
+ S_THREAD_LOCAL_VARIABLES = 0x13u,
+ S_THREAD_LOCAL_VARIABLE_POINTERS = 0x14u,
+ S_THREAD_LOCAL_INIT_FUNCTION_POINTERS = 0x15u
+ };
+
+ enum LLVM_ENUM_INT_TYPE(uint32_t) {
// Constant masks for the "flags[31:24]" field in llvm::MachO::section and
// llvm::MachO::section_64 (mask "flags" with SECTION_ATTRIBUTES_USR)
- SectionAttrUserPureInstructions = 0x80000000u, // S_ATTR_PURE_INSTRUCTIONS
- SectionAttrUserNoTableOfContents = 0x40000000u, // S_ATTR_NO_TOC
- SectionAttrUserCanStripStaticSymbols = 0x20000000u, // S_ATTR_STRIP_STATIC_SYMS
- SectionAttrUserNoDeadStrip = 0x10000000u, // S_ATTR_NO_DEAD_STRIP
- SectionAttrUserLiveSupport = 0x08000000u, // S_ATTR_LIVE_SUPPORT
- SectionAttrUserSelfModifyingCode = 0x04000000u, // S_ATTR_SELF_MODIFYING_CODE
- SectionAttrUserDebug = 0x02000000u, // S_ATTR_DEBUG
+ S_ATTR_PURE_INSTRUCTIONS = 0x80000000u,
+ S_ATTR_NO_TOC = 0x40000000u,
+ S_ATTR_STRIP_STATIC_SYMS = 0x20000000u,
+ S_ATTR_NO_DEAD_STRIP = 0x10000000u,
+ S_ATTR_LIVE_SUPPORT = 0x08000000u,
+ S_ATTR_SELF_MODIFYING_CODE = 0x04000000u,
+ S_ATTR_DEBUG = 0x02000000u,
// Constant masks for the "flags[23:8]" field in llvm::MachO::section and
// llvm::MachO::section_64 (mask "flags" with SECTION_ATTRIBUTES_SYS)
- SectionAttrSytemSomeInstructions = 0x00000400u, // S_ATTR_SOME_INSTRUCTIONS
- SectionAttrSytemHasExternalRelocations= 0x00000200u, // S_ATTR_EXT_RELOC
- SectionAttrSytemHasLocalRelocations = 0x00000100u, // S_ATTR_LOC_RELOC
-
- IndirectSymbolLocal = 0x80000000u, // INDIRECT_SYMBOL_LOCAL
- IndirectSymbolAbsolute = 0x40000000u, // INDIRECT_SYMBOL_ABS
-
- RebaseTypePointer = 1u, // REBASE_TYPE_POINTER
- RebaseTypeTextAbsolute32 = 2u, // REBASE_TYPE_TEXT_ABSOLUTE32
- RebaseTypeTextPCRelative32 = 3u, // REBASE_TYPE_TEXT_PCREL32
-
- RebaseOpcodeMask = 0xF0u, // REBASE_OPCODE_MASK
- RebaseImmediateMask = 0x0Fu, // REBASE_IMMEDIATE_MASK
- RebaseOpcodeDone = 0x00u, // REBASE_OPCODE_DONE
- RebaseOpcodeSetTypeImmediate = 0x10u, // REBASE_OPCODE_SET_TYPE_IMM
- RebaseOpcodeSetSegmentAndOffsetULEB = 0x20u, // REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB
- RebaseOpcodeAddAddressULEB = 0x30u, // REBASE_OPCODE_ADD_ADDR_ULEB
- RebaseOpcodeAddAddressImmediateScaled = 0x40u, // REBASE_OPCODE_ADD_ADDR_IMM_SCALED
- RebaseOpcodeDoRebaseImmediateTimes = 0x50u, // REBASE_OPCODE_DO_REBASE_IMM_TIMES
- RebaseOpcodeDoRebaseULEBTimes = 0x60u, // REBASE_OPCODE_DO_REBASE_ULEB_TIMES
- RebaseOpcodeDoRebaseAddAddressULEB = 0x70u, // REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB
- RebaseOpcodeDoRebaseULEBTimesSkippingULEB = 0x80u, // REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB
-
-
- BindTypePointer = 1u, // BIND_TYPE_POINTER
- BindTypeTextAbsolute32 = 2u, // BIND_TYPE_TEXT_ABSOLUTE32
- BindTypeTextPCRelative32 = 3u, // BIND_TYPE_TEXT_PCREL32
-
- BindSpecialDylibSelf = 0u, // BIND_SPECIAL_DYLIB_SELF
- BindSpecialDylibMainExecutable = -1u, // BIND_SPECIAL_DYLIB_MAIN_EXECUTABLE
- BindSpecialDylibFlatLookup = -2u, // BIND_SPECIAL_DYLIB_FLAT_LOOKUP
-
- BindSymbolFlagsWeakImport = 0x1u, // BIND_SYMBOL_FLAGS_WEAK_IMPORT
- BindSymbolFlagsNonWeakDefinition = 0x8u, // BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION
-
- BindOpcodeMask = 0xF0u, // BIND_OPCODE_MASK
- BindImmediateMask = 0x0Fu, // BIND_IMMEDIATE_MASK
- BindOpcodeDone = 0x00u, // BIND_OPCODE_DONE
- BindOpcodeSetDylibOrdinalImmediate = 0x10u, // BIND_OPCODE_SET_DYLIB_ORDINAL_IMM
- BindOpcodeSetDylibOrdinalULEB = 0x20u, // BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB
- BindOpcodeSetDylibSpecialImmediate = 0x30u, // BIND_OPCODE_SET_DYLIB_SPECIAL_IMM
- BindOpcodeSetSymbolTrailingFlagsImmediate = 0x40u, // BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM
- BindOpcodeSetTypeImmediate = 0x50u, // BIND_OPCODE_SET_TYPE_IMM
- BindOpcodeSetAppendSLEB = 0x60u, // BIND_OPCODE_SET_ADDEND_SLEB
- BindOpcodeSetSegmentAndOffsetULEB = 0x70u, // BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB
- BindOpcodeAddAddressULEB = 0x80u, // BIND_OPCODE_ADD_ADDR_ULEB
- BindOpcodeDoBind = 0x90u, // BIND_OPCODE_DO_BIND
- BindOpcodeDoBindAddAddressULEB = 0xA0u, // BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB
- BindOpcodeDoBindAddAddressImmediateScaled = 0xB0u, // BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED
- BindOpcodeDoBindULEBTimesSkippingULEB = 0xC0u, // BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB
-
- ExportSymbolFlagsKindMask = 0x03u, // EXPORT_SYMBOL_FLAGS_KIND_MASK
- ExportSymbolFlagsKindRegular = 0x00u, // EXPORT_SYMBOL_FLAGS_KIND_REGULAR
- ExportSymbolFlagsKindThreadLocal = 0x01u, // EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL
- ExportSymbolFlagsWeakDefinition = 0x04u, // EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION
- ExportSymbolFlagsIndirectDefinition = 0x08u, // EXPORT_SYMBOL_FLAGS_INDIRECT_DEFINITION
- ExportSymbolFlagsHasSpecializations = 0x10u, // EXPORT_SYMBOL_FLAGS_HAS_SPECIALIZATIONS
+ S_ATTR_SOME_INSTRUCTIONS = 0x00000400u,
+ S_ATTR_EXT_RELOC = 0x00000200u,
+ S_ATTR_LOC_RELOC = 0x00000100u,
+
+ // Constant masks for the value of an indirect symbol in an indirect
+ // symbol table
+ INDIRECT_SYMBOL_LOCAL = 0x80000000u,
+ INDIRECT_SYMBOL_ABS = 0x40000000u
+ };
+
+ enum DataRegionType {
+ // Constants for the "kind" field in a data_in_code_entry structure
+ DICE_KIND_DATA = 1u,
+ DICE_KIND_JUMP_TABLE8 = 2u,
+ DICE_KIND_JUMP_TABLE16 = 3u,
+ DICE_KIND_JUMP_TABLE32 = 4u,
+ DICE_KIND_ABS_JUMP_TABLE32 = 5u
+ };
+
+ enum RebaseType {
+ REBASE_TYPE_POINTER = 1u,
+ REBASE_TYPE_TEXT_ABSOLUTE32 = 2u,
+ REBASE_TYPE_TEXT_PCREL32 = 3u
+ };
+
+ enum {
+ REBASE_OPCODE_MASK = 0xF0u,
+ REBASE_IMMEDIATE_MASK = 0x0Fu
+ };
+
+ enum RebaseOpcode {
+ REBASE_OPCODE_DONE = 0x00u,
+ REBASE_OPCODE_SET_TYPE_IMM = 0x10u,
+ REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB = 0x20u,
+ REBASE_OPCODE_ADD_ADDR_ULEB = 0x30u,
+ REBASE_OPCODE_ADD_ADDR_IMM_SCALED = 0x40u,
+ REBASE_OPCODE_DO_REBASE_IMM_TIMES = 0x50u,
+ REBASE_OPCODE_DO_REBASE_ULEB_TIMES = 0x60u,
+ REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB = 0x70u,
+ REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB = 0x80u
+ };
+
+ enum BindType {
+ BIND_TYPE_POINTER = 1u,
+ BIND_TYPE_TEXT_ABSOLUTE32 = 2u,
+ BIND_TYPE_TEXT_PCREL32 = 3u
+ };
+ enum BindSpecialDylib {
+ BIND_SPECIAL_DYLIB_SELF = 0,
+ BIND_SPECIAL_DYLIB_MAIN_EXECUTABLE = -1,
+ BIND_SPECIAL_DYLIB_FLAT_LOOKUP = -2
+ };
+
+ enum {
+ BIND_SYMBOL_FLAGS_WEAK_IMPORT = 0x1u,
+ BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION = 0x8u,
+ BIND_OPCODE_MASK = 0xF0u,
+ BIND_IMMEDIATE_MASK = 0x0Fu
+ };
+
+ enum BindOpcode {
+ BIND_OPCODE_DONE = 0x00u,
+ BIND_OPCODE_SET_DYLIB_ORDINAL_IMM = 0x10u,
+ BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB = 0x20u,
+ BIND_OPCODE_SET_DYLIB_SPECIAL_IMM = 0x30u,
+ BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM = 0x40u,
+ BIND_OPCODE_SET_TYPE_IMM = 0x50u,
+ BIND_OPCODE_SET_ADDEND_SLEB = 0x60u,
+ BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB = 0x70u,
+ BIND_OPCODE_ADD_ADDR_ULEB = 0x80u,
+ BIND_OPCODE_DO_BIND = 0x90u,
+ BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB = 0xA0u,
+ BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED = 0xB0u,
+ BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB = 0xC0u
+ };
+
+ enum {
+ EXPORT_SYMBOL_FLAGS_KIND_MASK = 0x03u,
+ EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION = 0x04u,
+ EXPORT_SYMBOL_FLAGS_REEXPORT = 0x08u,
+ EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER = 0x10u
+ };
+
+ enum ExportSymbolKind {
+ EXPORT_SYMBOL_FLAGS_KIND_REGULAR = 0x00u,
+ EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL = 0x01u
+ };
+
+
+ enum {
// Constant masks for the "n_type" field in llvm::MachO::nlist and
// llvm::MachO::nlist_64
- NlistMaskStab = 0xe0, // N_STAB
- NlistMaskPrivateExternal = 0x10, // N_PEXT
- NlistMaskType = 0x0e, // N_TYPE
- NlistMaskExternal = 0x01, // N_EXT
+ N_STAB = 0xe0,
+ N_PEXT = 0x10,
+ N_TYPE = 0x0e,
+ N_EXT = 0x01
+ };
+ enum NListType {
// Constants for the "n_type & N_TYPE" llvm::MachO::nlist and
// llvm::MachO::nlist_64
- NListTypeUndefined = 0x0u, // N_UNDF
- NListTypeAbsolute = 0x2u, // N_ABS
- NListTypeSection = 0xeu, // N_SECT
- NListTypePreboundUndefined = 0xcu, // N_PBUD
- NListTypeIndirect = 0xau, // N_INDR
+ N_UNDF = 0x0u,
+ N_ABS = 0x2u,
+ N_SECT = 0xeu,
+ N_PBUD = 0xcu,
+ N_INDR = 0xau
+ };
- // Constant masks for the "n_sect" field in llvm::MachO::nlist and
+ enum SectionOrdinal {
+ // Constants for the "n_sect" field in llvm::MachO::nlist and
// llvm::MachO::nlist_64
- NListSectionNoSection = 0u, // NO_SECT
- NListSectionMaxSection = 0xffu, // MAX_SECT
+ NO_SECT = 0u,
+ MAX_SECT = 0xffu
+ };
- NListDescWeakRef = 0x40u,
- NListDescWeakDef = 0x80u,
+ enum {
+ // Constant masks for the "n_desc" field in llvm::MachO::nlist and
+ // llvm::MachO::nlist_64
+ N_ARM_THUMB_DEF = 0x0008u,
+ N_NO_DEAD_STRIP = 0x0020u,
+ N_WEAK_REF = 0x0040u,
+ N_WEAK_DEF = 0x0080u,
+ N_SYMBOL_RESOLVER = 0x0100u
+ };
+ enum StabType {
// Constant values for the "n_type" field in llvm::MachO::nlist and
// llvm::MachO::nlist_64 when "(n_type & NlistMaskStab) != 0"
- StabGlobalSymbol = 0x20u, // N_GSYM
- StabFunctionName = 0x22u, // N_FNAME
- StabFunction = 0x24u, // N_FUN
- StabStaticSymbol = 0x26u, // N_STSYM
- StabLocalCommon = 0x28u, // N_LCSYM
- StabBeginSymbol = 0x2Eu, // N_BNSYM
- StabSourceFileOptions = 0x3Cu, // N_OPT
- StabRegisterSymbol = 0x40u, // N_RSYM
- StabSourceLine = 0x44u, // N_SLINE
- StabEndSymbol = 0x4Eu, // N_ENSYM
- StabStructureType = 0x60u, // N_SSYM
- StabSourceFileName = 0x64u, // N_SO
- StabObjectFileName = 0x66u, // N_OSO
- StabLocalSymbol = 0x80u, // N_LSYM
- StabBeginIncludeFileName = 0x82u, // N_BINCL
- StabIncludeFileName = 0x84u, // N_SOL
- StabCompilerParameters = 0x86u, // N_PARAMS
- StabCompilerVersion = 0x88u, // N_VERSION
- StabCompilerOptLevel = 0x8Au, // N_OLEVEL
- StabParameter = 0xA0u, // N_PSYM
- StabEndIncludeFile = 0xA2u, // N_EINCL
- StabAlternateEntry = 0xA4u, // N_ENTRY
- StabLeftBracket = 0xC0u, // N_LBRAC
- StabDeletedIncludeFile = 0xC2u, // N_EXCL
- StabRightBracket = 0xE0u, // N_RBRAC
- StabBeginCommon = 0xE2u, // N_BCOMM
- StabEndCommon = 0xE4u, // N_ECOMM
- StabEndCommonLocal = 0xE8u, // N_ECOML
- StabLength = 0xFEu // N_LENG
-
+ N_GSYM = 0x20u,
+ N_FNAME = 0x22u,
+ N_FUN = 0x24u,
+ N_STSYM = 0x26u,
+ N_LCSYM = 0x28u,
+ N_BNSYM = 0x2Eu,
+ N_OPT = 0x3Cu,
+ N_RSYM = 0x40u,
+ N_SLINE = 0x44u,
+ N_ENSYM = 0x4Eu,
+ N_SSYM = 0x60u,
+ N_SO = 0x64u,
+ N_OSO = 0x66u,
+ N_LSYM = 0x80u,
+ N_BINCL = 0x82u,
+ N_SOL = 0x84u,
+ N_PARAMS = 0x86u,
+ N_VERSION = 0x88u,
+ N_OLEVEL = 0x8Au,
+ N_PSYM = 0xA0u,
+ N_EINCL = 0xA2u,
+ N_ENTRY = 0xA4u,
+ N_LBRAC = 0xC0u,
+ N_EXCL = 0xC2u,
+ N_RBRAC = 0xE0u,
+ N_BCOMM = 0xE2u,
+ N_ECOMM = 0xE4u,
+ N_ECOML = 0xE8u,
+ N_LENG = 0xFEu
+ };
+
+ enum LLVM_ENUM_INT_TYPE(uint32_t) {
+ // Constant values for the r_symbolnum field in an
+ // llvm::MachO::relocation_info structure when r_extern is 0.
+ R_ABS = 0,
+
+ // Constant bits for the r_address field in an
+ // llvm::MachO::relocation_info structure.
+ R_SCATTERED = 0x80000000
+ };
+
+ enum RelocationInfoType {
+ // Constant values for the r_type field in an
+ // llvm::MachO::relocation_info or llvm::MachO::scattered_relocation_info
+ // structure.
+ GENERIC_RELOC_VANILLA = 0,
+ GENERIC_RELOC_PAIR = 1,
+ GENERIC_RELOC_SECTDIFF = 2,
+ GENERIC_RELOC_PB_LA_PTR = 3,
+ GENERIC_RELOC_LOCAL_SECTDIFF = 4,
+ GENERIC_RELOC_TLV = 5,
+
+ // Constant values for the r_type field in a PowerPC architecture
+ // llvm::MachO::relocation_info or llvm::MachO::scattered_relocation_info
+ // structure.
+ PPC_RELOC_VANILLA = GENERIC_RELOC_VANILLA,
+ PPC_RELOC_PAIR = GENERIC_RELOC_PAIR,
+ PPC_RELOC_BR14 = 2,
+ PPC_RELOC_BR24 = 3,
+ PPC_RELOC_HI16 = 4,
+ PPC_RELOC_LO16 = 5,
+ PPC_RELOC_HA16 = 6,
+ PPC_RELOC_LO14 = 7,
+ PPC_RELOC_SECTDIFF = 8,
+ PPC_RELOC_PB_LA_PTR = 9,
+ PPC_RELOC_HI16_SECTDIFF = 10,
+ PPC_RELOC_LO16_SECTDIFF = 11,
+ PPC_RELOC_HA16_SECTDIFF = 12,
+ PPC_RELOC_JBSR = 13,
+ PPC_RELOC_LO14_SECTDIFF = 14,
+ PPC_RELOC_LOCAL_SECTDIFF = 15,
+
+ // Constant values for the r_type field in an ARM architecture
+ // llvm::MachO::relocation_info or llvm::MachO::scattered_relocation_info
+ // structure.
+ ARM_RELOC_VANILLA = GENERIC_RELOC_VANILLA,
+ ARM_RELOC_PAIR = GENERIC_RELOC_PAIR,
+ ARM_RELOC_SECTDIFF = GENERIC_RELOC_SECTDIFF,
+ ARM_RELOC_LOCAL_SECTDIFF = 3,
+ ARM_RELOC_PB_LA_PTR = 4,
+ ARM_RELOC_BR24 = 5,
+ ARM_THUMB_RELOC_BR22 = 6,
+ ARM_THUMB_32BIT_BRANCH = 7, // obsolete
+ ARM_RELOC_HALF = 8,
+ ARM_RELOC_HALF_SECTDIFF = 9,
+
+ // Constant values for the r_type field in an x86_64 architecture
+ // llvm::MachO::relocation_info or llvm::MachO::scattered_relocation_info
+ // structure
+ X86_64_RELOC_UNSIGNED = 0,
+ X86_64_RELOC_SIGNED = 1,
+ X86_64_RELOC_BRANCH = 2,
+ X86_64_RELOC_GOT_LOAD = 3,
+ X86_64_RELOC_GOT = 4,
+ X86_64_RELOC_SUBTRACTOR = 5,
+ X86_64_RELOC_SIGNED_1 = 6,
+ X86_64_RELOC_SIGNED_2 = 7,
+ X86_64_RELOC_SIGNED_4 = 8,
+ X86_64_RELOC_TLV = 9
+ };
+
+ // Values for segment_command.initprot.
+ // From <mach/vm_prot.h>
+ enum {
+ VM_PROT_READ = 0x1,
+ VM_PROT_WRITE = 0x2,
+ VM_PROT_EXECUTE = 0x4
};
+
// Structs from <mach-o/loader.h>
struct mach_header {
@@ -572,6 +718,18 @@ namespace llvm {
uint32_t datasize;
};
+ struct data_in_code_entry {
+ uint32_t offset;
+ uint16_t length;
+ uint16_t kind;
+ };
+
+ struct source_version_command {
+ uint32_t cmd;
+ uint32_t cmdsize;
+ uint64_t version;
+ };
+
struct encryption_info_command {
uint32_t cmd;
uint32_t cmdsize;
@@ -602,6 +760,12 @@ namespace llvm {
uint32_t export_size;
};
+ struct linker_options_command {
+ uint32_t cmd;
+ uint32_t cmdsize;
+ uint32_t count;
+ };
+
struct symseg_command {
uint32_t cmd;
uint32_t cmdsize;
@@ -621,6 +785,31 @@ namespace llvm {
uint32_t header_addr;
};
+ struct tlv_descriptor_32 {
+ uint32_t thunk;
+ uint32_t key;
+ uint32_t offset;
+ };
+
+ struct tlv_descriptor_64 {
+ uint64_t thunk;
+ uint64_t key;
+ uint64_t offset;
+ };
+
+ struct tlv_descriptor {
+ uintptr_t thunk;
+ uintptr_t key;
+ uintptr_t offset;
+ };
+
+ struct entry_point_command {
+ uint32_t cmd;
+ uint32_t cmdsize;
+ uint64_t entryoff;
+ uint64_t stacksize;
+ };
+
// Structs from <mach-o/fat.h>
struct fat_header {
@@ -636,7 +825,39 @@ namespace llvm {
uint32_t align;
};
- // Structs from <mach-o/fat.h>
+ // Structs from <mach-o/reloc.h>
+ struct relocation_info {
+ int32_t r_address;
+ uint32_t r_symbolnum:24,
+ r_pcrel:1,
+ r_length:2,
+ r_extern:1,
+ r_type:4;
+ };
+
+ struct scattered_relocation_info {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && (BYTE_ORDER == BIG_ENDIAN)
+ uint32_t r_scattered:1,
+ r_pcrel:1,
+ r_length:2,
+ r_type:4,
+ r_address:24;
+#else
+ uint32_t r_address:24,
+ r_type:4,
+ r_length:2,
+ r_pcrel:1,
+ r_scattered:1;
+#endif
+ int32_t r_value;
+ };
+
+ // Structs NOT from <mach-o/reloc.h>, but that make LLVM's life easier
+ struct any_relocation_info {
+ uint32_t r_word0, r_word1;
+ };
+
+ // Structs from <mach-o/nlist.h>
struct nlist {
uint32_t n_strx;
uint8_t n_type;
@@ -655,58 +876,132 @@ namespace llvm {
// Get/Set functions from <mach-o/nlist.h>
- static inline uint16_t GET_LIBRARY_ORDINAL(uint16_t n_desc)
- {
+ static inline uint16_t GET_LIBRARY_ORDINAL(uint16_t n_desc) {
return (((n_desc) >> 8u) & 0xffu);
}
- static inline void SET_LIBRARY_ORDINAL(uint16_t &n_desc, uint8_t ordinal)
- {
+ static inline void SET_LIBRARY_ORDINAL(uint16_t &n_desc, uint8_t ordinal) {
n_desc = (((n_desc) & 0x00ff) | (((ordinal) & 0xff) << 8));
}
- static inline uint8_t GET_COMM_ALIGN (uint16_t n_desc)
- {
+ static inline uint8_t GET_COMM_ALIGN (uint16_t n_desc) {
return (n_desc >> 8u) & 0x0fu;
}
- static inline void SET_COMM_ALIGN (uint16_t &n_desc, uint8_t align)
- {
+ static inline void SET_COMM_ALIGN (uint16_t &n_desc, uint8_t align) {
n_desc = ((n_desc & 0xf0ffu) | ((align & 0x0fu) << 8u));
}
// Enums from <mach/machine.h>
- enum {
+ enum LLVM_ENUM_INT_TYPE(uint32_t) {
// Capability bits used in the definition of cpu_type.
- CPUArchMask = 0xff000000, // Mask for architecture bits
- CPUArchABI64 = 0x01000000, // 64 bit ABI
-
- // Constants for the cputype field.
- CPUTypeI386 = 7,
- CPUTypeX86_64 = CPUTypeI386 | CPUArchABI64,
- CPUTypeARM = 12,
- CPUTypeSPARC = 14,
- CPUTypePowerPC = 18,
- CPUTypePowerPC64 = CPUTypePowerPC | CPUArchABI64,
-
-
- // Constants for the cpusubtype field.
-
- // X86
- CPUSubType_I386_ALL = 3,
- CPUSubType_X86_64_ALL = 3,
-
- // ARM
- CPUSubType_ARM_ALL = 0,
- CPUSubType_ARM_V4T = 5,
- CPUSubType_ARM_V5 = 7,
- CPUSubType_ARM_V6 = 6,
- CPUSubType_ARM_V7 = 9,
-
- // PowerPC
- CPUSubType_POWERPC_ALL = 0,
-
- CPUSubType_SPARC_ALL = 0
+ CPU_ARCH_MASK = 0xff000000, // Mask for architecture bits
+ CPU_ARCH_ABI64 = 0x01000000 // 64 bit ABI
+ };
+
+ // Constants for the cputype field.
+ enum CPUType {
+ CPU_TYPE_ANY = -1,
+ CPU_TYPE_X86 = 7,
+ CPU_TYPE_I386 = CPU_TYPE_X86,
+ CPU_TYPE_X86_64 = CPU_TYPE_X86 | CPU_ARCH_ABI64,
+ /* CPU_TYPE_MIPS = 8, */
+ CPU_TYPE_MC98000 = 10, // Old Motorola PowerPC
+ CPU_TYPE_ARM = 12,
+ CPU_TYPE_SPARC = 14,
+ CPU_TYPE_POWERPC = 18,
+ CPU_TYPE_POWERPC64 = CPU_TYPE_POWERPC | CPU_ARCH_ABI64
+ };
+
+ enum LLVM_ENUM_INT_TYPE(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
+
+ // Special CPU subtype constants.
+ CPU_SUBTYPE_MULTIPLE = ~0u
+ };
+
+ // Constants for the cpusubtype field.
+ enum CPUSubTypeX86 {
+ CPU_SUBTYPE_I386_ALL = 3,
+ CPU_SUBTYPE_386 = 3,
+ CPU_SUBTYPE_486 = 4,
+ CPU_SUBTYPE_486SX = 0x84,
+ CPU_SUBTYPE_586 = 5,
+ CPU_SUBTYPE_PENT = CPU_SUBTYPE_586,
+ CPU_SUBTYPE_PENTPRO = 0x16,
+ CPU_SUBTYPE_PENTII_M3 = 0x36,
+ CPU_SUBTYPE_PENTII_M5 = 0x56,
+ CPU_SUBTYPE_CELERON = 0x67,
+ CPU_SUBTYPE_CELERON_MOBILE = 0x77,
+ CPU_SUBTYPE_PENTIUM_3 = 0x08,
+ CPU_SUBTYPE_PENTIUM_3_M = 0x18,
+ CPU_SUBTYPE_PENTIUM_3_XEON = 0x28,
+ CPU_SUBTYPE_PENTIUM_M = 0x09,
+ CPU_SUBTYPE_PENTIUM_4 = 0x0a,
+ CPU_SUBTYPE_PENTIUM_4_M = 0x1a,
+ CPU_SUBTYPE_ITANIUM = 0x0b,
+ CPU_SUBTYPE_ITANIUM_2 = 0x1b,
+ CPU_SUBTYPE_XEON = 0x0c,
+ CPU_SUBTYPE_XEON_MP = 0x1c,
+
+ CPU_SUBTYPE_X86_ALL = 3,
+ CPU_SUBTYPE_X86_64_ALL = 3,
+ CPU_SUBTYPE_X86_ARCH1 = 4,
+ CPU_SUBTYPE_X86_64_H = 8
+ };
+ static inline int CPU_SUBTYPE_INTEL(int Family, int Model) {
+ return Family | (Model << 4);
+ }
+ static inline int CPU_SUBTYPE_INTEL_FAMILY(CPUSubTypeX86 ST) {
+ return ((int)ST) & 0x0f;
+ }
+ static inline int CPU_SUBTYPE_INTEL_MODEL(CPUSubTypeX86 ST) {
+ return ((int)ST) >> 4;
+ }
+ enum {
+ CPU_SUBTYPE_INTEL_FAMILY_MAX = 15,
+ CPU_SUBTYPE_INTEL_MODEL_ALL = 0
+ };
+
+ enum CPUSubTypeARM {
+ CPU_SUBTYPE_ARM_ALL = 0,
+ CPU_SUBTYPE_ARM_V4T = 5,
+ CPU_SUBTYPE_ARM_V6 = 6,
+ CPU_SUBTYPE_ARM_V5 = 7,
+ CPU_SUBTYPE_ARM_V5TEJ = 7,
+ CPU_SUBTYPE_ARM_XSCALE = 8,
+ CPU_SUBTYPE_ARM_V7 = 9,
+ CPU_SUBTYPE_ARM_V7F = 10,
+ CPU_SUBTYPE_ARM_V7S = 11,
+ CPU_SUBTYPE_ARM_V7K = 12,
+ CPU_SUBTYPE_ARM_V6M = 14,
+ CPU_SUBTYPE_ARM_V7M = 15,
+ CPU_SUBTYPE_ARM_V7EM = 16
+ };
+
+ enum CPUSubTypeSPARC {
+ CPU_SUBTYPE_SPARC_ALL = 0
+ };
+
+ enum CPUSubTypePowerPC {
+ CPU_SUBTYPE_POWERPC_ALL = 0,
+ CPU_SUBTYPE_POWERPC_601 = 1,
+ CPU_SUBTYPE_POWERPC_602 = 2,
+ CPU_SUBTYPE_POWERPC_603 = 3,
+ CPU_SUBTYPE_POWERPC_603e = 4,
+ CPU_SUBTYPE_POWERPC_603ev = 5,
+ CPU_SUBTYPE_POWERPC_604 = 6,
+ CPU_SUBTYPE_POWERPC_604e = 7,
+ CPU_SUBTYPE_POWERPC_620 = 8,
+ CPU_SUBTYPE_POWERPC_750 = 9,
+ CPU_SUBTYPE_POWERPC_7400 = 10,
+ CPU_SUBTYPE_POWERPC_7450 = 11,
+ CPU_SUBTYPE_POWERPC_970 = 100,
+
+ CPU_SUBTYPE_MC980000_ALL = CPU_SUBTYPE_POWERPC_ALL,
+ CPU_SUBTYPE_MC98601 = CPU_SUBTYPE_POWERPC_601
};
} // end namespace MachO
} // end namespace llvm
diff --git a/include/llvm/Support/ManagedStatic.h b/include/llvm/Support/ManagedStatic.h
index 4171d1b..5587618 100644
--- a/include/llvm/Support/ManagedStatic.h
+++ b/include/llvm/Support/ManagedStatic.h
@@ -99,7 +99,6 @@ public:
/// llvm_shutdown - Deallocate and destroy all ManagedStatic variables.
void llvm_shutdown();
-
/// llvm_shutdown_obj - This is a simple helper class that calls
/// llvm_shutdown() when it is destroyed.
struct llvm_shutdown_obj {
diff --git a/include/llvm/Support/MathExtras.h b/include/llvm/Support/MathExtras.h
index 00c6ad7..ff41608 100644
--- a/include/llvm/Support/MathExtras.h
+++ b/include/llvm/Support/MathExtras.h
@@ -21,7 +21,8 @@
#include <cstring>
#ifdef _MSC_VER
-# include <intrin.h>
+#include <intrin.h>
+#include <limits>
#endif
namespace llvm {
@@ -603,6 +604,13 @@ inline int64_t SignExtend64(uint64_t X, unsigned B) {
return int64_t(X << (64 - B)) >> (64 - B);
}
+#if defined(_MSC_VER)
+ // Visual Studio defines the HUGE_VAL class of macros using purposeful
+ // constant arithmetic overflow, which it then warns on when encountered.
+ const float huge_valf = std::numeric_limits<float>::infinity();
+#else
+ const float huge_valf = HUGE_VALF;
+#endif
} // End llvm namespace
#endif
diff --git a/include/llvm/Support/MemoryBuffer.h b/include/llvm/Support/MemoryBuffer.h
index 4f28da4..ff22fb6 100644
--- a/include/llvm/Support/MemoryBuffer.h
+++ b/include/llvm/Support/MemoryBuffer.h
@@ -14,7 +14,7 @@
#ifndef LLVM_SUPPORT_MEMORYBUFFER_H
#define LLVM_SUPPORT_MEMORYBUFFER_H
-#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Twine.h"
#include "llvm/Support/CBindingWrapping.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataTypes.h"
@@ -66,11 +66,7 @@ public:
/// MemoryBuffer if successful, otherwise returning null. If FileSize is
/// specified, this means that the client knows that the file exists and that
/// it has the specified size.
- static error_code getFile(StringRef Filename, OwningPtr<MemoryBuffer> &result,
- int64_t FileSize = -1,
- bool RequiresNullTerminator = true);
- static error_code getFile(const char *Filename,
- OwningPtr<MemoryBuffer> &result,
+ static error_code getFile(Twine Filename, OwningPtr<MemoryBuffer> &result,
int64_t FileSize = -1,
bool RequiresNullTerminator = true);
diff --git a/include/llvm/Support/PassNameParser.h b/include/llvm/Support/PassNameParser.h
index a73dc8f..c0914b1 100644
--- a/include/llvm/Support/PassNameParser.h
+++ b/include/llvm/Support/PassNameParser.h
@@ -86,10 +86,9 @@ public:
private:
// ValLessThan - Provide a sorting comparator for Values elements...
- static int ValLessThan(const void *VT1, const void *VT2) {
- typedef PassNameParser::OptionInfo ValType;
- return std::strcmp(static_cast<const ValType *>(VT1)->Name,
- static_cast<const ValType *>(VT2)->Name);
+ static int ValLessThan(const PassNameParser::OptionInfo *VT1,
+ const PassNameParser::OptionInfo *VT2) {
+ return std::strcmp(VT1->Name, VT2->Name);
}
};
diff --git a/include/llvm/Support/Path.h b/include/llvm/Support/Path.h
index f9a65e5..b2afe1b 100644
--- a/include/llvm/Support/Path.h
+++ b/include/llvm/Support/Path.h
@@ -173,6 +173,13 @@ void append(SmallVectorImpl<char> &path,
/// @param result Holds the result of the transformation.
void native(const Twine &path, SmallVectorImpl<char> &result);
+/// Convert path to the native form in place. This is used to give paths to
+/// users and operating system calls in the platform's normal way. For example,
+/// on Windows all '/' are converted to '\'.
+///
+/// @param path A path that is transformed to native format.
+void native(SmallVectorImpl<char> &path);
+
/// @}
/// @name Lexical Observers
/// @{
diff --git a/include/llvm/Support/PatternMatch.h b/include/llvm/Support/PatternMatch.h
index b1732b2..240bb81 100644
--- a/include/llvm/Support/PatternMatch.h
+++ b/include/llvm/Support/PatternMatch.h
@@ -1041,7 +1041,7 @@ inline Argument_match<Opnd_t> m_Argument(const Opnd_t &Op) {
/// Intrinsic matchers.
struct IntrinsicID_match {
unsigned ID;
- IntrinsicID_match(unsigned IntrID) : ID(IntrID) { }
+ IntrinsicID_match(Intrinsic::ID IntrID) : ID(IntrID) { }
template<typename OpTy>
bool match(OpTy *V) {
@@ -1080,29 +1080,29 @@ struct m_Intrinsic_Ty<T0, T1, T2, T3> {
/// Match intrinsic calls like this:
/// m_Intrinsic<Intrinsic::fabs>(m_Value(X))
-template <unsigned IntrID>
+template <Intrinsic::ID IntrID>
inline IntrinsicID_match
m_Intrinsic() { return IntrinsicID_match(IntrID); }
-template<unsigned IntrID, typename T0>
+template<Intrinsic::ID IntrID, typename T0>
inline typename m_Intrinsic_Ty<T0>::Ty
m_Intrinsic(const T0 &Op0) {
return m_CombineAnd(m_Intrinsic<IntrID>(), m_Argument<0>(Op0));
}
-template<unsigned IntrID, typename T0, typename T1>
+template<Intrinsic::ID IntrID, typename T0, typename T1>
inline typename m_Intrinsic_Ty<T0, T1>::Ty
m_Intrinsic(const T0 &Op0, const T1 &Op1) {
return m_CombineAnd(m_Intrinsic<IntrID>(Op0), m_Argument<1>(Op1));
}
-template<unsigned IntrID, typename T0, typename T1, typename T2>
+template<Intrinsic::ID IntrID, typename T0, typename T1, typename T2>
inline typename m_Intrinsic_Ty<T0, T1, T2>::Ty
m_Intrinsic(const T0 &Op0, const T1 &Op1, const T2 &Op2) {
return m_CombineAnd(m_Intrinsic<IntrID>(Op0, Op1), m_Argument<2>(Op2));
}
-template<unsigned IntrID, typename T0, typename T1, typename T2, typename T3>
+template<Intrinsic::ID IntrID, typename T0, typename T1, typename T2, typename T3>
inline typename m_Intrinsic_Ty<T0, T1, T2, T3>::Ty
m_Intrinsic(const T0 &Op0, const T1 &Op1, const T2 &Op2, const T3 &Op3) {
return m_CombineAnd(m_Intrinsic<IntrID>(Op0, Op1, Op2), m_Argument<3>(Op3));
diff --git a/include/llvm/Support/PrettyStackTrace.h b/include/llvm/Support/PrettyStackTrace.h
index 2122e06..4f68fca 100644
--- a/include/llvm/Support/PrettyStackTrace.h
+++ b/include/llvm/Support/PrettyStackTrace.h
@@ -21,11 +21,7 @@
namespace llvm {
class raw_ostream;
- /// DisablePrettyStackTrace - Set this to true to disable this module. This
- /// might be necessary if the host application installs its own signal
- /// handlers which conflict with the ones installed by this module.
- /// Defaults to false.
- extern bool DisablePrettyStackTrace;
+ void EnablePrettyStackTrace();
/// PrettyStackTraceEntry - This class is used to represent a frame of the
/// "pretty" stack trace that is dumped when a program crashes. You can define
@@ -64,7 +60,9 @@ namespace llvm {
const char *const *ArgV;
public:
PrettyStackTraceProgram(int argc, const char * const*argv)
- : ArgC(argc), ArgV(argv) {}
+ : ArgC(argc), ArgV(argv) {
+ EnablePrettyStackTrace();
+ }
virtual void print(raw_ostream &OS) const LLVM_OVERRIDE;
};
diff --git a/include/llvm/Support/Process.h b/include/llvm/Support/Process.h
index 0baf7b9..2172036 100644
--- a/include/llvm/Support/Process.h
+++ b/include/llvm/Support/Process.h
@@ -25,11 +25,17 @@
#ifndef LLVM_SUPPORT_PROCESS_H
#define LLVM_SUPPORT_PROCESS_H
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/Config/llvm-config.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/system_error.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/TimeValue.h"
namespace llvm {
+class StringRef;
+
namespace sys {
class self_process;
@@ -155,22 +161,24 @@ public:
static void GetTimeUsage(TimeValue &elapsed, TimeValue &user_time,
TimeValue &sys_time);
- /// This static function will return the process' current user id number.
- /// Not all operating systems support this feature. Where it is not
- /// supported, the function should return 65536 as the value.
- static int GetCurrentUserId();
-
- /// This static function will return the process' current group id number.
- /// Not all operating systems support this feature. Where it is not
- /// supported, the function should return 65536 as the value.
- static int GetCurrentGroupId();
-
/// This function makes the necessary calls to the operating system to
/// prevent core files or any other kind of large memory dumps that can
/// occur when a program fails.
/// @brief Prevent core file generation.
static void PreventCoreFiles();
+ // This function returns the environment variable \arg name's value as a UTF-8
+ // string. \arg Name is assumed to be in UTF-8 encoding too.
+ static Optional<std::string> GetEnv(StringRef name);
+
+ /// 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
+ GetArgumentVector(SmallVectorImpl<const char *> &Args,
+ ArrayRef<const char *> ArgsFromMain,
+ SpecificBumpPtrAllocator<char> &ArgAllocator);
+
/// This function determines if the standard input is connected directly
/// to a user's input (keyboard probably), rather than coming from a file
/// or pipe.
@@ -219,6 +227,12 @@ public:
/// terminal, this function returns false.
static bool StandardErrHasColors();
+ /// Enables or disables whether ANSI escape sequences are used to output
+ /// colors. This only has an effect on Windows.
+ /// Note: Setting this option is not thread-safe and should only be done
+ /// during initialization.
+ static void UseANSIEscapeCodes(bool enable);
+
/// Whether changing colors requires the output to be flushed.
/// This is needed on systems that don't support escape sequences for
/// changing colors.
diff --git a/include/llvm/Support/Program.h b/include/llvm/Support/Program.h
index 5134351..00571a4 100644
--- a/include/llvm/Support/Program.h
+++ b/include/llvm/Support/Program.h
@@ -30,6 +30,28 @@ namespace sys {
const char EnvPathSeparator = ';';
#endif
+/// @brief This struct encapsulates information about a process.
+struct ProcessInfo {
+#if defined(LLVM_ON_UNIX)
+ typedef pid_t ProcessId;
+#elif defined(LLVM_ON_WIN32)
+ typedef unsigned long ProcessId; // Must match the type of DWORD on Windows.
+ typedef void * HANDLE; // Must match the type of HANDLE on Windows.
+ /// The handle to the process (available on Windows only).
+ HANDLE ProcessHandle;
+#else
+#error "ProcessInfo is not defined for this platform!"
+#endif
+
+ /// The process identifier.
+ ProcessId Pid;
+
+ /// The return code, set after execution.
+ int ReturnCode;
+
+ ProcessInfo();
+};
+
/// This static constructor (factory) will attempt to locate a program in
/// the operating system's file system using some pre-determined set of
/// locations to search (e.g. the PATH on Unix). Paths with slashes are
@@ -87,15 +109,41 @@ namespace sys {
///< program.
bool *ExecutionFailed = 0);
- /// Similar to ExecuteAndWait, but return immediately.
- void ExecuteNoWait(StringRef Program, const char **args, const char **env = 0,
- const StringRef **redirects = 0, unsigned memoryLimit = 0,
- std::string *ErrMsg = 0);
+ /// Similar to ExecuteAndWait, but returns immediately.
+ /// @returns The \see ProcessInfo of the newly launced process.
+ /// \note On Microsoft Windows systems, users will need to either call \see
+ /// Wait until the process finished execution or win32 CloseHandle() API on
+ /// ProcessInfo.ProcessHandle to avoid memory leaks.
+ ProcessInfo
+ ExecuteNoWait(StringRef Program, const char **args, const char **env = 0,
+ const StringRef **redirects = 0, unsigned memoryLimit = 0,
+ std::string *ErrMsg = 0, bool *ExecutionFailed = 0);
- // Return true if the given arguments fit within system-specific
- // argument length limits.
+ /// Return true if the given arguments fit within system-specific
+ /// argument length limits.
bool argumentsFitWithinSystemLimits(ArrayRef<const char*> Args);
-}
+
+ /// This function waits for the process specified by \p PI to finish.
+ /// \returns A \see ProcessInfo struct with Pid set to:
+ /// \li The process id of the child process if the child process has changed
+ /// state.
+ /// \li 0 if the child process has not changed state.
+ /// \note Users of this function should always check the ReturnCode member of
+ /// the \see ProcessInfo returned from this function.
+ ProcessInfo Wait(
+ const ProcessInfo &PI, ///< The child process that should be waited on.
+ unsigned SecondsToWait, ///< If non-zero, this specifies the amount of
+ ///< time to wait for the child process to exit. If the time expires, the
+ ///< child is killed and this function returns. If zero, this function
+ ///< will perform a non-blocking wait on the child process.
+ bool WaitUntilTerminates, ///< If true, ignores \p SecondsToWait and waits
+ ///< until child has terminated.
+ std::string *ErrMsg = 0 ///< If non-zero, provides a pointer to a string
+ ///< instance in which error messages will be returned. If the string
+ ///< is non-empty upon return an error occurred while invoking the
+ ///< program.
+ );
+ }
}
#endif
diff --git a/include/llvm/Support/RecyclingAllocator.h b/include/llvm/Support/RecyclingAllocator.h
index f67503f..001d1cf 100644
--- a/include/llvm/Support/RecyclingAllocator.h
+++ b/include/llvm/Support/RecyclingAllocator.h
@@ -60,9 +60,10 @@ public:
}
template<class AllocatorType, class T, size_t Size, size_t Align>
-inline void *operator new(size_t,
+inline void *operator new(size_t size,
llvm::RecyclingAllocator<AllocatorType,
T, Size, Align> &Allocator) {
+ assert(size <= Size && "allocation size exceeded");
return Allocator.Allocate();
}
diff --git a/include/llvm/Support/SourceMgr.h b/include/llvm/Support/SourceMgr.h
index 5b33d42..dd48974 100644
--- a/include/llvm/Support/SourceMgr.h
+++ b/include/llvm/Support/SourceMgr.h
@@ -144,11 +144,17 @@ public:
///
/// @param ShowColors - Display colored messages if output is a terminal and
/// the default error handler is used.
- void PrintMessage(SMLoc Loc, DiagKind Kind, const Twine &Msg,
+ void PrintMessage(raw_ostream &OS, SMLoc Loc, DiagKind Kind,
+ const Twine &Msg,
ArrayRef<SMRange> Ranges = None,
ArrayRef<SMFixIt> FixIts = None,
bool ShowColors = true) const;
+ /// Emits a diagnostic to llvm::errs().
+ void PrintMessage(SMLoc Loc, DiagKind Kind, const Twine &Msg,
+ ArrayRef<SMRange> Ranges = None,
+ ArrayRef<SMFixIt> FixIts = None,
+ bool ShowColors = true) const;
/// GetMessage - Return an SMDiagnostic at the specified location with the
/// specified string.
diff --git a/include/llvm/Support/TargetRegistry.h b/include/llvm/Support/TargetRegistry.h
index 109b3a2..9ecee3b 100644
--- a/include/llvm/Support/TargetRegistry.h
+++ b/include/llvm/Support/TargetRegistry.h
@@ -46,18 +46,18 @@ namespace llvm {
class MCRelocationInfo;
class MCTargetAsmParser;
class TargetMachine;
+ class MCTargetStreamer;
class TargetOptions;
class raw_ostream;
class formatted_raw_ostream;
- MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
- bool isVerboseAsm,
+ MCStreamer *createAsmStreamer(MCContext &Ctx,
+ MCTargetStreamer *TargetStreamer,
+ formatted_raw_ostream &OS, bool isVerboseAsm,
bool useLoc, bool useCFI,
bool useDwarfDirectory,
- MCInstPrinter *InstPrint,
- MCCodeEmitter *CE,
- MCAsmBackend *TAB,
- bool ShowInst);
+ MCInstPrinter *InstPrint, MCCodeEmitter *CE,
+ MCAsmBackend *TAB, bool ShowInst);
MCRelocationInfo *createMCRelocationInfo(StringRef TT, MCContext &Ctx);
@@ -104,10 +104,12 @@ namespace llvm {
typedef AsmPrinter *(*AsmPrinterCtorTy)(TargetMachine &TM,
MCStreamer &Streamer);
typedef MCAsmBackend *(*MCAsmBackendCtorTy)(const Target &T,
+ const MCRegisterInfo &MRI,
StringRef TT,
StringRef CPU);
typedef MCTargetAsmParser *(*MCAsmParserCtorTy)(MCSubtargetInfo &STI,
- MCAsmParser &P);
+ MCAsmParser &P,
+ const MCInstrInfo &MII);
typedef MCDisassembler *(*MCDisassemblerCtorTy)(const Target &T,
const MCSubtargetInfo &STI);
typedef MCInstPrinter *(*MCInstPrinterCtorTy)(const Target &T,
@@ -234,9 +236,9 @@ namespace llvm {
MCSymbolizerCtorTy MCSymbolizerCtorFn;
public:
- Target() : AsmStreamerCtorFn(llvm::createAsmStreamer),
- MCRelocationInfoCtorFn(llvm::createMCRelocationInfo),
- MCSymbolizerCtorFn(llvm::createMCSymbolizer) {}
+ Target()
+ : AsmStreamerCtorFn(0), MCRelocationInfoCtorFn(0),
+ MCSymbolizerCtorFn(0) {}
/// @name Target Information
/// @{
@@ -263,27 +265,6 @@ namespace llvm {
/// hasMCAsmBackend - Check if this target supports .o generation.
bool hasMCAsmBackend() const { return MCAsmBackendCtorFn != 0; }
- /// hasAsmParser - Check if this target supports .s parsing.
- bool hasMCAsmParser() const { return MCAsmParserCtorFn != 0; }
-
- /// hasAsmPrinter - Check if this target supports .s printing.
- bool hasAsmPrinter() const { return AsmPrinterCtorFn != 0; }
-
- /// hasMCDisassembler - Check if this target has a disassembler.
- bool hasMCDisassembler() const { return MCDisassemblerCtorFn != 0; }
-
- /// hasMCInstPrinter - Check if this target has an instruction printer.
- bool hasMCInstPrinter() const { return MCInstPrinterCtorFn != 0; }
-
- /// hasMCCodeEmitter - Check if this target supports instruction encoding.
- bool hasMCCodeEmitter() const { return MCCodeEmitterCtorFn != 0; }
-
- /// hasMCObjectStreamer - Check if this target supports streaming to files.
- bool hasMCObjectStreamer() const { return MCObjectStreamerCtorFn != 0; }
-
- /// hasAsmStreamer - Check if this target supports streaming to files.
- bool hasAsmStreamer() const { return AsmStreamerCtorFn != 0; }
-
/// @}
/// @name Feature Constructors
/// @{
@@ -373,10 +354,11 @@ namespace llvm {
/// createMCAsmBackend - Create a target specific assembly parser.
///
/// \param Triple The target triple string.
- MCAsmBackend *createMCAsmBackend(StringRef Triple, StringRef CPU) const {
+ MCAsmBackend *createMCAsmBackend(const MCRegisterInfo &MRI,
+ StringRef Triple, StringRef CPU) const {
if (!MCAsmBackendCtorFn)
return 0;
- return MCAsmBackendCtorFn(*this, Triple, CPU);
+ return MCAsmBackendCtorFn(*this, MRI, Triple, CPU);
}
/// createMCAsmParser - Create a target specific assembly parser.
@@ -384,10 +366,11 @@ namespace llvm {
/// \param Parser The target independent parser implementation to use for
/// parsing and lexing.
MCTargetAsmParser *createMCAsmParser(MCSubtargetInfo &STI,
- MCAsmParser &Parser) const {
+ MCAsmParser &Parser,
+ const MCInstrInfo &MII) const {
if (!MCAsmParserCtorFn)
return 0;
- return MCAsmParserCtorFn(STI, Parser);
+ return MCAsmParserCtorFn(STI, Parser, MII);
}
/// createAsmPrinter - Create a target specific assembly printer pass. This
@@ -457,9 +440,13 @@ namespace llvm {
MCCodeEmitter *CE,
MCAsmBackend *TAB,
bool ShowInst) const {
- // AsmStreamerCtorFn is default to llvm::createAsmStreamer
- return AsmStreamerCtorFn(Ctx, OS, isVerboseAsm, useLoc, useCFI,
- useDwarfDirectory, InstPrint, CE, TAB, ShowInst);
+ if (AsmStreamerCtorFn)
+ return AsmStreamerCtorFn(Ctx, OS, isVerboseAsm, useLoc, useCFI,
+ useDwarfDirectory, InstPrint, CE, TAB,
+ ShowInst);
+ return llvm::createAsmStreamer(Ctx, 0, OS, isVerboseAsm, useLoc, useCFI,
+ useDwarfDirectory, InstPrint, CE, TAB,
+ ShowInst);
}
/// createMCRelocationInfo - Create a target specific MCRelocationInfo.
@@ -468,7 +455,10 @@ namespace llvm {
/// \param Ctx The target context.
MCRelocationInfo *
createMCRelocationInfo(StringRef TT, MCContext &Ctx) const {
- return MCRelocationInfoCtorFn(TT, Ctx);
+ MCRelocationInfoCtorTy Fn = MCRelocationInfoCtorFn
+ ? MCRelocationInfoCtorFn
+ : llvm::createMCRelocationInfo;
+ return Fn(TT, Ctx);
}
/// createMCSymbolizer - Create a target specific MCSymbolizer.
@@ -485,8 +475,9 @@ namespace llvm {
LLVMSymbolLookupCallback SymbolLookUp,
void *DisInfo,
MCContext *Ctx, MCRelocationInfo *RelInfo) const {
- return MCSymbolizerCtorFn(TT, GetOpInfo, SymbolLookUp, DisInfo,
- Ctx, RelInfo);
+ MCSymbolizerCtorTy Fn =
+ MCSymbolizerCtorFn ? MCSymbolizerCtorFn : llvm::createMCSymbolizer;
+ return Fn(TT, GetOpInfo, SymbolLookUp, DisInfo, Ctx, RelInfo);
}
/// @}
@@ -607,9 +598,7 @@ namespace llvm {
/// @param T - The target being registered.
/// @param Fn - A function to construct a MCAsmInfo for the target.
static void RegisterMCAsmInfo(Target &T, Target::MCAsmInfoCtorFnTy Fn) {
- // Ignore duplicate registration.
- if (!T.MCAsmInfoCtorFn)
- T.MCAsmInfoCtorFn = Fn;
+ T.MCAsmInfoCtorFn = Fn;
}
/// RegisterMCCodeGenInfo - Register a MCCodeGenInfo implementation for the
@@ -623,9 +612,7 @@ namespace llvm {
/// @param Fn - A function to construct a MCCodeGenInfo for the target.
static void RegisterMCCodeGenInfo(Target &T,
Target::MCCodeGenInfoCtorFnTy Fn) {
- // Ignore duplicate registration.
- if (!T.MCCodeGenInfoCtorFn)
- T.MCCodeGenInfoCtorFn = Fn;
+ T.MCCodeGenInfoCtorFn = Fn;
}
/// RegisterMCInstrInfo - Register a MCInstrInfo implementation for the
@@ -638,18 +625,14 @@ namespace llvm {
/// @param T - The target being registered.
/// @param Fn - A function to construct a MCInstrInfo for the target.
static void RegisterMCInstrInfo(Target &T, Target::MCInstrInfoCtorFnTy Fn) {
- // Ignore duplicate registration.
- if (!T.MCInstrInfoCtorFn)
- T.MCInstrInfoCtorFn = Fn;
+ T.MCInstrInfoCtorFn = Fn;
}
/// RegisterMCInstrAnalysis - Register a MCInstrAnalysis implementation for
/// the given target.
static void RegisterMCInstrAnalysis(Target &T,
Target::MCInstrAnalysisCtorFnTy Fn) {
- // Ignore duplicate registration.
- if (!T.MCInstrAnalysisCtorFn)
- T.MCInstrAnalysisCtorFn = Fn;
+ T.MCInstrAnalysisCtorFn = Fn;
}
/// RegisterMCRegInfo - Register a MCRegisterInfo implementation for the
@@ -662,9 +645,7 @@ namespace llvm {
/// @param T - The target being registered.
/// @param Fn - A function to construct a MCRegisterInfo for the target.
static void RegisterMCRegInfo(Target &T, Target::MCRegInfoCtorFnTy Fn) {
- // Ignore duplicate registration.
- if (!T.MCRegInfoCtorFn)
- T.MCRegInfoCtorFn = Fn;
+ T.MCRegInfoCtorFn = Fn;
}
/// RegisterMCSubtargetInfo - Register a MCSubtargetInfo implementation for
@@ -678,9 +659,7 @@ namespace llvm {
/// @param Fn - A function to construct a MCSubtargetInfo for the target.
static void RegisterMCSubtargetInfo(Target &T,
Target::MCSubtargetInfoCtorFnTy Fn) {
- // Ignore duplicate registration.
- if (!T.MCSubtargetInfoCtorFn)
- T.MCSubtargetInfoCtorFn = Fn;
+ T.MCSubtargetInfoCtorFn = Fn;
}
/// RegisterTargetMachine - Register a TargetMachine implementation for the
@@ -694,9 +673,7 @@ namespace llvm {
/// @param Fn - A function to construct a TargetMachine for the target.
static void RegisterTargetMachine(Target &T,
Target::TargetMachineCtorTy Fn) {
- // Ignore duplicate registration.
- if (!T.TargetMachineCtorFn)
- T.TargetMachineCtorFn = Fn;
+ T.TargetMachineCtorFn = Fn;
}
/// RegisterMCAsmBackend - Register a MCAsmBackend implementation for the
@@ -709,8 +686,7 @@ namespace llvm {
/// @param T - The target being registered.
/// @param Fn - A function to construct an AsmBackend for the target.
static void RegisterMCAsmBackend(Target &T, Target::MCAsmBackendCtorTy Fn) {
- if (!T.MCAsmBackendCtorFn)
- T.MCAsmBackendCtorFn = Fn;
+ T.MCAsmBackendCtorFn = Fn;
}
/// RegisterMCAsmParser - Register a MCTargetAsmParser implementation for
@@ -723,8 +699,7 @@ namespace llvm {
/// @param T - The target being registered.
/// @param Fn - A function to construct an MCTargetAsmParser for the target.
static void RegisterMCAsmParser(Target &T, Target::MCAsmParserCtorTy Fn) {
- if (!T.MCAsmParserCtorFn)
- T.MCAsmParserCtorFn = Fn;
+ T.MCAsmParserCtorFn = Fn;
}
/// RegisterAsmPrinter - Register an AsmPrinter implementation for the given
@@ -737,9 +712,7 @@ namespace llvm {
/// @param T - The target being registered.
/// @param Fn - A function to construct an AsmPrinter for the target.
static void RegisterAsmPrinter(Target &T, Target::AsmPrinterCtorTy Fn) {
- // Ignore duplicate registration.
- if (!T.AsmPrinterCtorFn)
- T.AsmPrinterCtorFn = Fn;
+ T.AsmPrinterCtorFn = Fn;
}
/// RegisterMCDisassembler - Register a MCDisassembler implementation for
@@ -753,8 +726,7 @@ namespace llvm {
/// @param Fn - A function to construct an MCDisassembler for the target.
static void RegisterMCDisassembler(Target &T,
Target::MCDisassemblerCtorTy Fn) {
- if (!T.MCDisassemblerCtorFn)
- T.MCDisassemblerCtorFn = Fn;
+ T.MCDisassemblerCtorFn = Fn;
}
/// RegisterMCInstPrinter - Register a MCInstPrinter implementation for the
@@ -768,8 +740,7 @@ namespace llvm {
/// @param Fn - A function to construct an MCInstPrinter for the target.
static void RegisterMCInstPrinter(Target &T,
Target::MCInstPrinterCtorTy Fn) {
- if (!T.MCInstPrinterCtorFn)
- T.MCInstPrinterCtorFn = Fn;
+ T.MCInstPrinterCtorFn = Fn;
}
/// RegisterMCCodeEmitter - Register a MCCodeEmitter implementation for the
@@ -783,8 +754,7 @@ namespace llvm {
/// @param Fn - A function to construct an MCCodeEmitter for the target.
static void RegisterMCCodeEmitter(Target &T,
Target::MCCodeEmitterCtorTy Fn) {
- if (!T.MCCodeEmitterCtorFn)
- T.MCCodeEmitterCtorFn = Fn;
+ T.MCCodeEmitterCtorFn = Fn;
}
/// RegisterMCObjectStreamer - Register a object code MCStreamer
@@ -798,8 +768,7 @@ namespace llvm {
/// @param Fn - A function to construct an MCStreamer for the target.
static void RegisterMCObjectStreamer(Target &T,
Target::MCObjectStreamerCtorTy Fn) {
- if (!T.MCObjectStreamerCtorFn)
- T.MCObjectStreamerCtorFn = Fn;
+ T.MCObjectStreamerCtorFn = Fn;
}
/// RegisterAsmStreamer - Register an assembly MCStreamer implementation
@@ -812,8 +781,7 @@ namespace llvm {
/// @param T - The target being registered.
/// @param Fn - A function to construct an MCStreamer for the target.
static void RegisterAsmStreamer(Target &T, Target::AsmStreamerCtorTy Fn) {
- if (T.AsmStreamerCtorFn == createAsmStreamer)
- T.AsmStreamerCtorFn = Fn;
+ T.AsmStreamerCtorFn = Fn;
}
/// RegisterMCRelocationInfo - Register an MCRelocationInfo
@@ -827,8 +795,7 @@ namespace llvm {
/// @param Fn - A function to construct an MCRelocationInfo for the target.
static void RegisterMCRelocationInfo(Target &T,
Target::MCRelocationInfoCtorTy Fn) {
- if (T.MCRelocationInfoCtorFn == llvm::createMCRelocationInfo)
- T.MCRelocationInfoCtorFn = Fn;
+ T.MCRelocationInfoCtorFn = Fn;
}
/// RegisterMCSymbolizer - Register an MCSymbolizer
@@ -842,8 +809,7 @@ namespace llvm {
/// @param Fn - A function to construct an MCSymbolizer for the target.
static void RegisterMCSymbolizer(Target &T,
Target::MCSymbolizerCtorTy Fn) {
- if (T.MCSymbolizerCtorFn == llvm::createMCSymbolizer)
- T.MCSymbolizerCtorFn = Fn;
+ T.MCSymbolizerCtorFn = Fn;
}
/// @}
@@ -1118,9 +1084,10 @@ namespace llvm {
}
private:
- static MCAsmBackend *Allocator(const Target &T, StringRef Triple,
- StringRef CPU) {
- return new MCAsmBackendImpl(T, Triple, CPU);
+ static MCAsmBackend *Allocator(const Target &T,
+ const MCRegisterInfo &MRI,
+ StringRef Triple, StringRef CPU) {
+ return new MCAsmBackendImpl(T, MRI, Triple, CPU);
}
};
@@ -1139,8 +1106,9 @@ namespace llvm {
}
private:
- static MCTargetAsmParser *Allocator(MCSubtargetInfo &STI, MCAsmParser &P) {
- return new MCAsmParserImpl(STI, P);
+ static MCTargetAsmParser *Allocator(MCSubtargetInfo &STI, MCAsmParser &P,
+ const MCInstrInfo &MII) {
+ return new MCAsmParserImpl(STI, P, MII);
}
};
diff --git a/include/llvm/Support/Unicode.h b/include/llvm/Support/Unicode.h
new file mode 100644
index 0000000..e6a52c4
--- /dev/null
+++ b/include/llvm/Support/Unicode.h
@@ -0,0 +1,62 @@
+//===- llvm/Support/Unicode.h - Unicode character properties -*- C++ -*-=====//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines functions that allow querying certain properties of Unicode
+// characters.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/StringRef.h"
+
+namespace llvm {
+namespace sys {
+namespace unicode {
+
+enum ColumnWidthErrors {
+ ErrorInvalidUTF8 = -2,
+ ErrorNonPrintableCharacter = -1
+};
+
+/// Determines if a character is likely to be displayed correctly on the
+/// terminal. Exact implementation would have to depend on the specific
+/// terminal, so we define the semantic that should be suitable for generic case
+/// of a terminal capable to output Unicode characters.
+///
+/// All characters from the Unicode code point range are considered printable
+/// except for:
+/// * C0 and C1 control character ranges;
+/// * default ignorable code points as per 5.21 of
+/// http://www.unicode.org/versions/Unicode6.2.0/UnicodeStandard-6.2.pdf
+/// except for U+00AD SOFT HYPHEN, as it's actually displayed on most
+/// terminals;
+/// * format characters (category = Cf);
+/// * surrogates (category = Cs);
+/// * unassigned characters (category = Cn).
+/// \return true if the character is considered printable.
+bool isPrintable(int UCS);
+
+/// Gets the number of positions the UTF8-encoded \p Text is likely to occupy
+/// when output on a terminal ("character width"). This depends on the
+/// implementation of the terminal, and there's no standard definition of
+/// character width.
+///
+/// The implementation defines it in a way that is expected to be compatible
+/// with a generic Unicode-capable terminal.
+///
+/// \return Character width:
+/// * ErrorNonPrintableCharacter (-1) if \p Text contains non-printable
+/// characters (as identified by isPrintable);
+/// * 0 for each non-spacing and enclosing combining mark;
+/// * 2 for each CJK character excluding halfwidth forms;
+/// * 1 for each of the remaining characters.
+int columnWidthUTF8(StringRef Text);
+
+} // namespace unicode
+} // namespace sys
+} // namespace llvm
diff --git a/include/llvm/Support/UnicodeCharRanges.h b/include/llvm/Support/UnicodeCharRanges.h
index 4a4d988..86faa38 100644
--- a/include/llvm/Support/UnicodeCharRanges.h
+++ b/include/llvm/Support/UnicodeCharRanges.h
@@ -17,82 +17,80 @@
#include "llvm/Support/MutexGuard.h"
#include "llvm/Support/raw_ostream.h"
-namespace {
+#include <algorithm>
+namespace llvm {
+namespace sys {
+
+/// \brief Represents a closed range of Unicode code points [Lower, Upper].
struct UnicodeCharRange {
uint32_t Lower;
uint32_t Upper;
};
-typedef llvm::ArrayRef<UnicodeCharRange> UnicodeCharSet;
-/// Returns true if each of the ranges in \p CharSet is a proper closed range
-/// [min, max], and if the ranges themselves are ordered and non-overlapping.
-static inline bool isValidCharSet(UnicodeCharSet CharSet) {
-#ifndef NDEBUG
- static llvm::SmallPtrSet<const UnicodeCharRange *, 16> Validated;
- static llvm::sys::Mutex ValidationMutex;
+inline bool operator<(uint32_t Value, UnicodeCharRange Range) {
+ return Value < Range.Lower;
+}
+inline bool operator<(UnicodeCharRange Range, uint32_t Value) {
+ return Range.Upper < Value;
+}
- // Check the validation cache.
- {
- llvm::MutexGuard Guard(ValidationMutex);
- if (Validated.count(CharSet.data()))
- return true;
- }
+/// \brief Holds a reference to an ordered array of UnicodeCharRange and allows
+/// to quickly check if a code point is contained in the set represented by this
+/// array.
+class UnicodeCharSet {
+public:
+ typedef llvm::ArrayRef<UnicodeCharRange> CharRanges;
- // Walk through the ranges.
- uint32_t Prev = 0;
- for (UnicodeCharSet::iterator I = CharSet.begin(), E = CharSet.end();
- I != E; ++I) {
- if (I != CharSet.begin() && Prev >= I->Lower) {
- DEBUG(llvm::dbgs() << "Upper bound 0x");
- DEBUG(llvm::dbgs().write_hex(Prev));
- DEBUG(llvm::dbgs() << " should be less than succeeding lower bound 0x");
- DEBUG(llvm::dbgs().write_hex(I->Lower) << "\n");
- return false;
- }
- if (I->Upper < I->Lower) {
- DEBUG(llvm::dbgs() << "Upper bound 0x");
- DEBUG(llvm::dbgs().write_hex(I->Lower));
- DEBUG(llvm::dbgs() << " should not be less than lower bound 0x");
- DEBUG(llvm::dbgs().write_hex(I->Upper) << "\n");
- return false;
- }
- Prev = I->Upper;
+ /// \brief Constructs a UnicodeCharSet instance from an array of
+ /// UnicodeCharRanges.
+ ///
+ /// Array pointed by \p Ranges should have the lifetime at least as long as
+ /// the UnicodeCharSet instance, and should not change. Array is validated by
+ /// the constructor, so it makes sense to create as few UnicodeCharSet
+ /// instances per each array of ranges, as possible.
+ UnicodeCharSet(CharRanges Ranges) : Ranges(Ranges) {
+ assert(rangesAreValid());
}
- // Update the validation cache.
- {
- llvm::MutexGuard Guard(ValidationMutex);
- Validated.insert(CharSet.data());
+ /// \brief Returns true if the character set contains the Unicode code point
+ /// \p C.
+ bool contains(uint32_t C) const {
+ return std::binary_search(Ranges.begin(), Ranges.end(), C);
}
-#endif
- return true;
-}
-
-} // namespace
+private:
+ /// \brief Returns true if each of the ranges is a proper closed range
+ /// [min, max], and if the ranges themselves are ordered and non-overlapping.
+ bool rangesAreValid() const {
+ uint32_t Prev = 0;
+ for (CharRanges::const_iterator I = Ranges.begin(), E = Ranges.end();
+ I != E; ++I) {
+ if (I != Ranges.begin() && Prev >= I->Lower) {
+ DEBUG(llvm::dbgs() << "Upper bound 0x");
+ DEBUG(llvm::dbgs().write_hex(Prev));
+ DEBUG(llvm::dbgs() << " should be less than succeeding lower bound 0x");
+ DEBUG(llvm::dbgs().write_hex(I->Lower) << "\n");
+ return false;
+ }
+ if (I->Upper < I->Lower) {
+ DEBUG(llvm::dbgs() << "Upper bound 0x");
+ DEBUG(llvm::dbgs().write_hex(I->Lower));
+ DEBUG(llvm::dbgs() << " should not be less than lower bound 0x");
+ DEBUG(llvm::dbgs().write_hex(I->Upper) << "\n");
+ return false;
+ }
+ Prev = I->Upper;
+ }
-/// Returns true if the Unicode code point \p C is within the set of
-/// characters specified by \p CharSet.
-LLVM_READONLY static inline bool isCharInSet(uint32_t C,
- UnicodeCharSet CharSet) {
- assert(isValidCharSet(CharSet));
+ return true;
+ }
- size_t LowPoint = 0;
- size_t HighPoint = CharSet.size();
+ const CharRanges Ranges;
+};
- // Binary search the set of char ranges.
- while (HighPoint != LowPoint) {
- size_t MidPoint = (HighPoint + LowPoint) / 2;
- if (C < CharSet[MidPoint].Lower)
- HighPoint = MidPoint;
- else if (C > CharSet[MidPoint].Upper)
- LowPoint = MidPoint + 1;
- else
- return true;
- }
+} // namespace sys
+} // namespace llvm
- return false;
-}
#endif // LLVM_SUPPORT_UNICODECHARRANGES_H
diff --git a/include/llvm/Support/Valgrind.h b/include/llvm/Support/Valgrind.h
index a1397db..7ae40af 100644
--- a/include/llvm/Support/Valgrind.h
+++ b/include/llvm/Support/Valgrind.h
@@ -13,8 +13,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SYSTEM_VALGRIND_H
-#define LLVM_SYSTEM_VALGRIND_H
+#ifndef LLVM_SUPPORT_VALGRIND_H
+#define LLVM_SUPPORT_VALGRIND_H
#include "llvm/Config/llvm-config.h"
#include "llvm/Support/Compiler.h"
diff --git a/include/llvm/Support/ValueHandle.h b/include/llvm/Support/ValueHandle.h
index b49341c..bc02ba3 100644
--- a/include/llvm/Support/ValueHandle.h
+++ b/include/llvm/Support/ValueHandle.h
@@ -339,6 +339,7 @@ public:
/// rearrange itself when the pointer changes). Unlike ValueHandleBase, this
/// class has a vtable and a virtual destructor.
class CallbackVH : public ValueHandleBase {
+ virtual void anchor();
protected:
CallbackVH(const CallbackVH &RHS)
: ValueHandleBase(Callback, RHS) {}
@@ -365,13 +366,13 @@ public:
///
/// All implementations must remove the reference from this object to the
/// Value that's being destroyed.
- virtual void deleted();
+ virtual void deleted() { setValPtr(NULL); }
/// Called when this->getValPtr()->replaceAllUsesWith(new_value) is called,
/// _before_ any of the uses have actually been replaced. If WeakVH were
/// implemented as a CallbackVH, it would use this method to call
/// setValPtr(new_value). AssertingVH would do nothing in this method.
- virtual void allUsesReplacedWith(Value *);
+ virtual void allUsesReplacedWith(Value *) {}
};
} // End llvm namespace
diff --git a/include/llvm/Support/YAMLParser.h b/include/llvm/Support/YAMLParser.h
index 338bb4b..7020449 100644
--- a/include/llvm/Support/YAMLParser.h
+++ b/include/llvm/Support/YAMLParser.h
@@ -43,6 +43,8 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/SMLoc.h"
+
+#include <map>
#include <limits>
#include <utility>
@@ -99,13 +101,11 @@ private:
OwningPtr<Document> CurrentDoc;
friend class Document;
-
- /// @brief Validate a %YAML x.x directive.
- void handleYAMLDirective(const Token &);
};
/// @brief Abstract base class for all Nodes.
class Node {
+ virtual void anchor();
public:
enum NodeKind {
NK_Null,
@@ -116,12 +116,21 @@ public:
NK_Alias
};
- Node(unsigned int Type, OwningPtr<Document>&, StringRef Anchor);
+ Node(unsigned int Type, OwningPtr<Document> &, StringRef Anchor,
+ StringRef Tag);
/// @brief Get the value of the anchor attached to this node. If it does not
/// have one, getAnchor().size() will be 0.
StringRef getAnchor() const { return Anchor; }
+ /// \brief Get the tag as it was written in the document. This does not
+ /// perform tag resolution.
+ StringRef getRawTag() const { return Tag; }
+
+ /// \brief Get the verbatium tag for a given Node. This performs tag resoluton
+ /// and substitution.
+ std::string getVerbatimTag() const;
+
SMRange getSourceRange() const { return SourceRange; }
void setSourceRange(SMRange SR) { SourceRange = SR; }
@@ -158,6 +167,8 @@ protected:
private:
unsigned int TypeID;
StringRef Anchor;
+ /// \brief The tag as typed in the document.
+ StringRef Tag;
};
/// @brief A null value.
@@ -165,8 +176,10 @@ private:
/// Example:
/// !!null null
class NullNode : public Node {
+ virtual void anchor();
public:
- NullNode(OwningPtr<Document> &D) : Node(NK_Null, D, StringRef()) {}
+ NullNode(OwningPtr<Document> &D)
+ : Node(NK_Null, D, StringRef(), StringRef()) {}
static inline bool classof(const Node *N) {
return N->getType() == NK_Null;
@@ -179,10 +192,11 @@ public:
/// Example:
/// Adena
class ScalarNode : public Node {
+ virtual void anchor();
public:
- ScalarNode(OwningPtr<Document> &D, StringRef Anchor, StringRef Val)
- : Node(NK_Scalar, D, Anchor)
- , Value(Val) {
+ ScalarNode(OwningPtr<Document> &D, StringRef Anchor, StringRef Tag,
+ StringRef Val)
+ : Node(NK_Scalar, D, Anchor, Tag), Value(Val) {
SMLoc Start = SMLoc::getFromPointer(Val.begin());
SMLoc End = SMLoc::getFromPointer(Val.end());
SourceRange = SMRange(Start, End);
@@ -220,9 +234,10 @@ private:
/// Example:
/// Section: .text
class KeyValueNode : public Node {
+ virtual void anchor();
public:
KeyValueNode(OwningPtr<Document> &D)
- : Node(NK_KeyValue, D, StringRef())
+ : Node(NK_KeyValue, D, StringRef(), StringRef())
, Key(0)
, Value(0)
{}
@@ -331,6 +346,7 @@ void skip(CollectionType &C) {
/// Name: _main
/// Scope: Global
class MappingNode : public Node {
+ virtual void anchor();
public:
enum MappingType {
MT_Block,
@@ -338,13 +354,10 @@ public:
MT_Inline ///< An inline mapping node is used for "[key: value]".
};
- MappingNode(OwningPtr<Document> &D, StringRef Anchor, MappingType MT)
- : Node(NK_Mapping, D, Anchor)
- , Type(MT)
- , IsAtBeginning(true)
- , IsAtEnd(false)
- , CurrentEntry(0)
- {}
+ MappingNode(OwningPtr<Document> &D, StringRef Anchor, StringRef Tag,
+ MappingType MT)
+ : Node(NK_Mapping, D, Anchor, Tag), Type(MT), IsAtBeginning(true),
+ IsAtEnd(false), CurrentEntry(0) {}
friend class basic_collection_iterator<MappingNode, KeyValueNode>;
typedef basic_collection_iterator<MappingNode, KeyValueNode> iterator;
@@ -383,6 +396,7 @@ private:
/// - Hello
/// - World
class SequenceNode : public Node {
+ virtual void anchor();
public:
enum SequenceType {
ST_Block,
@@ -397,14 +411,12 @@ public:
ST_Indentless
};
- SequenceNode(OwningPtr<Document> &D, StringRef Anchor, SequenceType ST)
- : Node(NK_Sequence, D, Anchor)
- , SeqType(ST)
- , IsAtBeginning(true)
- , IsAtEnd(false)
- , WasPreviousTokenFlowEntry(true) // Start with an imaginary ','.
- , CurrentEntry(0)
- {}
+ SequenceNode(OwningPtr<Document> &D, StringRef Anchor, StringRef Tag,
+ SequenceType ST)
+ : Node(NK_Sequence, D, Anchor, Tag), SeqType(ST), IsAtBeginning(true),
+ IsAtEnd(false),
+ WasPreviousTokenFlowEntry(true), // Start with an imaginary ','.
+ CurrentEntry(0) {}
friend class basic_collection_iterator<SequenceNode, Node>;
typedef basic_collection_iterator<SequenceNode, Node> iterator;
@@ -440,9 +452,10 @@ private:
/// Example:
/// *AnchorName
class AliasNode : public Node {
+ virtual void anchor();
public:
AliasNode(OwningPtr<Document> &D, StringRef Val)
- : Node(NK_Alias, D, StringRef()), Name(Val) {}
+ : Node(NK_Alias, D, StringRef(), StringRef()), Name(Val) {}
StringRef getName() const { return Name; }
Node *getTarget();
@@ -475,6 +488,10 @@ public:
return Root = parseBlockNode();
}
+ const std::map<StringRef, StringRef> &getTagMap() const {
+ return TagMap;
+ }
+
private:
friend class Node;
friend class document_iterator;
@@ -490,18 +507,23 @@ private:
/// document.
Node *Root;
+ /// \brief Maps tag prefixes to their expansion.
+ std::map<StringRef, StringRef> TagMap;
+
Token &peekNext();
Token getNext();
void setError(const Twine &Message, Token &Location) const;
bool failed() const;
- void handleTagDirective(const Token &Tag) {
- // TODO: Track tags.
- }
-
/// @brief Parse %BLAH directives and return true if any were encountered.
bool parseDirectives();
+ /// \brief Parse %YAML
+ void parseYAMLDirective();
+
+ /// \brief Parse %TAG
+ void parseTAGDirective();
+
/// @brief Consume the next token and error if it is not \a TK.
bool expectToken(int TK);
};
diff --git a/include/llvm/Support/YAMLTraits.h b/include/llvm/Support/YAMLTraits.h
index 0f57f44..c19eb23 100644
--- a/include/llvm/Support/YAMLTraits.h
+++ b/include/llvm/Support/YAMLTraits.h
@@ -18,6 +18,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Twine.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/YAMLParser.h"
@@ -317,18 +318,20 @@ public:
IO(void *Ctxt=NULL);
virtual ~IO();
- virtual bool outputting() = 0;
+ virtual bool outputting() const = 0;
virtual unsigned beginSequence() = 0;
virtual bool preflightElement(unsigned, void *&) = 0;
virtual void postflightElement(void*) = 0;
virtual void endSequence() = 0;
+ virtual bool canElideEmptySequence() = 0;
virtual unsigned beginFlowSequence() = 0;
virtual bool preflightFlowElement(unsigned, void *&) = 0;
virtual void postflightFlowElement(void*) = 0;
virtual void endFlowSequence() = 0;
+ virtual bool mapTag(StringRef Tag, bool Default=false) = 0;
virtual void beginMapping() = 0;
virtual void endMapping() = 0;
virtual bool preflightKey(const char*, bool, bool, bool &, void *&) = 0;
@@ -388,7 +391,7 @@ public:
typename llvm::enable_if_c<has_SequenceTraits<T>::value,void>::type
mapOptional(const char* Key, T& Val) {
// omit key/value instead of outputting empty sequence
- if ( this->outputting() && !(Val.begin() != Val.end()) )
+ if ( this->canElideEmptySequence() && !(Val.begin() != Val.end()) )
return;
this->processKey(Key, Val, false);
}
@@ -403,8 +406,7 @@ public:
void mapOptional(const char* Key, T& Val, const T& Default) {
this->processKeyWithDefault(Key, Val, Default, false);
}
-
-
+
private:
template <typename T>
void processKeyWithDefault(const char *Key, T &Val, const T& DefaultValue,
@@ -683,18 +685,23 @@ private:
///
class Input : public IO {
public:
- // Construct a yaml Input object from a StringRef and optional user-data.
- Input(StringRef InputContent, void *Ctxt=NULL);
+ // Construct a yaml Input object from a StringRef and optional
+ // user-data. The DiagHandler can be specified to provide
+ // alternative error reporting.
+ Input(StringRef InputContent,
+ void *Ctxt = NULL,
+ SourceMgr::DiagHandlerTy DiagHandler = NULL,
+ void *DiagHandlerCtxt = NULL);
~Input();
-
+
// Check if there was an syntax or semantic error during parsing.
llvm::error_code error();
- // To set alternate error reporting.
- void setDiagHandler(llvm::SourceMgr::DiagHandlerTy Handler, void *Ctxt = 0);
+ static bool classof(const IO *io) { return !io->outputting(); }
private:
- virtual bool outputting();
+ virtual bool outputting() const;
+ virtual bool mapTag(StringRef, bool);
virtual void beginMapping();
virtual void endMapping();
virtual bool preflightKey(const char *, bool, bool, bool &, void *&);
@@ -715,8 +722,10 @@ private:
virtual void endBitSetScalar();
virtual void scalarString(StringRef &);
virtual void setError(const Twine &message);
+ virtual bool canElideEmptySequence();
class HNode {
+ virtual void anchor();
public:
HNode(Node *n) : _node(n) { }
virtual ~HNode() { }
@@ -726,9 +735,9 @@ private:
};
class EmptyHNode : public HNode {
+ virtual void anchor();
public:
EmptyHNode(Node *n) : HNode(n) { }
- virtual ~EmptyHNode() {}
static inline bool classof(const HNode *n) {
return NullNode::classof(n->_node);
}
@@ -736,9 +745,9 @@ private:
};
class ScalarHNode : public HNode {
+ virtual void anchor();
public:
ScalarHNode(Node *n, StringRef s) : HNode(n), _value(s) { }
- virtual ~ScalarHNode() { }
StringRef value() const { return _value; }
@@ -816,7 +825,10 @@ public:
Output(llvm::raw_ostream &, void *Ctxt=NULL);
virtual ~Output();
- virtual bool outputting();
+ static bool classof(const IO *io) { return io->outputting(); }
+
+ virtual bool outputting() const;
+ virtual bool mapTag(StringRef, bool);
virtual void beginMapping();
virtual void endMapping();
virtual bool preflightKey(const char *key, bool, bool, bool &, void *&);
@@ -837,7 +849,7 @@ public:
virtual void endBitSetScalar();
virtual void scalarString(StringRef &);
virtual void setError(const Twine &message);
-
+ virtual bool canElideEmptySequence();
public:
// These are only used by operator<<. They could be private
// if that templated operator could be made a friend.
@@ -959,8 +971,8 @@ template <typename T>
inline
typename llvm::enable_if_c<has_SequenceTraits<T>::value,Input &>::type
operator>>(Input &yin, T &docSeq) {
- yin.setCurrentDocument();
- yamlize(yin, docSeq, true);
+ if (yin.setCurrentDocument())
+ yamlize(yin, docSeq, true);
return yin;
}