diff options
Diffstat (limited to 'include/llvm/Support')
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; } |