diff options
author | Derek Schuff <dschuff@chromium.org> | 2012-08-21 17:32:13 -0700 |
---|---|---|
committer | Derek Schuff <dschuff@chromium.org> | 2012-08-21 17:32:13 -0700 |
commit | 66f271497ed92ebb05c66f54616e512606a2e314 (patch) | |
tree | 96d54cd64804ab7c9f2f52f680c3301aa789ce1d /include/llvm/Support | |
parent | b62e9abf7dd9e39c95327914ce9dfe216386824a (diff) | |
parent | bc363931085587bac42a40653962a3e5acd1ffce (diff) |
Merge up to r162331, git commit bc363931085587bac42a40653962a3e5acd1ffce
Diffstat (limited to 'include/llvm/Support')
24 files changed, 593 insertions, 662 deletions
diff --git a/include/llvm/Support/AlignOf.h b/include/llvm/Support/AlignOf.h index 85607c8448..cf7125173e 100644 --- a/include/llvm/Support/AlignOf.h +++ b/include/llvm/Support/AlignOf.h @@ -107,8 +107,8 @@ LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(8192); // Any larger and MSVC complains. #undef LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT -/// \brief This class template exposes a typedef for type containing a suitable -/// aligned character array to hold elements of any of up to four types. +/// \brief This union template exposes a suitably aligned and sized character +/// array member which can hold elements of any of up to four types. /// /// These types may be arrays, structs, or any other types. The goal is to /// produce a union type containing a character array which, when used, forms @@ -116,7 +116,8 @@ LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(8192); /// than four types can be added at the cost of more boiler plate. template <typename T1, typename T2 = char, typename T3 = char, typename T4 = char> -class AlignedCharArray { +union AlignedCharArrayUnion { +private: class AlignerImpl { T1 t1; T2 t2; T3 t3; T4 t4; @@ -127,6 +128,12 @@ class AlignedCharArray { }; public: + /// \brief The character array buffer for use by clients. + /// + /// No other member of this union should be referenced. The exist purely to + /// constrain the layout of this character array. + char buffer[sizeof(SizerImpl)]; + // Sadly, Clang and GCC both fail to align a character array properly even // with an explicit alignment attribute. To work around this, we union // the character array that will actually be used with a struct that contains @@ -134,16 +141,10 @@ public: // and GCC will properly register the alignment of a struct containing an // aligned member, and this alignment should carry over to the character // array in the union. - union union_type { - // This is the only member of the union which should be used by clients: - char buffer[sizeof(SizerImpl)]; - - // This member of the union only exists to force the alignment. - struct { - typename llvm::AlignedCharArrayImpl<AlignOf<AlignerImpl>::Alignment>::type - nonce_inner_member; - } nonce_member; - }; + struct { + typename llvm::AlignedCharArrayImpl<AlignOf<AlignerImpl>::Alignment>::type + nonce_inner_member; + } nonce_member; }; } // end namespace llvm diff --git a/include/llvm/Support/COFF.h b/include/llvm/Support/COFF.h index b18ba2b550..ba8adb0181 100644 --- a/include/llvm/Support/COFF.h +++ b/include/llvm/Support/COFF.h @@ -50,6 +50,8 @@ namespace COFF { }; enum MachineTypes { + MT_Invalid = 0xffff, + IMAGE_FILE_MACHINE_UNKNOWN = 0x0, IMAGE_FILE_MACHINE_AM33 = 0x13, IMAGE_FILE_MACHINE_AMD64 = 0x8664, @@ -74,6 +76,8 @@ namespace COFF { }; enum Characteristics { + C_Invalid = 0, + /// The file does not contain base relocations and must be loaded at its /// preferred base. If this cannot be done, the loader will error. IMAGE_FILE_RELOCS_STRIPPED = 0x0001, @@ -138,6 +142,8 @@ namespace COFF { /// Storage class tells where and what the symbol represents enum SymbolStorageClass { + SSC_Invalid = 0xff, + IMAGE_SYM_CLASS_END_OF_FUNCTION = -1, ///< Physical end of function IMAGE_SYM_CLASS_NULL = 0, ///< No symbol IMAGE_SYM_CLASS_AUTOMATIC = 1, ///< Stack variable @@ -214,6 +220,8 @@ namespace COFF { }; enum SectionCharacteristics { + SC_Invalid = 0xffffffff, + IMAGE_SCN_TYPE_NO_PAD = 0x00000008, IMAGE_SCN_CNT_CODE = 0x00000020, IMAGE_SCN_CNT_INITIALIZED_DATA = 0x00000040, diff --git a/include/llvm/Support/CommandLine.h b/include/llvm/Support/CommandLine.h index 40c4300016..ae1570da9c 100644 --- a/include/llvm/Support/CommandLine.h +++ b/include/llvm/Support/CommandLine.h @@ -217,11 +217,11 @@ public: void setMiscFlag(enum MiscFlags M) { Misc |= M; } void setPosition(unsigned pos) { Position = pos; } protected: - explicit Option(enum NumOccurrencesFlag OccurrencesFlag, + explicit Option(enum NumOccurrencesFlag OccurrencesFlag, enum OptionHidden Hidden) - : NumOccurrences(0), Occurrences(OccurrencesFlag), HiddenFlag(Hidden), - Formatting(NormalFormatting), Position(0), - AdditionalVals(0), NextRegistered(0), + : NumOccurrences(0), Occurrences(OccurrencesFlag), Value(0), + HiddenFlag(Hidden), Formatting(NormalFormatting), Misc(0), + Position(0), AdditionalVals(0), NextRegistered(0), ArgStr(""), HelpStr(""), ValueStr("") { } diff --git a/include/llvm/Support/Compiler.h b/include/llvm/Support/Compiler.h index 5564db79c2..ea0a4da27f 100644 --- a/include/llvm/Support/Compiler.h +++ b/include/llvm/Support/Compiler.h @@ -38,6 +38,25 @@ #define llvm_move(value) (value) #endif +/// LLVM_DELETED_FUNCTION - Expands to = delete if the compiler supports it. +/// Use to mark functions as uncallable. Member functions with this should +/// be declared private so that some behaivor is kept in C++03 mode. +/// +/// class DontCopy { +/// private: +/// DontCopy(const DontCopy&) LLVM_DELETED_FUNCTION; +/// DontCopy &operator =(const DontCopy&) LLVM_DELETED_FUNCTION; +/// public: +/// ... +/// }; +#if (__has_feature(cxx_deleted_functions) \ + || defined(__GXX_EXPERIMENTAL_CXX0X__)) + // No version of MSVC currently supports this. +#define LLVM_DELETED_FUNCTION = delete +#else +#define LLVM_DELETED_FUNCTION +#endif + /// LLVM_LIBRARY_VISIBILITY - If a class marked with this attribute is linked /// into a shared library, then the class should be private to the library and /// not accessible from outside it. Can also be used to mark variables and @@ -121,7 +140,7 @@ // 3.4 supported this but is buggy in various cases and produces unimplemented // errors, just use it in GCC 4.0 and later. #if __GNUC__ > 3 -#define LLVM_ATTRIBUTE_ALWAYS_INLINE __attribute__((always_inline)) +#define LLVM_ATTRIBUTE_ALWAYS_INLINE inline __attribute__((always_inline)) #elif defined(_MSC_VER) #define LLVM_ATTRIBUTE_ALWAYS_INLINE __forceinline #else @@ -168,4 +187,13 @@ # define LLVM_BUILTIN_UNREACHABLE __builtin_unreachable() #endif +// LLVM_BUILTIN_TRAP - On compilers which support it, expands to an expression +// which causes the program to exit abnormally. +#if defined(__clang__) || (__GNUC__ > 4) \ + || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) +# define LLVM_BUILTIN_TRAP __builtin_trap() +#else +# define LLVM_BUILTIN_TRAP *(volatile int*)0x11 = 0 +#endif + #endif diff --git a/include/llvm/Support/DataTypes.h.cmake b/include/llvm/Support/DataTypes.h.cmake index a3a6489e8a..7484abd368 100644 --- a/include/llvm/Support/DataTypes.h.cmake +++ b/include/llvm/Support/DataTypes.h.cmake @@ -79,18 +79,6 @@ typedef u_int64_t uint64_t; #endif #endif -#ifdef _OpenBSD_ -#define INT8_MAX 127 -#define INT8_MIN -128 -#define UINT8_MAX 255 -#define INT16_MAX 32767 -#define INT16_MIN -32768 -#define UINT16_MAX 65535 -#define INT32_MAX 2147483647 -#define INT32_MIN -2147483648 -#define UINT32_MAX 4294967295U -#endif - #else /* _MSC_VER */ /* Visual C++ doesn't provide standard integer headers, but it does provide built-in data types. */ diff --git a/include/llvm/Support/DataTypes.h.in b/include/llvm/Support/DataTypes.h.in index b492bb14ba..b9fb48a1d4 100644 --- a/include/llvm/Support/DataTypes.h.in +++ b/include/llvm/Support/DataTypes.h.in @@ -79,18 +79,6 @@ typedef u_int64_t uint64_t; #endif #endif -#ifdef _OpenBSD_ -#define INT8_MAX 127 -#define INT8_MIN -128 -#define UINT8_MAX 255 -#define INT16_MAX 32767 -#define INT16_MIN -32768 -#define UINT16_MAX 65535 -#define INT32_MAX 2147483647 -#define INT32_MIN -2147483648 -#define UINT32_MAX 4294967295U -#endif - #else /* _MSC_VER */ /* Visual C++ doesn't provide standard integer headers, but it does provide built-in data types. */ diff --git a/include/llvm/Support/Debug.h b/include/llvm/Support/Debug.h index e72327271f..896fe849a6 100644 --- a/include/llvm/Support/Debug.h +++ b/include/llvm/Support/Debug.h @@ -19,7 +19,7 @@ // foo class. // // When compiling without assertions, the -debug-* options and all code in -// DEBUG() statements disappears, so it does not effect the runtime of the code. +// DEBUG() statements disappears, so it does not affect the runtime of the code. // //===----------------------------------------------------------------------===// @@ -49,11 +49,11 @@ extern bool DebugFlag; /// bool isCurrentDebugType(const char *Type); -/// SetCurrentDebugType - Set the current debug type, as if the -debug-only=X +/// setCurrentDebugType - Set the current debug type, as if the -debug-only=X /// option were specified. Note that DebugFlag also needs to be set to true for /// debug output to be produced. /// -void SetCurrentDebugType(const char *Type); +void setCurrentDebugType(const char *Type); /// DEBUG_WITH_TYPE macro - This macro should be used by passes to emit debug /// information. In the '-debug' option is specified on the commandline, and if @@ -70,7 +70,7 @@ void SetCurrentDebugType(const char *Type); #else #define isCurrentDebugType(X) (false) -#define SetCurrentDebugType(X) +#define setCurrentDebugType(X) #define DEBUG_WITH_TYPE(TYPE, X) do { } while (0) #endif diff --git a/include/llvm/Support/DebugLoc.h b/include/llvm/Support/DebugLoc.h index 2ee9f876c3..0498075707 100644 --- a/include/llvm/Support/DebugLoc.h +++ b/include/llvm/Support/DebugLoc.h @@ -15,9 +15,8 @@ #ifndef LLVM_SUPPORT_DEBUGLOC_H #define LLVM_SUPPORT_DEBUGLOC_H -#include "llvm/ADT/DenseMapInfo.h" - namespace llvm { + template <typename T> struct DenseMapInfo; class MDNode; class LLVMContext; @@ -103,10 +102,10 @@ namespace llvm { template <> struct DenseMapInfo<DebugLoc> { - static DebugLoc getEmptyKey(); - static DebugLoc getTombstoneKey(); + static DebugLoc getEmptyKey() { return DebugLoc::getEmptyKey(); } + static DebugLoc getTombstoneKey() { return DebugLoc::getTombstoneKey(); } static unsigned getHashValue(const DebugLoc &Key); - static bool isEqual(const DebugLoc &LHS, const DebugLoc &RHS); + static bool isEqual(DebugLoc LHS, DebugLoc RHS) { return LHS == RHS; } }; } // end namespace llvm diff --git a/include/llvm/Support/ELF.h b/include/llvm/Support/ELF.h index 25945cb3ec..705ff679f8 100644 --- a/include/llvm/Support/ELF.h +++ b/include/llvm/Support/ELF.h @@ -828,6 +828,8 @@ enum { SHT_GROUP = 17, // Section group. SHT_SYMTAB_SHNDX = 18, // Indices for SHN_XINDEX entries. SHT_LOOS = 0x60000000, // Lowest operating system-specific type. + SHT_GNU_ATTRIBUTES= 0x6ffffff5, // Object attributes. + SHT_GNU_HASH = 0x6ffffff6, // GNU-style hash table. SHT_GNU_verdef = 0x6ffffffd, // GNU version definitions. SHT_GNU_verneed = 0x6ffffffe, // GNU version references. SHT_GNU_versym = 0x6fffffff, // GNU symbol versions table. @@ -1109,6 +1111,9 @@ enum { PT_SUNW_EH_FRAME = 0x6474e550, PT_SUNW_UNWIND = 0x6464e550, + PT_GNU_STACK = 0x6474e551, // Indicates stack executability. + PT_GNU_RELRO = 0x6474e552, // Read-only after relocation. + PT_HIOS = 0x6fffffff, // Highest operating system-specific pt entry type. PT_LOPROC = 0x70000000, // Lowest processor-specific program hdr entry type. PT_HIPROC = 0x7fffffff // Highest processor-specific program hdr entry type. @@ -1187,7 +1192,16 @@ enum { DT_LOOS = 0x60000000, // Start of environment specific tags. DT_HIOS = 0x6FFFFFFF, // End of environment specific tags. DT_LOPROC = 0x70000000, // Start of processor specific tags. - DT_HIPROC = 0x7FFFFFFF // End of processor specific tags. + DT_HIPROC = 0x7FFFFFFF, // End of processor specific tags. + + DT_RELACOUNT = 0x6FFFFFF9, // ELF32_Rela count. + DT_RELCOUNT = 0x6FFFFFFA, // ELF32_Rel count. + + DT_FLAGS_1 = 0X6FFFFFFB, // Flags_1. + 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. + DT_VERNEEDNUM = 0X6FFFFFFF // The number of entries in DT_VERNEED. }; // DT_FLAGS values. @@ -1199,6 +1213,27 @@ enum { DF_STATIC_TLS = 0x10 // Reject attempts to load dynamically. }; +// State flags selectable in the `d_un.d_val' element of the DT_FLAGS_1 entry. +enum { + DF_1_NOW = 0x00000001, // Set RTLD_NOW for this object. + DF_1_GLOBAL = 0x00000002, // Set RTLD_GLOBAL for this object. + DF_1_GROUP = 0x00000004, // Set RTLD_GROUP for this object. + DF_1_NODELETE = 0x00000008, // Set RTLD_NODELETE for this object. + DF_1_LOADFLTR = 0x00000010, // Trigger filtee loading at runtime. + DF_1_INITFIRST = 0x00000020, // Set RTLD_INITFIRST for this object. + DF_1_NOOPEN = 0x00000040, // Set RTLD_NOOPEN for this object. + DF_1_ORIGIN = 0x00000080, // $ORIGIN must be handled. + DF_1_DIRECT = 0x00000100, // Direct binding enabled. + DF_1_TRANS = 0x00000200, + DF_1_INTERPOSE = 0x00000400, // Object is used to interpose. + DF_1_NODEFLIB = 0x00000800, // Ignore default lib search path. + DF_1_NODUMP = 0x00001000, // Object can't be dldump'ed. + DF_1_CONFALT = 0x00002000, // Configuration alternative created. + DF_1_ENDFILTEE = 0x00004000, // Filtee terminates filters search. + DF_1_DISPRELDNE = 0x00008000, // Disp reloc applied at build time. + DF_1_DISPRELPND = 0x00010000 // Disp reloc applied at run-time. +}; + // ElfXX_VerDef structure version (GNU versioning) enum { VER_DEF_NONE = 0, diff --git a/include/llvm/Support/FileOutputBuffer.h b/include/llvm/Support/FileOutputBuffer.h new file mode 100644 index 0000000000..0f07164eb8 --- /dev/null +++ b/include/llvm/Support/FileOutputBuffer.h @@ -0,0 +1,97 @@ +//=== FileOutputBuffer.h - File Output Buffer -------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Utility for creating a in-memory buffer that will be written to a file. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_FILEOUTPUTBUFFER_H +#define LLVM_SUPPORT_FILEOUTPUTBUFFER_H + +#include "llvm/ADT/SmallString.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/DataTypes.h" + +namespace llvm { + +class error_code; +template<class T> class OwningPtr; + +/// FileOutputBuffer - This interface provides simple way to create an in-memory +/// buffer which will be written to a file. During the lifetime of these +/// objects, the content or existence of the specified file is undefined. That +/// is, creating an OutputBuffer for a file may immediately remove the file. +/// If the FileOutputBuffer is committed, the target file's content will become +/// the buffer content at the time of the commit. If the FileOutputBuffer is +/// not committed, the file will be deleted in the FileOutputBuffer destructor. +class FileOutputBuffer { +public: + + enum { + F_executable = 1 /// set the 'x' bit on the resulting file + }; + + /// Factory method to create an OutputBuffer object which manages a read/write + /// buffer of the specified size. When committed, the buffer will be written + /// to the file at the specified path. + static error_code create(StringRef FilePath, size_t Size, + OwningPtr<FileOutputBuffer> &Result, + unsigned Flags=0); + + + /// Returns a pointer to the start of the buffer. + uint8_t *getBufferStart() const { + return BufferStart; + } + + /// Returns a pointer to the end of the buffer. + uint8_t *getBufferEnd() const { + return BufferEnd; + } + + /// Returns size of the buffer. + size_t getBufferSize() const { + return BufferEnd - BufferStart; + } + + /// Returns path where file will show up if buffer is committed. + StringRef getPath() const { + return FinalPath; + } + + /// Flushes the content of the buffer to its file and deallocates the + /// buffer. If commit() is not called before this object's destructor + /// is called, the file is deleted in the destructor. The optional parameter + /// is used if it turns out you want the file size to be smaller than + /// initially requested. + error_code commit(int64_t NewSmallerSize = -1); + + /// If this object was previously committed, the destructor just deletes + /// this object. If this object was not committed, the destructor + /// deallocates the buffer and the target file is never written. + ~FileOutputBuffer(); + + +protected: + FileOutputBuffer(const FileOutputBuffer &); // DO NOT IMPLEMENT + FileOutputBuffer &operator=(const FileOutputBuffer &); // DO NOT IMPLEMENT + FileOutputBuffer(uint8_t *Start, uint8_t *End, + StringRef Path, StringRef TempPath); + + uint8_t *BufferStart; + uint8_t *BufferEnd; + SmallString<128> FinalPath; + SmallString<128> TempPath; +}; + + + +} // end namespace llvm + +#endif diff --git a/include/llvm/Support/FileSystem.h b/include/llvm/Support/FileSystem.h index 4eb75c47bc..f4a9aa0e89 100644 --- a/include/llvm/Support/FileSystem.h +++ b/include/llvm/Support/FileSystem.h @@ -28,6 +28,7 @@ #define LLVM_SUPPORT_FILE_SYSTEM_H #include "llvm/ADT/IntrusiveRefCntPtr.h" +#include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/DataTypes.h" @@ -576,6 +577,82 @@ error_code FindLibrary(const Twine &short_name, SmallVectorImpl<char> &result); error_code GetMainExecutable(const char *argv0, void *MainAddr, SmallVectorImpl<char> &result); +/// This class represents a memory mapped file. It is based on +/// boost::iostreams::mapped_file. +class mapped_file_region { + mapped_file_region() LLVM_DELETED_FUNCTION; + mapped_file_region(mapped_file_region&) LLVM_DELETED_FUNCTION; + mapped_file_region &operator =(mapped_file_region&) LLVM_DELETED_FUNCTION; + +public: + enum mapmode { + readonly, //< May only access map via const_data as read only. + readwrite, //< May access map via data and modify it. Written to path. + priv //< May modify via data, but changes are lost on destruction. + }; + +private: + /// Platform specific mapping state. + mapmode Mode; + uint64_t Size; + void *Mapping; +#if LLVM_ON_WIN32 + int FileDescriptor; + void *FileHandle; + void *FileMappingHandle; +#endif + + error_code init(int FD, uint64_t Offset); + +public: + typedef char char_type; + +#if LLVM_USE_RVALUE_REFERENCES + mapped_file_region(mapped_file_region&&); + mapped_file_region &operator =(mapped_file_region&&); +#endif + + /// Construct a mapped_file_region at \a path starting at \a offset of length + /// \a length and with access \a mode. + /// + /// \param path Path to the file to map. If it does not exist it will be + /// created. + /// \param mode How to map the memory. + /// \param length Number of bytes to map in starting at \a offset. If the file + /// is shorter than this, it will be extended. If \a length is + /// 0, the entire file will be mapped. + /// \param offset Byte offset from the beginning of the file where the map + /// 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. + mapped_file_region(const Twine &path, + mapmode mode, + uint64_t length, + uint64_t offset, + error_code &ec); + + /// \param fd An open file descriptor to map. mapped_file_region takes + /// ownership. It must have been opended in the correct mode. + mapped_file_region(int fd, + mapmode mode, + uint64_t length, + uint64_t offset, + error_code &ec); + + ~mapped_file_region(); + + mapmode flags() const; + uint64_t size() const; + char *data() const; + + /// Get a const view of the data. Modifying this memory has undefined + /// behaivor. + const char *const_data() const; + + /// \returns The minimum alignment offset must be. + static int alignment(); +}; /// @brief Memory maps the contents of a file /// @@ -583,7 +660,7 @@ error_code GetMainExecutable(const char *argv0, void *MainAddr, /// @param file_offset Byte offset in file where mapping should begin. /// @param size_t Byte length of range of the file to map. /// @param map_writable If true, the file will be mapped in r/w such -/// that changes to the the mapped buffer will be flushed back +/// that changes to the mapped buffer will be flushed back /// to the file. If false, the file will be mapped read-only /// and the buffer will be read-only. /// @param result Set to the start address of the mapped buffer. diff --git a/include/llvm/Support/GCOV.h b/include/llvm/Support/GCOV.h index 49cd87fc7b..19e1ce89cb 100644 --- a/include/llvm/Support/GCOV.h +++ b/include/llvm/Support/GCOV.h @@ -63,8 +63,8 @@ public: bool readFunctionTag() { StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4); if (Tag.empty() || - Tag[0] != '\0' || Tag[1] != '\0' || - Tag[2] != '\0' || Tag[3] != '\1') { + Tag[0] != '\0' || Tag[1] != '\0' || + Tag[2] != '\0' || Tag[3] != '\1') { return false; } Cursor += 4; @@ -76,8 +76,8 @@ public: bool readBlockTag() { StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4); if (Tag.empty() || - Tag[0] != '\0' || Tag[1] != '\0' || - Tag[2] != '\x41' || Tag[3] != '\x01') { + Tag[0] != '\0' || Tag[1] != '\0' || + Tag[2] != '\x41' || Tag[3] != '\x01') { return false; } Cursor += 4; @@ -89,8 +89,8 @@ public: bool readEdgeTag() { StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4); if (Tag.empty() || - Tag[0] != '\0' || Tag[1] != '\0' || - Tag[2] != '\x43' || Tag[3] != '\x01') { + Tag[0] != '\0' || Tag[1] != '\0' || + Tag[2] != '\x43' || Tag[3] != '\x01') { return false; } Cursor += 4; @@ -102,8 +102,8 @@ public: bool readLineTag() { StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4); if (Tag.empty() || - Tag[0] != '\0' || Tag[1] != '\0' || - Tag[2] != '\x45' || Tag[3] != '\x01') { + Tag[0] != '\0' || Tag[1] != '\0' || + Tag[2] != '\x45' || Tag[3] != '\x01') { return false; } Cursor += 4; @@ -115,8 +115,8 @@ public: bool readArcTag() { StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4); if (Tag.empty() || - Tag[0] != '\0' || Tag[1] != '\0' || - Tag[2] != '\xa1' || Tag[3] != '\1') { + Tag[0] != '\0' || Tag[1] != '\0' || + Tag[2] != '\xa1' || Tag[3] != '\1') { return false; } Cursor += 4; diff --git a/include/llvm/Support/GraphWriter.h b/include/llvm/Support/GraphWriter.h index ae32da59dc..f178b0caa8 100644 --- a/include/llvm/Support/GraphWriter.h +++ b/include/llvm/Support/GraphWriter.h @@ -172,7 +172,7 @@ public: // If we should include the address of the node in the label, do so now. if (DTraits.hasNodeAddressLabel(Node, G)) - O << "|" << (void*)Node; + O << "|" << static_cast<const void*>(Node); } std::string edgeSourceLabels; @@ -192,7 +192,7 @@ public: // If we should include the address of the node in the label, do so now. if (DTraits.hasNodeAddressLabel(Node, G)) - O << "|" << (void*)Node; + O << "|" << static_cast<const void*>(Node); } if (DTraits.hasEdgeDestLabels()) { diff --git a/include/llvm/Support/InstVisitor.h b/include/llvm/Support/InstVisitor.h index 52de8f660d..109b3cff85 100644 --- a/include/llvm/Support/InstVisitor.h +++ b/include/llvm/Support/InstVisitor.h @@ -13,6 +13,8 @@ #include "llvm/Function.h" #include "llvm/Instructions.h" +#include "llvm/Intrinsics.h" +#include "llvm/IntrinsicInst.h" #include "llvm/Module.h" #include "llvm/Support/CallSite.h" #include "llvm/Support/ErrorHandling.h" @@ -145,14 +147,17 @@ public: // visitMul to proxy to visitBinaryOperator for instance in case the user does // not need this generality. // - // The one problem case we have to handle here though is that the PHINode - // class and opcode name are the exact same. Because of this, we cannot - // define visitPHINode (the inst version) to forward to visitPHINode (the - // generic version) without multiply defined symbols and recursion. To handle - // this, we do not autoexpand "Other" instructions, we do it manually. - // + // These functions can also implement fan-out, when a single opcode and + // instruction have multiple more specific Instruction subclasses. The Call + // instruction currently supports this. We implement that by redirecting that + // instruction to a special delegation helper. #define HANDLE_INST(NUM, OPCODE, CLASS) \ - RetTy visit##OPCODE(CLASS &I) { DELEGATE(CLASS); } + RetTy visit##OPCODE(CLASS &I) { \ + if (NUM == Instruction::Call) \ + return delegateCallInst(I); \ + else \ + DELEGATE(CLASS); \ + } #include "llvm/Instruction.def" // Specific Instruction type classes... note that all of the casts are @@ -195,6 +200,17 @@ public: RetTy visitInsertValueInst(InsertValueInst &I) { DELEGATE(Instruction); } RetTy visitLandingPadInst(LandingPadInst &I) { DELEGATE(Instruction); } + // Handle the special instrinsic instruction classes. + RetTy visitDbgDeclareInst(DbgDeclareInst &I) { DELEGATE(DbgInfoIntrinsic);} + RetTy visitDbgValueInst(DbgValueInst &I) { DELEGATE(DbgInfoIntrinsic);} + RetTy visitDbgInfoIntrinsic(DbgInfoIntrinsic &I) { DELEGATE(IntrinsicInst); } + RetTy visitMemSetInst(MemSetInst &I) { DELEGATE(MemIntrinsic); } + RetTy visitMemCpyInst(MemCpyInst &I) { DELEGATE(MemTransferInst); } + RetTy visitMemMoveInst(MemMoveInst &I) { DELEGATE(MemTransferInst); } + RetTy visitMemTransferInst(MemTransferInst &I) { DELEGATE(MemIntrinsic); } + RetTy visitMemIntrinsic(MemIntrinsic &I) { DELEGATE(IntrinsicInst); } + RetTy visitIntrinsicInst(IntrinsicInst &I) { DELEGATE(CallInst); } + // Call and Invoke are slightly different as they delegate first through // a generic CallSite visitor. RetTy visitCallInst(CallInst &I) { @@ -234,6 +250,29 @@ public: // Note that you MUST override this function if your return type is not void. // void visitInstruction(Instruction &I) {} // Ignore unhandled instructions + +private: + // Special helper function to delegate to CallInst subclass visitors. + RetTy delegateCallInst(CallInst &I) { + if (const Function *F = I.getCalledFunction()) { + switch ((Intrinsic::ID)F->getIntrinsicID()) { + default: DELEGATE(IntrinsicInst); + case Intrinsic::dbg_declare: DELEGATE(DbgDeclareInst); + case Intrinsic::dbg_value: DELEGATE(DbgValueInst); + case Intrinsic::memcpy: DELEGATE(MemCpyInst); + case Intrinsic::memmove: DELEGATE(MemMoveInst); + case Intrinsic::memset: DELEGATE(MemSetInst); + case Intrinsic::not_intrinsic: break; + } + } + DELEGATE(CallInst); + } + + // An overload that will never actually be called, it is used only from dead + // code in the dispatching from opcodes to instruction subclasses. + RetTy delegateCallInst(Instruction &I) { + llvm_unreachable("delegateCallInst called for non-CallInst"); + } }; #undef DELEGATE diff --git a/include/llvm/Support/IntegersSubsetMapping.h b/include/llvm/Support/IntegersSubsetMapping.h index 87d0755c51..cab18dce15 100644 --- a/include/llvm/Support/IntegersSubsetMapping.h +++ b/include/llvm/Support/IntegersSubsetMapping.h @@ -213,7 +213,7 @@ protected: } } - void onRLOpen(const IntTy &Pt, + void onLROpen(const IntTy &Pt, SuccessorClass *LS, SuccessorClass *RS) { switch (State) { @@ -229,7 +229,7 @@ protected: OpenPt = Pt; } - void onRLClose(const IntTy &Pt) { + void onLRClose(const IntTy &Pt) { switch (State) { case INTERSECT_OPENED: if (IntersectionMapping) @@ -256,11 +256,17 @@ public: 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; @@ -274,6 +280,33 @@ public: } 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) @@ -340,6 +373,11 @@ public: 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); @@ -348,6 +386,34 @@ public: /// 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, @@ -377,7 +443,7 @@ public: ++R; continue; } - + if (LRange.getLow() < RRange.getLow()) { // May be opened in previous iteration. if (!Machine.isLOpened()) @@ -390,7 +456,7 @@ public: Machine.onLOpen(LRange.getLow(), LCluster.second); } else - Machine.onRLOpen(LRange.getLow(), LCluster.second, RCluster.second); + Machine.onLROpen(LRange.getLow(), LCluster.second, RCluster.second); if (LRange.getHigh() < RRange.getHigh()) { Machine.onLClose(LRange.getHigh()); @@ -411,7 +477,7 @@ public: } } else { - Machine.onRLClose(LRange.getHigh()); + Machine.onLRClose(LRange.getHigh()); ++L; ++R; } @@ -441,7 +507,20 @@ public: } /// Builds the finalized case objects. - void getCases(Cases& TheCases) { + 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); @@ -458,6 +537,22 @@ public: 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(); } diff --git a/include/llvm/Support/LEB128.h b/include/llvm/Support/LEB128.h new file mode 100644 index 0000000000..410edd4dc7 --- /dev/null +++ b/include/llvm/Support/LEB128.h @@ -0,0 +1,95 @@ +//===- llvm/Support/LEB128.h - [SU]LEB128 utility functions -----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file declares some utility functions for encoding SLEB128 and +// ULEB128 values. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SYSTEM_LEB128_H +#define LLVM_SYSTEM_LEB128_H + +#include <llvm/Support/raw_ostream.h> + +namespace llvm { + +/// Utility function to encode a SLEB128 value to an output stream. +static inline void encodeSLEB128(int64_t Value, raw_ostream &OS) { + bool More; + do { + uint8_t Byte = Value & 0x7f; + // NOTE: this assumes that this signed shift is an arithmetic right shift. + Value >>= 7; + More = !((((Value == 0 ) && ((Byte & 0x40) == 0)) || + ((Value == -1) && ((Byte & 0x40) != 0)))); + if (More) + Byte |= 0x80; // Mark this byte that that more bytes will follow. + OS << char(Byte); + } while (More); +} + +/// Utility function to encode a ULEB128 value to an output stream. +static inline void encodeULEB128(uint64_t Value, raw_ostream &OS, + unsigned Padding = 0) { + do { + uint8_t Byte = Value & 0x7f; + Value >>= 7; + if (Value != 0 || Padding != 0) + Byte |= 0x80; // Mark this byte that that more bytes will follow. + OS << char(Byte); + } while (Value != 0); + + // Pad with 0x80 and emit a null byte at the end. + if (Padding != 0) { + for (; Padding != 1; --Padding) + OS << '\x80'; + OS << '\x00'; + } +} + +/// Utility function to encode a ULEB128 value to a buffer. Returns +/// the length in bytes of the encoded value. +static inline unsigned encodeULEB128(uint64_t Value, uint8_t *p, + unsigned Padding = 0) { + uint8_t *orig_p = p; + do { + uint8_t Byte = Value & 0x7f; + Value >>= 7; + if (Value != 0 || Padding != 0) + Byte |= 0x80; // Mark this byte that that more bytes will follow. + *p++ = Byte; + } while (Value != 0); + + // Pad with 0x80 and emit a null byte at the end. + if (Padding != 0) { + for (; Padding != 1; --Padding) + *p++ = '\x80'; + *p++ = '\x00'; + } + return (unsigned)(p - orig_p); +} + + +/// Utility function to decode a ULEB128 value. +static inline uint64_t decodeULEB128(const uint8_t *p, unsigned *n = 0) { + const uint8_t *orig_p = p; + uint64_t Value = 0; + unsigned Shift = 0; + do { + Value += (*p & 0x7f) << Shift; + Shift += 7; + } while (*p++ >= 128); + if (n) + *n = (unsigned)(p - orig_p); + return Value; +} + +} // namespace llvm + +#endif // LLVM_SYSTEM_LEB128_H diff --git a/include/llvm/Support/MDBuilder.h b/include/llvm/Support/MDBuilder.h deleted file mode 100644 index 855e58d699..0000000000 --- a/include/llvm/Support/MDBuilder.h +++ /dev/null @@ -1,141 +0,0 @@ -//===---- llvm/Support/MDBuilder.h - Builder for LLVM metadata --*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the MDBuilder class, which is used as a convenient way to -// create LLVM metadata with a consistent and simplified interface. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_SUPPORT_MDBUILDER_H -#define LLVM_SUPPORT_MDBUILDER_H - -#include "llvm/Constants.h" -#include "llvm/DerivedTypes.h" -#include "llvm/LLVMContext.h" -#include "llvm/Metadata.h" -#include "llvm/ADT/APInt.h" - -namespace llvm { - - class MDBuilder { - LLVMContext &Context; - - public: - MDBuilder(LLVMContext &context) : Context(context) {} - - /// \brief Return the given string as metadata. - MDString *createString(StringRef Str) { - return MDString::get(Context, Str); - } - - //===------------------------------------------------------------------===// - // FPMath metadata. - //===------------------------------------------------------------------===// - - /// \brief Return metadata with the given settings. The special value 0.0 - /// for the Accuracy parameter indicates the default (maximal precision) - /// setting. - MDNode *createFPMath(float Accuracy) { - if (Accuracy == 0.0) - return 0; - assert(Accuracy > 0.0 && "Invalid fpmath accuracy!"); - Value *Op = ConstantFP::get(Type::getFloatTy(Context), Accuracy); - return MDNode::get(Context, Op); - } - - //===------------------------------------------------------------------===// - // Prof metadata. - //===------------------------------------------------------------------===// - - /// \brief Return metadata containing two branch weights. - MDNode *createBranchWeights(uint32_t TrueWeight, uint32_t FalseWeight) { - uint32_t Weights[] = { TrueWeight, FalseWeight }; - return createBranchWeights(Weights); - } - - /// \brief Return metadata containing a number of branch weights. - MDNode *createBranchWeights(ArrayRef<uint32_t> Weights) { - assert(Weights.size() >= 2 && "Need at least two branch weights!"); - - SmallVector<Value *, 4> Vals(Weights.size()+1); - Vals[0] = createString("branch_weights"); - - Type *Int32Ty = Type::getInt32Ty(Context); - for (unsigned i = 0, e = Weights.size(); i != e; ++i) - Vals[i+1] = ConstantInt::get(Int32Ty, Weights[i]); - - return MDNode::get(Context, Vals); - } - - //===------------------------------------------------------------------===// - // Range metadata. - //===------------------------------------------------------------------===// - - /// \brief Return metadata describing the range [Lo, Hi). - MDNode *createRange(const APInt &Lo, const APInt &Hi) { - assert(Lo.getBitWidth() == Hi.getBitWidth() && "Mismatched bitwidths!"); - // If the range is everything then it is useless. - if (Hi == Lo) - return 0; - - // Return the range [Lo, Hi). - Type *Ty = IntegerType::get(Context, Lo.getBitWidth()); - Value *Range[2] = { ConstantInt::get(Ty, Lo), ConstantInt::get(Ty, Hi) }; - return MDNode::get(Context, Range); - } - - - //===------------------------------------------------------------------===// - // TBAA metadata. - //===------------------------------------------------------------------===// - - /// \brief Return metadata appropriate for a TBAA root node. Each returned - /// node is distinct from all other metadata and will never be identified - /// (uniqued) with anything else. - MDNode *createAnonymousTBAARoot() { - // To ensure uniqueness the root node is self-referential. - MDNode *Dummy = MDNode::getTemporary(Context, ArrayRef<Value*>()); - MDNode *Root = MDNode::get(Context, Dummy); - // At this point we have - // !0 = metadata !{} <- dummy - // !1 = metadata !{metadata !0} <- root - // Replace the dummy operand with the root node itself and delete the dummy. - Root->replaceOperandWith(0, Root); - MDNode::deleteTemporary(Dummy); - // We now have - // !1 = metadata !{metadata !1} <- self-referential root - return Root; - } - - /// \brief Return metadata appropriate for a TBAA root node with the given - /// name. This may be identified (uniqued) with other roots with the same - /// name. - MDNode *createTBAARoot(StringRef Name) { - return MDNode::get(Context, createString(Name)); - } - - /// \brief Return metadata for a non-root TBAA node with the given name, - /// parent in the TBAA tree, and value for 'pointsToConstantMemory'. - MDNode *createTBAANode(StringRef Name, MDNode *Parent, - bool isConstant = false) { - if (isConstant) { - Constant *Flags = ConstantInt::get(Type::getInt64Ty(Context), 1); - Value *Ops[3] = { createString(Name), Parent, Flags }; - return MDNode::get(Context, Ops); - } else { - Value *Ops[2] = { createString(Name), Parent }; - return MDNode::get(Context, Ops); - } - } - - }; - -} // end namespace llvm - -#endif diff --git a/include/llvm/Support/MachO.h b/include/llvm/Support/MachO.h index 44a7a791c5..7f28c3f500 100644 --- a/include/llvm/Support/MachO.h +++ b/include/llvm/Support/MachO.h @@ -174,50 +174,50 @@ namespace llvm { RebaseTypePointer = 1u, // REBASE_TYPE_POINTER RebaseTypeTextAbsolute32 = 2u, // REBASE_TYPE_TEXT_ABSOLUTE32 - RebaseTypeTextPCRelative32 = 3u, // REBASE_TYPE_TEXT_PCREL32 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 @@ -227,7 +227,7 @@ namespace llvm { // Constant masks for the "n_type" field in llvm::MachO::nlist and // llvm::MachO::nlist_64 NlistMaskStab = 0xe0, // N_STAB - NlistMaskPrivateExternal = 0x10, // N_PEXT + NlistMaskPrivateExternal = 0x10, // N_PEXT NlistMaskType = 0x0e, // N_TYPE NlistMaskExternal = 0x01, // N_EXT @@ -249,35 +249,35 @@ namespace llvm { // 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 + 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 + 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 + 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 + 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 }; @@ -490,12 +490,12 @@ namespace llvm { uint32_t nextrel; uint32_t locreloff; uint32_t nlocrel; - }; + }; struct dylib_table_of_contents { uint32_t symbol_index; uint32_t module_index; - }; + }; struct dylib_module { uint32_t module_name; @@ -511,7 +511,7 @@ namespace llvm { uint32_t ninit_nterm; uint32_t objc_module_info_addr; uint32_t objc_module_info_size; - }; + }; struct dylib_module_64 { uint32_t module_name; diff --git a/include/llvm/Support/NoFolder.h b/include/llvm/Support/NoFolder.h index 75c1a79265..8e41a64b17 100644 --- a/include/llvm/Support/NoFolder.h +++ b/include/llvm/Support/NoFolder.h @@ -181,6 +181,12 @@ public: ArrayRef<Constant *> IdxList) const { return ConstantExpr::getGetElementPtr(C, IdxList); } + Constant *CreateGetElementPtr(Constant *C, Constant *Idx) const { + // This form of the function only exists to avoid ambiguous overload + // warnings about whether to convert Idx to ArrayRef<Constant *> or + // ArrayRef<Value *>. + return ConstantExpr::getGetElementPtr(C, Idx); + } Instruction *CreateGetElementPtr(Constant *C, ArrayRef<Value *> IdxList) const { return GetElementPtrInst::Create(C, IdxList); @@ -190,6 +196,12 @@ public: ArrayRef<Constant *> IdxList) const { return ConstantExpr::getInBoundsGetElementPtr(C, IdxList); } + Constant *CreateInBoundsGetElementPtr(Constant *C, Constant *Idx) const { + // This form of the function only exists to avoid ambiguous overload + // warnings about whether to convert Idx to ArrayRef<Constant *> or + // ArrayRef<Value *>. + return ConstantExpr::getInBoundsGetElementPtr(C, Idx); + } Instruction *CreateInBoundsGetElementPtr(Constant *C, ArrayRef<Value *> IdxList) const { return GetElementPtrInst::CreateInBounds(C, IdxList); diff --git a/include/llvm/Support/Process.h b/include/llvm/Support/Process.h index 91b92788f2..088897c903 100644 --- a/include/llvm/Support/Process.h +++ b/include/llvm/Support/Process.h @@ -97,6 +97,10 @@ namespace sys { /// the user rather than being put on a pipe or stored in a file. static bool FileDescriptorIsDisplayed(int fd); + /// This function determines if the given file descriptor is displayd and + /// supports colors. + static bool FileDescriptorHasColors(int fd); + /// This function determines the number of columns in the window /// if standard output is connected to a "tty" or "console" /// window. If standard output is not connected to a tty or diff --git a/include/llvm/Support/SMLoc.h b/include/llvm/Support/SMLoc.h index 7e0811a1af..1bf810b4aa 100644 --- a/include/llvm/Support/SMLoc.h +++ b/include/llvm/Support/SMLoc.h @@ -24,7 +24,6 @@ class SMLoc { const char *Ptr; public: SMLoc() : Ptr(0) {} - SMLoc(const SMLoc &RHS) : Ptr(RHS.Ptr) {} bool isValid() const { return Ptr != 0; } diff --git a/include/llvm/Support/TypeBuilder.h b/include/llvm/Support/TypeBuilder.h deleted file mode 100644 index c75606917c..0000000000 --- a/include/llvm/Support/TypeBuilder.h +++ /dev/null @@ -1,399 +0,0 @@ -//===---- llvm/Support/TypeBuilder.h - Builder for LLVM types ---*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the TypeBuilder class, which is used as a convenient way to -// create LLVM types with a consistent and simplified interface. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_SUPPORT_TYPEBUILDER_H -#define LLVM_SUPPORT_TYPEBUILDER_H - -#include "llvm/DerivedTypes.h" -#include "llvm/LLVMContext.h" -#include <limits.h> - -namespace llvm { - -/// TypeBuilder - This provides a uniform API for looking up types -/// known at compile time. To support cross-compilation, we define a -/// series of tag types in the llvm::types namespace, like i<N>, -/// ieee_float, ppc_fp128, etc. TypeBuilder<T, false> allows T to be -/// any of these, a native C type (whose size may depend on the host -/// compiler), or a pointer, function, or struct type built out of -/// these. TypeBuilder<T, true> removes native C types from this set -/// to guarantee that its result is suitable for cross-compilation. -/// We define the primitive types, pointer types, and functions up to -/// 5 arguments here, but to use this class with your own types, -/// you'll need to specialize it. For example, say you want to call a -/// function defined externally as: -/// -/// struct MyType { -/// int32 a; -/// int32 *b; -/// void *array[1]; // Intended as a flexible array. -/// }; -/// int8 AFunction(struct MyType *value); -/// -/// You'll want to use -/// Function::Create(TypeBuilder<types::i<8>(MyType*), true>::get(), ...) -/// to declare the function, but when you first try this, your compiler will -/// complain that TypeBuilder<MyType, true>::get() doesn't exist. To fix this, -/// write: -/// -/// namespace llvm { -/// template<bool xcompile> class TypeBuilder<MyType, xcompile> { -/// public: -/// static StructType *get(LLVMContext &Context) { -/// // If you cache this result, be sure to cache it separately -/// // for each LLVMContext. -/// return StructType::get( -/// TypeBuilder<types::i<32>, xcompile>::get(Context), -/// TypeBuilder<types::i<32>*, xcompile>::get(Context), -/// TypeBuilder<types::i<8>*[], xcompile>::get(Context), -/// NULL); -/// } -/// -/// // You may find this a convenient place to put some constants -/// // to help with getelementptr. They don't have any effect on -/// // the operation of TypeBuilder. -/// enum Fields { -/// FIELD_A, -/// FIELD_B, -/// FIELD_ARRAY -/// }; -/// } -/// } // namespace llvm -/// -/// TypeBuilder cannot handle recursive types or types you only know at runtime. -/// If you try to give it a recursive type, it will deadlock, infinitely -/// recurse, or do something similarly undesirable. -template<typename T, bool cross_compilable> class TypeBuilder {}; - -// Types for use with cross-compilable TypeBuilders. These correspond -// exactly with an LLVM-native type. -namespace types { -/// i<N> corresponds to the LLVM IntegerType with N bits. -template<uint32_t num_bits> class i {}; - -// The following classes represent the LLVM floating types. -class ieee_float {}; -class ieee_double {}; -class x86_fp80 {}; -class fp128 {}; -class ppc_fp128 {}; -// X86 MMX. -class x86_mmx {}; -} // namespace types - -// LLVM doesn't have const or volatile types. -template<typename T, bool cross> class TypeBuilder<const T, cross> - : public TypeBuilder<T, cross> {}; -template<typename T, bool cross> class TypeBuilder<volatile T, cross> - : public TypeBuilder<T, cross> {}; -template<typename T, bool cross> class TypeBuilder<const volatile T, cross> - : public TypeBuilder<T, cross> {}; - -// Pointers -template<typename T, bool cross> class TypeBuilder<T*, cross> { -public: - static PointerType *get(LLVMContext &Context) { - return PointerType::getUnqual(TypeBuilder<T,cross>::get(Context)); - } -}; - -/// There is no support for references -template<typename T, bool cross> class TypeBuilder<T&, cross> {}; - -// Arrays -template<typename T, size_t N, bool cross> class TypeBuilder<T[N], cross> { -public: - static ArrayType *get(LLVMContext &Context) { - return ArrayType::get(TypeBuilder<T, cross>::get(Context), N); - } -}; -/// LLVM uses an array of length 0 to represent an unknown-length array. -template<typename T, bool cross> class TypeBuilder<T[], cross> { -public: - static ArrayType *get(LLVMContext &Context) { - return ArrayType::get(TypeBuilder<T, cross>::get(Context), 0); - } -}; - -// Define the C integral types only for TypeBuilder<T, false>. -// -// C integral types do not have a defined size. It would be nice to use the -// stdint.h-defined typedefs that do have defined sizes, but we'd run into the -// following problem: -// -// On an ILP32 machine, stdint.h might define: -// -// typedef int int32_t; -// typedef long long int64_t; -// typedef long size_t; -// -// If we defined TypeBuilder<int32_t> and TypeBuilder<int64_t>, then any use of -// TypeBuilder<size_t> would fail. We couldn't define TypeBuilder<size_t> in -// addition to the defined-size types because we'd get duplicate definitions on -// platforms where stdint.h instead defines: -// -// typedef int int32_t; -// typedef long long int64_t; -// typedef int size_t; -// -// So we define all the primitive C types and nothing else. -#define DEFINE_INTEGRAL_TYPEBUILDER(T) \ -template<> class TypeBuilder<T, false> { \ -public: \ - static IntegerType *get(LLVMContext &Context) { \ - return IntegerType::get(Context, sizeof(T) * CHAR_BIT); \ - } \ -}; \ -template<> class TypeBuilder<T, true> { \ - /* We provide a definition here so users don't accidentally */ \ - /* define these types to work. */ \ -} -DEFINE_INTEGRAL_TYPEBUILDER(char); -DEFINE_INTEGRAL_TYPEBUILDER(signed char); -DEFINE_INTEGRAL_TYPEBUILDER(unsigned char); -DEFINE_INTEGRAL_TYPEBUILDER(short); -DEFINE_INTEGRAL_TYPEBUILDER(unsigned short); -DEFINE_INTEGRAL_TYPEBUILDER(int); -DEFINE_INTEGRAL_TYPEBUILDER(unsigned int); -DEFINE_INTEGRAL_TYPEBUILDER(long); -DEFINE_INTEGRAL_TYPEBUILDER(unsigned long); -#ifdef _MSC_VER -DEFINE_INTEGRAL_TYPEBUILDER(__int64); -DEFINE_INTEGRAL_TYPEBUILDER(unsigned __int64); -#else /* _MSC_VER */ -DEFINE_INTEGRAL_TYPEBUILDER(long long); -DEFINE_INTEGRAL_TYPEBUILDER(unsigned long long); -#endif /* _MSC_VER */ -#undef DEFINE_INTEGRAL_TYPEBUILDER - -template<uint32_t num_bits, bool cross> -class TypeBuilder<types::i<num_bits>, cross> { -public: - static IntegerType *get(LLVMContext &C) { - return IntegerType::get(C, num_bits); - } -}; - -template<> class TypeBuilder<float, false> { -public: - static Type *get(LLVMContext& C) { - return Type::getFloatTy(C); - } -}; -template<> class TypeBuilder<float, true> {}; - -template<> class TypeBuilder<double, false> { -public: - static Type *get(LLVMContext& C) { - return Type::getDoubleTy(C); - } -}; -template<> class TypeBuilder<double, true> {}; - -template<bool cross> class TypeBuilder<types::ieee_float, cross> { -public: - static Type *get(LLVMContext& C) { return Type::getFloatTy(C); } -}; -template<bool cross> class TypeBuilder<types::ieee_double, cross> { -public: - static Type *get(LLVMContext& C) { return Type::getDoubleTy(C); } -}; -template<bool cross> class TypeBuilder<types::x86_fp80, cross> { -public: - static Type *get(LLVMContext& C) { return Type::getX86_FP80Ty(C); } -}; -template<bool cross> class TypeBuilder<types::fp128, cross> { -public: - static Type *get(LLVMContext& C) { return Type::getFP128Ty(C); } -}; -template<bool cross> class TypeBuilder<types::ppc_fp128, cross> { -public: - static Type *get(LLVMContext& C) { return Type::getPPC_FP128Ty(C); } -}; -template<bool cross> class TypeBuilder<types::x86_mmx, cross> { -public: - static Type *get(LLVMContext& C) { return Type::getX86_MMXTy(C); } -}; - -template<bool cross> class TypeBuilder<void, cross> { -public: - static Type *get(LLVMContext &C) { - return Type::getVoidTy(C); - } -}; - -/// void* is disallowed in LLVM types, but it occurs often enough in C code that -/// we special case it. -template<> class TypeBuilder<void*, false> - : public TypeBuilder<types::i<8>*, false> {}; -template<> class TypeBuilder<const void*, false> - : public TypeBuilder<types::i<8>*, false> {}; -template<> class TypeBuilder<volatile void*, false> - : public TypeBuilder<types::i<8>*, false> {}; -template<> class TypeBuilder<const volatile void*, false> - : public TypeBuilder<types::i<8>*, false> {}; - -template<typename R, bool cross> class TypeBuilder<R(), cross> { -public: - static FunctionType *get(LLVMContext &Context) { - return FunctionType::get(TypeBuilder<R, cross>::get(Context), false); - } -}; -template<typename R, typename A1, bool cross> class TypeBuilder<R(A1), cross> { -public: - static FunctionType *get(LLVMContext &Context) { - Type *params[] = { - TypeBuilder<A1, cross>::get(Context), - }; - return FunctionType::get(TypeBuilder<R, cross>::get(Context), - params, false); - } -}; -template<typename R, typename A1, typename A2, bool cross> -class TypeBuilder<R(A1, A2), cross> { -public: - static FunctionType *get(LLVMContext &Context) { - Type *params[] = { - TypeBuilder<A1, cross>::get(Context), - TypeBuilder<A2, cross>::get(Context), - }; - return FunctionType::get(TypeBuilder<R, cross>::get(Context), - params, false); - } -}; -template<typename R, typename A1, typename A2, typename A3, bool cross> -class TypeBuilder<R(A1, A2, A3), cross> { -public: - static FunctionType *get(LLVMContext &Context) { - Type *params[] = { - TypeBuilder<A1, cross>::get(Context), - TypeBuilder<A2, cross>::get(Context), - TypeBuilder<A3, cross>::get(Context), - }; - return FunctionType::get(TypeBuilder<R, cross>::get(Context), - params, false); - } -}; - -template<typename R, typename A1, typename A2, typename A3, typename A4, - bool cross> -class TypeBuilder<R(A1, A2, A3, A4), cross> { -public: - static FunctionType *get(LLVMContext &Context) { - Type *params[] = { - TypeBuilder<A1, cross>::get(Context), - TypeBuilder<A2, cross>::get(Context), - TypeBuilder<A3, cross>::get(Context), - TypeBuilder<A4, cross>::get(Context), - }; - return FunctionType::get(TypeBuilder<R, cross>::get(Context), - params, false); - } -}; - -template<typename R, typename A1, typename A2, typename A3, typename A4, - typename A5, bool cross> -class TypeBuilder<R(A1, A2, A3, A4, A5), cross> { -public: - static FunctionType *get(LLVMContext &Context) { - Type *params[] = { - TypeBuilder<A1, cross>::get(Context), - TypeBuilder<A2, cross>::get(Context), - TypeBuilder<A3, cross>::get(Context), - TypeBuilder<A4, cross>::get(Context), - TypeBuilder<A5, cross>::get(Context), - }; - return FunctionType::get(TypeBuilder<R, cross>::get(Context), - params, false); - } -}; - -template<typename R, bool cross> class TypeBuilder<R(...), cross> { -public: - static FunctionType *get(LLVMContext &Context) { - return FunctionType::get(TypeBuilder<R, cross>::get(Context), true); - } -}; -template<typename R, typename A1, bool cross> -class TypeBuilder<R(A1, ...), cross> { -public: - static FunctionType *get(LLVMContext &Context) { - Type *params[] = { - TypeBuilder<A1, cross>::get(Context), - }; - return FunctionType::get(TypeBuilder<R, cross>::get(Context), params, true); - } -}; -template<typename R, typename A1, typename A2, bool cross> -class TypeBuilder<R(A1, A2, ...), cross> { -public: - static FunctionType *get(LLVMContext &Context) { - Type *params[] = { - TypeBuilder<A1, cross>::get(Context), - TypeBuilder<A2, cross>::get(Context), - }; - return FunctionType::get(TypeBuilder<R, cross>::get(Context), - params, true); - } -}; -template<typename R, typename A1, typename A2, typename A3, bool cross> -class TypeBuilder<R(A1, A2, A3, ...), cross> { -public: - static FunctionType *get(LLVMContext &Context) { - Type *params[] = { - TypeBuilder<A1, cross>::get(Context), - TypeBuilder<A2, cross>::get(Context), - TypeBuilder<A3, cross>::get(Context), - }; - return FunctionType::get(TypeBuilder<R, cross>::get(Context), - params, true); - } -}; - -template<typename R, typename A1, typename A2, typename A3, typename A4, - bool cross> -class TypeBuilder<R(A1, A2, A3, A4, ...), cross> { -public: - static FunctionType *get(LLVMContext &Context) { - Type *params[] = { - TypeBuilder<A1, cross>::get(Context), - TypeBuilder<A2, cross>::get(Context), - TypeBuilder<A3, cross>::get(Context), - TypeBuilder<A4, cross>::get(Context), - }; - return FunctionType::get(TypeBuilder<R, cross>::get(Context), - params, true); - } -}; - -template<typename R, typename A1, typename A2, typename A3, typename A4, - typename A5, bool cross> -class TypeBuilder<R(A1, A2, A3, A4, A5, ...), cross> { -public: - static FunctionType *get(LLVMContext &Context) { - Type *params[] = { - TypeBuilder<A1, cross>::get(Context), - TypeBuilder<A2, cross>::get(Context), - TypeBuilder<A3, cross>::get(Context), - TypeBuilder<A4, cross>::get(Context), - TypeBuilder<A5, cross>::get(Context), - }; - return FunctionType::get(TypeBuilder<R, cross>::get(Context), - params, true); - } -}; - -} // namespace llvm - -#endif diff --git a/include/llvm/Support/ValueHandle.h b/include/llvm/Support/ValueHandle.h index 966af39a15..dfa95798b3 100644 --- a/include/llvm/Support/ValueHandle.h +++ b/include/llvm/Support/ValueHandle.h @@ -115,11 +115,12 @@ protected: V != DenseMapInfo<Value *>::getTombstoneKey(); } -private: +public: // Callbacks made from Value. static void ValueIsDeleted(Value *V); static void ValueIsRAUWd(Value *Old, Value *New); +private: // Internal implementation details. ValueHandleBase **getPrevPtr() const { return PrevPair.getPointer(); } HandleBaseKind getKind() const { return PrevPair.getInt(); } diff --git a/include/llvm/Support/raw_ostream.h b/include/llvm/Support/raw_ostream.h index 6c5d4787e0..5de749aeae 100644 --- a/include/llvm/Support/raw_ostream.h +++ b/include/llvm/Support/raw_ostream.h @@ -230,6 +230,9 @@ public: /// rather than being put on a pipe or stored in a file. virtual bool is_displayed() const { return false; } + /// This function determines if this stream is displayed and supports colors. + virtual bool has_colors() const { return is_displayed(); } + //===--------------------------------------------------------------------===// // Subclass Interface //===--------------------------------------------------------------------===// @@ -386,10 +389,12 @@ public: virtual bool is_displayed() const; + virtual bool has_colors() const; + /// has_error - Return the value of the flag in this raw_fd_ostream indicating /// whether an output error has been encountered. /// This doesn't implicitly flush any pending output. Also, it doesn't - /// guarantee to detect all errors unless the the stream has been closed. + /// guarantee to detect all errors unless the stream has been closed. bool has_error() const { return Error; } |