diff options
author | dim <dim@FreeBSD.org> | 2014-03-21 17:53:59 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2014-03-21 17:53:59 +0000 |
commit | 9cedb8bb69b89b0f0c529937247a6a80cabdbaec (patch) | |
tree | c978f0e9ec1ab92dc8123783f30b08a7fd1e2a39 /contrib/llvm/include/llvm/Support | |
parent | 03fdc2934eb61c44c049a02b02aa974cfdd8a0eb (diff) | |
download | FreeBSD-src-9cedb8bb69b89b0f0c529937247a6a80cabdbaec.zip FreeBSD-src-9cedb8bb69b89b0f0c529937247a6a80cabdbaec.tar.gz |
MFC 261991:
Upgrade our copy of llvm/clang to 3.4 release. This version supports
all of the features in the current working draft of the upcoming C++
standard, provisionally named C++1y.
The code generator's performance is greatly increased, and the loop
auto-vectorizer is now enabled at -Os and -O2 in addition to -O3. The
PowerPC backend has made several major improvements to code generation
quality and compile time, and the X86, SPARC, ARM32, Aarch64 and SystemZ
backends have all seen major feature work.
Release notes for llvm and clang can be found here:
<http://llvm.org/releases/3.4/docs/ReleaseNotes.html>
<http://llvm.org/releases/3.4/tools/clang/docs/ReleaseNotes.html>
MFC 262121 (by emaste):
Update lldb for clang/llvm 3.4 import
This commit largely restores the lldb source to the upstream r196259
snapshot with the addition of threaded inferior support and a few bug
fixes.
Specific upstream lldb revisions restored include:
SVN git
181387 779e6ac
181703 7bef4e2
182099 b31044e
182650 f2dcf35
182683 0d91b80
183862 15c1774
183929 99447a6
184177 0b2934b
184948 4dc3761
184954 007e7bc
186990 eebd175
Sponsored by: DARPA, AFRL
MFC 262186 (by emaste):
Fix mismerge in r262121
A break statement was lost in the merge. The error had no functional
impact, but restore it to reduce the diff against upstream.
MFC 262303:
Pull in r197521 from upstream clang trunk (by rdivacky):
Use the integrated assembler by default on FreeBSD/ppc and ppc64.
Requested by: jhibbits
MFC 262611:
Pull in r196874 from upstream llvm trunk:
Fix a crash that occurs when PWD is invalid.
MCJIT needs to be able to run in hostile environments, even when PWD
is invalid. There's no need to crash MCJIT in this case.
The obvious fix is to simply leave MCContext's CompilationDir empty
when PWD can't be determined. This way, MCJIT clients,
and other clients that link with LLVM don't need a valid working directory.
If we do want to guarantee valid CompilationDir, that should be done
only for clients of getCompilationDir(). This is as simple as checking
for an empty string.
The only current use of getCompilationDir is EmitGenDwarfInfo, which
won't conceivably run with an invalid working dir. However, in the
purely hypothetically and untestable case that this happens, the
AT_comp_dir will be omitted from the compilation_unit DIE.
This should help fix assertions occurring with ports-mgmt/tinderbox,
when it is using jails, and sometimes invalidates clang's current
working directory.
Reported by: decke
MFC 262809:
Pull in r203007 from upstream clang trunk:
Don't produce an alias between destructors with different calling conventions.
Fixes pr19007.
(Please note that is an LLVM PR identifier, not a FreeBSD one.)
This should fix Firefox and/or libxul crashes (due to problems with
regparm/stdcall calling conventions) on i386.
Reported by: multiple users on freebsd-current
PR: bin/187103
MFC 263048:
Repair recognition of "CC" as an alias for the C++ compiler, since it
was silently broken by upstream for a Windows-specific use-case.
Apparently some versions of CMake still rely on this archaic feature...
Reported by: rakuco
MFC 263049:
Garbage collect the old way of adding the libstdc++ include directories
in clang's InitHeaderSearch.cpp. This has been superseded by David
Chisnall's commit in r255321.
Moreover, if libc++ is used, the libstdc++ include directories should
not be in the search path at all. These directories are now only used
if you pass -stdlib=libstdc++.
Diffstat (limited to 'contrib/llvm/include/llvm/Support')
60 files changed, 2927 insertions, 3634 deletions
diff --git a/contrib/llvm/include/llvm/Support/Allocator.h b/contrib/llvm/include/llvm/Support/Allocator.h index 3243fd9..397f50f 100644 --- a/contrib/llvm/include/llvm/Support/Allocator.h +++ b/contrib/llvm/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/contrib/llvm/include/llvm/Support/BlockFrequency.h b/contrib/llvm/include/llvm/Support/BlockFrequency.h index 839cf93..21879e7 100644 --- a/contrib/llvm/include/llvm/Support/BlockFrequency.h +++ b/contrib/llvm/include/llvm/Support/BlockFrequency.h @@ -25,20 +25,44 @@ class BranchProbability; class BlockFrequency { uint64_t Frequency; - static const int64_t ENTRY_FREQ = 1024; + static const int64_t ENTRY_FREQ = 1 << 14; + + /// \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) { } + /// \brief Returns the frequency of the entry block of the function. static uint64_t getEntryFrequency() { return ENTRY_FREQ; } + + /// \brief Returns the maximum possible frequency, the saturation value. + static uint64_t getMaxFrequency() { return -1ULL; } + + /// \brief Returns the frequency as a fixpoint number scaled by the entry + /// frequency. uint64_t getFrequency() const { return Frequency; } + /// \brief Multiplies with a branch probability. The computation will never + /// overflow. BlockFrequency &operator*=(const BranchProbability &Prob); const BlockFrequency operator*(const BranchProbability &Prob) const; + /// \brief Divide by a non-zero branch probability using saturating + /// arithmetic. + BlockFrequency &operator/=(const BranchProbability &Prob); + BlockFrequency operator/(const BranchProbability &Prob) const; + + /// \brief Adds another block frequency using saturating arithmetic. 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/contrib/llvm/include/llvm/Support/CFG.h b/contrib/llvm/include/llvm/Support/CFG.h index 265b886..74ec726 100644 --- a/contrib/llvm/include/llvm/Support/CFG.h +++ b/contrib/llvm/include/llvm/Support/CFG.h @@ -240,6 +240,10 @@ inline succ_const_iterator succ_end(const BasicBlock *BB) { return succ_const_iterator(BB->getTerminator(), true); } +template <typename T, typename U> struct isPodLike<SuccIterator<T, U> > { + static const bool value = isPodLike<T>::value; +}; + //===--------------------------------------------------------------------===// @@ -324,7 +328,7 @@ template <> struct GraphTraits<Function*> : public GraphTraits<BasicBlock*> { typedef Function::iterator nodes_iterator; static nodes_iterator nodes_begin(Function *F) { return F->begin(); } static nodes_iterator nodes_end (Function *F) { return F->end(); } - static unsigned size (Function *F) { return F->size(); } + static size_t size (Function *F) { return F->size(); } }; template <> struct GraphTraits<const Function*> : public GraphTraits<const BasicBlock*> { @@ -334,7 +338,7 @@ template <> struct GraphTraits<const Function*> : typedef Function::const_iterator nodes_iterator; static nodes_iterator nodes_begin(const Function *F) { return F->begin(); } static nodes_iterator nodes_end (const Function *F) { return F->end(); } - static unsigned size (const Function *F) { return F->size(); } + static size_t size (const Function *F) { return F->size(); } }; diff --git a/contrib/llvm/include/llvm/Support/COFF.h b/contrib/llvm/include/llvm/Support/COFF.h index 823b43a..9cc3989 100644 --- a/contrib/llvm/include/llvm/Support/COFF.h +++ b/contrib/llvm/include/llvm/Support/COFF.h @@ -30,6 +30,9 @@ namespace llvm { namespace COFF { + // The PE signature bytes that follows the DOS stub header. + static const char PEMagic[] = { 'P', 'E', '\0', '\0' }; + // Sizes in bytes of various things in the COFF format. enum { HeaderSize = 20, @@ -219,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, @@ -448,8 +451,6 @@ namespace COFF { }; struct PEHeader { - uint32_t Signature; - header COFFHeader; uint16_t Magic; uint8_t MajorLinkerVersion; uint8_t MinorLinkerVersion; @@ -487,12 +488,32 @@ namespace COFF { uint32_t Size; }; + enum DataDirectoryIndex { + EXPORT_TABLE = 0, + IMPORT_TABLE, + RESOURCE_TABLE, + EXCEPTION_TABLE, + CERTIFICATE_TABLE, + BASE_RELOCATION_TABLE, + DEBUG, + ARCHITECTURE, + GLOBAL_PTR, + TLS_TABLE, + LOAD_CONFIG_TABLE, + BOUND_IMPORT, + IAT, + DELAY_IMPORT_DESCRIPTOR, + CLR_RUNTIME_HEADER + }; + enum WindowsSubsystem { IMAGE_SUBSYSTEM_UNKNOWN = 0, ///< An unknown subsystem. 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 @@ -500,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/contrib/llvm/include/llvm/Support/CallSite.h b/contrib/llvm/include/llvm/Support/CallSite.h index 92107ac..2a1c5ca 100644 --- a/contrib/llvm/include/llvm/Support/CallSite.h +++ b/contrib/llvm/include/llvm/Support/CallSite.h @@ -78,7 +78,7 @@ public: InstrTy *getInstruction() const { return I.getPointer(); } InstrTy *operator->() const { return I.getPointer(); } - operator bool() const { return I.getPointer(); } + LLVM_EXPLICIT operator bool() const { return I.getPointer(); } /// getCalledValue - Return the pointer to function that is being called. /// @@ -198,6 +198,12 @@ public: CALLSITE_DELEGATE_GETTER(getParamAlignment(i)); } + /// \brief Return true if the call should not be treated as a call to a + /// builtin. + bool isNoBuiltin() const { + CALLSITE_DELEGATE_GETTER(isNoBuiltin()); + } + /// @brief Return true if the call should not be inlined. bool isNoInline() const { CALLSITE_DELEGATE_GETTER(isNoInline()); @@ -251,6 +257,15 @@ public: return paramHasAttr(ArgNo + 1, Attribute::ByVal); } + bool doesNotAccessMemory(unsigned ArgNo) const { + return paramHasAttr(ArgNo + 1, Attribute::ReadNone); + } + + bool onlyReadsMemory(unsigned ArgNo) const { + return paramHasAttr(ArgNo + 1, Attribute::ReadOnly) || + paramHasAttr(ArgNo + 1, Attribute::ReadNone); + } + /// hasArgument - Returns true if this CallSite passes the given Value* as an /// argument to the called function. bool hasArgument(const Value *Arg) const { diff --git a/contrib/llvm/include/llvm/Support/Casting.h b/contrib/llvm/include/llvm/Support/Casting.h index 0d2d6c9..d70acbf 100644 --- a/contrib/llvm/include/llvm/Support/Casting.h +++ b/contrib/llvm/include/llvm/Support/Casting.h @@ -206,7 +206,10 @@ template<class To, class FromTy> struct cast_convert_val<To,FromTy,FromTy> { } }; - +template <class X> struct is_simple_type { + static const bool value = + is_same<X, typename simplify_type<X>::SimpleType>::value; +}; // cast<X> - Return the argument parameter cast to the specified type. This // casting operator asserts that the type is correct, so it does not return null @@ -216,10 +219,12 @@ template<class To, class FromTy> struct cast_convert_val<To,FromTy,FromTy> { // cast<Instruction>(myVal)->getParent() // template <class X, class Y> -inline typename cast_retty<X, const Y>::ret_type cast(const Y &Val) { +inline typename enable_if_c<!is_simple_type<Y>::value, + typename cast_retty<X, const Y>::ret_type>::type +cast(const Y &Val) { assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!"); - return cast_convert_val<X, const Y, - typename simplify_type<const Y>::SimpleType>::doit(Val); + return cast_convert_val< + X, const Y, typename simplify_type<const Y>::SimpleType>::doit(Val); } template <class X, class Y> @@ -230,10 +235,7 @@ inline typename cast_retty<X, Y>::ret_type cast(Y &Val) { } template <class X, class Y> -inline typename enable_if< - is_same<Y, typename simplify_type<Y>::SimpleType>, - typename cast_retty<X, Y*>::ret_type ->::type cast(Y *Val) { +inline typename cast_retty<X, Y *>::ret_type cast(Y *Val) { assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!"); return cast_convert_val<X, Y*, typename simplify_type<Y*>::SimpleType>::doit(Val); @@ -259,7 +261,9 @@ inline typename cast_retty<X, Y*>::ret_type cast_or_null(Y *Val) { // template <class X, class Y> -inline typename cast_retty<X, const Y>::ret_type dyn_cast(const Y &Val) { +inline typename enable_if_c<!is_simple_type<Y>::value, + typename cast_retty<X, const Y>::ret_type>::type +dyn_cast(const Y &Val) { return isa<X>(Val) ? cast<X>(Val) : 0; } @@ -269,10 +273,7 @@ inline typename cast_retty<X, Y>::ret_type dyn_cast(Y &Val) { } template <class X, class Y> -inline typename enable_if< - is_same<Y, typename simplify_type<Y>::SimpleType>, - typename cast_retty<X, Y*>::ret_type ->::type dyn_cast(Y *Val) { +inline typename cast_retty<X, Y *>::ret_type dyn_cast(Y *Val) { return isa<X>(Val) ? cast<X>(Val) : 0; } diff --git a/contrib/llvm/include/llvm/Support/CommandLine.h b/contrib/llvm/include/llvm/Support/CommandLine.h index bfaafda..4efb6a6 100644 --- a/contrib/llvm/include/llvm/Support/CommandLine.h +++ b/contrib/llvm/include/llvm/Support/CommandLine.h @@ -350,6 +350,7 @@ struct cat { struct GenericOptionValue { virtual ~GenericOptionValue() {} virtual bool compare(const GenericOptionValue &V) const = 0; + private: virtual void anchor(); }; @@ -1710,8 +1711,8 @@ void PrintVersionMessage(); /// /// NOTE: THIS FUNCTION TERMINATES THE PROGRAM! /// -/// \param hidden if true will print hidden options -/// \param categorized if true print options in categories +/// \param Hidden if true will print hidden options +/// \param Categorized if true print options in categories void PrintHelpMessage(bool Hidden=false, bool Categorized=false); @@ -1722,7 +1723,7 @@ void PrintHelpMessage(bool Hidden=false, bool Categorized=false); /// \brief Use this to get a StringMap to all registered named options /// (e.g. -help). Note \p Map Should be an empty StringMap. /// -/// \param [out] map will be filled with mappings where the key is the +/// \param [out] Map will be filled with mappings where the key is the /// Option argument string (e.g. "help") and value is the corresponding /// Option*. /// @@ -1747,6 +1748,60 @@ void PrintHelpMessage(bool Hidden=false, bool Categorized=false); /// llvm::cl::ParseCommandLineOptions(). void getRegisteredOptions(StringMap<Option*> &Map); +//===----------------------------------------------------------------------===// +// Standalone command line processing utilities. +// + +/// \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. +}; + +/// \brief Tokenizes a command line that can contain escapes and quotes. +// +/// The quoting rules match those used by GCC and other tools that use +/// libiberty's buildargv() or expandargv() utilities, and do not match bash. +/// They differ from buildargv() on treatment of backslashes that do not escape +/// a special character to make it possible to accept most Windows file paths. +/// +/// \param [in] Source The string to be split on whitespace with quotes. +/// \param [in] Saver Delegates back to the caller for saving parsed strings. +/// \param [out] NewArgv All parsed strings are appended to NewArgv. +void TokenizeGNUCommandLine(StringRef Source, StringSaver &Saver, + SmallVectorImpl<const char *> &NewArgv); + +/// \brief Tokenizes a Windows command line which may contain quotes and escaped +/// quotes. +/// +/// See MSDN docs for CommandLineToArgvW for information on the quoting rules. +/// http://msdn.microsoft.com/en-us/library/windows/desktop/17w5ykft(v=vs.85).aspx +/// +/// \param [in] Source The string to be split on whitespace with quotes. +/// \param [in] Saver Delegates back to the caller for saving parsed strings. +/// \param [out] NewArgv All parsed strings are appended to NewArgv. +void TokenizeWindowsCommandLine(StringRef Source, StringSaver &Saver, + SmallVectorImpl<const char *> &NewArgv); + +/// \brief String tokenization function type. Should be compatible with either +/// Windows or Unix command line tokenizers. +typedef void (*TokenizerCallback)(StringRef Source, StringSaver &Saver, + SmallVectorImpl<const char *> &NewArgv); + +/// \brief Expand response files on a command line recursively using the given +/// StringSaver and tokenization strategy. Argv should contain the command line +/// before expansion and will be modified in place. +/// +/// \param [in] Saver Delegates back to the caller for saving parsed strings. +/// \param [in] Tokenizer Tokenization strategy. Typically Unix or Windows. +/// \param [in,out] Argv Command line into which to expand response files. +/// \return true if all @files were expanded successfully or there were none. +bool ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer, + SmallVectorImpl<const char *> &Argv); + } // End namespace cl } // End namespace llvm diff --git a/contrib/llvm/include/llvm/Support/Compiler.h b/contrib/llvm/include/llvm/Support/Compiler.h index 13d057b..860f43e 100644 --- a/contrib/llvm/include/llvm/Support/Compiler.h +++ b/contrib/llvm/include/llvm/Support/Compiler.h @@ -21,6 +21,25 @@ # define __has_feature(x) 0 #endif +#ifndef __has_attribute +# define __has_attribute(x) 0 +#endif + +#ifndef __has_builtin +# define __has_builtin(x) 0 +#endif + +/// \macro __GNUC_PREREQ +/// \brief Defines __GNUC_PREREQ if glibc's features.h isn't available. +#ifndef __GNUC_PREREQ +# if defined(__GNUC__) && defined(__GNUC_MINOR__) +# define __GNUC_PREREQ(maj, min) \ + ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min)) +# else +# define __GNUC_PREREQ(maj, min) 0 +# endif +#endif + /// \brief Does the compiler support r-value references? /// This implies that <utility> provides the one-argument std::move; it /// does not imply the existence of any other C++ library features. @@ -146,18 +165,26 @@ /// 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 /// functions, making them private to any shared library they are linked into. -#if (__GNUC__ >= 4) && !defined(__MINGW32__) && !defined(__CYGWIN__) +/// On PE/COFF targets, library visibility is the default, so this isn't needed. +#if (__has_attribute(visibility) || __GNUC_PREREQ(4, 0)) && \ + !defined(__MINGW32__) && !defined(__CYGWIN__) && !defined(LLVM_ON_WIN32) #define LLVM_LIBRARY_VISIBILITY __attribute__ ((visibility("hidden"))) #else #define LLVM_LIBRARY_VISIBILITY #endif -#if (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) +#if __has_attribute(used) || __GNUC_PREREQ(3, 1) #define LLVM_ATTRIBUTE_USED __attribute__((__used__)) #else #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. @@ -166,31 +193,37 @@ // more portable solution: // (void)unused_var_name; // Prefer cast-to-void wherever it is sufficient. -#if (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) +#if __has_attribute(unused) || __GNUC_PREREQ(3, 1) #define LLVM_ATTRIBUTE_UNUSED __attribute__((__unused__)) #else #define LLVM_ATTRIBUTE_UNUSED #endif -#if (__GNUC__ >= 4) && !defined(__MINGW32__) && !defined(__CYGWIN__) +// FIXME: Provide this for PE/COFF targets. +#if (__has_attribute(weak) || __GNUC_PREREQ(4, 0)) && \ + (!defined(__MINGW32__) && !defined(__CYGWIN__) && !defined(LLVM_ON_WIN32)) #define LLVM_ATTRIBUTE_WEAK __attribute__((__weak__)) #else #define LLVM_ATTRIBUTE_WEAK #endif -#ifdef __GNUC__ // aka 'CONST' but following LLVM Conventions. +// Prior to clang 3.2, clang did not accept any spelling of +// __has_attribute(const), so assume it is supported. +#if defined(__clang__) || defined(__GNUC__) +// aka 'CONST' but following LLVM Conventions. #define LLVM_READNONE __attribute__((__const__)) #else #define LLVM_READNONE #endif -#ifdef __GNUC__ // aka 'PURE' but following LLVM Conventions. +#if __has_attribute(pure) || defined(__GNUC__) +// aka 'PURE' but following LLVM Conventions. #define LLVM_READONLY __attribute__((__pure__)) #else #define LLVM_READONLY #endif -#if (__GNUC__ >= 4) +#if __has_builtin(__builtin_expect) || __GNUC_PREREQ(4, 0) #define LLVM_LIKELY(EXPR) __builtin_expect((bool)(EXPR), true) #define LLVM_UNLIKELY(EXPR) __builtin_expect((bool)(EXPR), false) #else @@ -213,7 +246,7 @@ /// LLVM_ATTRIBUTE_NOINLINE - On compilers where we have a directive to do so, /// mark a method "not for inlining". -#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) +#if __has_attribute(noinline) || __GNUC_PREREQ(3, 4) #define LLVM_ATTRIBUTE_NOINLINE __attribute__((noinline)) #elif defined(_MSC_VER) #define LLVM_ATTRIBUTE_NOINLINE __declspec(noinline) @@ -225,7 +258,7 @@ /// so, mark a method "always inline" because it is performance sensitive. GCC /// 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 +#if __has_attribute(always_inline) || __GNUC_PREREQ(4, 0) #define LLVM_ATTRIBUTE_ALWAYS_INLINE inline __attribute__((always_inline)) #elif defined(_MSC_VER) #define LLVM_ATTRIBUTE_ALWAYS_INLINE __forceinline @@ -267,8 +300,7 @@ /// LLVM_BUILTIN_UNREACHABLE - On compilers which support it, expands /// to an expression which states that it is undefined behavior for the /// compiler to reach this point. Otherwise is not defined. -#if defined(__clang__) || (__GNUC__ > 4) \ - || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) +#if __has_builtin(__builtin_unreachable) || __GNUC_PREREQ(4, 5) # define LLVM_BUILTIN_UNREACHABLE __builtin_unreachable() #elif defined(_MSC_VER) # define LLVM_BUILTIN_UNREACHABLE __assume(false) @@ -276,8 +308,7 @@ /// 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) +#if __has_builtin(__builtin_trap) || __GNUC_PREREQ(4, 3) # define LLVM_BUILTIN_TRAP __builtin_trap() #else # define LLVM_BUILTIN_TRAP *(volatile int*)0x11 = 0 @@ -285,11 +316,10 @@ /// \macro LLVM_ASSUME_ALIGNED /// \brief Returns a pointer with an assumed alignment. -#if !defined(__clang__) && ((__GNUC__ > 4) \ - || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) -// FIXME: Enable on clang when it supports it. +#if __has_builtin(__builtin_assume_aligned) && __GNUC_PREREQ(4, 7) # define LLVM_ASSUME_ALIGNED(p, a) __builtin_assume_aligned(p, a) #elif defined(LLVM_BUILTIN_UNREACHABLE) +// As of today, clang does not support __builtin_assume_aligned. # define LLVM_ASSUME_ALIGNED(p, a) \ (((uintptr_t(p) % (a)) == 0) ? (p) : (LLVM_BUILTIN_UNREACHABLE, (p))) #else @@ -361,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/contrib/llvm/include/llvm/Support/Compression.h b/contrib/llvm/include/llvm/Support/Compression.h index 9b1142d..bef9146 100644 --- a/contrib/llvm/include/llvm/Support/Compression.h +++ b/contrib/llvm/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/contrib/llvm/include/llvm/Support/ConstantRange.h b/contrib/llvm/include/llvm/Support/ConstantRange.h index 0f29256..f757c6e 100644 --- a/contrib/llvm/include/llvm/Support/ConstantRange.h +++ b/contrib/llvm/include/llvm/Support/ConstantRange.h @@ -42,6 +42,14 @@ namespace llvm { class ConstantRange { APInt Lower, Upper; +#if LLVM_HAS_RVALUE_REFERENCES + // If we have move semantics, pass APInts by value and move them into place. + typedef APInt APIntMoveTy; +#else + // Otherwise pass by const ref to save one copy. + typedef const APInt &APIntMoveTy; +#endif + public: /// Initialize a full (the default) or empty set for the specified bit width. /// @@ -49,12 +57,12 @@ public: /// Initialize a range to hold the single specified value. /// - ConstantRange(const APInt &Value); + ConstantRange(APIntMoveTy Value); /// @brief Initialize a range of values explicitly. This will assert out if /// Lower==Upper and Lower != Min or Max value for its type. It will also /// assert out if the two APInt's are not the same bit width. - ConstantRange(const APInt &Lower, const APInt &Upper); + ConstantRange(APIntMoveTy Lower, APIntMoveTy Upper); /// makeICmpRegion - Produce the smallest range that contains all values that /// might satisfy the comparison specified by Pred when compared to any value diff --git a/contrib/llvm/include/llvm/Support/ConvertUTF.h b/contrib/llvm/include/llvm/Support/ConvertUTF.h index 1eae6d6..2820366 100644 --- a/contrib/llvm/include/llvm/Support/ConvertUTF.h +++ b/contrib/llvm/include/llvm/Support/ConvertUTF.h @@ -87,8 +87,8 @@ ------------------------------------------------------------------------ */ -#ifndef CLANG_BASIC_CONVERTUTF_H -#define CLANG_BASIC_CONVERTUTF_H +#ifndef LLVM_SUPPORT_CONVERTUTF_H +#define LLVM_SUPPORT_CONVERTUTF_H /* --------------------------------------------------------------------- The following 4 definitions are compiler-specific. @@ -112,6 +112,9 @@ typedef unsigned char Boolean; /* 0 or 1 */ #define UNI_MAX_UTF8_BYTES_PER_CODE_POINT 4 +#define UNI_UTF16_BYTE_ORDER_MARK_NATIVE 0xFEFF +#define UNI_UTF16_BYTE_ORDER_MARK_SWAPPED 0xFFFE + typedef enum { conversionOK, /* conversion successful */ sourceExhausted, /* partial character in source, but hit end */ @@ -165,6 +168,7 @@ unsigned getNumBytesForUTF8(UTF8 firstByte); /*************************************************************************/ /* Below are LLVM-specific wrappers of the functions above. */ +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" namespace llvm { @@ -219,6 +223,22 @@ static inline ConversionResult convertUTF8Sequence(const UTF8 **source, return sourceExhausted; return ConvertUTF8toUTF32(source, *source + size, &target, target + 1, flags); } + +/** + * Returns true if a blob of text starts with a UTF-16 big or little endian byte + * order mark. + */ +bool hasUTF16ByteOrderMark(ArrayRef<char> SrcBytes); + +/** + * Converts a stream of raw bytes assumed to be UTF16 into a UTF8 std::string. + * + * \param [in] SrcBytes A buffer of what is assumed to be UTF-16 encoded text. + * \param [out] Out Converted UTF-8 is stored here on success. + * \returns true on success + */ +bool convertUTF16ToUTF8String(ArrayRef<char> SrcBytes, std::string &Out); + } /* end namespace llvm */ #endif diff --git a/contrib/llvm/include/llvm/Support/DataTypes.h.in b/contrib/llvm/include/llvm/Support/DataTypes.h.in index b9fb48a..7fc9b72 100644 --- a/contrib/llvm/include/llvm/Support/DataTypes.h.in +++ b/contrib/llvm/include/llvm/Support/DataTypes.h.in @@ -26,7 +26,6 @@ #ifndef SUPPORT_DATATYPES_H #define SUPPORT_DATATYPES_H -#undef HAVE_SYS_TYPES_H #undef HAVE_INTTYPES_H #undef HAVE_STDINT_H #undef HAVE_UINT64_T @@ -54,9 +53,7 @@ #endif /* Note that <inttypes.h> includes <stdint.h>, if this is a C99 system. */ -#ifdef HAVE_SYS_TYPES_H #include <sys/types.h> -#endif #ifdef HAVE_INTTYPES_H #include <inttypes.h> @@ -98,7 +95,12 @@ typedef short int16_t; typedef unsigned short uint16_t; typedef signed char int8_t; typedef unsigned char uint8_t; -typedef signed int ssize_t; +#if defined(_WIN64) + typedef signed __int64 ssize_t; +#else + typedef signed int ssize_t; +#endif + #ifndef INT8_MAX # define INT8_MAX 127 #endif diff --git a/contrib/llvm/include/llvm/Support/Debug.h b/contrib/llvm/include/llvm/Support/Debug.h index 896fe84..2702408 100644 --- a/contrib/llvm/include/llvm/Support/Debug.h +++ b/contrib/llvm/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/contrib/llvm/include/llvm/Support/DebugLoc.h b/contrib/llvm/include/llvm/Support/DebugLoc.h index f35d407..05f31d7 100644 --- a/contrib/llvm/include/llvm/Support/DebugLoc.h +++ b/contrib/llvm/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/contrib/llvm/include/llvm/Support/Dwarf.h b/contrib/llvm/include/llvm/Support/Dwarf.h index 2491b4c..23bbd1c 100644 --- a/contrib/llvm/include/llvm/Support/Dwarf.h +++ b/contrib/llvm/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, @@ -272,6 +297,8 @@ enum dwarf_constants { DW_AT_GNU_vector = 0x2107, DW_AT_GNU_template_name = 0x2110, + DW_AT_GNU_odr_signature = 0x210f, + // Extensions for Fission proposal. DW_AT_GNU_dwo_name = 0x2130, DW_AT_GNU_dwo_id = 0x2131, @@ -293,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, @@ -324,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, @@ -489,8 +520,10 @@ enum dwarf_constants { // 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, @@ -509,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, @@ -563,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, @@ -605,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, @@ -654,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, @@ -672,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, @@ -766,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/contrib/llvm/include/llvm/Support/ELF.h b/contrib/llvm/include/llvm/Support/ELF.h index 7069899..2868f35 100644 --- a/contrib/llvm/include/llvm/Support/ELF.h +++ b/contrib/llvm/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> @@ -276,7 +277,6 @@ enum { EM_STM8 = 186, // STMicroeletronics STM8 8-bit microcontroller EM_TILE64 = 187, // Tilera TILE64 multicore architecture family EM_TILEPRO = 188, // Tilera TILEPro multicore architecture family - EM_MICROBLAZE = 189, // Xilinx MicroBlaze 32-bit RISC soft processor core EM_CUDA = 190, // NVIDIA CUDA architecture EM_TILEGX = 191, // Tilera TILE-Gx multicore architecture family EM_CLOUDSHIELD = 192, // CloudShield architecture family @@ -287,8 +287,7 @@ enum { EM_RL78 = 197, // Renesas RL78 family EM_VIDEOCORE5 = 198, // Broadcom VideoCore V processor EM_78KOR = 199, // Renesas 78KOR family - EM_56800EX = 200, // Freescale 56800EX Digital Signal Controller (DSC) - EM_MBLAZE = 47787 // Xilinx MicroBlaze + EM_56800EX = 200 // Freescale 56800EX Digital Signal Controller (DSC) }; // Object file classes. @@ -310,7 +309,8 @@ enum { ELFOSABI_NONE = 0, // UNIX System V ABI ELFOSABI_HPUX = 1, // HP-UX operating system ELFOSABI_NETBSD = 2, // NetBSD - ELFOSABI_LINUX = 3, // GNU/Linux + ELFOSABI_GNU = 3, // GNU/Linux + ELFOSABI_LINUX = 3, // Historical alias for ELFOSABI_GNU. ELFOSABI_HURD = 4, // GNU/Hurd ELFOSABI_SOLARIS = 6, // Solaris ELFOSABI_AIX = 7, // AIX @@ -417,32 +417,6 @@ enum { R_386_NUM = 43 }; -// MBlaze relocations. -enum { - R_MICROBLAZE_NONE = 0, - R_MICROBLAZE_32 = 1, - R_MICROBLAZE_32_PCREL = 2, - R_MICROBLAZE_64_PCREL = 3, - R_MICROBLAZE_32_PCREL_LO = 4, - R_MICROBLAZE_64 = 5, - R_MICROBLAZE_32_LO = 6, - R_MICROBLAZE_SRO32 = 7, - R_MICROBLAZE_SRW32 = 8, - R_MICROBLAZE_64_NONE = 9, - R_MICROBLAZE_32_SYM_OP_SYM = 10, - R_MICROBLAZE_GNU_VTINHERIT = 11, - R_MICROBLAZE_GNU_VTENTRY = 12, - R_MICROBLAZE_GOTPC_64 = 13, - R_MICROBLAZE_GOT_64 = 14, - R_MICROBLAZE_PLT_64 = 15, - R_MICROBLAZE_REL = 16, - R_MICROBLAZE_JUMP_SLOT = 17, - R_MICROBLAZE_GLOB_DAT = 18, - R_MICROBLAZE_GOTOFF_64 = 19, - R_MICROBLAZE_GOTOFF_32 = 20, - R_MICROBLAZE_COPY = 21 -}; - // ELF Relocation types for PPC32 enum { R_PPC_NONE = 0, /* No relocation. */ @@ -459,45 +433,131 @@ enum { R_PPC_REL14 = 11, R_PPC_REL14_BRTAKEN = 12, R_PPC_REL14_BRNTAKEN = 13, + R_PPC_GOT16 = 14, + R_PPC_GOT16_LO = 15, + R_PPC_GOT16_HI = 16, + R_PPC_GOT16_HA = 17, R_PPC_REL32 = 26, + R_PPC_TLS = 67, + R_PPC_DTPMOD32 = 68, + R_PPC_TPREL16 = 69, R_PPC_TPREL16_LO = 70, - R_PPC_TPREL16_HA = 72 + R_PPC_TPREL16_HI = 71, + R_PPC_TPREL16_HA = 72, + R_PPC_TPREL32 = 73, + R_PPC_DTPREL16 = 74, + R_PPC_DTPREL16_LO = 75, + R_PPC_DTPREL16_HI = 76, + R_PPC_DTPREL16_HA = 77, + R_PPC_DTPREL32 = 78, + R_PPC_GOT_TLSGD16 = 79, + R_PPC_GOT_TLSGD16_LO = 80, + R_PPC_GOT_TLSGD16_HI = 81, + R_PPC_GOT_TLSGD16_HA = 82, + R_PPC_GOT_TLSLD16 = 83, + R_PPC_GOT_TLSLD16_LO = 84, + R_PPC_GOT_TLSLD16_HI = 85, + R_PPC_GOT_TLSLD16_HA = 86, + R_PPC_GOT_TPREL16 = 87, + R_PPC_GOT_TPREL16_LO = 88, + R_PPC_GOT_TPREL16_HI = 89, + R_PPC_GOT_TPREL16_HA = 90, + R_PPC_GOT_DTPREL16 = 91, + R_PPC_GOT_DTPREL16_LO = 92, + R_PPC_GOT_DTPREL16_HI = 93, + R_PPC_GOT_DTPREL16_HA = 94, + R_PPC_TLSGD = 95, + R_PPC_TLSLD = 96, + R_PPC_REL16 = 249, + R_PPC_REL16_LO = 250, + R_PPC_REL16_HI = 251, + R_PPC_REL16_HA = 252 }; // ELF Relocation types for PPC64 enum { R_PPC64_NONE = 0, R_PPC64_ADDR32 = 1, + R_PPC64_ADDR24 = 2, + R_PPC64_ADDR16 = 3, R_PPC64_ADDR16_LO = 4, R_PPC64_ADDR16_HI = 5, + R_PPC64_ADDR16_HA = 6, R_PPC64_ADDR14 = 7, + R_PPC64_ADDR14_BRTAKEN = 8, + R_PPC64_ADDR14_BRNTAKEN = 9, R_PPC64_REL24 = 10, + R_PPC64_REL14 = 11, + R_PPC64_REL14_BRTAKEN = 12, + R_PPC64_REL14_BRNTAKEN = 13, + R_PPC64_GOT16 = 14, + R_PPC64_GOT16_LO = 15, + R_PPC64_GOT16_HI = 16, + R_PPC64_GOT16_HA = 17, R_PPC64_REL32 = 26, R_PPC64_ADDR64 = 38, R_PPC64_ADDR16_HIGHER = 39, + R_PPC64_ADDR16_HIGHERA = 40, R_PPC64_ADDR16_HIGHEST = 41, + R_PPC64_ADDR16_HIGHESTA = 42, R_PPC64_REL64 = 44, R_PPC64_TOC16 = 47, R_PPC64_TOC16_LO = 48, + R_PPC64_TOC16_HI = 49, R_PPC64_TOC16_HA = 50, R_PPC64_TOC = 51, R_PPC64_ADDR16_DS = 56, R_PPC64_ADDR16_LO_DS = 57, + R_PPC64_GOT16_DS = 58, + R_PPC64_GOT16_LO_DS = 59, R_PPC64_TOC16_DS = 63, R_PPC64_TOC16_LO_DS = 64, R_PPC64_TLS = 67, + R_PPC64_DTPMOD64 = 68, + R_PPC64_TPREL16 = 69, R_PPC64_TPREL16_LO = 70, + R_PPC64_TPREL16_HI = 71, R_PPC64_TPREL16_HA = 72, + R_PPC64_TPREL64 = 73, + R_PPC64_DTPREL16 = 74, R_PPC64_DTPREL16_LO = 75, + R_PPC64_DTPREL16_HI = 76, R_PPC64_DTPREL16_HA = 77, + R_PPC64_DTPREL64 = 78, + R_PPC64_GOT_TLSGD16 = 79, R_PPC64_GOT_TLSGD16_LO = 80, + R_PPC64_GOT_TLSGD16_HI = 81, R_PPC64_GOT_TLSGD16_HA = 82, + R_PPC64_GOT_TLSLD16 = 83, R_PPC64_GOT_TLSLD16_LO = 84, + R_PPC64_GOT_TLSLD16_HI = 85, R_PPC64_GOT_TLSLD16_HA = 86, + R_PPC64_GOT_TPREL16_DS = 87, R_PPC64_GOT_TPREL16_LO_DS = 88, + R_PPC64_GOT_TPREL16_HI = 89, R_PPC64_GOT_TPREL16_HA = 90, + R_PPC64_GOT_DTPREL16_DS = 91, + R_PPC64_GOT_DTPREL16_LO_DS = 92, + R_PPC64_GOT_DTPREL16_HI = 93, + R_PPC64_GOT_DTPREL16_HA = 94, + R_PPC64_TPREL16_DS = 95, + R_PPC64_TPREL16_LO_DS = 96, + R_PPC64_TPREL16_HIGHER = 97, + R_PPC64_TPREL16_HIGHERA = 98, + R_PPC64_TPREL16_HIGHEST = 99, + R_PPC64_TPREL16_HIGHESTA = 100, + R_PPC64_DTPREL16_DS = 101, + R_PPC64_DTPREL16_LO_DS = 102, + R_PPC64_DTPREL16_HIGHER = 103, + R_PPC64_DTPREL16_HIGHERA = 104, + R_PPC64_DTPREL16_HIGHEST = 105, + R_PPC64_DTPREL16_HIGHESTA = 106, R_PPC64_TLSGD = 107, - R_PPC64_TLSLD = 108 + R_PPC64_TLSLD = 108, + R_PPC64_REL16 = 249, + R_PPC64_REL16_LO = 250, + R_PPC64_REL16_HI = 251, + R_PPC64_REL16_HA = 252 }; // ELF Relocation types for AArch64 @@ -591,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, @@ -741,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 @@ -781,6 +841,8 @@ enum { R_MIPS_PC16 = 10, R_MIPS_CALL16 = 11, R_MIPS_GPREL32 = 12, + R_MIPS_UNUSED1 = 13, + R_MIPS_UNUSED2 = 14, R_MIPS_SHIFT5 = 16, R_MIPS_SHIFT6 = 17, R_MIPS_64 = 18, @@ -819,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 }; @@ -1055,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. @@ -1103,7 +1178,7 @@ enum { }; // Section flags. -enum { +enum LLVM_ENUM_INT_TYPE(unsigned) { // Section data should be writable during execution. SHF_WRITE = 0x1, @@ -1135,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 @@ -1165,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 @@ -1383,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 @@ -1465,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/contrib/llvm/include/llvm/Support/ErrorOr.h b/contrib/llvm/include/llvm/Support/ErrorOr.h index f3ac305..d5b11cb 100644 --- a/contrib/llvm/include/llvm/Support/ErrorOr.h +++ b/contrib/llvm/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/contrib/llvm/include/llvm/Support/FileSystem.h b/contrib/llvm/include/llvm/Support/FileSystem.h index ffa6427..d301f84 100644 --- a/contrib/llvm/include/llvm/Support/FileSystem.h +++ b/contrib/llvm/include/llvm/Support/FileSystem.h @@ -33,6 +33,7 @@ #include "llvm/ADT/Twine.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/TimeValue.h" #include "llvm/Support/system_error.h" #include <ctime> #include <iterator> @@ -72,22 +73,6 @@ private: int v_; }; -/// copy_option - An "enum class" enumeration of copy semantics for copy -/// operations. -struct copy_option { - enum _ { - fail_if_exists, - overwrite_if_exists - }; - - copy_option(_ v) : v_(v) {} - explicit copy_option(int v) : v_(_(v)) {} - operator int() const {return v_;} - -private: - int v_; -}; - /// space_info - Self explanatory. struct space_info { uint64_t capacity; @@ -95,30 +80,28 @@ struct space_info { uint64_t available; }; - enum perms { - no_perms = 0, - owner_read = 0400, - owner_write = 0200, - owner_exe = 0100, - owner_all = owner_read | owner_write | owner_exe, - group_read = 040, - group_write = 020, - group_exe = 010, - group_all = group_read | group_write | group_exe, - others_read = 04, - others_write = 02, - others_exe = 01, - others_all = others_read | others_write | others_exe, - all_all = owner_all | group_all | others_all, - set_uid_on_exe = 04000, - set_gid_on_exe = 02000, - sticky_bit = 01000, - perms_mask = all_all | set_uid_on_exe | set_gid_on_exe | sticky_bit, - perms_not_known = 0xFFFF, - add_perms = 0x1000, - remove_perms = 0x2000, - symlink_perms = 0x4000 + no_perms = 0, + owner_read = 0400, + owner_write = 0200, + owner_exe = 0100, + owner_all = owner_read | owner_write | owner_exe, + group_read = 040, + group_write = 020, + group_exe = 010, + group_all = group_read | group_write | group_exe, + others_read = 04, + others_write = 02, + others_exe = 01, + others_all = others_read | others_write | others_exe, + all_read = owner_read | group_read | others_read, + all_write = owner_write | group_write | others_write, + all_exe = owner_exe | group_exe | others_exe, + all_all = owner_all | group_all | others_all, + set_uid_on_exe = 04000, + set_gid_on_exe = 02000, + sticky_bit = 01000, + perms_not_known = 0xFFFF }; // Helper functions so that you can use & and | to manipulate perms bits: @@ -142,8 +125,25 @@ inline perms operator~(perms x) { return static_cast<perms>(~static_cast<unsigned short>(x)); } +class UniqueID { + uint64_t Device; + uint64_t File; + +public: + UniqueID() {} + UniqueID(uint64_t Device, uint64_t File) : Device(Device), File(File) {} + bool operator==(const UniqueID &Other) const { + return Device == Other.Device && File == Other.File; + } + bool operator!=(const UniqueID &Other) const { return !(*this == Other); } + bool operator<(const UniqueID &Other) const { + return Device < Other.Device || + (Device == Other.Device && File < Other.File); + } + uint64_t getDevice() const { return Device; } + uint64_t getFile() const { return File; } +}; - /// file_status - Represents the result of a call to stat and friends. It has /// a platform specific member to store the result. class file_status @@ -151,6 +151,10 @@ class file_status #if defined(LLVM_ON_UNIX) dev_t fs_st_dev; ino_t fs_st_ino; + time_t fs_st_mtime; + uid_t fs_st_uid; + gid_t fs_st_gid; + off_t fs_st_size; #elif defined (LLVM_ON_WIN32) uint32_t LastWriteTimeHigh; uint32_t LastWriteTimeLow; @@ -161,18 +165,51 @@ class file_status uint32_t FileIndexLow; #endif friend bool equivalent(file_status A, file_status B); - friend error_code status(const Twine &path, file_status &result); file_type Type; perms Perms; public: - explicit file_status(file_type v=file_type::status_error, - perms prms=perms_not_known) - : Type(v), Perms(prms) {} + file_status() : Type(file_type::status_error) {} + file_status(file_type Type) : Type(Type) {} + + #if defined(LLVM_ON_UNIX) + file_status(file_type Type, perms Perms, dev_t Dev, ino_t Ino, time_t MTime, + uid_t UID, gid_t GID, off_t Size) + : fs_st_dev(Dev), fs_st_ino(Ino), fs_st_mtime(MTime), fs_st_uid(UID), + fs_st_gid(GID), fs_st_size(Size), Type(Type), Perms(Perms) {} + #elif defined(LLVM_ON_WIN32) + file_status(file_type Type, uint32_t LastWriteTimeHigh, + uint32_t LastWriteTimeLow, uint32_t VolumeSerialNumber, + uint32_t FileSizeHigh, uint32_t FileSizeLow, + uint32_t FileIndexHigh, uint32_t FileIndexLow) + : LastWriteTimeHigh(LastWriteTimeHigh), + LastWriteTimeLow(LastWriteTimeLow), + VolumeSerialNumber(VolumeSerialNumber), FileSizeHigh(FileSizeHigh), + FileSizeLow(FileSizeLow), FileIndexHigh(FileIndexHigh), + FileIndexLow(FileIndexLow), Type(Type), Perms(perms_not_known) {} + #endif // getters file_type type() const { return Type; } perms permissions() const { return Perms; } - + TimeValue getLastModificationTime() const; + UniqueID getUniqueID() const; + + #if defined(LLVM_ON_UNIX) + uint32_t getUser() const { return fs_st_uid; } + uint32_t getGroup() const { return fs_st_gid; } + uint64_t getSize() const { return fs_st_size; } + #elif defined (LLVM_ON_WIN32) + uint32_t getUser() const { + return 9999; // Not applicable to Windows, so... + } + uint32_t getGroup() const { + return 9999; // Not applicable to Windows, so... + } + uint64_t getSize() const { + return (uint64_t(FileSizeHigh) << 32) + FileSizeLow; + } + #endif + // setters void type(file_type v) { Type = v; } void permissions(perms p) { Perms = p; } @@ -181,7 +218,7 @@ public: /// file_magic - An "enum class" enumeration of file types based on magic (the first /// N bytes of the file). struct file_magic { - enum _ { + enum Impl { unknown = 0, ///< Unrecognized file bitcode, ///< Bitcode file archive, ///< ar style archive file @@ -193,27 +230,29 @@ struct file_magic { macho_executable, ///< Mach-O Executable macho_fixed_virtual_memory_shared_lib, ///< Mach-O Shared Lib, FVM macho_core, ///< Mach-O Core File - macho_preload_executabl, ///< Mach-O Preloaded Executable + macho_preload_executable, ///< Mach-O Preloaded Executable macho_dynamically_linked_shared_lib, ///< Mach-O dynlinked shared lib macho_dynamic_linker, ///< The Mach-O dynamic linker macho_bundle, ///< Mach-O Bundle file macho_dynamically_linked_shared_lib_stub, ///< Mach-O Shared lib stub 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 { - return v_ == unknown ? false : true; + return V == unknown ? false : true; } - file_magic() : v_(unknown) {} - file_magic(_ v) : v_(v) {} - explicit file_magic(int v) : v_(_(v)) {} - operator int() const {return v_;} + file_magic() : V(unknown) {} + file_magic(Impl V) : V(V) {} + operator Impl() const { return V; } private: - int v_; + Impl V; }; /// @} @@ -233,18 +272,6 @@ private: /// platform specific error_code. error_code make_absolute(SmallVectorImpl<char> &path); -/// @brief Copy the file at \a from to the path \a to. -/// -/// @param from The path to copy the file from. -/// @param to The path to copy the file to. -/// @param copt Behavior if \a to already exists. -/// @returns errc::success if the file has been successfully copied. -/// errc::file_exists if \a to already exists and \a copt == -/// copy_option::fail_if_exists. Otherwise a platform specific -/// error_code. -error_code copy_file(const Twine &from, const Twine &to, - copy_option copt = copy_option::fail_if_exists); - /// @brief Create all the non-existent directories in path. /// /// @param path Directories to create. @@ -253,6 +280,13 @@ error_code copy_file(const Twine &from, const Twine &to, /// otherwise a platform specific error_code. error_code create_directories(const Twine &path, bool &existed); +/// @brief Convenience function for clients that don't need to know if the +/// directory existed or not. +inline error_code create_directories(const Twine &Path) { + bool Existed; + return create_directories(Path, Existed); +} + /// @brief Create the directory in path. /// /// @param path Directory to create. @@ -261,6 +295,13 @@ error_code create_directories(const Twine &path, bool &existed); /// otherwise a platform specific error_code. error_code create_directory(const Twine &path, bool &existed); +/// @brief Convenience function for clients that don't need to know if the +/// directory existed or not. +inline error_code create_directory(const Twine &Path) { + bool Existed; + return create_directory(Path, Existed); +} + /// @brief Create a hard link from \a from to \a to. /// /// @param to The path to hard link to. @@ -293,6 +334,13 @@ error_code current_path(SmallVectorImpl<char> &result); /// successfully set, otherwise a platform specific error_code. error_code remove(const Twine &path, bool &existed); +/// @brief Convenience function for clients that don't need to know if the file +/// existed or not. +inline error_code remove(const Twine &Path) { + bool Existed; + return remove(Path, Existed); +} + /// @brief Recursively remove all files below \a path, then \a path. Files are /// removed as if by POSIX remove(). /// @@ -302,6 +350,13 @@ error_code remove(const Twine &path, bool &existed); /// successfully set, otherwise a platform specific error_code. error_code remove_all(const Twine &path, uint32_t &num_removed); +/// @brief Convenience function for clients that don't need to know how many +/// files were removed. +inline error_code remove_all(const Twine &Path) { + uint32_t Removed; + return remove_all(Path, Removed); +} + /// @brief Rename \a from to \a to. Files are renamed as if by POSIX rename(). /// /// @param from The path to rename from. @@ -343,6 +398,18 @@ inline bool exists(const Twine &path) { return !exists(path, result) && result; } +/// @brief Can we execute this file? +/// +/// @param Path Input path. +/// @returns True if we can execute it, false otherwise. +bool can_execute(const Twine &Path); + +/// @brief Can we write this file? +/// +/// @param Path Input path. +/// @returns True if we can write to it, false otherwise. +bool can_write(const Twine &Path); + /// @brief Do file_status's represent the same thing? /// /// @param A Input file_status. @@ -373,14 +440,6 @@ inline bool equivalent(const Twine &A, const Twine &B) { return !equivalent(A, B, result) && result; } -/// @brief Get file size. -/// -/// @param path Input path. -/// @param result Set to the size of the file in \a path. -/// @returns errc::success if result has been successfully set, otherwise a -/// platform specific error_code. -error_code file_size(const Twine &path, uint64_t &result); - /// @brief Does status represent a directory? /// /// @param status A file_status previously returned from status. @@ -396,6 +455,13 @@ bool is_directory(file_status status); /// platform specific error_code. error_code is_directory(const Twine &path, bool &result); +/// @brief Simpler version of is_directory for clients that don't need to +/// differentiate between an error and false. +inline bool is_directory(const Twine &Path) { + bool Result; + return !is_directory(Path, Result) && Result; +} + /// @brief Does status represent a regular file? /// /// @param status A file_status previously returned from status. @@ -411,6 +477,15 @@ bool is_regular_file(file_status status); /// platform specific error_code. error_code is_regular_file(const Twine &path, bool &result); +/// @brief Simpler version of is_regular_file for clients that don't need to +/// differentiate between an error and false. +inline bool is_regular_file(const Twine &Path) { + bool Result; + if (is_regular_file(Path, Result)) + return false; + return Result; +} + /// @brief Does this status represent something that exists but is not a /// directory, regular file, or symlink? /// @@ -452,12 +527,25 @@ error_code is_symlink(const Twine &path, bool &result); /// platform specific error_code. error_code status(const Twine &path, file_status &result); -/// @brief Modifies permission bits on a file +/// @brief A version for when a file descriptor is already available. +error_code status(int FD, file_status &Result); + +/// @brief Get file size. /// -/// @param path Input path. -/// @returns errc::success if permissions have been changed, otherwise a +/// @param Path Input path. +/// @param Result Set to the size of the file in \a Path. +/// @returns errc::success if result has been successfully set, otherwise a /// platform specific error_code. -error_code permissions(const Twine &path, perms prms); +inline error_code file_size(const Twine &Path, uint64_t &Result) { + file_status Status; + error_code EC = status(Path, Status); + if (EC) + return EC; + Result = Status.getSize(); + return error_code::success(); +} + +error_code setLastModificationAndAccessTime(int FD, TimeValue Time); /// @brief Is status available? /// @@ -473,39 +561,84 @@ bool status_known(file_status s); /// platform specific error_code. error_code status_known(const Twine &path, bool &result); -/// @brief Generate a unique path and open it as a file. +/// @brief Create a uniquely named file. /// /// Generates a unique path suitable for a temporary file and then opens it as a /// file. The name is based on \a model with '%' replaced by a random char in /// [0-9a-f]. If \a model is not an absolute path, a suitable temporary /// directory will be prepended. /// +/// Example: clang-%%-%%-%%-%%-%%.s => clang-a0-b1-c2-d3-e4.s +/// /// This is an atomic operation. Either the file is created and opened, or the /// file system is left untouched. /// -/// clang-%%-%%-%%-%%-%%.s => /tmp/clang-a0-b1-c2-d3-e4.s +/// The intendend use is for files that are to be kept, possibly after +/// renaming them. For example, when running 'clang -c foo.o', the file can +/// be first created as foo-abc123.o and then renamed. /// -/// @param model Name to base unique path off of. -/// @param result_fd Set to the opened file's file descriptor. -/// @param result_path Set to the opened file's absolute path. -/// @param makeAbsolute If true and \a model is not an absolute path, a temp -/// directory will be prepended. -/// @returns errc::success if result_{fd,path} have been successfully set, +/// @param Model Name to base unique path off of. +/// @param ResultFD Set to the opened file's file descriptor. +/// @param ResultPath Set to the opened file's absolute path. +/// @returns errc::success if Result{FD,Path} have been successfully set, /// otherwise a platform specific error_code. -error_code unique_file(const Twine &model, int &result_fd, - SmallVectorImpl<char> &result_path, - bool makeAbsolute = true, unsigned mode = 0600); +error_code createUniqueFile(const Twine &Model, int &ResultFD, + SmallVectorImpl<char> &ResultPath, + unsigned Mode = all_read | all_write); + +/// @brief Simpler version for clients that don't want an open file. +error_code createUniqueFile(const Twine &Model, + SmallVectorImpl<char> &ResultPath); -/// @brief Canonicalize path. +/// @brief Create a file in the system temporary directory. /// -/// 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. +/// The filename is of the form prefix-random_chars.suffix. Since the directory +/// is not know to the caller, Prefix and Suffix cannot have path separators. +/// The files are created with mode 0600. /// -/// @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); +/// This should be used for things like a temporary .s that is removed after +/// running the assembler. +error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix, + int &ResultFD, + SmallVectorImpl<char> &ResultPath); + +/// @brief Simpler version for clients that don't want an open file. +error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix, + SmallVectorImpl<char> &ResultPath); + +error_code createUniqueDirectory(const Twine &Prefix, + SmallVectorImpl<char> &ResultPath); + +enum OpenFlags { + F_None = 0, + + /// F_Excl - When opening a file, this flag makes raw_fd_ostream + /// report an error if the file already exists. + F_Excl = 1, + + /// F_Append - When opening a file, if it already exists append to the + /// existing file instead of returning an error. This may not be specified + /// with F_Excl. + F_Append = 2, + + /// F_Binary - The file should be opened in binary mode on platforms that + /// make this distinction. + F_Binary = 4 +}; + +inline OpenFlags operator|(OpenFlags A, OpenFlags B) { + return OpenFlags(unsigned(A) | unsigned(B)); +} + +inline OpenFlags &operator|=(OpenFlags &A, OpenFlags B) { + A = A | B; + return A; +} + +error_code openFileForWrite(const Twine &Name, int &ResultFD, OpenFlags Flags, + unsigned Mode = 0666); + +error_code openFileForRead(const Twine &Name, int &ResultFD); /// @brief Are \a path's first bytes \a magic? /// @@ -534,48 +667,12 @@ file_magic identify_magic(StringRef magic); /// @brief Get and identify \a path's type based on its content. /// /// @param path Input path. -/// @param result Set to the type of file, or LLVMFileType::Unknown_FileType. +/// @param result Set to the type of file, or file_magic::unknown. /// @returns errc::success if result has been successfully set, otherwise a /// platform specific error_code. error_code identify_magic(const Twine &path, file_magic &result); -/// @brief Get library paths the system linker uses. -/// -/// @param result Set to the list of system library paths. -/// @returns errc::success if result has been successfully set, otherwise a -/// platform specific error_code. -error_code GetSystemLibraryPaths(SmallVectorImpl<std::string> &result); - -/// @brief Get bitcode library paths the system linker uses -/// + LLVM_LIB_SEARCH_PATH + LLVM_LIBDIR. -/// -/// @param result Set to the list of bitcode library paths. -/// @returns errc::success if result has been successfully set, otherwise a -/// platform specific error_code. -error_code GetBitcodeLibraryPaths(SmallVectorImpl<std::string> &result); - -/// @brief Find a library. -/// -/// Find the path to a library using its short name. Use the system -/// dependent library paths to locate the library. -/// -/// c => /usr/lib/libc.so -/// -/// @param short_name Library name one would give to the system linker. -/// @param result Set to the absolute path \a short_name represents. -/// @returns errc::success if result has been successfully set, otherwise a -/// platform specific error_code. -error_code FindLibrary(const Twine &short_name, SmallVectorImpl<char> &result); - -/// @brief Get absolute path of main executable. -/// -/// @param argv0 The program name as it was spelled on the command line. -/// @param MainAddr Address of some symbol in the executable (not in a library). -/// @param result Set to the absolute path of the current executable. -/// @returns errc::success if result has been successfully set, otherwise a -/// platform specific error_code. -error_code GetMainExecutable(const char *argv0, void *MainAddr, - SmallVectorImpl<char> &result); +error_code getUniqueID(const Twine Path, UniqueID &Result); /// This class represents a memory mapped file. It is based on /// boost::iostreams::mapped_file. @@ -625,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, @@ -649,7 +746,7 @@ public: char *data() const; /// Get a const view of the data. Modifying this memory has undefined - /// behaivor. + /// behavior. const char *const_data() const; /// \returns The minimum alignment offset must be. @@ -680,7 +777,10 @@ error_code map_file_pages(const Twine &path, off_t file_offset, size_t size, /// platform specific error_code. error_code unmap_file_pages(void *base, size_t size); - +/// Return the path to the main executable, given the value of argv[0] from +/// program startup and the address of main itself. In extremis, this function +/// may fail and return an empty path. +std::string getMainExecutable(const char *argv0, void *MainExecAddr); /// @} /// @name Iterators @@ -760,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) { @@ -772,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; } @@ -811,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; @@ -855,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/contrib/llvm/include/llvm/Support/FileUtilities.h b/contrib/llvm/include/llvm/Support/FileUtilities.h index 5456eb7..79c59e4 100644 --- a/contrib/llvm/include/llvm/Support/FileUtilities.h +++ b/contrib/llvm/include/llvm/Support/FileUtilities.h @@ -27,8 +27,8 @@ namespace llvm { /// option, it will set the string to an error message if an error occurs, or /// if the files are different. /// - int DiffFilesWithTolerance(const sys::PathWithStatus &FileA, - const sys::PathWithStatus &FileB, + int DiffFilesWithTolerance(StringRef FileA, + StringRef FileB, double AbsTol, double RelTol, std::string *Error = 0); diff --git a/contrib/llvm/include/llvm/Support/FormattedStream.h b/contrib/llvm/include/llvm/Support/FormattedStream.h index 2e4bd5a..df1f218 100644 --- a/contrib/llvm/include/llvm/Support/FormattedStream.h +++ b/contrib/llvm/include/llvm/Support/FormattedStream.h @@ -16,11 +16,13 @@ #define LLVM_SUPPORT_FORMATTEDSTREAM_H #include "llvm/Support/raw_ostream.h" +#include <utility> namespace llvm { /// formatted_raw_ostream - A raw_ostream that wraps another one and keeps track -/// of column position, allowing padding out to specific column boundaries. +/// of line and column position, allowing padding out to specific column +/// boundaries and querying the number of lines written to the stream. /// class formatted_raw_ostream : public raw_ostream { public: @@ -44,11 +46,11 @@ private: /// bool DeleteStream; - /// ColumnScanned - The current output column of the data that's + /// Position - The current output column and line of the data that's /// been flushed and the portion of the buffer that's been - /// scanned. The column scheme is zero-based. + /// scanned. The line and column scheme is zero-based. /// - unsigned ColumnScanned; + std::pair<unsigned, unsigned> Position; /// Scanned - This points to one past the last character in the /// buffer we've scanned. @@ -66,10 +68,10 @@ private: return TheStream->tell(); } - /// ComputeColumn - Examine the given output buffer and figure out which - /// column we end up in after output. + /// ComputePosition - Examine the given output buffer and figure out the new + /// position after output. /// - void ComputeColumn(const char *Ptr, size_t size); + void ComputePosition(const char *Ptr, size_t size); public: /// formatted_raw_ostream - Open the specified file for @@ -83,11 +85,11 @@ public: /// underneath it. /// formatted_raw_ostream(raw_ostream &Stream, bool Delete = false) - : raw_ostream(), TheStream(0), DeleteStream(false), ColumnScanned(0) { + : raw_ostream(), TheStream(0), DeleteStream(false), Position(0, 0) { setStream(Stream, Delete); } explicit formatted_raw_ostream() - : raw_ostream(), TheStream(0), DeleteStream(false), ColumnScanned(0) { + : raw_ostream(), TheStream(0), DeleteStream(false), Position(0, 0) { Scanned = 0; } @@ -122,6 +124,33 @@ public: /// \param NewCol - The column to move to. formatted_raw_ostream &PadToColumn(unsigned NewCol); + /// getColumn - Return the column number + unsigned getColumn() { return Position.first; } + + /// 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() { // Delete the stream if needed. Otherwise, transfer the buffer diff --git a/contrib/llvm/include/llvm/Support/GCOV.h b/contrib/llvm/include/llvm/Support/GCOV.h index f1040f5..0aa716a 100644 --- a/contrib/llvm/include/llvm/Support/GCOV.h +++ b/contrib/llvm/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/contrib/llvm/include/llvm/Support/GetElementPtrTypeIterator.h b/contrib/llvm/include/llvm/Support/GetElementPtrTypeIterator.h index 5a90553..aacb531 100644 --- a/contrib/llvm/include/llvm/Support/GetElementPtrTypeIterator.h +++ b/contrib/llvm/include/llvm/Support/GetElementPtrTypeIterator.h @@ -105,7 +105,7 @@ namespace llvm { template<typename T> inline generic_gep_type_iterator<const T *> - gep_type_end(Type *Op0, ArrayRef<T> A) { + gep_type_end(Type * /*Op0*/, ArrayRef<T> A) { return generic_gep_type_iterator<const T *>::end(A.end()); } } // end namespace llvm diff --git a/contrib/llvm/include/llvm/Support/GraphWriter.h b/contrib/llvm/include/llvm/Support/GraphWriter.h index 22181d4..62547dd 100644 --- a/contrib/llvm/include/llvm/Support/GraphWriter.h +++ b/contrib/llvm/include/llvm/Support/GraphWriter.h @@ -50,7 +50,8 @@ namespace GraphProgram { }; } -void DisplayGraph(const sys::Path& Filename, bool wait=true, GraphProgram::Name program = GraphProgram::DOT); +void DisplayGraph(StringRef Filename, bool wait = true, + GraphProgram::Name program = GraphProgram::DOT); template<typename GraphType> class GraphWriter { @@ -318,34 +319,23 @@ raw_ostream &WriteGraph(raw_ostream &O, const GraphType &G, return O; } -template<typename GraphType> -sys::Path WriteGraph(const GraphType &G, const Twine &Name, - bool ShortNames = false, const Twine &Title = "") { - std::string ErrMsg; - sys::Path Filename = sys::Path::GetTemporaryDirectory(&ErrMsg); - if (Filename.isEmpty()) { - errs() << "Error: " << ErrMsg << "\n"; - return Filename; - } - Filename.appendComponent((Name + ".dot").str()); - if (Filename.makeUnique(true,&ErrMsg)) { - errs() << "Error: " << ErrMsg << "\n"; - return sys::Path(); - } +std::string createGraphFilename(const Twine &Name, int &FD); - errs() << "Writing '" << Filename.str() << "'... "; +template <typename GraphType> +std::string WriteGraph(const GraphType &G, const Twine &Name, + bool ShortNames = false, const Twine &Title = "") { + int FD; + std::string Filename = createGraphFilename(Name, FD); + raw_fd_ostream O(FD, /*shouldClose=*/ true); - std::string ErrorInfo; - raw_fd_ostream O(Filename.c_str(), ErrorInfo); - - if (ErrorInfo.empty()) { - llvm::WriteGraph(O, G, ShortNames, Title); - errs() << " done. \n"; - } else { - errs() << "error opening file '" << Filename.str() << "' for writing!\n"; - Filename.clear(); + if (FD == -1) { + errs() << "error opening file '" << Filename << "' for writing!\n"; + return ""; } + llvm::WriteGraph(O, G, ShortNames, Title); + errs() << " done. \n"; + return Filename; } @@ -356,9 +346,9 @@ template<typename GraphType> void ViewGraph(const GraphType &G, const Twine &Name, bool ShortNames = false, const Twine &Title = "", GraphProgram::Name Program = GraphProgram::DOT) { - sys::Path Filename = llvm::WriteGraph(G, Name, ShortNames, Title); + std::string Filename = llvm::WriteGraph(G, Name, ShortNames, Title); - if (Filename.isEmpty()) + if (Filename.empty()) return; DisplayGraph(Filename, true, Program); diff --git a/contrib/llvm/include/llvm/Support/Host.h b/contrib/llvm/include/llvm/Support/Host.h index 9a4036a..28c4cc7 100644 --- a/contrib/llvm/include/llvm/Support/Host.h +++ b/contrib/llvm/include/llvm/Support/Host.h @@ -16,10 +16,10 @@ #include "llvm/ADT/StringMap.h" -#if defined(__linux__) +#if defined(__linux__) || defined(__GNU__) #include <endian.h> #else -#ifndef LLVM_ON_WIN32 +#if !defined(BYTE_ORDER) && !defined(LLVM_ON_WIN32) #include <machine/endian.h> #endif #endif diff --git a/contrib/llvm/include/llvm/Support/IntegersSubset.h b/contrib/llvm/include/llvm/Support/IntegersSubset.h deleted file mode 100644 index ce34d78..0000000 --- a/contrib/llvm/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 (unsigned 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. - unsigned 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 (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; - 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/contrib/llvm/include/llvm/Support/IntegersSubsetMapping.h b/contrib/llvm/include/llvm/Support/IntegersSubsetMapping.h deleted file mode 100644 index 641ce78..0000000 --- a/contrib/llvm/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/contrib/llvm/include/llvm/Support/LEB128.h b/contrib/llvm/include/llvm/Support/LEB128.h index 802b4f3..3d73792 100644 --- a/contrib/llvm/include/llvm/Support/LEB128.h +++ b/contrib/llvm/include/llvm/Support/LEB128.h @@ -20,7 +20,7 @@ namespace llvm { /// Utility function to encode a SLEB128 value to an output stream. -static inline void encodeSLEB128(int64_t Value, raw_ostream &OS) { +inline void encodeSLEB128(int64_t Value, raw_ostream &OS) { bool More; do { uint8_t Byte = Value & 0x7f; @@ -29,19 +29,19 @@ static inline void encodeSLEB128(int64_t Value, raw_ostream &OS) { More = !((((Value == 0 ) && ((Byte & 0x40) == 0)) || ((Value == -1) && ((Byte & 0x40) != 0)))); if (More) - Byte |= 0x80; // Mark this byte that that more bytes will follow. + Byte |= 0x80; // Mark this byte to show 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) { +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. + Byte |= 0x80; // Mark this byte to show that more bytes will follow. OS << char(Byte); } while (Value != 0); @@ -55,14 +55,14 @@ static inline void encodeULEB128(uint64_t Value, raw_ostream &OS, /// 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) { +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. + Byte |= 0x80; // Mark this byte to show that more bytes will follow. *p++ = Byte; } while (Value != 0); @@ -77,7 +77,7 @@ static inline unsigned encodeULEB128(uint64_t Value, uint8_t *p, /// Utility function to decode a ULEB128 value. -static inline uint64_t decodeULEB128(const uint8_t *p, unsigned *n = 0) { +inline uint64_t decodeULEB128(const uint8_t *p, unsigned *n = 0) { const uint8_t *orig_p = p; uint64_t Value = 0; unsigned Shift = 0; diff --git a/contrib/llvm/include/llvm/Support/MD5.h b/contrib/llvm/include/llvm/Support/MD5.h new file mode 100644 index 0000000..b2b8c2d --- /dev/null +++ b/contrib/llvm/include/llvm/Support/MD5.h @@ -0,0 +1,71 @@ +/* + * This code is derived from (original license follows): + * + * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc. + * MD5 Message-Digest Algorithm (RFC 1321). + * + * Homepage: + * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5 + * + * Author: + * Alexander Peslyak, better known as Solar Designer <solar at openwall.com> + * + * This software was written by Alexander Peslyak in 2001. No copyright is + * claimed, and the software is hereby placed in the public domain. + * In case this attempt to disclaim copyright and place the software in the + * public domain is deemed null and void, then the software is + * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the + * general public under the following terms: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted. + * + * There's ABSOLUTELY NO WARRANTY, express or implied. + * + * See md5.c for more information. + */ + +#ifndef LLVM_SYSTEM_MD5_H +#define LLVM_SYSTEM_MD5_H + +#include "llvm/ADT/SmallString.h" +#include "llvm/Support/DataTypes.h" + +namespace llvm { + +template <typename T> class ArrayRef; + +class MD5 { + // Any 32-bit or wider unsigned integer data type will do. + typedef uint32_t MD5_u32plus; + + MD5_u32plus a, b, c, d; + MD5_u32plus hi, lo; + uint8_t buffer[64]; + MD5_u32plus block[16]; + +public: + typedef uint8_t MD5Result[16]; + + MD5(); + + /// \brief Updates the hash for the byte stream provided. + void update(ArrayRef<uint8_t> Data); + + /// \brief Updates the hash for the StringRef provided. + void update(StringRef Str); + + /// \brief Finishes off the hash and puts the result in result. + void final(MD5Result &result); + + /// \brief Translates the bytes in \p Res to a hex string that is + /// deposited into \p Str. The result will be of length 32. + static void stringifyResult(MD5Result &Res, SmallString<32> &Str); + +private: + const uint8_t *body(ArrayRef<uint8_t> Data); +}; + +} + +#endif diff --git a/contrib/llvm/include/llvm/Support/MachO.h b/contrib/llvm/include/llvm/Support/MachO.h index 7f28c3f..897a611 100644 --- a/contrib/llvm/include/llvm/Support/MachO.h +++ b/contrib/llvm/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/contrib/llvm/include/llvm/Support/ManagedStatic.h b/contrib/llvm/include/llvm/Support/ManagedStatic.h index 4171d1b..5587618 100644 --- a/contrib/llvm/include/llvm/Support/ManagedStatic.h +++ b/contrib/llvm/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/contrib/llvm/include/llvm/Support/MathExtras.h b/contrib/llvm/include/llvm/Support/MathExtras.h index d6ae58d..ff41608 100644 --- a/contrib/llvm/include/llvm/Support/MathExtras.h +++ b/contrib/llvm/include/llvm/Support/MathExtras.h @@ -14,13 +14,235 @@ #ifndef LLVM_SUPPORT_MATHEXTRAS_H #define LLVM_SUPPORT_MATHEXTRAS_H +#include "llvm/Support/Compiler.h" #include "llvm/Support/SwapByteOrder.h" +#include "llvm/Support/type_traits.h" + +#include <cstring> #ifdef _MSC_VER -# include <intrin.h> +#include <intrin.h> +#include <limits> #endif namespace llvm { +/// \brief The behavior an operation has on an input of 0. +enum ZeroBehavior { + /// \brief The returned value is undefined. + ZB_Undefined, + /// \brief The returned value is numeric_limits<T>::max() + ZB_Max, + /// \brief The returned value is numeric_limits<T>::digits + ZB_Width +}; + +/// \brief Count number of 0's from the least significant bit to the most +/// stopping at the first 1. +/// +/// Only unsigned integral types are allowed. +/// +/// \param ZB the behavior on an input of 0. Only ZB_Width and ZB_Undefined are +/// valid arguments. +template <typename T> +typename enable_if_c<std::numeric_limits<T>::is_integer && + !std::numeric_limits<T>::is_signed, std::size_t>::type +countTrailingZeros(T Val, ZeroBehavior ZB = ZB_Width) { + (void)ZB; + + if (!Val) + return std::numeric_limits<T>::digits; + if (Val & 0x1) + return 0; + + // Bisection method. + std::size_t ZeroBits = 0; + T Shift = std::numeric_limits<T>::digits >> 1; + T Mask = std::numeric_limits<T>::max() >> Shift; + while (Shift) { + if ((Val & Mask) == 0) { + Val >>= Shift; + ZeroBits |= Shift; + } + Shift >>= 1; + Mask >>= Shift; + } + return ZeroBits; +} + +// Disable signed. +template <typename T> +typename enable_if_c<std::numeric_limits<T>::is_integer && + std::numeric_limits<T>::is_signed, std::size_t>::type +countTrailingZeros(T Val, ZeroBehavior ZB = ZB_Width) LLVM_DELETED_FUNCTION; + +#if __GNUC__ >= 4 || _MSC_VER +template <> +inline std::size_t countTrailingZeros<uint32_t>(uint32_t Val, ZeroBehavior ZB) { + if (ZB != ZB_Undefined && Val == 0) + return 32; + +#if __has_builtin(__builtin_ctz) || __GNUC_PREREQ(4, 0) + return __builtin_ctz(Val); +#elif _MSC_VER + unsigned long Index; + _BitScanForward(&Index, Val); + return Index; +#endif +} + +#if !defined(_MSC_VER) || defined(_M_X64) +template <> +inline std::size_t countTrailingZeros<uint64_t>(uint64_t Val, ZeroBehavior ZB) { + if (ZB != ZB_Undefined && Val == 0) + return 64; + +#if __has_builtin(__builtin_ctzll) || __GNUC_PREREQ(4, 0) + return __builtin_ctzll(Val); +#elif _MSC_VER + unsigned long Index; + _BitScanForward64(&Index, Val); + return Index; +#endif +} +#endif +#endif + +/// \brief Count number of 0's from the most significant bit to the least +/// stopping at the first 1. +/// +/// Only unsigned integral types are allowed. +/// +/// \param ZB the behavior on an input of 0. Only ZB_Width and ZB_Undefined are +/// valid arguments. +template <typename T> +typename enable_if_c<std::numeric_limits<T>::is_integer && + !std::numeric_limits<T>::is_signed, std::size_t>::type +countLeadingZeros(T Val, ZeroBehavior ZB = ZB_Width) { + (void)ZB; + + if (!Val) + return std::numeric_limits<T>::digits; + + // Bisection method. + std::size_t ZeroBits = 0; + for (T Shift = std::numeric_limits<T>::digits >> 1; Shift; Shift >>= 1) { + T Tmp = Val >> Shift; + if (Tmp) + Val = Tmp; + else + ZeroBits |= Shift; + } + return ZeroBits; +} + +// Disable signed. +template <typename T> +typename enable_if_c<std::numeric_limits<T>::is_integer && + std::numeric_limits<T>::is_signed, std::size_t>::type +countLeadingZeros(T Val, ZeroBehavior ZB = ZB_Width) LLVM_DELETED_FUNCTION; + +#if __GNUC__ >= 4 || _MSC_VER +template <> +inline std::size_t countLeadingZeros<uint32_t>(uint32_t Val, ZeroBehavior ZB) { + if (ZB != ZB_Undefined && Val == 0) + return 32; + +#if __has_builtin(__builtin_clz) || __GNUC_PREREQ(4, 0) + return __builtin_clz(Val); +#elif _MSC_VER + unsigned long Index; + _BitScanReverse(&Index, Val); + return Index ^ 31; +#endif +} + +#if !defined(_MSC_VER) || defined(_M_X64) +template <> +inline std::size_t countLeadingZeros<uint64_t>(uint64_t Val, ZeroBehavior ZB) { + if (ZB != ZB_Undefined && Val == 0) + return 64; + +#if __has_builtin(__builtin_clzll) || __GNUC_PREREQ(4, 0) + return __builtin_clzll(Val); +#elif _MSC_VER + unsigned long Index; + _BitScanReverse64(&Index, Val); + return Index ^ 63; +#endif +} +#endif +#endif + +/// \brief Get the index of the first set bit starting from the least +/// significant bit. +/// +/// Only unsigned integral types are allowed. +/// +/// \param ZB the behavior on an input of 0. Only ZB_Max and ZB_Undefined are +/// valid arguments. +template <typename T> +typename enable_if_c<std::numeric_limits<T>::is_integer && + !std::numeric_limits<T>::is_signed, T>::type +findFirstSet(T Val, ZeroBehavior ZB = ZB_Max) { + if (ZB == ZB_Max && Val == 0) + return std::numeric_limits<T>::max(); + + return countTrailingZeros(Val, ZB_Undefined); +} + +// Disable signed. +template <typename T> +typename enable_if_c<std::numeric_limits<T>::is_integer && + std::numeric_limits<T>::is_signed, T>::type +findFirstSet(T Val, ZeroBehavior ZB = ZB_Max) LLVM_DELETED_FUNCTION; + +/// \brief Get the index of the last set bit starting from the least +/// significant bit. +/// +/// Only unsigned integral types are allowed. +/// +/// \param ZB the behavior on an input of 0. Only ZB_Max and ZB_Undefined are +/// valid arguments. +template <typename T> +typename enable_if_c<std::numeric_limits<T>::is_integer && + !std::numeric_limits<T>::is_signed, T>::type +findLastSet(T Val, ZeroBehavior ZB = ZB_Max) { + if (ZB == ZB_Max && Val == 0) + return std::numeric_limits<T>::max(); + + // Use ^ instead of - because both gcc and llvm can remove the associated ^ + // in the __builtin_clz intrinsic on x86. + return countLeadingZeros(Val, ZB_Undefined) ^ + (std::numeric_limits<T>::digits - 1); +} + +// Disable signed. +template <typename T> +typename enable_if_c<std::numeric_limits<T>::is_integer && + std::numeric_limits<T>::is_signed, T>::type +findLastSet(T Val, ZeroBehavior ZB = ZB_Max) LLVM_DELETED_FUNCTION; + +/// \brief Macro compressed bit reversal table for 256 bits. +/// +/// http://graphics.stanford.edu/~seander/bithacks.html#BitReverseTable +static const unsigned char BitReverseTable256[256] = { +#define R2(n) n, n + 2 * 64, n + 1 * 64, n + 3 * 64 +#define R4(n) R2(n), R2(n + 2 * 16), R2(n + 1 * 16), R2(n + 3 * 16) +#define R6(n) R4(n), R4(n + 2 * 4), R4(n + 1 * 4), R4(n + 3 * 4) + R6(0), R6(2), R6(1), R6(3) +}; + +/// \brief Reverse the bits in \p Val. +template <typename T> +T reverseBits(T Val) { + unsigned char in[sizeof(Val)]; + unsigned char out[sizeof(Val)]; + std::memcpy(in, &Val, sizeof(Val)); + for (unsigned i = 0; i < sizeof(Val); ++i) + out[(sizeof(Val) - i) - 1] = BitReverseTable256[in[i]]; + std::memcpy(&Val, out, sizeof(Val)); + return Val; +} // NOTE: The following support functions use the _32/_64 extensions instead of // type overloading so that signed and unsigned integers can be used without @@ -157,84 +379,12 @@ inline uint64_t ByteSwap_64(uint64_t Value) { return sys::SwapByteOrder_64(Value); } -/// CountLeadingZeros_32 - this function performs the platform optimal form of -/// counting the number of zeros from the most significant bit to the first one -/// bit. Ex. CountLeadingZeros_32(0x00F000FF) == 8. -/// Returns 32 if the word is zero. -inline unsigned CountLeadingZeros_32(uint32_t Value) { - unsigned Count; // result -#if __GNUC__ >= 4 - // PowerPC is defined for __builtin_clz(0) -#if !defined(__ppc__) && !defined(__ppc64__) - if (!Value) return 32; -#endif - Count = __builtin_clz(Value); -#else - if (!Value) return 32; - Count = 0; - // bisection method for count leading zeros - for (unsigned Shift = 32 >> 1; Shift; Shift >>= 1) { - uint32_t Tmp = Value >> Shift; - if (Tmp) { - Value = Tmp; - } else { - Count |= Shift; - } - } -#endif - return Count; -} - /// CountLeadingOnes_32 - this function performs the operation of /// counting the number of ones from the most significant bit to the first zero /// bit. Ex. CountLeadingOnes_32(0xFF0FFF00) == 8. /// Returns 32 if the word is all ones. inline unsigned CountLeadingOnes_32(uint32_t Value) { - return CountLeadingZeros_32(~Value); -} - -/// CountLeadingZeros_64 - This function performs the platform optimal form -/// of counting the number of zeros from the most significant bit to the first -/// one bit (64 bit edition.) -/// Returns 64 if the word is zero. -inline unsigned CountLeadingZeros_64(uint64_t Value) { - unsigned Count; // result -#if __GNUC__ >= 4 - // PowerPC is defined for __builtin_clzll(0) -#if !defined(__ppc__) && !defined(__ppc64__) - if (!Value) return 64; -#endif - Count = __builtin_clzll(Value); -#else - if (sizeof(long) == sizeof(int64_t)) { - if (!Value) return 64; - Count = 0; - // bisection method for count leading zeros - for (unsigned Shift = 64 >> 1; Shift; Shift >>= 1) { - uint64_t Tmp = Value >> Shift; - if (Tmp) { - Value = Tmp; - } else { - Count |= Shift; - } - } - } else { - // get hi portion - uint32_t Hi = Hi_32(Value); - - // if some bits in hi portion - if (Hi) { - // leading zeros in hi portion plus all bits in lo portion - Count = CountLeadingZeros_32(Hi); - } else { - // get lo portion - uint32_t Lo = Lo_32(Value); - // same as 32 bit value - Count = CountLeadingZeros_32(Lo)+32; - } - } -#endif - return Count; + return countLeadingZeros(~Value); } /// CountLeadingOnes_64 - This function performs the operation @@ -242,27 +392,7 @@ inline unsigned CountLeadingZeros_64(uint64_t Value) { /// zero bit (64 bit edition.) /// Returns 64 if the word is all ones. inline unsigned CountLeadingOnes_64(uint64_t Value) { - return CountLeadingZeros_64(~Value); -} - -/// CountTrailingZeros_32 - this function performs the platform optimal form of -/// counting the number of zeros from the least significant bit to the first one -/// bit. Ex. CountTrailingZeros_32(0xFF00FF00) == 8. -/// Returns 32 if the word is zero. -inline unsigned CountTrailingZeros_32(uint32_t Value) { -#if __GNUC__ >= 4 - return Value ? __builtin_ctz(Value) : 32; -#else - static const unsigned Mod37BitPosition[] = { - 32, 0, 1, 26, 2, 23, 27, 0, 3, 16, 24, 30, 28, 11, 0, 13, - 4, 7, 17, 0, 25, 22, 31, 15, 29, 10, 12, 6, 0, 21, 14, 9, - 5, 20, 8, 19, 18 - }; - // Replace "-Value" by "1+~Value" in the following commented code to avoid - // MSVC warning C4146 - // return Mod37BitPosition[(-Value & Value) % 37]; - return Mod37BitPosition[((1 + ~Value) & Value) % 37]; -#endif + return countLeadingZeros(~Value); } /// CountTrailingOnes_32 - this function performs the operation of @@ -270,29 +400,7 @@ inline unsigned CountTrailingZeros_32(uint32_t Value) { /// bit. Ex. CountTrailingOnes_32(0x00FF00FF) == 8. /// Returns 32 if the word is all ones. inline unsigned CountTrailingOnes_32(uint32_t Value) { - return CountTrailingZeros_32(~Value); -} - -/// CountTrailingZeros_64 - This function performs the platform optimal form -/// of counting the number of zeros from the least significant bit to the first -/// one bit (64 bit edition.) -/// Returns 64 if the word is zero. -inline unsigned CountTrailingZeros_64(uint64_t Value) { -#if __GNUC__ >= 4 - return Value ? __builtin_ctzll(Value) : 64; -#else - static const unsigned Mod67Position[] = { - 64, 0, 1, 39, 2, 15, 40, 23, 3, 12, 16, 59, 41, 19, 24, 54, - 4, 64, 13, 10, 17, 62, 60, 28, 42, 30, 20, 51, 25, 44, 55, - 47, 5, 32, 65, 38, 14, 22, 11, 58, 18, 53, 63, 9, 61, 27, - 29, 50, 43, 46, 31, 37, 21, 57, 52, 8, 26, 49, 45, 36, 56, - 7, 48, 35, 6, 34, 33, 0 - }; - // Replace "-Value" by "1+~Value" in the following commented code to avoid - // MSVC warning C4146 - // return Mod67Position[(-Value & Value) % 67]; - return Mod67Position[((1 + ~Value) & Value) % 67]; -#endif + return countTrailingZeros(~Value); } /// CountTrailingOnes_64 - This function performs the operation @@ -300,7 +408,7 @@ inline unsigned CountTrailingZeros_64(uint64_t Value) { /// zero bit (64 bit edition.) /// Returns 64 if the word is all ones. inline unsigned CountTrailingOnes_64(uint64_t Value) { - return CountTrailingZeros_64(~Value); + return countTrailingZeros(~Value); } /// CountPopulation_32 - this function counts the number of set bits in a value. @@ -333,26 +441,26 @@ inline unsigned CountPopulation_64(uint64_t Value) { /// -1 if the value is zero. (32 bit edition.) /// Ex. Log2_32(32) == 5, Log2_32(1) == 0, Log2_32(0) == -1, Log2_32(6) == 2 inline unsigned Log2_32(uint32_t Value) { - return 31 - CountLeadingZeros_32(Value); + return 31 - countLeadingZeros(Value); } /// Log2_64 - This function returns the floor log base 2 of the specified value, /// -1 if the value is zero. (64 bit edition.) inline unsigned Log2_64(uint64_t Value) { - return 63 - CountLeadingZeros_64(Value); + return 63 - countLeadingZeros(Value); } /// Log2_32_Ceil - This function returns the ceil log base 2 of the specified /// value, 32 if the value is zero. (32 bit edition). /// Ex. Log2_32_Ceil(32) == 5, Log2_32_Ceil(1) == 0, Log2_32_Ceil(6) == 3 inline unsigned Log2_32_Ceil(uint32_t Value) { - return 32-CountLeadingZeros_32(Value-1); + return 32 - countLeadingZeros(Value - 1); } /// Log2_64_Ceil - This function returns the ceil log base 2 of the specified /// value, 64 if the value is zero. (64 bit edition.) inline unsigned Log2_64_Ceil(uint64_t Value) { - return 64-CountLeadingZeros_64(Value-1); + return 64 - countLeadingZeros(Value - 1); } /// GreatestCommonDivisor64 - Return the greatest common divisor of the two @@ -496,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/contrib/llvm/include/llvm/Support/MemoryBuffer.h b/contrib/llvm/include/llvm/Support/MemoryBuffer.h index 0cce726..ff22fb6 100644 --- a/contrib/llvm/include/llvm/Support/MemoryBuffer.h +++ b/contrib/llvm/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,21 +66,22 @@ 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); - /// getOpenFile - Given an already-open file descriptor, read the file and - /// return a MemoryBuffer. + /// Given an already-open file descriptor, map some slice of it into a + /// MemoryBuffer. The slice is specified by an \p Offset and \p MapSize. + /// Since this is in the middle of a file, the buffer is not null terminated. + static error_code getOpenFileSlice(int FD, const char *Filename, + OwningPtr<MemoryBuffer> &Result, + uint64_t MapSize, int64_t Offset); + + /// Given an already-open file descriptor, read the file and return a + /// MemoryBuffer. static error_code getOpenFile(int FD, const char *Filename, - OwningPtr<MemoryBuffer> &result, - uint64_t FileSize = -1, - uint64_t MapSize = -1, - int64_t Offset = 0, + OwningPtr<MemoryBuffer> &Result, + uint64_t FileSize, bool RequiresNullTerminator = true); /// getMemBuffer - Open the specified memory range as a MemoryBuffer. Note @@ -119,11 +120,7 @@ public: static error_code getFileOrSTDIN(StringRef Filename, OwningPtr<MemoryBuffer> &result, int64_t FileSize = -1); - static error_code getFileOrSTDIN(const char *Filename, - OwningPtr<MemoryBuffer> &result, - int64_t FileSize = -1); - - + //===--------------------------------------------------------------------===// // Provided for performance analysis. //===--------------------------------------------------------------------===// diff --git a/contrib/llvm/include/llvm/Support/MemoryObject.h b/contrib/llvm/include/llvm/Support/MemoryObject.h index 732b0f0..17aa9d2 100644 --- a/contrib/llvm/include/llvm/Support/MemoryObject.h +++ b/contrib/llvm/include/llvm/Support/MemoryObject.h @@ -42,7 +42,7 @@ public: /// @param ptr - A pointer to a byte to be filled in. Must be non-NULL. /// @result - 0 if successful; -1 if not. Failure may be due to a /// bounds violation or an implementation-specific error. - virtual int readByte(uint64_t address, uint8_t* ptr) const = 0; + virtual int readByte(uint64_t address, uint8_t *ptr) const = 0; /// readBytes - Tries to read a contiguous range of bytes from the /// region, up to the end of the region. @@ -51,17 +51,12 @@ public: /// /// @param address - The address of the first byte, in the same space as /// getBase(). - /// @param size - The maximum number of bytes to copy. + /// @param size - The number of bytes to copy. /// @param buf - A pointer to a buffer to be filled in. Must be non-NULL /// and large enough to hold size bytes. - /// @param copied - A pointer to a nunber that is filled in with the number - /// of bytes actually read. May be NULL. /// @result - 0 if successful; -1 if not. Failure may be due to a /// bounds violation or an implementation-specific error. - virtual int readBytes(uint64_t address, - uint64_t size, - uint8_t* buf, - uint64_t* copied) const; + virtual int readBytes(uint64_t address, uint64_t size, uint8_t *buf) const; }; } diff --git a/contrib/llvm/include/llvm/Support/PassNameParser.h b/contrib/llvm/include/llvm/Support/PassNameParser.h index 317416c..c0914b1 100644 --- a/contrib/llvm/include/llvm/Support/PassNameParser.h +++ b/contrib/llvm/include/llvm/Support/PassNameParser.h @@ -7,9 +7,9 @@ // //===----------------------------------------------------------------------===// // -// This file the PassNameParser and FilteredPassNameParser<> classes, which are -// used to add command line arguments to a utility for all of the passes that -// have been registered into the system. +// This file contains the PassNameParser and FilteredPassNameParser<> classes, +// which are used to add command line arguments to a utility for all of the +// passes that have been registered into the system. // // The PassNameParser class adds ALL passes linked into the system (that are // creatable) as command line arguments to the tool (when instantiated with the @@ -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/contrib/llvm/include/llvm/Support/Path.h b/contrib/llvm/include/llvm/Support/Path.h index 196eecc..b2afe1b 100644 --- a/contrib/llvm/include/llvm/Support/Path.h +++ b/contrib/llvm/include/llvm/Support/Path.h @@ -7,10 +7,383 @@ // //===----------------------------------------------------------------------===// // -// This file currently includes both PathV1 and PathV2 to facilitate moving -// clients over to the new interface. +// This file declares the llvm::sys::path namespace. It is designed after +// TR2/boost filesystem (v3), but modified to remove exception handling and the +// path class. // //===----------------------------------------------------------------------===// -#include "llvm/Support/PathV1.h" -#include "llvm/Support/PathV2.h" +#ifndef LLVM_SUPPORT_PATH_H +#define LLVM_SUPPORT_PATH_H + +#include "llvm/ADT/SmallString.h" +#include "llvm/ADT/Twine.h" +#include "llvm/Support/DataTypes.h" +#include <iterator> + +namespace llvm { +namespace sys { +namespace path { + +/// @name Lexical Component Iterator +/// @{ + +/// @brief Path iterator. +/// +/// This is a bidirectional iterator that iterates over the individual +/// components in \a path. The forward traversal order is as follows: +/// * The root-name element, if present. +/// * The root-directory element, if present. +/// * Each successive filename element, if present. +/// * Dot, if one or more trailing non-root slash characters are present. +/// The backwards traversal order is the reverse of forward traversal. +/// +/// Iteration examples. Each component is separated by ',': +/// @code +/// / => / +/// /foo => /,foo +/// foo/ => foo,. +/// /foo/bar => /,foo,bar +/// ../ => ..,. +/// C:\foo\bar => C:,/,foo,bar +/// @endcode +class const_iterator { + StringRef Path; ///< The entire path. + StringRef Component; ///< The current component. Not necessarily in Path. + size_t Position; ///< The iterators current position within Path. + + // An end iterator has Position = Path.size() + 1. + friend const_iterator begin(StringRef path); + friend const_iterator end(StringRef path); + +public: + typedef const StringRef value_type; + typedef ptrdiff_t difference_type; + typedef value_type &reference; + typedef value_type *pointer; + typedef std::bidirectional_iterator_tag iterator_category; + + reference operator*() const { return Component; } + pointer operator->() const { return &Component; } + const_iterator &operator++(); // preincrement + const_iterator &operator++(int); // postincrement + const_iterator &operator--(); // predecrement + const_iterator &operator--(int); // postdecrement + bool operator==(const const_iterator &RHS) const; + bool operator!=(const const_iterator &RHS) const; + + /// @brief Difference in bytes between this and RHS. + ptrdiff_t operator-(const const_iterator &RHS) const; +}; + +typedef std::reverse_iterator<const_iterator> reverse_iterator; + +/// @brief Get begin iterator over \a path. +/// @param path Input path. +/// @returns Iterator initialized with the first component of \a path. +const_iterator begin(StringRef path); + +/// @brief Get end iterator over \a path. +/// @param path Input path. +/// @returns Iterator initialized to the end of \a path. +const_iterator end(StringRef path); + +/// @brief Get reverse begin iterator over \a path. +/// @param path Input path. +/// @returns Iterator initialized with the first reverse component of \a path. +inline reverse_iterator rbegin(StringRef path) { + return reverse_iterator(end(path)); +} + +/// @brief Get reverse end iterator over \a path. +/// @param path Input path. +/// @returns Iterator initialized to the reverse end of \a path. +inline reverse_iterator rend(StringRef path) { + return reverse_iterator(begin(path)); +} + +/// @} +/// @name Lexical Modifiers +/// @{ + +/// @brief Remove the last component from \a path unless it is the root dir. +/// +/// @code +/// directory/filename.cpp => directory/ +/// directory/ => directory +/// filename.cpp => <empty> +/// / => / +/// @endcode +/// +/// @param path A path that is modified to not have a file component. +void remove_filename(SmallVectorImpl<char> &path); + +/// @brief Replace the file extension of \a path with \a extension. +/// +/// @code +/// ./filename.cpp => ./filename.extension +/// ./filename => ./filename.extension +/// ./ => ./.extension +/// @endcode +/// +/// @param path A path that has its extension replaced with \a extension. +/// @param extension The extension to be added. It may be empty. It may also +/// optionally start with a '.', if it does not, one will be +/// prepended. +void replace_extension(SmallVectorImpl<char> &path, const Twine &extension); + +/// @brief Append to path. +/// +/// @code +/// /foo + bar/f => /foo/bar/f +/// /foo/ + bar/f => /foo/bar/f +/// foo + bar/f => foo/bar/f +/// @endcode +/// +/// @param path Set to \a path + \a component. +/// @param a The component to be appended to \a path. +void append(SmallVectorImpl<char> &path, const Twine &a, + const Twine &b = "", + const Twine &c = "", + const Twine &d = ""); + +/// @brief Append to path. +/// +/// @code +/// /foo + [bar,f] => /foo/bar/f +/// /foo/ + [bar,f] => /foo/bar/f +/// foo + [bar,f] => foo/bar/f +/// @endcode +/// +/// @param path Set to \a path + [\a begin, \a end). +/// @param begin Start of components to append. +/// @param end One past the end of components to append. +void append(SmallVectorImpl<char> &path, + const_iterator begin, const_iterator end); + +/// @} +/// @name Transforms (or some other better name) +/// @{ + +/// Convert path to the native form. 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. +/// @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 +/// @{ + +/// @brief Get root name. +/// +/// @code +/// //net/hello => //net +/// c:/hello => c: (on Windows, on other platforms nothing) +/// /hello => <empty> +/// @endcode +/// +/// @param path Input path. +/// @result The root name of \a path if it has one, otherwise "". +const StringRef root_name(StringRef path); + +/// @brief Get root directory. +/// +/// @code +/// /goo/hello => / +/// c:/hello => / +/// d/file.txt => <empty> +/// @endcode +/// +/// @param path Input path. +/// @result The root directory of \a path if it has one, otherwise +/// "". +const StringRef root_directory(StringRef path); + +/// @brief Get root path. +/// +/// Equivalent to root_name + root_directory. +/// +/// @param path Input path. +/// @result The root path of \a path if it has one, otherwise "". +const StringRef root_path(StringRef path); + +/// @brief Get relative path. +/// +/// @code +/// C:\hello\world => hello\world +/// foo/bar => foo/bar +/// /foo/bar => foo/bar +/// @endcode +/// +/// @param path Input path. +/// @result The path starting after root_path if one exists, otherwise "". +const StringRef relative_path(StringRef path); + +/// @brief Get parent path. +/// +/// @code +/// / => <empty> +/// /foo => / +/// foo/../bar => foo/.. +/// @endcode +/// +/// @param path Input path. +/// @result The parent path of \a path if one exists, otherwise "". +const StringRef parent_path(StringRef path); + +/// @brief Get filename. +/// +/// @code +/// /foo.txt => foo.txt +/// . => . +/// .. => .. +/// / => / +/// @endcode +/// +/// @param path Input path. +/// @result The filename part of \a path. This is defined as the last component +/// of \a path. +const StringRef filename(StringRef path); + +/// @brief Get stem. +/// +/// If filename contains a dot but not solely one or two dots, result is the +/// substring of filename ending at (but not including) the last dot. Otherwise +/// it is filename. +/// +/// @code +/// /foo/bar.txt => bar +/// /foo/bar => bar +/// /foo/.txt => <empty> +/// /foo/. => . +/// /foo/.. => .. +/// @endcode +/// +/// @param path Input path. +/// @result The stem of \a path. +const StringRef stem(StringRef path); + +/// @brief Get extension. +/// +/// If filename contains a dot but not solely one or two dots, result is the +/// substring of filename starting at (and including) the last dot, and ending +/// at the end of \a path. Otherwise "". +/// +/// @code +/// /foo/bar.txt => .txt +/// /foo/bar => <empty> +/// /foo/.txt => .txt +/// @endcode +/// +/// @param path Input path. +/// @result The extension of \a path. +const StringRef extension(StringRef path); + +/// @brief Check whether the given char is a path separator on the host OS. +/// +/// @param value a character +/// @result true if \a value is a path separator character on the host OS +bool is_separator(char value); + +/// @brief Get the typical temporary directory for the system, e.g., +/// "/var/tmp" or "C:/TEMP" +/// +/// @param erasedOnReboot Whether to favor a path that is erased on reboot +/// rather than one that potentially persists longer. This parameter will be +/// ignored if the user or system has set the typical environment variable +/// (e.g., TEMP on Windows, TMPDIR on *nix) to specify a temporary directory. +/// +/// @param result Holds the resulting path name. +void system_temp_directory(bool erasedOnReboot, SmallVectorImpl<char> &result); + +/// @brief Has root name? +/// +/// root_name != "" +/// +/// @param path Input path. +/// @result True if the path has a root name, false otherwise. +bool has_root_name(const Twine &path); + +/// @brief Has root directory? +/// +/// root_directory != "" +/// +/// @param path Input path. +/// @result True if the path has a root directory, false otherwise. +bool has_root_directory(const Twine &path); + +/// @brief Has root path? +/// +/// root_path != "" +/// +/// @param path Input path. +/// @result True if the path has a root path, false otherwise. +bool has_root_path(const Twine &path); + +/// @brief Has relative path? +/// +/// relative_path != "" +/// +/// @param path Input path. +/// @result True if the path has a relative path, false otherwise. +bool has_relative_path(const Twine &path); + +/// @brief Has parent path? +/// +/// parent_path != "" +/// +/// @param path Input path. +/// @result True if the path has a parent path, false otherwise. +bool has_parent_path(const Twine &path); + +/// @brief Has filename? +/// +/// filename != "" +/// +/// @param path Input path. +/// @result True if the path has a filename, false otherwise. +bool has_filename(const Twine &path); + +/// @brief Has stem? +/// +/// stem != "" +/// +/// @param path Input path. +/// @result True if the path has a stem, false otherwise. +bool has_stem(const Twine &path); + +/// @brief Has extension? +/// +/// extension != "" +/// +/// @param path Input path. +/// @result True if the path has a extension, false otherwise. +bool has_extension(const Twine &path); + +/// @brief Is path absolute? +/// +/// @param path Input path. +/// @result True if the path is absolute, false if it is not. +bool is_absolute(const Twine &path); + +/// @brief Is path relative? +/// +/// @param path Input path. +/// @result True if the path is relative, false if it is not. +bool is_relative(const Twine &path); + +} // end namespace path +} // end namespace sys +} // end namespace llvm + +#endif diff --git a/contrib/llvm/include/llvm/Support/PathV1.h b/contrib/llvm/include/llvm/Support/PathV1.h deleted file mode 100644 index 86328f0..0000000 --- a/contrib/llvm/include/llvm/Support/PathV1.h +++ /dev/null @@ -1,743 +0,0 @@ -//===- llvm/Support/PathV1.h - Path Operating System Concept ----*- 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 the llvm::sys::Path class. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_SUPPORT_PATHV1_H -#define LLVM_SUPPORT_PATHV1_H - -#include "llvm/ADT/StringRef.h" -#include "llvm/Support/Compiler.h" -#include "llvm/Support/TimeValue.h" -#include <set> -#include <string> -#include <vector> - -#define LLVM_PATH_DEPRECATED_MSG(replacement) \ - "PathV1 has been deprecated and will be removed as soon as all LLVM and" \ - " Clang clients have been moved over to PathV2. Please use `" #replacement \ - "` from PathV2 instead." - -namespace llvm { -namespace sys { - - /// This structure provides basic file system information about a file. It - /// is patterned after the stat(2) Unix operating system call but made - /// platform independent and eliminates many of the unix-specific fields. - /// However, to support llvm-ar, the mode, user, and group fields are - /// retained. These pertain to unix security and may not have a meaningful - /// value on non-Unix platforms. However, the other fields should - /// always be applicable on all platforms. The structure is filled in by - /// the PathWithStatus class. - /// @brief File status structure - class FileStatus { - public: - uint64_t fileSize; ///< Size of the file in bytes - TimeValue modTime; ///< Time of file's modification - uint32_t mode; ///< Mode of the file, if applicable - uint32_t user; ///< User ID of owner, if applicable - uint32_t group; ///< Group ID of owner, if applicable - uint64_t uniqueID; ///< A number to uniquely ID this file - bool isDir : 1; ///< True if this is a directory. - bool isFile : 1; ///< True if this is a file. - - FileStatus() : fileSize(0), modTime(0,0), mode(0777), user(999), - group(999), uniqueID(0), isDir(false), isFile(false) { } - - TimeValue getTimestamp() const { return modTime; } - uint64_t getSize() const { return fileSize; } - uint32_t getMode() const { return mode; } - uint32_t getUser() const { return user; } - uint32_t getGroup() const { return group; } - uint64_t getUniqueID() const { return uniqueID; } - }; - - /// This class provides an abstraction for the path to a file or directory - /// in the operating system's filesystem and provides various basic operations - /// on it. Note that this class only represents the name of a path to a file - /// or directory which may or may not be valid for a given machine's file - /// system. The class is patterned after the java.io.File class with various - /// extensions and several omissions (not relevant to LLVM). A Path object - /// ensures that the path it encapsulates is syntactically valid for the - /// operating system it is running on but does not ensure correctness for - /// any particular file system. That is, a syntactically valid path might - /// specify path components that do not exist in the file system and using - /// such a Path to act on the file system could produce errors. There is one - /// invalid Path value which is permitted: the empty path. The class should - /// never allow a syntactically invalid non-empty path name to be assigned. - /// Empty paths are required in order to indicate an error result in some - /// situations. If the path is empty, the isValid operation will return - /// false. All operations will fail if isValid is false. Operations that - /// change the path will either return false if it would cause a syntactically - /// invalid path name (in which case the Path object is left unchanged) or - /// throw an std::string exception indicating the error. The methods are - /// grouped into four basic categories: Path Accessors (provide information - /// about the path without accessing disk), Disk Accessors (provide - /// information about the underlying file or directory), Path Mutators - /// (change the path information, not the disk), and Disk Mutators (change - /// the disk file/directory referenced by the path). The Disk Mutator methods - /// all have the word "disk" embedded in their method name to reinforce the - /// notion that the operation modifies the file system. - /// @since 1.4 - /// @brief An abstraction for operating system paths. - class Path { - /// @name Constructors - /// @{ - public: - /// Construct a path to the root directory of the file system. The root - /// directory is a top level directory above which there are no more - /// directories. For example, on UNIX, the root directory is /. On Windows - /// it is file:///. Other operating systems may have different notions of - /// what the root directory is or none at all. In that case, a consistent - /// default root directory will be used. - LLVM_ATTRIBUTE_DEPRECATED(static Path GetRootDirectory(), - LLVM_PATH_DEPRECATED_MSG(NOTHING)); - - /// Construct a path to a unique temporary directory that is created in - /// a "standard" place for the operating system. The directory is - /// guaranteed to be created on exit from this function. If the directory - /// cannot be created, the function will throw an exception. - /// @returns an invalid path (empty) on error - /// @param ErrMsg Optional place for an error message if an error occurs - /// @brief Construct a path to an new, unique, existing temporary - /// directory. - static Path GetTemporaryDirectory(std::string* ErrMsg = 0); - - /// Construct a vector of sys::Path that contains the "standard" system - /// library paths suitable for linking into programs. - /// @brief Construct a path to the system library directory - static void GetSystemLibraryPaths(std::vector<sys::Path>& Paths); - - /// Construct a vector of sys::Path that contains the "standard" bitcode - /// library paths suitable for linking into an llvm program. This function - /// *must* return the value of LLVM_LIB_SEARCH_PATH as well as the value - /// of LLVM_LIBDIR. It also must provide the System library paths as - /// returned by GetSystemLibraryPaths. - /// @see GetSystemLibraryPaths - /// @brief Construct a list of directories in which bitcode could be - /// found. - static void GetBitcodeLibraryPaths(std::vector<sys::Path>& Paths); - - /// Find the path to a library using its short name. Use the system - /// dependent library paths to locate the library. - /// @brief Find a library. - static Path FindLibrary(std::string& short_name); - - /// Construct a path to the current user's home directory. The - /// implementation must use an operating system specific mechanism for - /// determining the user's home directory. For example, the environment - /// variable "HOME" could be used on Unix. If a given operating system - /// does not have the concept of a user's home directory, this static - /// constructor must provide the same result as GetRootDirectory. - /// @brief Construct a path to the current user's "home" directory - static Path GetUserHomeDirectory(); - - /// Construct a path to the current directory for the current process. - /// @returns The current working directory. - /// @brief Returns the current working directory. - static Path GetCurrentDirectory(); - - /// Return the suffix commonly used on file names that contain an - /// executable. - /// @returns The executable file suffix for the current platform. - /// @brief Return the executable file suffix. - static StringRef GetEXESuffix(); - - /// Return the suffix commonly used on file names that contain a shared - /// object, shared archive, or dynamic link library. Such files are - /// linked at runtime into a process and their code images are shared - /// between processes. - /// @returns The dynamic link library suffix for the current platform. - /// @brief Return the dynamic link library suffix. - static StringRef GetDLLSuffix(); - - /// GetMainExecutable - Return the path to the main executable, given the - /// value of argv[0] from program startup and the address of main itself. - /// In extremis, this function may fail and return an empty path. - static Path GetMainExecutable(const char *argv0, void *MainAddr); - - /// This is one of the very few ways in which a path can be constructed - /// with a syntactically invalid name. The only *legal* invalid name is an - /// empty one. Other invalid names are not permitted. Empty paths are - /// provided so that they can be used to indicate null or error results in - /// other lib/System functionality. - /// @brief Construct an empty (and invalid) path. - Path() : path() {} - Path(const Path &that) : path(that.path) {} - - /// This constructor will accept a char* or std::string as a path. No - /// checking is done on this path to determine if it is valid. To - /// determine validity of the path, use the isValid method. - /// @param p The path to assign. - /// @brief Construct a Path from a string. - explicit Path(StringRef p); - - /// This constructor will accept a character range as a path. No checking - /// is done on this path to determine if it is valid. To determine - /// validity of the path, use the isValid method. - /// @param StrStart A pointer to the first character of the path name - /// @param StrLen The length of the path name at StrStart - /// @brief Construct a Path from a string. - Path(const char *StrStart, unsigned StrLen); - - /// @} - /// @name Operators - /// @{ - public: - /// Makes a copy of \p that to \p this. - /// @returns \p this - /// @brief Assignment Operator - Path &operator=(const Path &that) { - path = that.path; - return *this; - } - - /// Makes a copy of \p that to \p this. - /// @param that A StringRef denoting the path - /// @returns \p this - /// @brief Assignment Operator - Path &operator=(StringRef that); - - /// Compares \p this Path with \p that Path for equality. - /// @returns true if \p this and \p that refer to the same thing. - /// @brief Equality Operator - bool operator==(const Path &that) const; - - /// Compares \p this Path with \p that Path for inequality. - /// @returns true if \p this and \p that refer to different things. - /// @brief Inequality Operator - bool operator!=(const Path &that) const { return !(*this == that); } - - /// Determines if \p this Path is less than \p that Path. This is required - /// so that Path objects can be placed into ordered collections (e.g. - /// std::map). The comparison is done lexicographically as defined by - /// the std::string::compare method. - /// @returns true if \p this path is lexicographically less than \p that. - /// @brief Less Than Operator - bool operator<(const Path& that) const; - - /// @} - /// @name Path Accessors - /// @{ - public: - /// This function will use an operating system specific algorithm to - /// determine if the current value of \p this is a syntactically valid - /// path name for the operating system. The path name does not need to - /// exist, validity is simply syntactical. Empty paths are always invalid. - /// @returns true iff the path name is syntactically legal for the - /// host operating system. - /// @brief Determine if a path is syntactically valid or not. - bool isValid() const; - - /// This function determines if the contents of the path name are empty. - /// That is, the path name has a zero length. This does NOT determine if - /// if the file is empty. To get the length of the file itself, Use the - /// PathWithStatus::getFileStatus() method and then the getSize() method - /// on the returned FileStatus object. - /// @returns true iff the path is empty. - /// @brief Determines if the path name is empty (invalid). - bool isEmpty() const { return path.empty(); } - - /// This function returns the last component of the path name. The last - /// component is the file or directory name occurring after the last - /// directory separator. If no directory separator is present, the entire - /// path name is returned (i.e. same as toString). - /// @returns StringRef containing the last component of the path name. - /// @brief Returns the last component of the path name. - LLVM_ATTRIBUTE_DEPRECATED( - StringRef getLast() const, - LLVM_PATH_DEPRECATED_MSG(path::filename)); - - /// This function strips off the path and suffix of the file or directory - /// name and returns just the basename. For example /a/foo.bar would cause - /// this function to return "foo". - /// @returns StringRef containing the basename of the path - /// @brief Get the base name of the path - LLVM_ATTRIBUTE_DEPRECATED(StringRef getBasename() const, - LLVM_PATH_DEPRECATED_MSG(path::stem)); - - /// This function strips off the suffix of the path beginning with the - /// path separator ('/' on Unix, '\' on Windows) and returns the result. - LLVM_ATTRIBUTE_DEPRECATED(StringRef getDirname() const, - LLVM_PATH_DEPRECATED_MSG(path::parent_path)); - - /// This function strips off the path and basename(up to and - /// including the last dot) of the file or directory name and - /// returns just the suffix. For example /a/foo.bar would cause - /// this function to return "bar". - /// @returns StringRef containing the suffix of the path - /// @brief Get the suffix of the path - LLVM_ATTRIBUTE_DEPRECATED(StringRef getSuffix() const, - LLVM_PATH_DEPRECATED_MSG(path::extension)); - - /// Obtain a 'C' string for the path name. - /// @returns a 'C' string containing the path name. - /// @brief Returns the path as a C string. - const char *c_str() const { return path.c_str(); } - const std::string &str() const { return path; } - - - /// size - Return the length in bytes of this path name. - size_t size() const { return path.size(); } - - /// empty - Returns true if the path is empty. - unsigned empty() const { return path.empty(); } - - /// @} - /// @name Disk Accessors - /// @{ - public: - /// This function determines if the path name is absolute, as opposed to - /// relative. - /// @brief Determine if the path is absolute. - LLVM_ATTRIBUTE_DEPRECATED( - bool isAbsolute() const, - LLVM_PATH_DEPRECATED_MSG(path::is_absolute)); - - /// This function determines if the path name is absolute, as opposed to - /// relative. - /// @brief Determine if the path is absolute. - LLVM_ATTRIBUTE_DEPRECATED( - static bool isAbsolute(const char *NameStart, unsigned NameLen), - LLVM_PATH_DEPRECATED_MSG(path::is_absolute)); - - /// This function opens the file associated with the path name provided by - /// the Path object and reads its magic number. If the magic number at the - /// start of the file matches \p magic, true is returned. In all other - /// cases (file not found, file not accessible, etc.) it returns false. - /// @returns true if the magic number of the file matches \p magic. - /// @brief Determine if file has a specific magic number - LLVM_ATTRIBUTE_DEPRECATED(bool hasMagicNumber(StringRef magic) const, - LLVM_PATH_DEPRECATED_MSG(fs::has_magic)); - - /// This function retrieves the first \p len bytes of the file associated - /// with \p this. These bytes are returned as the "magic number" in the - /// \p Magic parameter. - /// @returns true if the Path is a file and the magic number is retrieved, - /// false otherwise. - /// @brief Get the file's magic number. - bool getMagicNumber(std::string& Magic, unsigned len) const; - - /// This function determines if the path name in the object references an - /// archive file by looking at its magic number. - /// @returns true if the file starts with the magic number for an archive - /// file. - /// @brief Determine if the path references an archive file. - bool isArchive() const; - - /// This function determines if the path name in the object references an - /// LLVM Bitcode file by looking at its magic number. - /// @returns true if the file starts with the magic number for LLVM - /// bitcode files. - /// @brief Determine if the path references a bitcode file. - bool isBitcodeFile() const; - - /// This function determines if the path name in the object references a - /// native Dynamic Library (shared library, shared object) by looking at - /// the file's magic number. The Path object must reference a file, not a - /// directory. - /// @returns true if the file starts with the magic number for a native - /// shared library. - /// @brief Determine if the path references a dynamic library. - bool isDynamicLibrary() const; - - /// This function determines if the path name in the object references a - /// native object file by looking at it's magic number. The term object - /// file is defined as "an organized collection of separate, named - /// sequences of binary data." This covers the obvious file formats such - /// as COFF and ELF, but it also includes llvm ir bitcode, archives, - /// libraries, etc... - /// @returns true if the file starts with the magic number for an object - /// file. - /// @brief Determine if the path references an object file. - bool isObjectFile() const; - - /// This function determines if the path name references an existing file - /// or directory in the file system. - /// @returns true if the pathname references an existing file or - /// directory. - /// @brief Determines if the path is a file or directory in - /// the file system. - LLVM_ATTRIBUTE_DEPRECATED(bool exists() const, - LLVM_PATH_DEPRECATED_MSG(fs::exists)); - - /// This function determines if the path name references an - /// existing directory. - /// @returns true if the pathname references an existing directory. - /// @brief Determines if the path is a directory in the file system. - LLVM_ATTRIBUTE_DEPRECATED(bool isDirectory() const, - LLVM_PATH_DEPRECATED_MSG(fs::is_directory)); - - /// This function determines if the path name references an - /// existing symbolic link. - /// @returns true if the pathname references an existing symlink. - /// @brief Determines if the path is a symlink in the file system. - LLVM_ATTRIBUTE_DEPRECATED(bool isSymLink() const, - LLVM_PATH_DEPRECATED_MSG(fs::is_symlink)); - - /// This function determines if the path name references a readable file - /// or directory in the file system. This function checks for - /// the existence and readability (by the current program) of the file - /// or directory. - /// @returns true if the pathname references a readable file. - /// @brief Determines if the path is a readable file or directory - /// in the file system. - bool canRead() const; - - /// This function determines if the path name references a writable file - /// or directory in the file system. This function checks for the - /// existence and writability (by the current program) of the file or - /// directory. - /// @returns true if the pathname references a writable file. - /// @brief Determines if the path is a writable file or directory - /// in the file system. - bool canWrite() const; - - /// This function checks that what we're trying to work only on a regular - /// file. Check for things like /dev/null, any block special file, or - /// other things that aren't "regular" regular files. - /// @returns true if the file is S_ISREG. - /// @brief Determines if the file is a regular file - bool isRegularFile() const; - - /// This function determines if the path name references an executable - /// file in the file system. This function checks for the existence and - /// executability (by the current program) of the file. - /// @returns true if the pathname references an executable file. - /// @brief Determines if the path is an executable file in the file - /// system. - bool canExecute() const; - - /// This function builds a list of paths that are the names of the - /// files and directories in a directory. - /// @returns true if an error occurs, true otherwise - /// @brief Build a list of directory's contents. - bool getDirectoryContents( - std::set<Path> &paths, ///< The resulting list of file & directory names - std::string* ErrMsg ///< Optional place to return an error message. - ) const; - - /// @} - /// @name Path Mutators - /// @{ - public: - /// The path name is cleared and becomes empty. This is an invalid - /// path name but is the *only* invalid path name. This is provided - /// so that path objects can be used to indicate the lack of a - /// valid path being found. - /// @brief Make the path empty. - void clear() { path.clear(); } - - /// This method sets the Path object to \p unverified_path. This can fail - /// if the \p unverified_path does not pass the syntactic checks of the - /// isValid() method. If verification fails, the Path object remains - /// unchanged and false is returned. Otherwise true is returned and the - /// Path object takes on the path value of \p unverified_path - /// @returns true if the path was set, false otherwise. - /// @param unverified_path The path to be set in Path object. - /// @brief Set a full path from a StringRef - bool set(StringRef unverified_path); - - /// One path component is removed from the Path. If only one component is - /// present in the path, the Path object becomes empty. If the Path object - /// is empty, no change is made. - /// @returns false if the path component could not be removed. - /// @brief Removes the last directory component of the Path. - bool eraseComponent(); - - /// The \p component is added to the end of the Path if it is a legal - /// name for the operating system. A directory separator will be added if - /// needed. - /// @returns false if the path component could not be added. - /// @brief Appends one path component to the Path. - bool appendComponent(StringRef component); - - /// A period and the \p suffix are appended to the end of the pathname. - /// When the \p suffix is empty, no action is performed. - /// @brief Adds a period and the \p suffix to the end of the pathname. - void appendSuffix(StringRef suffix); - - /// The suffix of the filename is erased. The suffix begins with and - /// includes the last . character in the filename after the last directory - /// separator and extends until the end of the name. If no . character is - /// after the last directory separator, then the file name is left - /// unchanged (i.e. it was already without a suffix) but the function - /// returns false. - /// @returns false if there was no suffix to remove, true otherwise. - /// @brief Remove the suffix from a path name. - bool eraseSuffix(); - - /// The current Path name is made unique in the file system. Upon return, - /// the Path will have been changed to make a unique file in the file - /// system or it will not have been changed if the current path name is - /// already unique. - /// @throws std::string if an unrecoverable error occurs. - /// @brief Make the current path name unique in the file system. - bool makeUnique( bool reuse_current /*= true*/, std::string* ErrMsg ); - - /// The current Path name is made absolute by prepending the - /// current working directory if necessary. - LLVM_ATTRIBUTE_DEPRECATED( - void makeAbsolute(), - LLVM_PATH_DEPRECATED_MSG(fs::make_absolute)); - - /// @} - /// @name Disk Mutators - /// @{ - public: - /// This method attempts to make the file referenced by the Path object - /// available for reading so that the canRead() method will return true. - /// @brief Make the file readable; - bool makeReadableOnDisk(std::string* ErrMsg = 0); - - /// This method attempts to make the file referenced by the Path object - /// available for writing so that the canWrite() method will return true. - /// @brief Make the file writable; - bool makeWriteableOnDisk(std::string* ErrMsg = 0); - - /// This method attempts to make the file referenced by the Path object - /// available for execution so that the canExecute() method will return - /// true. - /// @brief Make the file readable; - bool makeExecutableOnDisk(std::string* ErrMsg = 0); - - /// This method allows the last modified time stamp and permission bits - /// to be set on the disk object referenced by the Path. - /// @throws std::string if an error occurs. - /// @returns true on error. - /// @brief Set the status information. - bool setStatusInfoOnDisk(const FileStatus &SI, - std::string *ErrStr = 0) const; - - /// This method attempts to create a directory in the file system with the - /// same name as the Path object. The \p create_parents parameter controls - /// whether intermediate directories are created or not. if \p - /// create_parents is true, then an attempt will be made to create all - /// intermediate directories, as needed. If \p create_parents is false, - /// then only the final directory component of the Path name will be - /// created. The created directory will have no entries. - /// @returns true if the directory could not be created, false otherwise - /// @brief Create the directory this Path refers to. - bool createDirectoryOnDisk( - bool create_parents = false, ///< Determines whether non-existent - ///< directory components other than the last one (the "parents") - ///< are created or not. - std::string* ErrMsg = 0 ///< Optional place to put error messages. - ); - - /// This method attempts to create a file in the file system with the same - /// name as the Path object. The intermediate directories must all exist - /// at the time this method is called. Use createDirectoriesOnDisk to - /// accomplish that. The created file will be empty upon return from this - /// function. - /// @returns true if the file could not be created, false otherwise. - /// @brief Create the file this Path refers to. - bool createFileOnDisk( - std::string* ErrMsg = 0 ///< Optional place to put error messages. - ); - - /// This is like createFile except that it creates a temporary file. A - /// unique temporary file name is generated based on the contents of - /// \p this before the call. The new name is assigned to \p this and the - /// file is created. Note that this will both change the Path object - /// *and* create the corresponding file. This function will ensure that - /// the newly generated temporary file name is unique in the file system. - /// @returns true if the file couldn't be created, false otherwise. - /// @brief Create a unique temporary file - bool createTemporaryFileOnDisk( - bool reuse_current = false, ///< When set to true, this parameter - ///< indicates that if the current file name does not exist then - ///< it will be used without modification. - std::string* ErrMsg = 0 ///< Optional place to put error messages - ); - - /// This method renames the file referenced by \p this as \p newName. The - /// file referenced by \p this must exist. The file referenced by - /// \p newName does not need to exist. - /// @returns true on error, false otherwise - /// @brief Rename one file as another. - bool renamePathOnDisk(const Path& newName, std::string* ErrMsg); - - /// This method attempts to destroy the file or directory named by the - /// last component of the Path. If the Path refers to a directory and the - /// \p destroy_contents is false, an attempt will be made to remove just - /// the directory (the final Path component). If \p destroy_contents is - /// true, an attempt will be made to remove the entire contents of the - /// directory, recursively. If the Path refers to a file, the - /// \p destroy_contents parameter is ignored. - /// @param destroy_contents Indicates whether the contents of a destroyed - /// @param Err An optional string to receive an error message. - /// directory should also be destroyed (recursively). - /// @returns false if the file/directory was destroyed, true on error. - /// @brief Removes the file or directory from the filesystem. - bool eraseFromDisk(bool destroy_contents = false, - std::string *Err = 0) const; - - - /// MapInFilePages - This is a low level system API to map in the file - /// that is currently opened as FD into the current processes' address - /// space for read only access. This function may return null on failure - /// or if the system cannot provide the following constraints: - /// 1) The pages must be valid after the FD is closed, until - /// UnMapFilePages is called. - /// 2) Any padding after the end of the file must be zero filled, if - /// present. - /// 3) The pages must be contiguous. - /// - /// This API is not intended for general use, clients should use - /// MemoryBuffer::getFile instead. - static const char *MapInFilePages(int FD, size_t FileSize, - off_t Offset); - - /// UnMapFilePages - Free pages mapped into the current process by - /// MapInFilePages. - /// - /// This API is not intended for general use, clients should use - /// MemoryBuffer::getFile instead. - static void UnMapFilePages(const char *Base, size_t FileSize); - - /// @} - /// @name Data - /// @{ - protected: - // Our win32 implementation relies on this string being mutable. - mutable std::string path; ///< Storage for the path name. - - - /// @} - }; - - /// This class is identical to Path class except it allows you to obtain the - /// file status of the Path as well. The reason for the distinction is one of - /// efficiency. First, the file status requires additional space and the space - /// is incorporated directly into PathWithStatus without an additional malloc. - /// Second, obtaining status information is an expensive operation on most - /// operating systems so we want to be careful and explicit about where we - /// allow this operation in LLVM. - /// @brief Path with file status class. - class PathWithStatus : public Path { - /// @name Constructors - /// @{ - public: - /// @brief Default constructor - PathWithStatus() : Path(), status(), fsIsValid(false) {} - - /// @brief Copy constructor - PathWithStatus(const PathWithStatus &that) - : Path(static_cast<const Path&>(that)), status(that.status), - fsIsValid(that.fsIsValid) {} - - /// This constructor allows construction from a Path object - /// @brief Path constructor - PathWithStatus(const Path &other) - : Path(other), status(), fsIsValid(false) {} - - /// This constructor will accept a char* or std::string as a path. No - /// checking is done on this path to determine if it is valid. To - /// determine validity of the path, use the isValid method. - /// @brief Construct a Path from a string. - explicit PathWithStatus( - StringRef p ///< The path to assign. - ) : Path(p), status(), fsIsValid(false) {} - - /// This constructor will accept a character range as a path. No checking - /// is done on this path to determine if it is valid. To determine - /// validity of the path, use the isValid method. - /// @brief Construct a Path from a string. - explicit PathWithStatus( - const char *StrStart, ///< Pointer to the first character of the path - unsigned StrLen ///< Length of the path. - ) : Path(StrStart, StrLen), status(), fsIsValid(false) {} - - /// Makes a copy of \p that to \p this. - /// @returns \p this - /// @brief Assignment Operator - PathWithStatus &operator=(const PathWithStatus &that) { - static_cast<Path&>(*this) = static_cast<const Path&>(that); - status = that.status; - fsIsValid = that.fsIsValid; - return *this; - } - - /// Makes a copy of \p that to \p this. - /// @returns \p this - /// @brief Assignment Operator - PathWithStatus &operator=(const Path &that) { - static_cast<Path&>(*this) = static_cast<const Path&>(that); - fsIsValid = false; - return *this; - } - - /// @} - /// @name Methods - /// @{ - public: - /// This function returns status information about the file. The type of - /// path (file or directory) is updated to reflect the actual contents - /// of the file system. - /// @returns 0 on failure, with Error explaining why (if non-zero), - /// otherwise returns a pointer to a FileStatus structure on success. - /// @brief Get file status. - const FileStatus *getFileStatus( - bool forceUpdate = false, ///< Force an update from the file system - std::string *Error = 0 ///< Optional place to return an error msg. - ) const; - - /// @} - /// @name Data - /// @{ - private: - mutable FileStatus status; ///< Status information. - mutable bool fsIsValid; ///< Whether we've obtained it or not - - /// @} - }; - - /// This enumeration delineates the kinds of files that LLVM knows about. - enum LLVMFileType { - Unknown_FileType = 0, ///< Unrecognized file - Bitcode_FileType, ///< Bitcode file - Archive_FileType, ///< ar style archive file - ELF_Relocatable_FileType, ///< ELF Relocatable object file - ELF_Executable_FileType, ///< ELF Executable image - ELF_SharedObject_FileType, ///< ELF dynamically linked shared lib - ELF_Core_FileType, ///< ELF core image - Mach_O_Object_FileType, ///< Mach-O Object file - Mach_O_Executable_FileType, ///< Mach-O Executable - Mach_O_FixedVirtualMemorySharedLib_FileType, ///< Mach-O Shared Lib, FVM - Mach_O_Core_FileType, ///< Mach-O Core File - Mach_O_PreloadExecutable_FileType, ///< Mach-O Preloaded Executable - Mach_O_DynamicallyLinkedSharedLib_FileType, ///< Mach-O dynlinked shared lib - Mach_O_DynamicLinker_FileType, ///< The Mach-O dynamic linker - Mach_O_Bundle_FileType, ///< Mach-O Bundle file - Mach_O_DynamicallyLinkedSharedLibStub_FileType, ///< Mach-O Shared lib stub - Mach_O_DSYMCompanion_FileType, ///< Mach-O dSYM companion file - COFF_FileType ///< COFF object file or lib - }; - - /// This utility function allows any memory block to be examined in order - /// to determine its file type. - LLVMFileType IdentifyFileType(const char*magic, unsigned length); - - /// This function can be used to copy the file specified by Src to the - /// file specified by Dest. If an error occurs, Dest is removed. - /// @returns true if an error occurs, false otherwise - /// @brief Copy one file to another. - bool CopyFile(const Path& Dest, const Path& Src, std::string* ErrMsg); - - /// This is the OS-specific path separator: a colon on Unix or a semicolon - /// on Windows. - extern const char PathSeparator; -} - -} - -#endif diff --git a/contrib/llvm/include/llvm/Support/PathV2.h b/contrib/llvm/include/llvm/Support/PathV2.h deleted file mode 100644 index ae1a21c..0000000 --- a/contrib/llvm/include/llvm/Support/PathV2.h +++ /dev/null @@ -1,381 +0,0 @@ -//===- llvm/Support/PathV2.h - Path Operating System Concept ----*- 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 the llvm::sys::path namespace. It is designed after -// TR2/boost filesystem (v3), but modified to remove exception handling and the -// path class. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_SUPPORT_PATHV2_H -#define LLVM_SUPPORT_PATHV2_H - -#include "llvm/ADT/SmallString.h" -#include "llvm/ADT/Twine.h" -#include "llvm/Support/DataTypes.h" -#include <iterator> - -namespace llvm { -namespace sys { -namespace path { - -/// @name Lexical Component Iterator -/// @{ - -/// @brief Path iterator. -/// -/// This is a bidirectional iterator that iterates over the individual -/// components in \a path. The forward traversal order is as follows: -/// * The root-name element, if present. -/// * The root-directory element, if present. -/// * Each successive filename element, if present. -/// * Dot, if one or more trailing non-root slash characters are present. -/// The backwards traversal order is the reverse of forward traversal. -/// -/// Iteration examples. Each component is separated by ',': -/// @code -/// / => / -/// /foo => /,foo -/// foo/ => foo,. -/// /foo/bar => /,foo,bar -/// ../ => ..,. -/// C:\foo\bar => C:,/,foo,bar -/// @endcode -class const_iterator { - StringRef Path; ///< The entire path. - StringRef Component; ///< The current component. Not necessarily in Path. - size_t Position; ///< The iterators current position within Path. - - // An end iterator has Position = Path.size() + 1. - friend const_iterator begin(StringRef path); - friend const_iterator end(StringRef path); - -public: - typedef const StringRef value_type; - typedef ptrdiff_t difference_type; - typedef value_type &reference; - typedef value_type *pointer; - typedef std::bidirectional_iterator_tag iterator_category; - - reference operator*() const { return Component; } - pointer operator->() const { return &Component; } - const_iterator &operator++(); // preincrement - const_iterator &operator++(int); // postincrement - const_iterator &operator--(); // predecrement - const_iterator &operator--(int); // postdecrement - bool operator==(const const_iterator &RHS) const; - bool operator!=(const const_iterator &RHS) const; - - /// @brief Difference in bytes between this and RHS. - ptrdiff_t operator-(const const_iterator &RHS) const; -}; - -typedef std::reverse_iterator<const_iterator> reverse_iterator; - -/// @brief Get begin iterator over \a path. -/// @param path Input path. -/// @returns Iterator initialized with the first component of \a path. -const_iterator begin(StringRef path); - -/// @brief Get end iterator over \a path. -/// @param path Input path. -/// @returns Iterator initialized to the end of \a path. -const_iterator end(StringRef path); - -/// @brief Get reverse begin iterator over \a path. -/// @param path Input path. -/// @returns Iterator initialized with the first reverse component of \a path. -inline reverse_iterator rbegin(StringRef path) { - return reverse_iterator(end(path)); -} - -/// @brief Get reverse end iterator over \a path. -/// @param path Input path. -/// @returns Iterator initialized to the reverse end of \a path. -inline reverse_iterator rend(StringRef path) { - return reverse_iterator(begin(path)); -} - -/// @} -/// @name Lexical Modifiers -/// @{ - -/// @brief Remove the last component from \a path unless it is the root dir. -/// -/// @code -/// directory/filename.cpp => directory/ -/// directory/ => directory -/// / => / -/// @endcode -/// -/// @param path A path that is modified to not have a file component. -void remove_filename(SmallVectorImpl<char> &path); - -/// @brief Replace the file extension of \a path with \a extension. -/// -/// @code -/// ./filename.cpp => ./filename.extension -/// ./filename => ./filename.extension -/// ./ => ./.extension -/// @endcode -/// -/// @param path A path that has its extension replaced with \a extension. -/// @param extension The extension to be added. It may be empty. It may also -/// optionally start with a '.', if it does not, one will be -/// prepended. -void replace_extension(SmallVectorImpl<char> &path, const Twine &extension); - -/// @brief Append to path. -/// -/// @code -/// /foo + bar/f => /foo/bar/f -/// /foo/ + bar/f => /foo/bar/f -/// foo + bar/f => foo/bar/f -/// @endcode -/// -/// @param path Set to \a path + \a component. -/// @param a The component to be appended to \a path. -void append(SmallVectorImpl<char> &path, const Twine &a, - const Twine &b = "", - const Twine &c = "", - const Twine &d = ""); - -/// @brief Append to path. -/// -/// @code -/// /foo + [bar,f] => /foo/bar/f -/// /foo/ + [bar,f] => /foo/bar/f -/// foo + [bar,f] => foo/bar/f -/// @endcode -/// -/// @param path Set to \a path + [\a begin, \a end). -/// @param begin Start of components to append. -/// @param end One past the end of components to append. -void append(SmallVectorImpl<char> &path, - const_iterator begin, const_iterator end); - -/// @} -/// @name Transforms (or some other better name) -/// @{ - -/// Convert path to the native form. 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. -/// @param result Holds the result of the transformation. -void native(const Twine &path, SmallVectorImpl<char> &result); - -/// @} -/// @name Lexical Observers -/// @{ - -/// @brief Get root name. -/// -/// @code -/// //net/hello => //net -/// c:/hello => c: (on Windows, on other platforms nothing) -/// /hello => <empty> -/// @endcode -/// -/// @param path Input path. -/// @result The root name of \a path if it has one, otherwise "". -const StringRef root_name(StringRef path); - -/// @brief Get root directory. -/// -/// @code -/// /goo/hello => / -/// c:/hello => / -/// d/file.txt => <empty> -/// @endcode -/// -/// @param path Input path. -/// @result The root directory of \a path if it has one, otherwise -/// "". -const StringRef root_directory(StringRef path); - -/// @brief Get root path. -/// -/// Equivalent to root_name + root_directory. -/// -/// @param path Input path. -/// @result The root path of \a path if it has one, otherwise "". -const StringRef root_path(StringRef path); - -/// @brief Get relative path. -/// -/// @code -/// C:\hello\world => hello\world -/// foo/bar => foo/bar -/// /foo/bar => foo/bar -/// @endcode -/// -/// @param path Input path. -/// @result The path starting after root_path if one exists, otherwise "". -const StringRef relative_path(StringRef path); - -/// @brief Get parent path. -/// -/// @code -/// / => <empty> -/// /foo => / -/// foo/../bar => foo/.. -/// @endcode -/// -/// @param path Input path. -/// @result The parent path of \a path if one exists, otherwise "". -const StringRef parent_path(StringRef path); - -/// @brief Get filename. -/// -/// @code -/// /foo.txt => foo.txt -/// . => . -/// .. => .. -/// / => / -/// @endcode -/// -/// @param path Input path. -/// @result The filename part of \a path. This is defined as the last component -/// of \a path. -const StringRef filename(StringRef path); - -/// @brief Get stem. -/// -/// If filename contains a dot but not solely one or two dots, result is the -/// substring of filename ending at (but not including) the last dot. Otherwise -/// it is filename. -/// -/// @code -/// /foo/bar.txt => bar -/// /foo/bar => bar -/// /foo/.txt => <empty> -/// /foo/. => . -/// /foo/.. => .. -/// @endcode -/// -/// @param path Input path. -/// @result The stem of \a path. -const StringRef stem(StringRef path); - -/// @brief Get extension. -/// -/// If filename contains a dot but not solely one or two dots, result is the -/// substring of filename starting at (and including) the last dot, and ending -/// at the end of \a path. Otherwise "". -/// -/// @code -/// /foo/bar.txt => .txt -/// /foo/bar => <empty> -/// /foo/.txt => .txt -/// @endcode -/// -/// @param path Input path. -/// @result The extension of \a path. -const StringRef extension(StringRef path); - -/// @brief Check whether the given char is a path separator on the host OS. -/// -/// @param value a character -/// @result true if \a value is a path separator character on the host OS -bool is_separator(char value); - -/// @brief Get the typical temporary directory for the system, e.g., -/// "/var/tmp" or "C:/TEMP" -/// -/// @param erasedOnReboot Whether to favor a path that is erased on reboot -/// rather than one that potentially persists longer. This parameter will be -/// ignored if the user or system has set the typical environment variable -/// (e.g., TEMP on Windows, TMPDIR on *nix) to specify a temporary directory. -/// -/// @param result Holds the resulting path name. -void system_temp_directory(bool erasedOnReboot, SmallVectorImpl<char> &result); - -/// @brief Has root name? -/// -/// root_name != "" -/// -/// @param path Input path. -/// @result True if the path has a root name, false otherwise. -bool has_root_name(const Twine &path); - -/// @brief Has root directory? -/// -/// root_directory != "" -/// -/// @param path Input path. -/// @result True if the path has a root directory, false otherwise. -bool has_root_directory(const Twine &path); - -/// @brief Has root path? -/// -/// root_path != "" -/// -/// @param path Input path. -/// @result True if the path has a root path, false otherwise. -bool has_root_path(const Twine &path); - -/// @brief Has relative path? -/// -/// relative_path != "" -/// -/// @param path Input path. -/// @result True if the path has a relative path, false otherwise. -bool has_relative_path(const Twine &path); - -/// @brief Has parent path? -/// -/// parent_path != "" -/// -/// @param path Input path. -/// @result True if the path has a parent path, false otherwise. -bool has_parent_path(const Twine &path); - -/// @brief Has filename? -/// -/// filename != "" -/// -/// @param path Input path. -/// @result True if the path has a filename, false otherwise. -bool has_filename(const Twine &path); - -/// @brief Has stem? -/// -/// stem != "" -/// -/// @param path Input path. -/// @result True if the path has a stem, false otherwise. -bool has_stem(const Twine &path); - -/// @brief Has extension? -/// -/// extension != "" -/// -/// @param path Input path. -/// @result True if the path has a extension, false otherwise. -bool has_extension(const Twine &path); - -/// @brief Is path absolute? -/// -/// @param path Input path. -/// @result True if the path is absolute, false if it is not. -bool is_absolute(const Twine &path); - -/// @brief Is path relative? -/// -/// @param path Input path. -/// @result True if the path is relative, false if it is not. -bool is_relative(const Twine &path); - -} // end namespace path -} // end namespace sys -} // end namespace llvm - -#endif diff --git a/contrib/llvm/include/llvm/Support/PatternMatch.h b/contrib/llvm/include/llvm/Support/PatternMatch.h index 95d9d78..240bb81 100644 --- a/contrib/llvm/include/llvm/Support/PatternMatch.h +++ b/contrib/llvm/include/llvm/Support/PatternMatch.h @@ -696,10 +696,17 @@ m_ZExt(const OpTy &Op) { /// m_UIToFP template<typename OpTy> inline CastClass_match<OpTy, Instruction::UIToFP> -m_UIToFp(const OpTy &Op) { +m_UIToFP(const OpTy &Op) { return CastClass_match<OpTy, Instruction::UIToFP>(Op); } +/// m_SIToFP +template<typename OpTy> +inline CastClass_match<OpTy, Instruction::SIToFP> +m_SIToFP(const OpTy &Op) { + return CastClass_match<OpTy, Instruction::SIToFP>(Op); +} + //===----------------------------------------------------------------------===// // Matchers for unary operators // @@ -1034,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) { @@ -1073,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/contrib/llvm/include/llvm/Support/PrettyStackTrace.h b/contrib/llvm/include/llvm/Support/PrettyStackTrace.h index 2122e06..4f68fca2 100644 --- a/contrib/llvm/include/llvm/Support/PrettyStackTrace.h +++ b/contrib/llvm/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/contrib/llvm/include/llvm/Support/Process.h b/contrib/llvm/include/llvm/Support/Process.h index 4256d4a..2172036 100644 --- a/contrib/llvm/include/llvm/Support/Process.h +++ b/contrib/llvm/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; @@ -50,13 +56,13 @@ protected: public: /// \brief Operating system specific type to identify a process. /// - /// Note that the windows one is defined to 'void *' as this is the - /// documented type for HANDLE on windows, and we don't want to pull in the + /// Note that the windows one is defined to 'unsigned long' as this is the + /// documented type for DWORD on windows, and we don't want to pull in the /// Windows headers here. #if defined(LLVM_ON_UNIX) typedef pid_t id_type; #elif defined(LLVM_ON_WIN32) - typedef void *id_type; // Must match the type of HANDLE. + typedef unsigned long id_type; // Must match the type of DWORD. #else #error Unsupported operating system. #endif @@ -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/contrib/llvm/include/llvm/Support/Program.h b/contrib/llvm/include/llvm/Support/Program.h index fb177de..00571a4 100644 --- a/contrib/llvm/include/llvm/Support/Program.h +++ b/contrib/llvm/include/llvm/Support/Program.h @@ -16,136 +16,134 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/Support/Path.h" +#include "llvm/Support/system_error.h" namespace llvm { class error_code; namespace sys { - // TODO: Add operations to communicate with the process, redirect its I/O, - // etc. - - /// This class provides an abstraction for programs that are executable by the - /// operating system. It provides a platform generic way to find executable - /// programs from the path and to execute them in various ways. The sys::Path - /// class is used to specify the location of the Program. - /// @since 1.4 - /// @brief An abstraction for finding and executing programs. - class Program { - /// Opaque handle for target specific data. - void *Data_; - - // Noncopyable. - Program(const Program& other) LLVM_DELETED_FUNCTION; - Program& operator=(const Program& other) LLVM_DELETED_FUNCTION; - - /// @name Methods - /// @{ + /// This is the OS-specific separator for PATH like environment variables: + // a colon on Unix or a semicolon on Windows. +#if defined(LLVM_ON_UNIX) + const char EnvPathSeparator = ':'; +#elif defined (LLVM_ON_WIN32) + const char EnvPathSeparator = ';'; +#endif - Program(); - ~Program(); +/// @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 - /// This function executes the program using the \p arguments provided. The - /// invoked program will inherit the stdin, stdout, and stderr file - /// descriptors, the environment and other configuration settings of the - /// invoking program. If Path::executable() does not return true when this - /// function is called then a std::string is thrown. - /// @returns false in case of error, true otherwise. - /// @see FindProgramByName - /// @brief Executes the program with the given set of \p args. - bool Execute - ( const Path& path, ///< sys::Path object providing the path of the - ///< program to be executed. It is presumed this is the result of - ///< the FindProgramByName method. - const char** args, ///< A vector of strings that are passed to the + /// 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 + /// returned unmodified. + /// @returns A Path object initialized to the path of the program or a + /// Path object that is empty (invalid) if the program could not be found. + /// @brief Construct a Program by finding it by name. + std::string FindProgramByName(const std::string& name); + + // These functions change the specified standard stream (stdin, stdout, or + // stderr) to binary mode. They return errc::success if the specified stream + // was changed. Otherwise a platform dependent error is returned. + error_code ChangeStdinToBinary(); + error_code ChangeStdoutToBinary(); + error_code ChangeStderrToBinary(); + + /// This function executes the program using the arguments provided. The + /// invoked program will inherit the stdin, stdout, and stderr file + /// descriptors, the environment and other configuration settings of the + /// invoking program. + /// This function waits the program to finish. + /// @returns an integer result code indicating the status of the program. + /// A zero or positive value indicates the result code of the program. + /// -1 indicates failure to execute + /// -2 indicates a crash during execution or timeout + int ExecuteAndWait( + StringRef Program, ///< Path of the program to be executed. It is + /// presumed this is the result of the FindProgramByName method. + const char **args, ///< A vector of strings that are passed to the ///< program. The first element should be the name of the program. ///< The list *must* be terminated by a null char* entry. - const char ** env = 0, ///< An optional vector of strings to use for + const char **env = 0, ///< An optional vector of strings to use for ///< the program's environment. If not provided, the current program's ///< environment will be used. - const sys::Path** redirects = 0, ///< An optional array of pointers to - ///< Paths. If the array is null, no redirection is done. The array - ///< should have a size of at least three. If the pointer in the array - ///< are not null, then the inferior process's stdin(0), stdout(1), - ///< and stderr(2) will be redirected to the corresponding Paths. - ///< When an empty Path is passed in, the corresponding file + const StringRef **redirects = 0, ///< An optional array of pointers to + ///< paths. If the array is null, no redirection is done. The array + ///< should have a size of at least three. The inferior process's + ///< stdin(0), stdout(1), and stderr(2) will be redirected to the + ///< corresponding paths. + ///< When an empty path is passed in, the corresponding file ///< descriptor will be disconnected (ie, /dev/null'd) in a portable ///< way. + unsigned secondsToWait = 0, ///< 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 call returns. If zero, + ///< this function will wait until the child finishes or forever if + ///< it doesn't. unsigned memoryLimit = 0, ///< If non-zero, this specifies max. amount ///< of memory can be allocated by process. If memory usage will be ///< higher limit, the child is killed and this call returns. If zero ///< - no memory limit. - std::string* ErrMsg = 0 ///< If non-zero, provides a pointer to a string + 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. - ); + bool *ExecutionFailed = 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. + bool argumentsFitWithinSystemLimits(ArrayRef<const char*> Args); - /// This function waits for the program to exit. This function will block - /// the current program until the invoked program exits. - /// @returns an integer result code indicating the status of the program. - /// A zero or positive value indicates the result code of the program. - /// -1 indicates failure to execute - /// -2 indicates a crash during execution or timeout - /// @see Execute - /// @brief Waits for the program to exit. - int Wait - ( const Path& path, ///< The path to the child process executable. - 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 call returns. If zero, - ///< this function will wait until the child finishes or forever if - ///< it doesn't. - std::string* ErrMsg ///< If non-zero, provides a pointer to a string + /// 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 waiting. + ///< is non-empty upon return an error occurred while invoking the + ///< program. ); - - public: - /// 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 - /// returned unmodified. - /// @returns A Path object initialized to the path of the program or a - /// Path object that is empty (invalid) if the program could not be found. - /// @brief Construct a Program by finding it by name. - static Path FindProgramByName(const std::string& name); - - // These methods change the specified standard stream (stdin, stdout, or - // stderr) to binary mode. They return errc::success if the specified stream - // was changed. Otherwise a platform dependent error is returned. - static error_code ChangeStdinToBinary(); - static error_code ChangeStdoutToBinary(); - static error_code ChangeStderrToBinary(); - - /// A convenience function equivalent to Program prg; prg.Execute(..); - /// prg.Wait(..); - /// @see Execute, Wait - static int ExecuteAndWait(const Path& path, - const char** args, - const char ** env = 0, - const sys::Path** redirects = 0, - unsigned secondsToWait = 0, - unsigned memoryLimit = 0, - std::string* ErrMsg = 0, - bool *ExecutionFailed = 0); - - /// A convenience function equivalent to Program prg; prg.Execute(..); - /// @see Execute - static void ExecuteNoWait(const Path& path, - const char** args, - const char ** env = 0, - const sys::Path** redirects = 0, - unsigned memoryLimit = 0, - std::string* ErrMsg = 0); - - /// @} - - }; - - // Return true if the given arguments fit within system-specific - // argument length limits. - bool argumentsFitWithinSystemLimits(ArrayRef<const char*> Args); -} + } } #endif diff --git a/contrib/llvm/include/llvm/Support/RecyclingAllocator.h b/contrib/llvm/include/llvm/Support/RecyclingAllocator.h index 34ab874..001d1cf 100644 --- a/contrib/llvm/include/llvm/Support/RecyclingAllocator.h +++ b/contrib/llvm/include/llvm/Support/RecyclingAllocator.h @@ -51,15 +51,19 @@ public: template<class SubClass> void Deallocate(SubClass* E) { return Base.Deallocate(Allocator, E); } - void PrintStats() { Base.PrintStats(); } + void PrintStats() { + Allocator.PrintStats(); + Base.PrintStats(); + } }; } 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/contrib/llvm/include/llvm/Support/Regex.h b/contrib/llvm/include/llvm/Support/Regex.h index 82df2c6..3d071be 100644 --- a/contrib/llvm/include/llvm/Support/Regex.h +++ b/contrib/llvm/include/llvm/Support/Regex.h @@ -77,6 +77,10 @@ namespace llvm { /// string. std::string sub(StringRef Repl, StringRef String, std::string *Error = 0); + /// \brief If this function returns true, ^Str$ is an extended regular + /// expression that matches Str and only Str. + static bool isLiteralERE(StringRef Str); + private: struct llvm_regex *preg; int error; diff --git a/contrib/llvm/include/llvm/Support/Registry.h b/contrib/llvm/include/llvm/Support/Registry.h index 29eafb6..073becd 100644 --- a/contrib/llvm/include/llvm/Support/Registry.h +++ b/contrib/llvm/include/llvm/Support/Registry.h @@ -14,6 +14,8 @@ #ifndef LLVM_SUPPORT_REGISTRY_H #define LLVM_SUPPORT_REGISTRY_H +#include "llvm/Support/Compiler.h" + namespace llvm { /// A simple registry entry which provides only a name, description, and /// no-argument constructor. diff --git a/contrib/llvm/include/llvm/Support/Signals.h b/contrib/llvm/include/llvm/Support/Signals.h index 465656b..58ed175 100644 --- a/contrib/llvm/include/llvm/Support/Signals.h +++ b/contrib/llvm/include/llvm/Support/Signals.h @@ -28,11 +28,11 @@ namespace sys { /// This function registers signal handlers to ensure that if a signal gets /// delivered that the named file is removed. /// @brief Remove a file if a fatal signal occurs. - bool RemoveFileOnSignal(const Path &Filename, std::string* ErrMsg = 0); + bool RemoveFileOnSignal(StringRef Filename, std::string* ErrMsg = 0); /// This function removes a file from the list of files to be removed on /// signal delivery. - void DontRemoveFileOnSignal(const Path &Filename); + void DontRemoveFileOnSignal(StringRef Filename); /// When an error signal (such as SIBABRT or SIGSEGV) is delivered to the /// process, print a stack trace and then exit. diff --git a/contrib/llvm/include/llvm/Support/Solaris.h b/contrib/llvm/include/llvm/Support/Solaris.h index 6228c4b..b082285 100644 --- a/contrib/llvm/include/llvm/Support/Solaris.h +++ b/contrib/llvm/include/llvm/Support/Solaris.h @@ -17,6 +17,15 @@ #include <sys/types.h> #include <sys/regset.h> +/* Solaris doesn't have endian.h. SPARC is the only supported big-endian ISA. */ +#define BIG_ENDIAN 4321 +#define LITTLE_ENDIAN 1234 +#if defined(__sparc) || defined(__sparc__) +#define BYTE_ORDER BIG_ENDIAN +#else +#define BYTE_ORDER LITTLE_ENDIAN +#endif + #undef CS #undef DS #undef ES diff --git a/contrib/llvm/include/llvm/Support/SourceMgr.h b/contrib/llvm/include/llvm/Support/SourceMgr.h index d67914a..dd48974 100644 --- a/contrib/llvm/include/llvm/Support/SourceMgr.h +++ b/contrib/llvm/include/llvm/Support/SourceMgr.h @@ -39,7 +39,7 @@ public: DK_Warning, DK_Note }; - + /// DiagHandlerTy - Clients that want to handle their own diagnostics in a /// custom way can register a function pointer+context as a diagnostic /// handler. It gets called each time PrintMessage is invoked. @@ -98,7 +98,7 @@ public: return Buffers[i].Buffer; } - unsigned getNumBuffers() const { + size_t getNumBuffers() const { return Buffers.size(); } @@ -109,20 +109,20 @@ public: /// AddNewSourceBuffer - Add a new source buffer to this source manager. This /// takes ownership of the memory buffer. - unsigned AddNewSourceBuffer(MemoryBuffer *F, SMLoc IncludeLoc) { + size_t AddNewSourceBuffer(MemoryBuffer *F, SMLoc IncludeLoc) { SrcBuffer NB; NB.Buffer = F; NB.IncludeLoc = IncludeLoc; Buffers.push_back(NB); - return Buffers.size()-1; + return Buffers.size() - 1; } /// AddIncludeFile - Search for a file with the specified name in the current /// directory or in one of the IncludeDirs. If no file is found, this returns /// ~0, otherwise it returns the buffer ID of the stacked file. /// The full path to the included file can be found in IncludedFile. - unsigned AddIncludeFile(const std::string &Filename, SMLoc IncludeLoc, - std::string &IncludedFile); + size_t AddIncludeFile(const std::string &Filename, SMLoc IncludeLoc, + std::string &IncludedFile); /// FindBufferContainingLoc - Return the ID of the buffer containing the /// specified location, returning -1 if not found. @@ -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. @@ -221,7 +227,7 @@ public: SMDiagnostic(StringRef filename, SourceMgr::DiagKind Knd, StringRef Msg) : SM(0), Filename(filename), LineNo(-1), ColumnNo(-1), Kind(Knd), Message(Msg) {} - + // Diagnostic with a location. SMDiagnostic(const SourceMgr &sm, SMLoc L, StringRef FN, int Line, int Col, SourceMgr::DiagKind Kind, diff --git a/contrib/llvm/include/llvm/Support/StreamableMemoryObject.h b/contrib/llvm/include/llvm/Support/StreamableMemoryObject.h index 3855485..e823d48 100644 --- a/contrib/llvm/include/llvm/Support/StreamableMemoryObject.h +++ b/contrib/llvm/include/llvm/Support/StreamableMemoryObject.h @@ -38,7 +38,7 @@ class StreamableMemoryObject : public MemoryObject { /// getBase - Returns the lowest valid address in the region. /// /// @result - The lowest valid address. - virtual uint64_t getBase() const = 0; + virtual uint64_t getBase() const LLVM_OVERRIDE = 0; /// getExtent - Returns the size of the region in bytes. (The region is /// contiguous, so the highest valid address of the region @@ -46,7 +46,7 @@ class StreamableMemoryObject : public MemoryObject { /// May block until all bytes in the stream have been read /// /// @result - The size of the region. - virtual uint64_t getExtent() const = 0; + virtual uint64_t getExtent() const LLVM_OVERRIDE = 0; /// readByte - Tries to read a single byte from the region. /// May block until (address - base) bytes have been read @@ -54,7 +54,7 @@ class StreamableMemoryObject : public MemoryObject { /// @param ptr - A pointer to a byte to be filled in. Must be non-NULL. /// @result - 0 if successful; -1 if not. Failure may be due to a /// bounds violation or an implementation-specific error. - virtual int readByte(uint64_t address, uint8_t* ptr) const = 0; + virtual int readByte(uint64_t address, uint8_t *ptr) const LLVM_OVERRIDE = 0; /// readBytes - Tries to read a contiguous range of bytes from the /// region, up to the end of the region. @@ -65,17 +65,14 @@ class StreamableMemoryObject : public MemoryObject { /// /// @param address - The address of the first byte, in the same space as /// getBase(). - /// @param size - The maximum number of bytes to copy. + /// @param size - The number of bytes to copy. /// @param buf - A pointer to a buffer to be filled in. Must be non-NULL /// and large enough to hold size bytes. - /// @param copied - A pointer to a nunber that is filled in with the number - /// of bytes actually read. May be NULL. /// @result - 0 if successful; -1 if not. Failure may be due to a /// bounds violation or an implementation-specific error. virtual int readBytes(uint64_t address, uint64_t size, - uint8_t* buf, - uint64_t* copied) const = 0; + uint8_t *buf) const LLVM_OVERRIDE = 0; /// getPointer - Ensures that the requested data is in memory, and returns /// A pointer to it. More efficient than using readBytes if the @@ -110,11 +107,10 @@ public: StreamingMemoryObject(DataStreamer *streamer); virtual uint64_t getBase() const LLVM_OVERRIDE { return 0; } virtual uint64_t getExtent() const LLVM_OVERRIDE; - virtual int readByte(uint64_t address, uint8_t* ptr) const LLVM_OVERRIDE; + virtual int readByte(uint64_t address, uint8_t *ptr) const LLVM_OVERRIDE; virtual int readBytes(uint64_t address, uint64_t size, - uint8_t* buf, - uint64_t* copied) const LLVM_OVERRIDE; + uint8_t *buf) const LLVM_OVERRIDE; virtual const uint8_t *getPointer(uint64_t address, uint64_t size) const LLVM_OVERRIDE { // This could be fixed by ensuring the bytes are fetched and making a copy, diff --git a/contrib/llvm/include/llvm/Support/StringRefMemoryObject.h b/contrib/llvm/include/llvm/Support/StringRefMemoryObject.h new file mode 100644 index 0000000..994fa34 --- /dev/null +++ b/contrib/llvm/include/llvm/Support/StringRefMemoryObject.h @@ -0,0 +1,41 @@ +//===- llvm/Support/StringRefMemoryObject.h ---------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains the declaration of the StringRefMemObject class, a simple +// wrapper around StringRef implementing the MemoryObject interface. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_STRINGREFMEMORYOBJECT_H +#define LLVM_SUPPORT_STRINGREFMEMORYOBJECT_H + +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/Compiler.h" +#include "llvm/Support/MemoryObject.h" + +namespace llvm { + +/// StringRefMemoryObject - Simple StringRef-backed MemoryObject +class StringRefMemoryObject : public MemoryObject { + StringRef Bytes; + uint64_t Base; +public: + StringRefMemoryObject(StringRef Bytes, uint64_t Base = 0) + : Bytes(Bytes), Base(Base) {} + + uint64_t getBase() const LLVM_OVERRIDE { return Base; } + uint64_t getExtent() const LLVM_OVERRIDE { return Bytes.size(); } + + int readByte(uint64_t Addr, uint8_t *Byte) const LLVM_OVERRIDE; + int readBytes(uint64_t Addr, uint64_t Size, uint8_t *Buf) const LLVM_OVERRIDE; +}; + +} + +#endif diff --git a/contrib/llvm/include/llvm/Support/SystemUtils.h b/contrib/llvm/include/llvm/Support/SystemUtils.h index 399aee5..d2d08b2 100644 --- a/contrib/llvm/include/llvm/Support/SystemUtils.h +++ b/contrib/llvm/include/llvm/Support/SystemUtils.h @@ -19,7 +19,6 @@ namespace llvm { class raw_ostream; - namespace sys { class Path; } /// Determine if the raw_ostream provided is connected to a terminal. If so, /// generate a warning message to errs() advising against display of bitcode @@ -30,15 +29,6 @@ bool CheckBitcodeOutputToConsole( bool print_warning = true ///< Control whether warnings are printed ); -/// PrependMainExecutablePath - Prepend the path to the program being executed -/// to \p ExeName, given the value of argv[0] and the address of main() -/// itself. This allows us to find another LLVM tool if it is built in the same -/// directory. An empty string is returned on error; note that this function -/// just mainpulates the path and doesn't check for executability. -/// @brief Find a named executable. -sys::Path PrependMainExecutablePath(const std::string &ExeName, - const char *Argv0, void *MainAddr); - } // End llvm namespace #endif diff --git a/contrib/llvm/include/llvm/Support/TargetRegistry.h b/contrib/llvm/include/llvm/Support/TargetRegistry.h index b06676d..9ecee3b 100644 --- a/contrib/llvm/include/llvm/Support/TargetRegistry.h +++ b/contrib/llvm/include/llvm/Support/TargetRegistry.h @@ -21,6 +21,7 @@ #include "llvm/ADT/Triple.h" #include "llvm/Support/CodeGen.h" +#include "llvm-c/Disassembler.h" #include <cassert> #include <string> @@ -41,20 +42,30 @@ namespace llvm { class MCRegisterInfo; class MCStreamer; class MCSubtargetInfo; + class MCSymbolizer; + 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); + + MCSymbolizer *createMCSymbolizer(StringRef TT, LLVMOpInfoCallback GetOpInfo, + LLVMSymbolLookupCallback SymbolLookUp, + void *DisInfo, + MCContext *Ctx, + MCRelocationInfo *RelInfo); /// Target - Wrapper for Target specific information. /// @@ -70,7 +81,7 @@ namespace llvm { typedef unsigned (*TripleMatchQualityFnTy)(const std::string &TT); - typedef MCAsmInfo *(*MCAsmInfoCtorFnTy)(const Target &T, + typedef MCAsmInfo *(*MCAsmInfoCtorFnTy)(const MCRegisterInfo &MRI, StringRef TT); typedef MCCodeGenInfo *(*MCCodeGenInfoCtorFnTy)(StringRef TT, Reloc::Model RM, @@ -93,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, @@ -127,6 +140,14 @@ namespace llvm { MCCodeEmitter *CE, MCAsmBackend *TAB, bool ShowInst); + typedef MCRelocationInfo *(*MCRelocationInfoCtorTy)(StringRef TT, + MCContext &Ctx); + typedef MCSymbolizer *(*MCSymbolizerCtorTy)(StringRef TT, + LLVMOpInfoCallback GetOpInfo, + LLVMSymbolLookupCallback SymbolLookUp, + void *DisInfo, + MCContext *Ctx, + MCRelocationInfo *RelInfo); private: /// Next - The next registered target in the linked list, maintained by the @@ -206,8 +227,18 @@ namespace llvm { /// AsmStreamer, if registered (default = llvm::createAsmStreamer). AsmStreamerCtorTy AsmStreamerCtorFn; + /// MCRelocationInfoCtorFn - Construction function for this target's + /// MCRelocationInfo, if registered (default = llvm::createMCRelocationInfo) + MCRelocationInfoCtorTy MCRelocationInfoCtorFn; + + /// MCSymbolizerCtorFn - Construction function for this target's + /// MCSymbolizer, if registered (default = llvm::createMCSymbolizer) + MCSymbolizerCtorTy MCSymbolizerCtorFn; + public: - Target() : AsmStreamerCtorFn(llvm::createAsmStreamer) {} + Target() + : AsmStreamerCtorFn(0), MCRelocationInfoCtorFn(0), + MCSymbolizerCtorFn(0) {} /// @name Target Information /// @{ @@ -234,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 /// @{ @@ -266,10 +276,11 @@ namespace llvm { /// feature set; it should always be provided. Generally this should be /// either the target triple from the module, or the target triple of the /// host if that does not exist. - MCAsmInfo *createMCAsmInfo(StringRef Triple) const { + MCAsmInfo *createMCAsmInfo(const MCRegisterInfo &MRI, + StringRef Triple) const { if (!MCAsmInfoCtorFn) return 0; - return MCAsmInfoCtorFn(*this, Triple); + return MCAsmInfoCtorFn(MRI, Triple); } /// createMCCodeGenInfo - Create a MCCodeGenInfo implementation. @@ -343,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. @@ -354,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 @@ -427,9 +440,44 @@ 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. + /// + /// \param TT The target triple. + /// \param Ctx The target context. + MCRelocationInfo * + createMCRelocationInfo(StringRef TT, MCContext &Ctx) const { + MCRelocationInfoCtorTy Fn = MCRelocationInfoCtorFn + ? MCRelocationInfoCtorFn + : llvm::createMCRelocationInfo; + return Fn(TT, Ctx); + } + + /// createMCSymbolizer - Create a target specific MCSymbolizer. + /// + /// \param TT The target triple. + /// \param GetOpInfo The function to get the symbolic information for operands. + /// \param SymbolLookUp The function to lookup a symbol name. + /// \param DisInfo The pointer to the block of symbolic information for above call + /// back. + /// \param Ctx The target context. + /// \param RelInfo The relocation information for this target. Takes ownership. + MCSymbolizer * + createMCSymbolizer(StringRef TT, LLVMOpInfoCallback GetOpInfo, + LLVMSymbolLookupCallback SymbolLookUp, + void *DisInfo, + MCContext *Ctx, MCRelocationInfo *RelInfo) const { + MCSymbolizerCtorTy Fn = + MCSymbolizerCtorFn ? MCSymbolizerCtorFn : llvm::createMCSymbolizer; + return Fn(TT, GetOpInfo, SymbolLookUp, DisInfo, Ctx, RelInfo); } /// @} @@ -550,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 @@ -566,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 @@ -581,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 @@ -605,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 @@ -621,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 @@ -637,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 @@ -652,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 @@ -666,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 @@ -680,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 @@ -696,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 @@ -711,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 @@ -726,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 @@ -741,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 @@ -755,8 +781,35 @@ 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 + /// implementation for the given target. + /// + /// Clients are responsible for ensuring that registration doesn't occur + /// while another thread is attempting to access the registry. Typically + /// this is done by initializing all targets at program startup. + /// + /// @param T - The target being registered. + /// @param Fn - A function to construct an MCRelocationInfo for the target. + static void RegisterMCRelocationInfo(Target &T, + Target::MCRelocationInfoCtorTy Fn) { + T.MCRelocationInfoCtorFn = Fn; + } + + /// RegisterMCSymbolizer - Register an MCSymbolizer + /// implementation for the given target. + /// + /// Clients are responsible for ensuring that registration doesn't occur + /// while another thread is attempting to access the registry. Typically + /// this is done by initializing all targets at program startup. + /// + /// @param T - The target being registered. + /// @param Fn - A function to construct an MCSymbolizer for the target. + static void RegisterMCSymbolizer(Target &T, + Target::MCSymbolizerCtorTy Fn) { + T.MCSymbolizerCtorFn = Fn; } /// @} @@ -804,8 +857,8 @@ namespace llvm { TargetRegistry::RegisterMCAsmInfo(T, &Allocator); } private: - static MCAsmInfo *Allocator(const Target &T, StringRef TT) { - return new MCAsmInfoImpl(T, TT); + static MCAsmInfo *Allocator(const MCRegisterInfo &/*MRI*/, StringRef TT) { + return new MCAsmInfoImpl(TT); } }; @@ -838,8 +891,9 @@ namespace llvm { TargetRegistry::RegisterMCCodeGenInfo(T, &Allocator); } private: - static MCCodeGenInfo *Allocator(StringRef TT, Reloc::Model RM, - CodeModel::Model CM, CodeGenOpt::Level OL) { + static MCCodeGenInfo *Allocator(StringRef /*TT*/, Reloc::Model /*RM*/, + CodeModel::Model /*CM*/, + CodeGenOpt::Level /*OL*/) { return new MCCodeGenInfoImpl(); } }; @@ -938,7 +992,7 @@ namespace llvm { TargetRegistry::RegisterMCRegInfo(T, &Allocator); } private: - static MCRegisterInfo *Allocator(StringRef TT) { + static MCRegisterInfo *Allocator(StringRef /*TT*/) { return new MCRegisterInfoImpl(); } }; @@ -971,8 +1025,8 @@ namespace llvm { TargetRegistry::RegisterMCSubtargetInfo(T, &Allocator); } private: - static MCSubtargetInfo *Allocator(StringRef TT, StringRef CPU, - StringRef FS) { + static MCSubtargetInfo *Allocator(StringRef /*TT*/, StringRef /*CPU*/, + StringRef /*FS*/) { return new MCSubtargetInfoImpl(); } }; @@ -1030,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); } }; @@ -1051,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); } }; @@ -1091,10 +1147,10 @@ namespace llvm { } private: - static MCCodeEmitter *Allocator(const MCInstrInfo &II, - const MCRegisterInfo &MRI, - const MCSubtargetInfo &STI, - MCContext &Ctx) { + static MCCodeEmitter *Allocator(const MCInstrInfo &/*II*/, + const MCRegisterInfo &/*MRI*/, + const MCSubtargetInfo &/*STI*/, + MCContext &/*Ctx*/) { return new MCCodeEmitterImpl(); } }; diff --git a/contrib/llvm/include/llvm/Support/TimeValue.h b/contrib/llvm/include/llvm/Support/TimeValue.h index 4b48b84..2785408 100644 --- a/contrib/llvm/include/llvm/Support/TimeValue.h +++ b/contrib/llvm/include/llvm/Support/TimeValue.h @@ -253,9 +253,10 @@ namespace sys { /// Converts the TimeValue into the corresponding number of "ticks" for /// Win32 platforms, correcting for the difference in Win32 zero time. - /// @brief Convert to windows time (seconds since 12:00:00a Jan 1, 1601) + /// @brief Convert to Win32's FILETIME + /// (100ns intervals since 00:00:00 Jan 1, 1601 UTC) uint64_t toWin32Time() const { - uint64_t result = seconds_ - Win32ZeroTimeSeconds; + uint64_t result = (uint64_t)10000000 * (seconds_ - Win32ZeroTimeSeconds); result += nanos_ / NANOSECONDS_PER_WIN32_TICK; return result; } diff --git a/contrib/llvm/include/llvm/Support/ToolOutputFile.h b/contrib/llvm/include/llvm/Support/ToolOutputFile.h index b3b7c57..a2191ad 100644 --- a/contrib/llvm/include/llvm/Support/ToolOutputFile.h +++ b/contrib/llvm/include/llvm/Support/ToolOutputFile.h @@ -47,7 +47,9 @@ public: /// tool_output_file - This constructor's arguments are passed to /// to raw_fd_ostream's constructor. tool_output_file(const char *filename, std::string &ErrorInfo, - unsigned Flags = 0); + sys::fs::OpenFlags Flags = sys::fs::F_None); + + tool_output_file(const char *Filename, int FD); /// os - Return the contained raw_fd_ostream. raw_fd_ostream &os() { return OS; } diff --git a/contrib/llvm/include/llvm/Support/Unicode.h b/contrib/llvm/include/llvm/Support/Unicode.h new file mode 100644 index 0000000..e6a52c4 --- /dev/null +++ b/contrib/llvm/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/contrib/llvm/include/llvm/Support/UnicodeCharRanges.h b/contrib/llvm/include/llvm/Support/UnicodeCharRanges.h new file mode 100644 index 0000000..86faa38 --- /dev/null +++ b/contrib/llvm/include/llvm/Support/UnicodeCharRanges.h @@ -0,0 +1,96 @@ +//===--- UnicodeCharRanges.h - Types and functions for character ranges ---===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_SUPPORT_UNICODECHARRANGES_H +#define LLVM_SUPPORT_UNICODECHARRANGES_H + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/Support/Compiler.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/Mutex.h" +#include "llvm/Support/MutexGuard.h" +#include "llvm/Support/raw_ostream.h" + +#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; +}; + +inline bool operator<(uint32_t Value, UnicodeCharRange Range) { + return Value < Range.Lower; +} +inline bool operator<(UnicodeCharRange Range, uint32_t Value) { + return Range.Upper < Value; +} + +/// \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; + + /// \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()); + } + + /// \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); + } + +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; + } + + return true; + } + + const CharRanges Ranges; +}; + +} // namespace sys +} // namespace llvm + + +#endif // LLVM_SUPPORT_UNICODECHARRANGES_H diff --git a/contrib/llvm/include/llvm/Support/Valgrind.h b/contrib/llvm/include/llvm/Support/Valgrind.h index a1397db..7ae40af 100644 --- a/contrib/llvm/include/llvm/Support/Valgrind.h +++ b/contrib/llvm/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/contrib/llvm/include/llvm/Support/ValueHandle.h b/contrib/llvm/include/llvm/Support/ValueHandle.h index b49341c..bc02ba3 100644 --- a/contrib/llvm/include/llvm/Support/ValueHandle.h +++ b/contrib/llvm/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/contrib/llvm/include/llvm/Support/YAMLParser.h b/contrib/llvm/include/llvm/Support/YAMLParser.h index 6e4f57f..7020449 100644 --- a/contrib/llvm/include/llvm/Support/YAMLParser.h +++ b/contrib/llvm/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); }; @@ -516,7 +538,7 @@ public: if (isAtEnd() || Other.isAtEnd()) return isAtEnd() && Other.isAtEnd(); - return *Doc == *Other.Doc; + return Doc == Other.Doc; } bool operator !=(const document_iterator &Other) { return !(*this == Other); @@ -543,7 +565,7 @@ public: private: bool isAtEnd() const { - return Doc == 0 || *Doc == 0; + return !Doc || !*Doc; } OwningPtr<Document> *Doc; diff --git a/contrib/llvm/include/llvm/Support/YAMLTraits.h b/contrib/llvm/include/llvm/Support/YAMLTraits.h index 801868f..c19eb23 100644 --- a/contrib/llvm/include/llvm/Support/YAMLTraits.h +++ b/contrib/llvm/include/llvm/Support/YAMLTraits.h @@ -14,10 +14,11 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseMapInfo.h" #include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/StringMap.h" #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; } @@ -760,15 +769,7 @@ private: } static inline bool classof(const MapHNode *) { return true; } - struct StrMappingInfo { - static StringRef getEmptyKey() { return StringRef(); } - static StringRef getTombstoneKey() { return StringRef(" ", 0); } - static unsigned getHashValue(StringRef const val) { - return llvm::HashString(val); } - static bool isEqual(StringRef const lhs, - StringRef const rhs) { return lhs.equals(rhs); } - }; - typedef llvm::DenseMap<StringRef, HNode*, StrMappingInfo> NameToNode; + typedef llvm::StringMap<HNode*> NameToNode; bool isValidKey(StringRef key); @@ -824,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 *&); @@ -845,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. @@ -967,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; } diff --git a/contrib/llvm/include/llvm/Support/raw_ostream.h b/contrib/llvm/include/llvm/Support/raw_ostream.h index d2b4a2a..ec7e06b 100644 --- a/contrib/llvm/include/llvm/Support/raw_ostream.h +++ b/contrib/llvm/include/llvm/Support/raw_ostream.h @@ -17,6 +17,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/DataTypes.h" +#include "llvm/Support/FileSystem.h" namespace llvm { class format_object_base; @@ -335,22 +336,6 @@ class raw_fd_ostream : public raw_ostream { void error_detected() { Error = true; } public: - - enum { - /// F_Excl - When opening a file, this flag makes raw_fd_ostream - /// report an error if the file already exists. - F_Excl = 1, - - /// F_Append - When opening a file, if it already exists append to the - /// existing file instead of returning an error. This may not be specified - /// with F_Excl. - F_Append = 2, - - /// F_Binary - The file should be opened in binary mode on platforms that - /// make this distinction. - F_Binary = 4 - }; - /// raw_fd_ostream - Open the specified file for writing. If an error occurs, /// information about the error is put into ErrorInfo, and the stream should /// be immediately destroyed; the string will be empty if no error occurred. @@ -362,7 +347,7 @@ public: /// file descriptor when it is done (this is necessary to detect /// output errors). raw_fd_ostream(const char *Filename, std::string &ErrorInfo, - unsigned Flags = 0); + sys::fs::OpenFlags Flags = sys::fs::F_None); /// raw_fd_ostream ctor - FD is the file descriptor that this writes to. If /// ShouldClose is true, this closes the file when the stream is destroyed. |