summaryrefslogtreecommitdiff
path: root/include/llvm/Support
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/Support')
-rw-r--r--include/llvm/Support/Allocator.h15
-rw-r--r--include/llvm/Support/BlockFrequency.h26
-rw-r--r--include/llvm/Support/CFG.h8
-rw-r--r--include/llvm/Support/COFF.h30
-rw-r--r--include/llvm/Support/CallSite.h17
-rw-r--r--include/llvm/Support/Casting.h27
-rw-r--r--include/llvm/Support/CommandLine.h61
-rw-r--r--include/llvm/Support/Compiler.h82
-rw-r--r--include/llvm/Support/Compression.h2
-rw-r--r--include/llvm/Support/ConstantRange.h12
-rw-r--r--include/llvm/Support/ConvertUTF.h24
-rw-r--r--include/llvm/Support/DataTypes.h.cmake9
-rw-r--r--include/llvm/Support/DataTypes.h.in10
-rw-r--r--include/llvm/Support/Debug.h4
-rw-r--r--include/llvm/Support/DebugLoc.h4
-rw-r--r--include/llvm/Support/Dwarf.h252
-rw-r--r--include/llvm/Support/ELF.h289
-rw-r--r--include/llvm/Support/ErrorOr.h266
-rw-r--r--include/llvm/Support/FileSystem.h390
-rw-r--r--include/llvm/Support/FileUtilities.h4
-rw-r--r--include/llvm/Support/FormattedStream.h47
-rw-r--r--include/llvm/Support/GCOV.h105
-rw-r--r--include/llvm/Support/GetElementPtrTypeIterator.h2
-rw-r--r--include/llvm/Support/GraphWriter.h44
-rw-r--r--include/llvm/Support/Host.h4
-rw-r--r--include/llvm/Support/IntegersSubset.h540
-rw-r--r--include/llvm/Support/IntegersSubsetMapping.h588
-rw-r--r--include/llvm/Support/LEB128.h18
-rw-r--r--include/llvm/Support/MD5.h71
-rw-r--r--include/llvm/Support/MachO.h823
-rw-r--r--include/llvm/Support/ManagedStatic.h1
-rw-r--r--include/llvm/Support/MathExtras.h361
-rw-r--r--include/llvm/Support/MemoryBuffer.h31
-rw-r--r--include/llvm/Support/MemoryObject.h11
-rw-r--r--include/llvm/Support/PassNameParser.h13
-rw-r--r--include/llvm/Support/Path.h381
-rw-r--r--include/llvm/Support/PathV1.h743
-rw-r--r--include/llvm/Support/PathV2.h381
-rw-r--r--include/llvm/Support/PatternMatch.h21
-rw-r--r--include/llvm/Support/PrettyStackTrace.h10
-rw-r--r--include/llvm/Support/Process.h40
-rw-r--r--include/llvm/Support/Program.h212
-rw-r--r--include/llvm/Support/RecyclingAllocator.h8
-rw-r--r--include/llvm/Support/Regex.h4
-rw-r--r--include/llvm/Support/Registry.h2
-rw-r--r--include/llvm/Support/Signals.h4
-rw-r--r--include/llvm/Support/Solaris.h9
-rw-r--r--include/llvm/Support/SourceMgr.h22
-rw-r--r--include/llvm/Support/StreamableMemoryObject.h18
-rw-r--r--include/llvm/Support/StringRefMemoryObject.h41
-rw-r--r--include/llvm/Support/SystemUtils.h10
-rw-r--r--include/llvm/Support/TargetRegistry.h242
-rw-r--r--include/llvm/Support/TimeValue.h5
-rw-r--r--include/llvm/Support/ToolOutputFile.h4
-rw-r--r--include/llvm/Support/Unicode.h62
-rw-r--r--include/llvm/Support/UnicodeCharRanges.h96
-rw-r--r--include/llvm/Support/Valgrind.h4
-rw-r--r--include/llvm/Support/ValueHandle.h5
-rw-r--r--include/llvm/Support/YAMLParser.h84
-rw-r--r--include/llvm/Support/YAMLTraits.h56
-rw-r--r--include/llvm/Support/raw_ostream.h19
61 files changed, 3035 insertions, 3639 deletions
diff --git a/include/llvm/Support/Allocator.h b/include/llvm/Support/Allocator.h
index 3243fd9cea57e..397f50fbe3603 100644
--- a/include/llvm/Support/Allocator.h
+++ b/include/llvm/Support/Allocator.h
@@ -99,6 +99,9 @@ class BumpPtrAllocator {
/// allocate a separate slab.
size_t SizeThreshold;
+ /// \brief the default allocator used if one is not provided
+ MallocSlabAllocator DefaultSlabAllocator;
+
/// Allocator - The underlying allocator we use to get slabs of memory. This
/// defaults to MallocSlabAllocator, which wraps malloc, but it could be
/// changed to use a custom allocator.
@@ -133,12 +136,10 @@ class BumpPtrAllocator {
/// one.
void DeallocateSlabs(MemSlab *Slab);
- static MallocSlabAllocator DefaultSlabAllocator;
-
template<typename T> friend class SpecificBumpPtrAllocator;
public:
- BumpPtrAllocator(size_t size = 4096, size_t threshold = 4096,
- SlabAllocator &allocator = DefaultSlabAllocator);
+ BumpPtrAllocator(size_t size = 4096, size_t threshold = 4096);
+ BumpPtrAllocator(size_t size, size_t threshold, SlabAllocator &allocator);
~BumpPtrAllocator();
/// Reset - Deallocate all but the current slab and reset the current pointer
@@ -189,8 +190,10 @@ template <typename T>
class SpecificBumpPtrAllocator {
BumpPtrAllocator Allocator;
public:
- SpecificBumpPtrAllocator(size_t size = 4096, size_t threshold = 4096,
- SlabAllocator &allocator = BumpPtrAllocator::DefaultSlabAllocator)
+ SpecificBumpPtrAllocator(size_t size = 4096, size_t threshold = 4096)
+ : Allocator(size, threshold) {}
+ SpecificBumpPtrAllocator(size_t size, size_t threshold,
+ SlabAllocator &allocator)
: Allocator(size, threshold, allocator) {}
~SpecificBumpPtrAllocator() {
diff --git a/include/llvm/Support/BlockFrequency.h b/include/llvm/Support/BlockFrequency.h
index 839cf93712472..21879e7cbe415 100644
--- a/include/llvm/Support/BlockFrequency.h
+++ b/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/include/llvm/Support/CFG.h b/include/llvm/Support/CFG.h
index 265b886daff7e..74ec7260927c0 100644
--- a/include/llvm/Support/CFG.h
+++ b/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/include/llvm/Support/COFF.h b/include/llvm/Support/COFF.h
index 823b43ad938ad..9cc3989df043e 100644
--- a/include/llvm/Support/COFF.h
+++ b/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/include/llvm/Support/CallSite.h b/include/llvm/Support/CallSite.h
index 92107ac025263..2a1c5ca4d47b6 100644
--- a/include/llvm/Support/CallSite.h
+++ b/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/include/llvm/Support/Casting.h b/include/llvm/Support/Casting.h
index 0d2d6c92fdb0a..d70acbf24c425 100644
--- a/include/llvm/Support/Casting.h
+++ b/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/include/llvm/Support/CommandLine.h b/include/llvm/Support/CommandLine.h
index bfaafda50c174..4efb6a67cf62b 100644
--- a/include/llvm/Support/CommandLine.h
+++ b/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/include/llvm/Support/Compiler.h b/include/llvm/Support/Compiler.h
index 13d057be049f3..860f43e9423e5 100644
--- a/include/llvm/Support/Compiler.h
+++ b/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/include/llvm/Support/Compression.h b/include/llvm/Support/Compression.h
index 9b1142d035da2..bef9146d07dfc 100644
--- a/include/llvm/Support/Compression.h
+++ b/include/llvm/Support/Compression.h
@@ -50,6 +50,8 @@ Status uncompress(StringRef InputBuffer,
OwningPtr<MemoryBuffer> &UncompressedBuffer,
size_t UncompressedSize);
+uint32_t crc32(StringRef Buffer);
+
} // End of namespace zlib
} // End of namespace llvm
diff --git a/include/llvm/Support/ConstantRange.h b/include/llvm/Support/ConstantRange.h
index 0f29256b80458..f757c6ea60f0b 100644
--- a/include/llvm/Support/ConstantRange.h
+++ b/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/include/llvm/Support/ConvertUTF.h b/include/llvm/Support/ConvertUTF.h
index 1eae6d6622294..282036619c497 100644
--- a/include/llvm/Support/ConvertUTF.h
+++ b/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/include/llvm/Support/DataTypes.h.cmake b/include/llvm/Support/DataTypes.h.cmake
index 7484abd368687..a26070cdc9fe5 100644
--- a/include/llvm/Support/DataTypes.h.cmake
+++ b/include/llvm/Support/DataTypes.h.cmake
@@ -26,7 +26,6 @@
#ifndef SUPPORT_DATATYPES_H
#define SUPPORT_DATATYPES_H
-#cmakedefine HAVE_SYS_TYPES_H ${HAVE_SYS_TYPES_H}
#cmakedefine HAVE_INTTYPES_H ${HAVE_INTTYPES_H}
#cmakedefine HAVE_STDINT_H ${HAVE_STDINT_H}
#cmakedefine HAVE_UINT64_T ${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>
@@ -101,7 +98,11 @@ 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/include/llvm/Support/DataTypes.h.in b/include/llvm/Support/DataTypes.h.in
index b9fb48a1d498b..7fc9b725244e0 100644
--- a/include/llvm/Support/DataTypes.h.in
+++ b/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/include/llvm/Support/Debug.h b/include/llvm/Support/Debug.h
index 896fe849a6be5..27024082962ba 100644
--- a/include/llvm/Support/Debug.h
+++ b/include/llvm/Support/Debug.h
@@ -26,9 +26,9 @@
#ifndef LLVM_SUPPORT_DEBUG_H
#define LLVM_SUPPORT_DEBUG_H
-namespace llvm {
+#include "llvm/Support/raw_ostream.h"
-class raw_ostream;
+namespace llvm {
/// DEBUG_TYPE macro - Files can specify a DEBUG_TYPE as a string, which causes
/// all of their DEBUG statements to be activatable with -debug-only=thatstring.
diff --git a/include/llvm/Support/DebugLoc.h b/include/llvm/Support/DebugLoc.h
index f35d40729263c..05f31d7a4994d 100644
--- a/include/llvm/Support/DebugLoc.h
+++ b/include/llvm/Support/DebugLoc.h
@@ -15,6 +15,8 @@
#ifndef LLVM_SUPPORT_DEBUGLOC_H
#define LLVM_SUPPORT_DEBUGLOC_H
+#include "llvm/Support/DataTypes.h"
+
namespace llvm {
template <typename T> struct DenseMapInfo;
class MDNode;
@@ -45,7 +47,7 @@ namespace llvm {
/// LineCol - This 32-bit value encodes the line and column number for the
/// location, encoded as 24-bits for line and 8 bits for col. A value of 0
/// for either means unknown.
- unsigned LineCol;
+ uint32_t LineCol;
/// ScopeIdx - This is an opaque ID# for Scope/InlinedAt information,
/// decoded by LLVMContext. 0 is unknown.
diff --git a/include/llvm/Support/Dwarf.h b/include/llvm/Support/Dwarf.h
index b52914f93851f..23bbd1c384cf3 100644
--- a/include/llvm/Support/Dwarf.h
+++ b/include/llvm/Support/Dwarf.h
@@ -16,60 +16,59 @@
#ifndef LLVM_SUPPORT_DWARF_H
#define LLVM_SUPPORT_DWARF_H
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataTypes.h"
-
namespace llvm {
//===----------------------------------------------------------------------===//
// Debug info constants.
-enum {
- LLVMDebugVersion = (12 << 16), // Current version of debug information.
- LLVMDebugVersion11 = (11 << 16), // Constant for version 11.
- LLVMDebugVersion10 = (10 << 16), // Constant for version 10.
- LLVMDebugVersion9 = (9 << 16), // Constant for version 9.
- LLVMDebugVersion8 = (8 << 16), // Constant for version 8.
- LLVMDebugVersion7 = (7 << 16), // Constant for version 7.
- LLVMDebugVersion6 = (6 << 16), // Constant for version 6.
- LLVMDebugVersion5 = (5 << 16), // Constant for version 5.
- LLVMDebugVersion4 = (4 << 16), // Constant for version 4.
- LLVMDebugVersionMask = 0xffff0000 // Mask for version number.
+enum LLVM_ENUM_INT_TYPE(uint32_t) {
+ LLVMDebugVersion = (12 << 16), // Current version of debug information.
+ LLVMDebugVersion11 = (11 << 16), // Constant for version 11.
+ LLVMDebugVersion10 = (10 << 16), // Constant for version 10.
+ LLVMDebugVersion9 = (9 << 16), // Constant for version 9.
+ LLVMDebugVersion8 = (8 << 16), // Constant for version 8.
+ LLVMDebugVersion7 = (7 << 16), // Constant for version 7.
+ LLVMDebugVersion6 = (6 << 16), // Constant for version 6.
+ LLVMDebugVersion5 = (5 << 16), // Constant for version 5.
+ LLVMDebugVersion4 = (4 << 16), // Constant for version 4.
+ LLVMDebugVersionMask = 0xffff0000 // Mask for version number.
};
namespace dwarf {
//===----------------------------------------------------------------------===//
// Dwarf constants as gleaned from the DWARF Debugging Information Format V.4
-// reference manual http://dwarf.freestandards.org .
+// reference manual http://dwarf.freestandards.org.
//
// Do not mix the following two enumerations sets. DW_TAG_invalid changes the
// enumeration base type.
-enum llvm_dwarf_constants {
+enum LLVMConstants LLVM_ENUM_INT_TYPE(uint32_t) {
// llvm mock tags
- DW_TAG_invalid = ~0U, // Tag for invalid results.
+ DW_TAG_invalid = ~0U, // Tag for invalid results.
- DW_TAG_auto_variable = 0x100, // Tag for local (auto) variables.
- DW_TAG_arg_variable = 0x101, // Tag for argument variables.
+ DW_TAG_auto_variable = 0x100, // Tag for local (auto) variables.
+ DW_TAG_arg_variable = 0x101, // Tag for argument variables.
- DW_TAG_user_base = 0x1000, // Recommended base for user tags.
+ DW_TAG_user_base = 0x1000, // Recommended base for user tags.
- DW_CIE_VERSION = 1 // Common frame information version.
+ DWARF_VERSION = 4, // Default dwarf version we output.
+ DW_CIE_VERSION = 1, // Common frame information version.
+ DW_PUBTYPES_VERSION = 2, // Section version number for .debug_pubtypes.
+ DW_PUBNAMES_VERSION = 2, // Section version number for .debug_pubnames.
+ DW_ARANGES_VERSION = 2 // Section version number for .debug_aranges.
};
-
// Special ID values that distinguish a CIE from a FDE in DWARF CFI.
// Not inside an enum because a 64-bit value is needed.
const uint32_t DW_CIE_ID = UINT32_MAX;
const uint64_t DW64_CIE_ID = UINT64_MAX;
-
-enum dwarf_constants {
- DWARF_VERSION = 2,
-
- // Tags
+enum Tag LLVM_ENUM_INT_TYPE(uint16_t) {
DW_TAG_array_type = 0x01,
DW_TAG_class_type = 0x02,
DW_TAG_entry_point = 0x03,
@@ -139,12 +138,38 @@ enum dwarf_constants {
DW_TAG_GNU_formal_parameter_pack = 0x4108,
DW_TAG_lo_user = 0x4080,
DW_TAG_APPLE_property = 0x4200,
- DW_TAG_hi_user = 0xffff,
-
- // Children flag
- DW_CHILDREN_no = 0x00,
- DW_CHILDREN_yes = 0x01,
+ DW_TAG_hi_user = 0xffff
+};
+inline bool isType(Tag T) {
+ switch (T) {
+ case DW_TAG_array_type:
+ case DW_TAG_class_type:
+ case DW_TAG_interface_type:
+ case DW_TAG_enumeration_type:
+ case DW_TAG_pointer_type:
+ case DW_TAG_reference_type:
+ case DW_TAG_rvalue_reference_type:
+ case DW_TAG_string_type:
+ case DW_TAG_structure_type:
+ case DW_TAG_subroutine_type:
+ case DW_TAG_union_type:
+ case DW_TAG_ptr_to_member_type:
+ case DW_TAG_set_type:
+ case DW_TAG_subrange_type:
+ case DW_TAG_base_type:
+ case DW_TAG_const_type:
+ case DW_TAG_file_type:
+ case DW_TAG_packed_type:
+ case DW_TAG_volatile_type:
+ case DW_TAG_typedef:
+ return true;
+ default:
+ return false;
+ }
+}
+
+enum Attribute LLVM_ENUM_INT_TYPE(uint16_t) {
// Attributes
DW_AT_sibling = 0x01,
DW_AT_location = 0x02,
@@ -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,
@@ -484,10 +515,15 @@ enum dwarf_constants {
DW_OP_lo_user = 0xe0,
DW_OP_hi_user = 0xff,
+ // Extensions for GNU-style thread-local storage.
+ DW_OP_GNU_push_tls_address = 0xe0,
+
// Extensions for Fission proposal.
DW_OP_GNU_addr_index = 0xfb,
- DW_OP_GNU_const_index = 0xfc,
+ DW_OP_GNU_const_index = 0xfc
+};
+enum TypeKind {
// Encoding attribute values
DW_ATE_address = 0x01,
DW_ATE_boolean = 0x02,
@@ -506,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,
@@ -560,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,
@@ -602,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,
@@ -651,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,
@@ -669,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,
@@ -763,6 +837,84 @@ const char *MacinfoString(unsigned Encoding);
/// CallFrameString - Return the string for the specified call frame instruction
/// encodings.
const char *CallFrameString(unsigned Encoding);
+
+// Constants for the DWARF5 Accelerator Table Proposal
+enum AcceleratorTable {
+ // Data layout descriptors.
+ DW_ATOM_null = 0u, // Marker as the end of a list of atoms.
+ DW_ATOM_die_offset = 1u, // DIE offset in the debug_info section.
+ DW_ATOM_cu_offset = 2u, // Offset of the compile unit header that contains the
+ // item in question.
+ DW_ATOM_die_tag = 3u, // A tag entry.
+ DW_ATOM_type_flags = 4u, // Set of flags for a type.
+
+ // DW_ATOM_type_flags values.
+
+ // Always set for C++, only set for ObjC if this is the @implementation for a
+ // class.
+ DW_FLAG_type_implementation = 2u,
+
+ // Hash functions.
+
+ // Daniel J. Bernstein hash.
+ DW_hash_function_djb = 0u
+};
+
+/// AtomTypeString - Return the string for the specified Atom type.
+const char *AtomTypeString(unsigned Atom);
+
+// Constants for the GNU pubnames/pubtypes extensions supporting gdb index.
+enum GDBIndexEntryKind {
+ GIEK_NONE,
+ GIEK_TYPE,
+ GIEK_VARIABLE,
+ GIEK_FUNCTION,
+ GIEK_OTHER,
+ GIEK_UNUSED5,
+ GIEK_UNUSED6,
+ GIEK_UNUSED7
+};
+
+const char *GDBIndexEntryKindString(GDBIndexEntryKind Kind);
+
+enum GDBIndexEntryLinkage {
+ GIEL_EXTERNAL,
+ GIEL_STATIC
+};
+
+const char *GDBIndexEntryLinkageString(GDBIndexEntryLinkage Linkage);
+
+/// The gnu_pub* kind looks like:
+///
+/// 0-3 reserved
+/// 4-6 symbol kind
+/// 7 0 == global, 1 == static
+///
+/// A gdb_index descriptor includes the above kind, shifted 24 bits up with the
+/// offset of the cu within the debug_info section stored in those 24 bits.
+struct PubIndexEntryDescriptor {
+ GDBIndexEntryKind Kind;
+ GDBIndexEntryLinkage Linkage;
+ PubIndexEntryDescriptor(GDBIndexEntryKind Kind, GDBIndexEntryLinkage Linkage)
+ : Kind(Kind), Linkage(Linkage) {}
+ /* implicit */ PubIndexEntryDescriptor(GDBIndexEntryKind Kind)
+ : Kind(Kind), Linkage(GIEL_EXTERNAL) {}
+ explicit PubIndexEntryDescriptor(uint8_t Value)
+ : Kind(static_cast<GDBIndexEntryKind>((Value & KIND_MASK) >>
+ KIND_OFFSET)),
+ Linkage(static_cast<GDBIndexEntryLinkage>((Value & LINKAGE_MASK) >>
+ LINKAGE_OFFSET)) {}
+ uint8_t toBits() { return Kind << KIND_OFFSET | Linkage << LINKAGE_OFFSET; }
+
+private:
+ enum {
+ KIND_OFFSET = 4,
+ KIND_MASK = 7 << KIND_OFFSET,
+ LINKAGE_OFFSET = 7,
+ LINKAGE_MASK = 1 << LINKAGE_OFFSET
+ };
+};
+
} // End of namespace dwarf
} // End of namespace llvm
diff --git a/include/llvm/Support/ELF.h b/include/llvm/Support/ELF.h
index c46dfebd37958..2868f35a01a1b 100644
--- a/include/llvm/Support/ELF.h
+++ b/include/llvm/Support/ELF.h
@@ -20,6 +20,7 @@
#ifndef LLVM_SUPPORT_ELF_H
#define LLVM_SUPPORT_ELF_H
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataTypes.h"
#include <cstring>
@@ -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,10 +1570,85 @@ 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.
- DT_VERNEEDNUM = 0X6FFFFFFF // The number of entries in DT_VERNEED.
+ DT_VERNEEDNUM = 0X6FFFFFFF, // The number of entries in DT_VERNEED.
+
+ // Mips specific dynamic table entry tags.
+ DT_MIPS_RLD_VERSION = 0x70000001, // 32 bit version number for runtime
+ // linker interface.
+ DT_MIPS_TIME_STAMP = 0x70000002, // Time stamp.
+ DT_MIPS_ICHECKSUM = 0x70000003, // Checksum of external strings
+ // and common sizes.
+ DT_MIPS_IVERSION = 0x70000004, // Index of version string
+ // in string table.
+ DT_MIPS_FLAGS = 0x70000005, // 32 bits of flags.
+ DT_MIPS_BASE_ADDRESS = 0x70000006, // Base address of the segment.
+ DT_MIPS_MSYM = 0x70000007, // Address of .msym section.
+ DT_MIPS_CONFLICT = 0x70000008, // Address of .conflict section.
+ DT_MIPS_LIBLIST = 0x70000009, // Address of .liblist section.
+ DT_MIPS_LOCAL_GOTNO = 0x7000000a, // Number of local global offset
+ // table entries.
+ DT_MIPS_CONFLICTNO = 0x7000000b, // Number of entries
+ // in the .conflict section.
+ DT_MIPS_LIBLISTNO = 0x70000010, // Number of entries
+ // in the .liblist section.
+ DT_MIPS_SYMTABNO = 0x70000011, // Number of entries
+ // in the .dynsym section.
+ DT_MIPS_UNREFEXTNO = 0x70000012, // Index of first external dynamic symbol
+ // not referenced locally.
+ DT_MIPS_GOTSYM = 0x70000013, // Index of first dynamic symbol
+ // in global offset table.
+ DT_MIPS_HIPAGENO = 0x70000014, // Number of page table entries
+ // in global offset table.
+ DT_MIPS_RLD_MAP = 0x70000016, // Address of run time loader map,
+ // used for debugging.
+ DT_MIPS_DELTA_CLASS = 0x70000017, // Delta C++ class definition.
+ DT_MIPS_DELTA_CLASS_NO = 0x70000018, // Number of entries
+ // in DT_MIPS_DELTA_CLASS.
+ DT_MIPS_DELTA_INSTANCE = 0x70000019, // Delta C++ class instances.
+ DT_MIPS_DELTA_INSTANCE_NO = 0x7000001A, // Number of entries
+ // in DT_MIPS_DELTA_INSTANCE.
+ DT_MIPS_DELTA_RELOC = 0x7000001B, // Delta relocations.
+ DT_MIPS_DELTA_RELOC_NO = 0x7000001C, // Number of entries
+ // in DT_MIPS_DELTA_RELOC.
+ DT_MIPS_DELTA_SYM = 0x7000001D, // Delta symbols that Delta
+ // relocations refer to.
+ DT_MIPS_DELTA_SYM_NO = 0x7000001E, // Number of entries
+ // in DT_MIPS_DELTA_SYM.
+ DT_MIPS_DELTA_CLASSSYM = 0x70000020, // Delta symbols that hold
+ // class declarations.
+ DT_MIPS_DELTA_CLASSSYM_NO = 0x70000021, // Number of entries
+ // in DT_MIPS_DELTA_CLASSSYM.
+ DT_MIPS_CXX_FLAGS = 0x70000022, // Flags indicating information
+ // about C++ flavor.
+ DT_MIPS_PIXIE_INIT = 0x70000023, // Pixie information.
+ DT_MIPS_SYMBOL_LIB = 0x70000024, // Address of .MIPS.symlib
+ DT_MIPS_LOCALPAGE_GOTIDX = 0x70000025, // The GOT index of the first PTE
+ // for a segment
+ DT_MIPS_LOCAL_GOTIDX = 0x70000026, // The GOT index of the first PTE
+ // for a local symbol
+ DT_MIPS_HIDDEN_GOTIDX = 0x70000027, // The GOT index of the first PTE
+ // for a hidden symbol
+ DT_MIPS_PROTECTED_GOTIDX = 0x70000028, // The GOT index of the first PTE
+ // for a protected symbol
+ DT_MIPS_OPTIONS = 0x70000029, // Address of `.MIPS.options'.
+ DT_MIPS_INTERFACE = 0x7000002A, // Address of `.interface'.
+ DT_MIPS_DYNSTR_ALIGN = 0x7000002B, // Unknown.
+ DT_MIPS_INTERFACE_SIZE = 0x7000002C, // Size of the .interface section.
+ DT_MIPS_RLD_TEXT_RESOLVE_ADDR = 0x7000002D, // Size of rld_text_resolve
+ // function stored in the GOT.
+ DT_MIPS_PERF_SUFFIX = 0x7000002E, // Default suffix of DSO to be added
+ // by rld on dlopen() calls.
+ DT_MIPS_COMPACT_SIZE = 0x7000002F, // Size of compact relocation
+ // section (O32).
+ DT_MIPS_GP_VALUE = 0x70000030, // GP value for auxiliary GOTs.
+ DT_MIPS_AUX_DYNAMIC = 0x70000031, // Address of auxiliary .dynamic.
+ DT_MIPS_PLTGOT = 0x70000032, // Address of the base of the PLTGOT.
+ DT_MIPS_RWPLT = 0x70000034 // Points to the base
+ // of a writable PLT.
};
// DT_FLAGS values.
@@ -1501,6 +1681,31 @@ enum {
DF_1_DISPRELPND = 0x00010000 // Disp reloc applied at run-time.
};
+// DT_MIPS_FLAGS values.
+enum {
+ RHF_NONE = 0x00000000, // No flags.
+ RHF_QUICKSTART = 0x00000001, // Uses shortcut pointers.
+ RHF_NOTPOT = 0x00000002, // Hash size is not a power of two.
+ RHS_NO_LIBRARY_REPLACEMENT = 0x00000004, // Ignore LD_LIBRARY_PATH.
+ RHF_NO_MOVE = 0x00000008, // DSO address may not be relocated.
+ RHF_SGI_ONLY = 0x00000010, // SGI specific features.
+ RHF_GUARANTEE_INIT = 0x00000020, // Guarantee that .init will finish
+ // executing before any non-init
+ // code in DSO is called.
+ RHF_DELTA_C_PLUS_PLUS = 0x00000040, // Contains Delta C++ code.
+ RHF_GUARANTEE_START_INIT = 0x00000080, // Guarantee that .init will start
+ // executing before any non-init
+ // code in DSO is called.
+ RHF_PIXIE = 0x00000100, // Generated by pixie.
+ RHF_DEFAULT_DELAY_LOAD = 0x00000200, // Delay-load DSO by default.
+ RHF_REQUICKSTART = 0x00000400, // Object may be requickstarted
+ RHF_REQUICKSTARTED = 0x00000800, // Object has been requickstarted
+ RHF_CORD = 0x00001000, // Generated by cord.
+ RHF_NO_UNRES_UNDEF = 0x00002000, // Object contains no unresolved
+ // undef symbols.
+ RHF_RLD_ORDER_SAFE = 0x00004000 // Symbol table is in a safe order.
+};
+
// ElfXX_VerDef structure version (GNU versioning)
enum {
VER_DEF_NONE = 0,
diff --git a/include/llvm/Support/ErrorOr.h b/include/llvm/Support/ErrorOr.h
index f3ac305fe7756..d5b11cbe52233 100644
--- a/include/llvm/Support/ErrorOr.h
+++ b/include/llvm/Support/ErrorOr.h
@@ -27,38 +27,6 @@
#endif
namespace llvm {
-struct ErrorHolderBase {
- error_code Error;
- uint16_t RefCount;
- bool HasUserData;
-
- ErrorHolderBase() : RefCount(1) {}
-
- void aquire() {
- ++RefCount;
- }
-
- void release() {
- if (--RefCount == 0)
- delete this;
- }
-
-protected:
- virtual ~ErrorHolderBase() {}
-};
-
-template<class T>
-struct ErrorHolder : ErrorHolderBase {
-#if LLVM_HAS_RVALUE_REFERENCES
- ErrorHolder(T &&UD) : UserData(llvm_move(UD)) {}
-#else
- ErrorHolder(T &UD) : UserData(UD) {}
-#endif
- T UserData;
-};
-
-template<class Tp> struct ErrorOrUserDataTraits : llvm::false_type {};
-
#if LLVM_HAS_CXX11_TYPETRAITS && LLVM_HAS_RVALUE_REFERENCES
template<class T, class V>
typename std::enable_if< std::is_constructible<T, V>::value
@@ -111,44 +79,6 @@ public:
/// buffer->write("adena");
/// \endcode
///
-/// ErrorOr<T> also supports user defined data for specific error_codes. To use
-/// this feature you must first add a template specialization of
-/// ErrorOrUserDataTraits derived from std::true_type for your type in the lld
-/// namespace. This specialization must have a static error_code error()
-/// function that returns the error_code this data is used with.
-///
-/// getError<UserData>() may be called to get either the stored user data, or
-/// a default constructed UserData if none was stored.
-///
-/// Example:
-/// \code
-/// struct InvalidArgError {
-/// InvalidArgError() {}
-/// InvalidArgError(std::string S) : ArgName(S) {}
-/// std::string ArgName;
-/// };
-///
-/// namespace llvm {
-/// template<>
-/// struct ErrorOrUserDataTraits<InvalidArgError> : std::true_type {
-/// static error_code error() {
-/// return make_error_code(errc::invalid_argument);
-/// }
-/// };
-/// } // end namespace llvm
-///
-/// using namespace llvm;
-///
-/// ErrorOr<int> foo() {
-/// return InvalidArgError("adena");
-/// }
-///
-/// int main() {
-/// auto a = foo();
-/// if (!a && error_code(a) == errc::invalid_argument)
-/// llvm::errs() << a.getError<InvalidArgError>().ArgName << "\n";
-/// }
-/// \endcode
///
/// An implicit conversion to bool provides a way to check if there was an
/// error. The unary * and -> operators provide pointer like access to the
@@ -178,43 +108,28 @@ private:
typedef typename remove_reference<T>::type *pointer;
public:
- ErrorOr() : IsValid(false) {}
-
template <class E>
ErrorOr(E ErrorCode, typename enable_if_c<is_error_code_enum<E>::value ||
is_error_condition_enum<E>::value,
void *>::type = 0)
- : HasError(true), IsValid(true) {
- Error = new ErrorHolderBase;
- Error->Error = make_error_code(ErrorCode);
- Error->HasUserData = false;
- }
-
- ErrorOr(llvm::error_code EC) : HasError(true), IsValid(true) {
- Error = new ErrorHolderBase;
- Error->Error = EC;
- Error->HasUserData = false;
+ : HasError(true) {
+ new (getError()) error_code(make_error_code(ErrorCode));
}
- template<class UserDataT>
- ErrorOr(UserDataT UD, typename
- enable_if_c<ErrorOrUserDataTraits<UserDataT>::value>::type* = 0)
- : HasError(true), IsValid(true) {
- Error = new ErrorHolder<UserDataT>(llvm_move(UD));
- Error->Error = ErrorOrUserDataTraits<UserDataT>::error();
- Error->HasUserData = true;
+ ErrorOr(llvm::error_code EC) : HasError(true) {
+ new (getError()) error_code(EC);
}
- ErrorOr(T Val) : HasError(false), IsValid(true) {
+ ErrorOr(T Val) : HasError(false) {
new (get()) storage_type(moveIfMoveConstructible<storage_type>(Val));
}
- ErrorOr(const ErrorOr &Other) : IsValid(false) {
+ ErrorOr(const ErrorOr &Other) {
copyConstruct(Other);
}
template <class OtherT>
- ErrorOr(const ErrorOr<OtherT> &Other) : IsValid(false) {
+ ErrorOr(const ErrorOr<OtherT> &Other) {
copyConstruct(Other);
}
@@ -230,12 +145,12 @@ public:
}
#if LLVM_HAS_RVALUE_REFERENCES
- ErrorOr(ErrorOr &&Other) : IsValid(false) {
+ ErrorOr(ErrorOr &&Other) {
moveConstruct(std::move(Other));
}
template <class OtherT>
- ErrorOr(ErrorOr<OtherT> &&Other) : IsValid(false) {
+ ErrorOr(ErrorOr<OtherT> &&Other) {
moveConstruct(std::move(Other));
}
@@ -252,37 +167,20 @@ public:
#endif
~ErrorOr() {
- if (!IsValid)
- return;
- if (HasError)
- Error->release();
- else
+ if (!HasError)
get()->~storage_type();
}
- template<class ET>
- ET getError() const {
- assert(IsValid && "Cannot get the error of a default constructed ErrorOr!");
- assert(HasError && "Cannot get an error if none exists!");
- assert(ErrorOrUserDataTraits<ET>::error() == Error->Error &&
- "Incorrect user error data type for error!");
- if (!Error->HasUserData)
- return ET();
- return reinterpret_cast<const ErrorHolder<ET>*>(Error)->UserData;
- }
-
typedef void (*unspecified_bool_type)();
static void unspecified_bool_true() {}
/// \brief Return false if there is an error.
operator unspecified_bool_type() const {
- assert(IsValid && "Can't do anything on a default constructed ErrorOr!");
return HasError ? 0 : unspecified_bool_true;
}
operator llvm::error_code() const {
- assert(IsValid && "Can't do anything on a default constructed ErrorOr!");
- return HasError ? Error->Error : llvm::error_code::success();
+ return HasError ? *getError() : llvm::error_code::success();
}
pointer operator ->() {
@@ -296,19 +194,14 @@ public:
private:
template <class OtherT>
void copyConstruct(const ErrorOr<OtherT> &Other) {
- // Construct an invalid ErrorOr if other is invalid.
- if (!Other.IsValid)
- return;
- IsValid = true;
if (!Other.HasError) {
// Get the other value.
HasError = false;
new (get()) storage_type(*Other.get());
} else {
// Get other's error.
- Error = Other.Error;
HasError = true;
- Error->aquire();
+ new (getError()) error_code(Other);
}
}
@@ -334,22 +227,14 @@ private:
#if LLVM_HAS_RVALUE_REFERENCES
template <class OtherT>
void moveConstruct(ErrorOr<OtherT> &&Other) {
- // Construct an invalid ErrorOr if other is invalid.
- if (!Other.IsValid)
- return;
- IsValid = true;
if (!Other.HasError) {
// Get the other value.
HasError = false;
new (get()) storage_type(std::move(*Other.get()));
- // Tell other not to do any destruction.
- Other.IsValid = false;
} else {
// Get other's error.
- Error = Other.Error;
HasError = true;
- // Tell other not to do any destruction.
- Other.IsValid = false;
+ new (getError()) error_code(Other);
}
}
@@ -372,135 +257,30 @@ private:
}
storage_type *get() {
- assert(IsValid && "Can't do anything on a default constructed ErrorOr!");
assert(!HasError && "Cannot get value when an error exists!");
return reinterpret_cast<storage_type*>(TStorage.buffer);
}
const storage_type *get() const {
- assert(IsValid && "Can't do anything on a default constructed ErrorOr!");
assert(!HasError && "Cannot get value when an error exists!");
return reinterpret_cast<const storage_type*>(TStorage.buffer);
}
- union {
- AlignedCharArrayUnion<storage_type> TStorage;
- ErrorHolderBase *Error;
- };
- bool HasError : 1;
- bool IsValid : 1;
-};
-
-// ErrorOr specialization for void.
-template <>
-class ErrorOr<void> {
-public:
- ErrorOr() : Error(0, 0) {}
-
- template <class E>
- ErrorOr(E ErrorCode, typename enable_if_c<is_error_code_enum<E>::value ||
- is_error_condition_enum<E>::value,
- void *> ::type = 0)
- : Error(0, 0) {
- error_code EC = make_error_code(ErrorCode);
- if (EC == errc::success) {
- Error.setInt(1);
- return;
- }
- ErrorHolderBase *EHB = new ErrorHolderBase;
- EHB->Error = EC;
- EHB->HasUserData = false;
- Error.setPointer(EHB);
- }
-
- ErrorOr(llvm::error_code EC) : Error(0, 0) {
- if (EC == errc::success) {
- Error.setInt(1);
- return;
- }
- ErrorHolderBase *E = new ErrorHolderBase;
- E->Error = EC;
- E->HasUserData = false;
- Error.setPointer(E);
- }
-
- template<class UserDataT>
- ErrorOr(UserDataT UD, typename
- enable_if_c<ErrorOrUserDataTraits<UserDataT>::value>::type* = 0)
- : Error(0, 0) {
- ErrorHolderBase *E = new ErrorHolder<UserDataT>(llvm_move(UD));
- E->Error = ErrorOrUserDataTraits<UserDataT>::error();
- E->HasUserData = true;
- Error.setPointer(E);
+ error_code *getError() {
+ assert(HasError && "Cannot get error when a value exists!");
+ return reinterpret_cast<error_code*>(ErrorStorage.buffer);
}
- ErrorOr(const ErrorOr &Other) : Error(0, 0) {
- Error = Other.Error;
- if (Other.Error.getPointer()->Error) {
- Error.getPointer()->aquire();
- }
+ const error_code *getError() const {
+ return const_cast<ErrorOr<T> *>(this)->getError();
}
- ErrorOr &operator =(const ErrorOr &Other) {
- if (this == &Other)
- return *this;
-
- this->~ErrorOr();
- new (this) ErrorOr(Other);
- return *this;
- }
-
-#if LLVM_HAS_RVALUE_REFERENCES
- ErrorOr(ErrorOr &&Other) : Error(0) {
- // Get other's error.
- Error = Other.Error;
- // Tell other not to do any destruction.
- Other.Error.setPointer(0);
- }
-
- ErrorOr &operator =(ErrorOr &&Other) {
- if (this == &Other)
- return *this;
-
- this->~ErrorOr();
- new (this) ErrorOr(std::move(Other));
-
- return *this;
- }
-#endif
-
- ~ErrorOr() {
- if (Error.getPointer())
- Error.getPointer()->release();
- }
-
- template<class ET>
- ET getError() const {
- assert(ErrorOrUserDataTraits<ET>::error() == *this &&
- "Incorrect user error data type for error!");
- if (!Error.getPointer()->HasUserData)
- return ET();
- return reinterpret_cast<const ErrorHolder<ET> *>(
- Error.getPointer())->UserData;
- }
-
- typedef void (*unspecified_bool_type)();
- static void unspecified_bool_true() {}
-
- /// \brief Return false if there is an error.
- operator unspecified_bool_type() const {
- return Error.getInt() ? unspecified_bool_true : 0;
- }
-
- operator llvm::error_code() const {
- return Error.getInt() ? make_error_code(errc::success)
- : Error.getPointer()->Error;
- }
-
-private:
- // If the bit is 1, the error is success.
- llvm::PointerIntPair<ErrorHolderBase *, 1> Error;
+ union {
+ AlignedCharArrayUnion<storage_type> TStorage;
+ AlignedCharArrayUnion<error_code> ErrorStorage;
+ };
+ bool HasError : 1;
};
template<class T, class E>
diff --git a/include/llvm/Support/FileSystem.h b/include/llvm/Support/FileSystem.h
index ffa642787b0b6..d301f842ea9f9 100644
--- a/include/llvm/Support/FileSystem.h
+++ b/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/include/llvm/Support/FileUtilities.h b/include/llvm/Support/FileUtilities.h
index 5456eb730a171..79c59e4306c92 100644
--- a/include/llvm/Support/FileUtilities.h
+++ b/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/include/llvm/Support/FormattedStream.h b/include/llvm/Support/FormattedStream.h
index 2e4bd5aeca2d3..df1f2183e6ccb 100644
--- a/include/llvm/Support/FormattedStream.h
+++ b/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/include/llvm/Support/GCOV.h b/include/llvm/Support/GCOV.h
index f1040f545c930..0aa716aac0772 100644
--- a/include/llvm/Support/GCOV.h
+++ b/include/llvm/Support/GCOV.h
@@ -15,6 +15,7 @@
#ifndef LLVM_SUPPORT_GCOV_H
#define LLVM_SUPPORT_GCOV_H
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Support/MemoryBuffer.h"
@@ -24,7 +25,6 @@ namespace llvm {
class GCOVFunction;
class GCOVBlock;
-class GCOVLines;
class FileInfo;
namespace GCOV {
@@ -125,30 +125,65 @@ public:
return true;
}
- uint32_t readInt() {
- uint32_t Result;
+ /// readObjectTag - If cursor points to an object summary tag then increment
+ /// the cursor and return true otherwise return false.
+ bool readObjectTag() {
+ StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4);
+ if (Tag.empty() ||
+ Tag[0] != '\0' || Tag[1] != '\0' ||
+ Tag[2] != '\0' || Tag[3] != '\xa1') {
+ return false;
+ }
+ Cursor += 4;
+ return true;
+ }
+
+ /// readProgramTag - If cursor points to a program summary tag then increment
+ /// the cursor and return true otherwise return false.
+ bool readProgramTag() {
+ StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4);
+ if (Tag.empty() ||
+ Tag[0] != '\0' || Tag[1] != '\0' ||
+ Tag[2] != '\0' || Tag[3] != '\xa3') {
+ return false;
+ }
+ Cursor += 4;
+ return true;
+ }
+
+ bool readInt(uint32_t &Val) {
+ if (Buffer->getBuffer().size() < Cursor+4) {
+ errs() << "Unexpected end of memory buffer: " << Cursor+4 << ".\n";
+ return false;
+ }
StringRef Str = Buffer->getBuffer().slice(Cursor, Cursor+4);
- assert (Str.empty() == false && "Unexpected memory buffer end!");
Cursor += 4;
- Result = *(const uint32_t *)(Str.data());
- return Result;
+ Val = *(const uint32_t *)(Str.data());
+ return true;
}
- uint64_t readInt64() {
- uint64_t Lo = readInt();
- uint64_t Hi = readInt();
- uint64_t Result = Lo | (Hi << 32);
- return Result;
+ bool readInt64(uint64_t &Val) {
+ uint32_t Lo, Hi;
+ if (!readInt(Lo) || !readInt(Hi)) return false;
+ Val = ((uint64_t)Hi << 32) | Lo;
+ return true;
}
- StringRef readString() {
- uint32_t Len = readInt() * 4;
- StringRef Str = Buffer->getBuffer().slice(Cursor, Cursor+Len);
+ bool readString(StringRef &Str) {
+ uint32_t Len;
+ if (!readInt(Len)) return false;
+ Len *= 4;
+ if (Buffer->getBuffer().size() < Cursor+Len) {
+ errs() << "Unexpected end of memory buffer: " << Cursor+Len << ".\n";
+ return false;
+ }
+ Str = Buffer->getBuffer().slice(Cursor, Cursor+Len).split('\0').first;
Cursor += Len;
- return Str;
+ return true;
}
uint64_t getCursor() const { return Cursor; }
+ void advanceCursor(uint32_t n) { Cursor += n*4; }
private:
MemoryBuffer *Buffer;
uint64_t Cursor;
@@ -158,13 +193,15 @@ private:
/// (.gcno and .gcda).
class GCOVFile {
public:
- GCOVFile() {}
+ GCOVFile() : Functions(), RunCount(0), ProgramCount(0) {}
~GCOVFile();
bool read(GCOVBuffer &Buffer);
void dump();
void collectLineCounts(FileInfo &FI);
private:
SmallVector<GCOVFunction *, 16> Functions;
+ uint32_t RunCount;
+ uint32_t ProgramCount;
};
/// GCOVFunction - Collects function information.
@@ -173,6 +210,7 @@ public:
GCOVFunction() : Ident(0), LineNumber(0) {}
~GCOVFunction();
bool read(GCOVBuffer &Buffer, GCOV::GCOVFormat Format);
+ StringRef getFilename() const { return Filename; }
void dump();
void collectLineCounts(FileInfo &FI);
private:
@@ -186,39 +224,36 @@ private:
/// GCOVBlock - Collects block information.
class GCOVBlock {
public:
- GCOVBlock(uint32_t N) : Number(N), Counter(0) {}
+ GCOVBlock(GCOVFunction &P, uint32_t N) :
+ Parent(P), Number(N), Counter(0), Edges(), Lines() {}
~GCOVBlock();
void addEdge(uint32_t N) { Edges.push_back(N); }
- void addLine(StringRef Filename, uint32_t LineNo);
- void addCount(uint64_t N) { Counter = N; }
+ void addLine(uint32_t N) { Lines.push_back(N); }
+ void addCount(uint64_t N) { Counter += N; }
+ size_t getNumEdges() { return Edges.size(); }
void dump();
void collectLineCounts(FileInfo &FI);
private:
+ GCOVFunction &Parent;
uint32_t Number;
uint64_t Counter;
SmallVector<uint32_t, 16> Edges;
- StringMap<GCOVLines *> Lines;
+ SmallVector<uint32_t, 16> Lines;
};
-/// GCOVLines - A wrapper around a vector of int to keep track of line nos.
-class GCOVLines {
-public:
- ~GCOVLines() { Lines.clear(); }
- void add(uint32_t N) { Lines.push_back(N); }
- void collectLineCounts(FileInfo &FI, StringRef Filename, uint32_t Count);
- void dump();
-
-private:
- SmallVector<uint32_t, 4> Lines;
-};
-
-typedef SmallVector<uint32_t, 16> LineCounts;
+typedef DenseMap<uint32_t, uint64_t> LineCounts;
class FileInfo {
public:
- void addLineCount(StringRef Filename, uint32_t Line, uint32_t Count);
- void print();
+ void addLineCount(StringRef Filename, uint32_t Line, uint64_t Count) {
+ LineInfo[Filename][Line-1] += Count;
+ }
+ void setRunCount(uint32_t Runs) { RunCount = Runs; }
+ void setProgramCount(uint32_t Programs) { ProgramCount = Programs; }
+ void print(raw_fd_ostream &OS, StringRef gcnoFile, StringRef gcdaFile);
private:
StringMap<LineCounts> LineInfo;
+ uint32_t RunCount;
+ uint32_t ProgramCount;
};
}
diff --git a/include/llvm/Support/GetElementPtrTypeIterator.h b/include/llvm/Support/GetElementPtrTypeIterator.h
index 5a90553a0074e..aacb53162cf7f 100644
--- a/include/llvm/Support/GetElementPtrTypeIterator.h
+++ b/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/include/llvm/Support/GraphWriter.h b/include/llvm/Support/GraphWriter.h
index 22181d4e1d463..62547ddf0cef2 100644
--- a/include/llvm/Support/GraphWriter.h
+++ b/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/include/llvm/Support/Host.h b/include/llvm/Support/Host.h
index 9a4036a8affbc..28c4cc790fe50 100644
--- a/include/llvm/Support/Host.h
+++ b/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/include/llvm/Support/IntegersSubset.h b/include/llvm/Support/IntegersSubset.h
deleted file mode 100644
index ce34d785d593f..0000000000000
--- a/include/llvm/Support/IntegersSubset.h
+++ /dev/null
@@ -1,540 +0,0 @@
-//===-- llvm/IntegersSubset.h - The subset of integers ----------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-/// @file
-/// This file contains class that implements constant set of ranges:
-/// [<Low0,High0>,...,<LowN,HighN>]. Initially, this class was created for
-/// SwitchInst and was used for case value representation that may contain
-/// multiple ranges for a single successor.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SUPPORT_INTEGERSSUBSET_H
-#define LLVM_SUPPORT_INTEGERSSUBSET_H
-
-#include "llvm/IR/Constants.h"
-#include "llvm/IR/DerivedTypes.h"
-#include "llvm/IR/LLVMContext.h"
-#include <list>
-
-namespace llvm {
-
- // The IntItem is a wrapper for APInt.
- // 1. It determines sign of integer, it allows to use
- // comparison operators >,<,>=,<=, and as result we got shorter and cleaner
- // constructions.
- // 2. It helps to implement PR1255 (case ranges) as a series of small patches.
- // 3. Currently we can interpret IntItem both as ConstantInt and as APInt.
- // It allows to provide SwitchInst methods that works with ConstantInt for
- // non-updated passes. And it allows to use APInt interface for new methods.
- // 4. IntItem can be easily replaced with APInt.
-
- // The set of macros that allows to propagate APInt operators to the IntItem.
-
-#define INT_ITEM_DEFINE_COMPARISON(op,func) \
- bool operator op (const APInt& RHS) const { \
- return getAPIntValue().func(RHS); \
- }
-
-#define INT_ITEM_DEFINE_UNARY_OP(op) \
- IntItem operator op () const { \
- APInt res = op(getAPIntValue()); \
- Constant *NewVal = ConstantInt::get(ConstantIntVal->getContext(), res); \
- return IntItem(cast<ConstantInt>(NewVal)); \
- }
-
-#define INT_ITEM_DEFINE_BINARY_OP(op) \
- IntItem operator op (const APInt& RHS) const { \
- APInt res = getAPIntValue() op RHS; \
- Constant *NewVal = ConstantInt::get(ConstantIntVal->getContext(), res); \
- return IntItem(cast<ConstantInt>(NewVal)); \
- }
-
-#define INT_ITEM_DEFINE_ASSIGNMENT_BY_OP(op) \
- IntItem& operator op (const APInt& RHS) {\
- APInt res = getAPIntValue();\
- res op RHS; \
- Constant *NewVal = ConstantInt::get(ConstantIntVal->getContext(), res); \
- ConstantIntVal = cast<ConstantInt>(NewVal); \
- return *this; \
- }
-
-#define INT_ITEM_DEFINE_PREINCDEC(op) \
- IntItem& operator op () { \
- APInt res = getAPIntValue(); \
- op(res); \
- Constant *NewVal = ConstantInt::get(ConstantIntVal->getContext(), res); \
- ConstantIntVal = cast<ConstantInt>(NewVal); \
- return *this; \
- }
-
-#define INT_ITEM_DEFINE_POSTINCDEC(op) \
- IntItem& operator op (int) { \
- APInt res = getAPIntValue();\
- op(res); \
- Constant *NewVal = ConstantInt::get(ConstantIntVal->getContext(), res); \
- OldConstantIntVal = ConstantIntVal; \
- ConstantIntVal = cast<ConstantInt>(NewVal); \
- return IntItem(OldConstantIntVal); \
- }
-
-#define INT_ITEM_DEFINE_OP_STANDARD_INT(RetTy, op, IntTy) \
- RetTy operator op (IntTy RHS) const { \
- return (*this) op APInt(getAPIntValue().getBitWidth(), RHS); \
- }
-
-class IntItem {
- ConstantInt *ConstantIntVal;
- const APInt* APIntVal;
- IntItem(const ConstantInt *V) :
- ConstantIntVal(const_cast<ConstantInt*>(V)),
- APIntVal(&ConstantIntVal->getValue()){}
- const APInt& getAPIntValue() const {
- return *APIntVal;
- }
-public:
-
- IntItem() {}
-
- operator const APInt&() const {
- return getAPIntValue();
- }
-
- // Propagate APInt operators.
- // Note, that
- // /,/=,>>,>>= are not implemented in APInt.
- // <<= is implemented for unsigned RHS, but not implemented for APInt RHS.
-
- INT_ITEM_DEFINE_COMPARISON(<, ult)
- INT_ITEM_DEFINE_COMPARISON(>, ugt)
- INT_ITEM_DEFINE_COMPARISON(<=, ule)
- INT_ITEM_DEFINE_COMPARISON(>=, uge)
-
- INT_ITEM_DEFINE_COMPARISON(==, eq)
- INT_ITEM_DEFINE_OP_STANDARD_INT(bool,==,uint64_t)
-
- INT_ITEM_DEFINE_COMPARISON(!=, ne)
- INT_ITEM_DEFINE_OP_STANDARD_INT(bool,!=,uint64_t)
-
- INT_ITEM_DEFINE_BINARY_OP(*)
- INT_ITEM_DEFINE_BINARY_OP(+)
- INT_ITEM_DEFINE_OP_STANDARD_INT(IntItem,+,uint64_t)
- INT_ITEM_DEFINE_BINARY_OP(-)
- INT_ITEM_DEFINE_OP_STANDARD_INT(IntItem,-,uint64_t)
- INT_ITEM_DEFINE_BINARY_OP(<<)
- INT_ITEM_DEFINE_OP_STANDARD_INT(IntItem,<<,unsigned)
- INT_ITEM_DEFINE_BINARY_OP(&)
- INT_ITEM_DEFINE_BINARY_OP(^)
- INT_ITEM_DEFINE_BINARY_OP(|)
-
- INT_ITEM_DEFINE_ASSIGNMENT_BY_OP(*=)
- INT_ITEM_DEFINE_ASSIGNMENT_BY_OP(+=)
- INT_ITEM_DEFINE_ASSIGNMENT_BY_OP(-=)
- INT_ITEM_DEFINE_ASSIGNMENT_BY_OP(&=)
- INT_ITEM_DEFINE_ASSIGNMENT_BY_OP(^=)
- INT_ITEM_DEFINE_ASSIGNMENT_BY_OP(|=)
-
- // Special case for <<=
- IntItem& operator <<= (unsigned RHS) {
- APInt res = getAPIntValue();
- res <<= RHS;
- Constant *NewVal = ConstantInt::get(ConstantIntVal->getContext(), res);
- ConstantIntVal = cast<ConstantInt>(NewVal);
- return *this;
- }
-
- INT_ITEM_DEFINE_UNARY_OP(-)
- INT_ITEM_DEFINE_UNARY_OP(~)
-
- INT_ITEM_DEFINE_PREINCDEC(++)
- INT_ITEM_DEFINE_PREINCDEC(--)
-
- // The set of workarounds, since currently we use ConstantInt implemented
- // integer.
-
- static IntItem fromConstantInt(const ConstantInt *V) {
- return IntItem(V);
- }
- static IntItem fromType(Type* Ty, const APInt& V) {
- ConstantInt *C = cast<ConstantInt>(ConstantInt::get(Ty, V));
- return fromConstantInt(C);
- }
- static IntItem withImplLikeThis(const IntItem& LikeThis, const APInt& V) {
- ConstantInt *C = cast<ConstantInt>(ConstantInt::get(
- LikeThis.ConstantIntVal->getContext(), V));
- return fromConstantInt(C);
- }
- ConstantInt *toConstantInt() const {
- return ConstantIntVal;
- }
-};
-
-template<class IntType>
-class IntRange {
-protected:
- IntType Low;
- IntType High;
- bool IsEmpty : 1;
- bool IsSingleNumber : 1;
-
-public:
- typedef IntRange<IntType> self;
- typedef std::pair<self, self> SubRes;
-
- IntRange() : IsEmpty(true) {}
- IntRange(const self &RHS) :
- Low(RHS.Low), High(RHS.High),
- IsEmpty(RHS.IsEmpty), IsSingleNumber(RHS.IsSingleNumber) {}
- IntRange(const IntType &C) :
- Low(C), High(C), IsEmpty(false), IsSingleNumber(true) {}
-
- IntRange(const IntType &L, const IntType &H) : Low(L), High(H),
- IsEmpty(false), IsSingleNumber(Low == High) {}
-
- bool isEmpty() const { return IsEmpty; }
- bool isSingleNumber() const { return IsSingleNumber; }
-
- const IntType& getLow() const {
- assert(!IsEmpty && "Range is empty.");
- return Low;
- }
- const IntType& getHigh() const {
- assert(!IsEmpty && "Range is empty.");
- return High;
- }
-
- bool operator<(const self &RHS) const {
- assert(!IsEmpty && "Left range is empty.");
- assert(!RHS.IsEmpty && "Right range is empty.");
- if (Low == RHS.Low) {
- if (High > RHS.High)
- return true;
- return false;
- }
- if (Low < RHS.Low)
- return true;
- return false;
- }
-
- bool operator==(const self &RHS) const {
- assert(!IsEmpty && "Left range is empty.");
- assert(!RHS.IsEmpty && "Right range is empty.");
- return Low == RHS.Low && High == RHS.High;
- }
-
- bool operator!=(const self &RHS) const {
- return !operator ==(RHS);
- }
-
- static bool LessBySize(const self &LHS, const self &RHS) {
- return (LHS.High - LHS.Low) < (RHS.High - RHS.Low);
- }
-
- bool isInRange(const IntType &IntVal) const {
- assert(!IsEmpty && "Range is empty.");
- return IntVal >= Low && IntVal <= High;
- }
-
- SubRes sub(const self &RHS) const {
- SubRes Res;
-
- // RHS is either more global and includes this range or
- // if it doesn't intersected with this range.
- if (!isInRange(RHS.Low) && !isInRange(RHS.High)) {
-
- // If RHS more global (it is enough to check
- // only one border in this case.
- if (RHS.isInRange(Low))
- return std::make_pair(self(Low, High), self());
-
- return Res;
- }
-
- if (Low < RHS.Low) {
- Res.first.Low = Low;
- IntType NewHigh = RHS.Low;
- --NewHigh;
- Res.first.High = NewHigh;
- }
- if (High > RHS.High) {
- IntType NewLow = RHS.High;
- ++NewLow;
- Res.second.Low = NewLow;
- Res.second.High = High;
- }
- return Res;
- }
- };
-
-//===----------------------------------------------------------------------===//
-/// IntegersSubsetGeneric - class that implements the subset of integers. It
-/// consists from ranges and single numbers.
-template <class IntTy>
-class IntegersSubsetGeneric {
-public:
- // Use Chris Lattner idea, that was initially described here:
- // http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20120213/136954.html
- // In short, for more compact memory consumption we can store flat
- // numbers collection, and define range as pair of indices.
- // In that case we can safe some memory on 32 bit machines.
- typedef std::vector<IntTy> FlatCollectionTy;
- typedef std::pair<IntTy*, IntTy*> RangeLinkTy;
- typedef std::vector<RangeLinkTy> RangeLinksTy;
- typedef typename RangeLinksTy::const_iterator RangeLinksConstIt;
-
- typedef IntegersSubsetGeneric<IntTy> self;
-
-protected:
-
- FlatCollectionTy FlatCollection;
- RangeLinksTy RangeLinks;
-
- bool IsSingleNumber;
- bool IsSingleNumbersOnly;
-
-public:
-
- template<class RangesCollectionTy>
- explicit IntegersSubsetGeneric(const RangesCollectionTy& Links) {
- assert(Links.size() && "Empty ranges are not allowed.");
-
- // In case of big set of single numbers consumes additional RAM space,
- // but allows to avoid additional reallocation.
- FlatCollection.reserve(Links.size() * 2);
- RangeLinks.reserve(Links.size());
- IsSingleNumbersOnly = true;
- for (typename RangesCollectionTy::const_iterator i = Links.begin(),
- e = Links.end(); i != e; ++i) {
- RangeLinkTy RangeLink;
- FlatCollection.push_back(i->getLow());
- RangeLink.first = &FlatCollection.back();
- if (i->getLow() != i->getHigh()) {
- FlatCollection.push_back(i->getHigh());
- IsSingleNumbersOnly = false;
- }
- RangeLink.second = &FlatCollection.back();
- RangeLinks.push_back(RangeLink);
- }
- IsSingleNumber = IsSingleNumbersOnly && RangeLinks.size() == 1;
- }
-
- IntegersSubsetGeneric(const self& RHS) {
- *this = RHS;
- }
-
- self& operator=(const self& RHS) {
- FlatCollection.clear();
- RangeLinks.clear();
- FlatCollection.reserve(RHS.RangeLinks.size() * 2);
- RangeLinks.reserve(RHS.RangeLinks.size());
- for (RangeLinksConstIt i = RHS.RangeLinks.begin(), e = RHS.RangeLinks.end();
- i != e; ++i) {
- RangeLinkTy RangeLink;
- FlatCollection.push_back(*(i->first));
- RangeLink.first = &FlatCollection.back();
- if (i->first != i->second)
- FlatCollection.push_back(*(i->second));
- RangeLink.second = &FlatCollection.back();
- RangeLinks.push_back(RangeLink);
- }
- IsSingleNumber = RHS.IsSingleNumber;
- IsSingleNumbersOnly = RHS.IsSingleNumbersOnly;
- return *this;
- }
-
- typedef IntRange<IntTy> Range;
-
- /// Checks is the given constant satisfies this case. Returns
- /// true if it equals to one of contained values or belongs to the one of
- /// contained ranges.
- bool isSatisfies(const IntTy &CheckingVal) const {
- if (IsSingleNumber)
- return FlatCollection.front() == CheckingVal;
- if (IsSingleNumbersOnly)
- return std::find(FlatCollection.begin(),
- FlatCollection.end(),
- CheckingVal) != FlatCollection.end();
-
- for (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/include/llvm/Support/IntegersSubsetMapping.h b/include/llvm/Support/IntegersSubsetMapping.h
deleted file mode 100644
index 641ce78c5d877..0000000000000
--- a/include/llvm/Support/IntegersSubsetMapping.h
+++ /dev/null
@@ -1,588 +0,0 @@
-//===- IntegersSubsetMapping.h - Mapping subset ==> Successor ---*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-/// @file
-/// IntegersSubsetMapping is mapping from A to B, where
-/// Items in A is subsets of integers,
-/// Items in B some pointers (Successors).
-/// If user which to add another subset for successor that is already
-/// exists in mapping, IntegersSubsetMapping merges existing subset with
-/// added one.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SUPPORT_INTEGERSSUBSETMAPPING_H
-#define LLVM_SUPPORT_INTEGERSSUBSETMAPPING_H
-
-#include "llvm/Support/IntegersSubset.h"
-#include <list>
-#include <map>
-#include <vector>
-
-namespace llvm {
-
-template <class SuccessorClass,
- class IntegersSubsetTy = IntegersSubset,
- class IntTy = IntItem>
-class IntegersSubsetMapping {
- // FIXME: To much similar iterators typedefs, similar names.
- // - Rename RangeIterator to the cluster iterator.
- // - Remove unused "add" methods.
- // - Class contents needs cleaning.
-public:
-
- typedef IntRange<IntTy> RangeTy;
-
- struct RangeEx : public RangeTy {
- RangeEx() : Weight(1) {}
- RangeEx(const RangeTy &R) : RangeTy(R), Weight(1) {}
- RangeEx(const RangeTy &R, unsigned W) : RangeTy(R), Weight(W) {}
- RangeEx(const IntTy &C) : RangeTy(C), Weight(1) {}
- RangeEx(const IntTy &L, const IntTy &H) : RangeTy(L, H), Weight(1) {}
- RangeEx(const IntTy &L, const IntTy &H, unsigned W) :
- RangeTy(L, H), Weight(W) {}
- unsigned Weight;
- };
-
- typedef std::pair<RangeEx, SuccessorClass*> Cluster;
-
- typedef std::list<RangeTy> RangesCollection;
- typedef typename RangesCollection::iterator RangesCollectionIt;
- typedef typename RangesCollection::const_iterator RangesCollectionConstIt;
- typedef IntegersSubsetMapping<SuccessorClass, IntegersSubsetTy, IntTy> self;
-
-protected:
-
- typedef std::list<Cluster> CaseItems;
- typedef typename CaseItems::iterator CaseItemIt;
- typedef typename CaseItems::const_iterator CaseItemConstIt;
-
- // TODO: Change unclean CRS prefixes to SubsetMap for example.
- typedef std::map<SuccessorClass*, RangesCollection > CRSMap;
- typedef typename CRSMap::iterator CRSMapIt;
-
- struct ClustersCmp {
- bool operator()(const Cluster &C1, const Cluster &C2) {
- return C1.first < C2.first;
- }
- };
-
- CaseItems Items;
- bool Sorted;
-
- bool isIntersected(CaseItemIt& LItem, CaseItemIt& RItem) {
- return LItem->first.getHigh() >= RItem->first.getLow();
- }
-
- bool isJoinable(CaseItemIt& LItem, CaseItemIt& RItem) {
- if (LItem->second != RItem->second) {
- assert(!isIntersected(LItem, RItem) &&
- "Intersected items with different successors!");
- return false;
- }
- APInt RLow = RItem->first.getLow();
- if (RLow != APInt::getNullValue(RLow.getBitWidth()))
- --RLow;
- return LItem->first.getHigh() >= RLow;
- }
-
- void sort() {
- if (!Sorted) {
- std::vector<Cluster> clustersVector;
- clustersVector.reserve(Items.size());
- clustersVector.insert(clustersVector.begin(), Items.begin(), Items.end());
- std::sort(clustersVector.begin(), clustersVector.end(), ClustersCmp());
- Items.clear();
- Items.insert(Items.begin(), clustersVector.begin(), clustersVector.end());
- Sorted = true;
- }
- }
-
- enum DiffProcessState {
- L_OPENED,
- INTERSECT_OPENED,
- R_OPENED,
- ALL_IS_CLOSED
- };
-
- class DiffStateMachine {
-
- DiffProcessState State;
- IntTy OpenPt;
- SuccessorClass *CurrentLSuccessor;
- SuccessorClass *CurrentRSuccessor;
-
- self *LeftMapping;
- self *IntersectionMapping;
- self *RightMapping;
-
- public:
-
- typedef
- IntegersSubsetMapping<SuccessorClass, IntegersSubsetTy, IntTy> MappingTy;
-
- DiffStateMachine(MappingTy *L,
- MappingTy *Intersection,
- MappingTy *R) :
- State(ALL_IS_CLOSED),
- LeftMapping(L),
- IntersectionMapping(Intersection),
- RightMapping(R)
- {}
-
- void onLOpen(const IntTy &Pt, SuccessorClass *S) {
- switch (State) {
- case R_OPENED:
- if (Pt > OpenPt/*Don't add empty ranges.*/ && RightMapping)
- RightMapping->add(OpenPt, Pt-1, CurrentRSuccessor);
- State = INTERSECT_OPENED;
- break;
- case ALL_IS_CLOSED:
- State = L_OPENED;
- break;
- default:
- assert(0 && "Got unexpected point.");
- break;
- }
- CurrentLSuccessor = S;
- OpenPt = Pt;
- }
-
- void onLClose(const IntTy &Pt) {
- switch (State) {
- case L_OPENED:
- assert(Pt >= OpenPt &&
- "Subset is not sorted or contains overlapped ranges");
- if (LeftMapping)
- LeftMapping->add(OpenPt, Pt, CurrentLSuccessor);
- State = ALL_IS_CLOSED;
- break;
- case INTERSECT_OPENED:
- if (IntersectionMapping)
- IntersectionMapping->add(OpenPt, Pt, CurrentLSuccessor);
- OpenPt = Pt + 1;
- State = R_OPENED;
- break;
- default:
- assert(0 && "Got unexpected point.");
- break;
- }
- }
-
- void onROpen(const IntTy &Pt, SuccessorClass *S) {
- switch (State) {
- case L_OPENED:
- if (Pt > OpenPt && LeftMapping)
- LeftMapping->add(OpenPt, Pt-1, CurrentLSuccessor);
- State = INTERSECT_OPENED;
- break;
- case ALL_IS_CLOSED:
- State = R_OPENED;
- break;
- default:
- assert(0 && "Got unexpected point.");
- break;
- }
- CurrentRSuccessor = S;
- OpenPt = Pt;
- }
-
- void onRClose(const IntTy &Pt) {
- switch (State) {
- case R_OPENED:
- assert(Pt >= OpenPt &&
- "Subset is not sorted or contains overlapped ranges");
- if (RightMapping)
- RightMapping->add(OpenPt, Pt, CurrentRSuccessor);
- State = ALL_IS_CLOSED;
- break;
- case INTERSECT_OPENED:
- if (IntersectionMapping)
- IntersectionMapping->add(OpenPt, Pt, CurrentLSuccessor);
- OpenPt = Pt + 1;
- State = L_OPENED;
- break;
- default:
- assert(0 && "Got unexpected point.");
- break;
- }
- }
-
- void onLROpen(const IntTy &Pt,
- SuccessorClass *LS,
- SuccessorClass *RS) {
- switch (State) {
- case ALL_IS_CLOSED:
- State = INTERSECT_OPENED;
- break;
- default:
- assert(0 && "Got unexpected point.");
- break;
- }
- CurrentLSuccessor = LS;
- CurrentRSuccessor = RS;
- OpenPt = Pt;
- }
-
- void onLRClose(const IntTy &Pt) {
- switch (State) {
- case INTERSECT_OPENED:
- if (IntersectionMapping)
- IntersectionMapping->add(OpenPt, Pt, CurrentLSuccessor);
- State = ALL_IS_CLOSED;
- break;
- default:
- assert(0 && "Got unexpected point.");
- break;
- }
- }
-
- bool isLOpened() { return State == L_OPENED; }
- bool isROpened() { return State == R_OPENED; }
- };
-
-public:
-
- // Don't public CaseItems itself. Don't allow edit the Items directly.
- // Just present the user way to iterate over the internal collection
- // sharing iterator, begin() and end(). Editing should be controlled by
- // factory.
- typedef CaseItemIt RangeIterator;
-
- typedef std::pair<SuccessorClass*, IntegersSubsetTy> Case;
- typedef std::list<Case> Cases;
- typedef typename Cases::iterator CasesIt;
-
- IntegersSubsetMapping() {
- Sorted = false;
- }
-
- bool verify() {
- RangeIterator DummyErrItem;
- return verify(DummyErrItem);
- }
-
- bool verify(RangeIterator& errItem) {
- if (Items.empty())
- return true;
- sort();
- for (CaseItemIt j = Items.begin(), i = j++, e = Items.end();
- j != e; i = j++) {
- if (isIntersected(i, j) && i->second != j->second) {
- errItem = j;
- return false;
- }
- }
- return true;
- }
-
- bool isOverlapped(self &RHS) {
- if (Items.empty() || RHS.empty())
- return true;
-
- for (CaseItemIt L = Items.begin(), R = RHS.Items.begin(),
- el = Items.end(), er = RHS.Items.end(); L != el && R != er;) {
-
- const RangeTy &LRange = L->first;
- const RangeTy &RRange = R->first;
-
- if (LRange.getLow() > RRange.getLow()) {
- if (RRange.isSingleNumber() || LRange.getLow() > RRange.getHigh())
- ++R;
- else
- return true;
- } else if (LRange.getLow() < RRange.getLow()) {
- if (LRange.isSingleNumber() || LRange.getHigh() < RRange.getLow())
- ++L;
- else
- return true;
- } else // iRange.getLow() == jRange.getLow()
- return true;
- }
- return false;
- }
-
-
- void optimize() {
- if (Items.size() < 2)
- return;
- sort();
- CaseItems OldItems = Items;
- Items.clear();
- const IntTy *Low = &OldItems.begin()->first.getLow();
- const IntTy *High = &OldItems.begin()->first.getHigh();
- unsigned Weight = OldItems.begin()->first.Weight;
- SuccessorClass *Successor = OldItems.begin()->second;
- for (CaseItemIt j = OldItems.begin(), i = j++, e = OldItems.end();
- j != e; i = j++) {
- if (isJoinable(i, j)) {
- const IntTy *CurHigh = &j->first.getHigh();
- Weight += j->first.Weight;
- if (*CurHigh > *High)
- High = CurHigh;
- } else {
- RangeEx R(*Low, *High, Weight);
- add(R, Successor);
- Low = &j->first.getLow();
- High = &j->first.getHigh();
- Weight = j->first.Weight;
- Successor = j->second;
- }
- }
- RangeEx R(*Low, *High, Weight);
- add(R, Successor);
- // We recollected the Items, but we kept it sorted.
- Sorted = true;
- }
-
- /// Adds a constant value.
- void add(const IntTy &C, SuccessorClass *S = 0) {
- RangeTy R(C);
- add(R, S);
- }
-
- /// Adds a range.
- void add(const IntTy &Low, const IntTy &High, SuccessorClass *S = 0) {
- RangeTy R(Low, High);
- add(R, S);
- }
- void add(const RangeTy &R, SuccessorClass *S = 0) {
- RangeEx REx = R;
- add(REx, S);
- }
- void add(const RangeEx &R, SuccessorClass *S = 0) {
- Items.push_back(std::make_pair(R, S));
- Sorted = false;
- }
-
- /// Adds all ranges and values from given ranges set to the current
- /// mapping.
- void add(const IntegersSubsetTy &CRS, SuccessorClass *S = 0,
- unsigned Weight = 0) {
- unsigned ItemWeight = 1;
- if (Weight)
- // Weight is associated with CRS, for now we perform a division to
- // get the weight for each item.
- ItemWeight = Weight / CRS.getNumItems();
- for (unsigned i = 0, e = CRS.getNumItems(); i < e; ++i) {
- RangeTy R = CRS.getItem(i);
- RangeEx REx(R, ItemWeight);
- add(REx, S);
- }
- }
-
- void add(self& RHS) {
- Items.insert(Items.end(), RHS.Items.begin(), RHS.Items.end());
- }
-
- void add(self& RHS, SuccessorClass *S) {
- for (CaseItemIt i = RHS.Items.begin(), e = RHS.Items.end(); i != e; ++i)
- add(i->first, S);
- }
-
- void add(const RangesCollection& RHS, SuccessorClass *S = 0) {
- for (RangesCollectionConstIt i = RHS.begin(), e = RHS.end(); i != e; ++i)
- add(*i, S);
- }
-
- /// Removes items from set.
- void removeItem(RangeIterator i) { Items.erase(i); }
-
- /// Moves whole case from current mapping to the NewMapping object.
- void detachCase(self& NewMapping, SuccessorClass *Succ) {
- for (CaseItemIt i = Items.begin(); i != Items.end();)
- if (i->second == Succ) {
- NewMapping.add(i->first, i->second);
- Items.erase(i++);
- } else
- ++i;
- }
-
- /// Removes all clusters for given successor.
- void removeCase(SuccessorClass *Succ) {
- for (CaseItemIt i = Items.begin(); i != Items.end();)
- if (i->second == Succ) {
- Items.erase(i++);
- } else
- ++i;
- }
-
- /// Find successor that satisfies given value.
- SuccessorClass *findSuccessor(const IntTy& Val) {
- for (CaseItemIt i = Items.begin(); i != Items.end(); ++i) {
- if (i->first.isInRange(Val))
- return i->second;
- }
- return 0;
- }
-
- /// Calculates the difference between this mapping and RHS.
- /// THIS without RHS is placed into LExclude,
- /// RHS without THIS is placed into RExclude,
- /// THIS intersect RHS is placed into Intersection.
- void diff(self *LExclude, self *Intersection, self *RExclude,
- const self& RHS) {
-
- DiffStateMachine Machine(LExclude, Intersection, RExclude);
-
- CaseItemConstIt L = Items.begin(), R = RHS.Items.begin();
- while (L != Items.end() && R != RHS.Items.end()) {
- const Cluster &LCluster = *L;
- const RangeEx &LRange = LCluster.first;
- const Cluster &RCluster = *R;
- const RangeEx &RRange = RCluster.first;
-
- if (LRange.getHigh() < RRange.getLow()) {
- Machine.onLOpen(LRange.getLow(), LCluster.second);
- Machine.onLClose(LRange.getHigh());
- ++L;
- continue;
- }
-
- if (LRange.getLow() > RRange.getHigh()) {
- Machine.onROpen(RRange.getLow(), RCluster.second);
- Machine.onRClose(RRange.getHigh());
- ++R;
- continue;
- }
-
- if (LRange.getLow() < RRange.getLow()) {
- // May be opened in previous iteration.
- if (!Machine.isLOpened())
- Machine.onLOpen(LRange.getLow(), LCluster.second);
- Machine.onROpen(RRange.getLow(), RCluster.second);
- }
- else if (RRange.getLow() < LRange.getLow()) {
- if (!Machine.isROpened())
- Machine.onROpen(RRange.getLow(), RCluster.second);
- Machine.onLOpen(LRange.getLow(), LCluster.second);
- }
- else
- Machine.onLROpen(LRange.getLow(), LCluster.second, RCluster.second);
-
- if (LRange.getHigh() < RRange.getHigh()) {
- Machine.onLClose(LRange.getHigh());
- ++L;
- while(L != Items.end() && L->first.getHigh() < RRange.getHigh()) {
- Machine.onLOpen(L->first.getLow(), L->second);
- Machine.onLClose(L->first.getHigh());
- ++L;
- }
- }
- else if (RRange.getHigh() < LRange.getHigh()) {
- Machine.onRClose(RRange.getHigh());
- ++R;
- while(R != RHS.Items.end() && R->first.getHigh() < LRange.getHigh()) {
- Machine.onROpen(R->first.getLow(), R->second);
- Machine.onRClose(R->first.getHigh());
- ++R;
- }
- }
- else {
- Machine.onLRClose(LRange.getHigh());
- ++L;
- ++R;
- }
- }
-
- if (L != Items.end()) {
- if (Machine.isLOpened()) {
- Machine.onLClose(L->first.getHigh());
- ++L;
- }
- if (LExclude)
- while (L != Items.end()) {
- LExclude->add(L->first, L->second);
- ++L;
- }
- } else if (R != RHS.Items.end()) {
- if (Machine.isROpened()) {
- Machine.onRClose(R->first.getHigh());
- ++R;
- }
- if (RExclude)
- while (R != RHS.Items.end()) {
- RExclude->add(R->first, R->second);
- ++R;
- }
- }
- }
-
- /// Builds the finalized case objects.
- void getCases(Cases& TheCases, bool PreventMerging = false) {
- //FIXME: PreventMerging is a temporary parameter.
- //Currently a set of passes is still knows nothing about
- //switches with case ranges, and if these passes meet switch
- //with complex case that crashs the application.
- if (PreventMerging) {
- for (RangeIterator i = this->begin(); i != this->end(); ++i) {
- RangesCollection SingleRange;
- SingleRange.push_back(i->first);
- TheCases.push_back(std::make_pair(i->second,
- IntegersSubsetTy(SingleRange)));
- }
- return;
- }
- CRSMap TheCRSMap;
- for (RangeIterator i = this->begin(); i != this->end(); ++i)
- TheCRSMap[i->second].push_back(i->first);
- for (CRSMapIt i = TheCRSMap.begin(), e = TheCRSMap.end(); i != e; ++i)
- TheCases.push_back(std::make_pair(i->first, IntegersSubsetTy(i->second)));
- }
-
- /// Builds the finalized case objects ignoring successor values, as though
- /// all ranges belongs to the same successor.
- IntegersSubsetTy getCase() {
- RangesCollection Ranges;
- for (RangeIterator i = this->begin(); i != this->end(); ++i)
- Ranges.push_back(i->first);
- return IntegersSubsetTy(Ranges);
- }
-
- /// Returns pointer to value of case if it is single-numbered or 0
- /// in another case.
- const IntTy* getCaseSingleNumber(SuccessorClass *Succ) {
- const IntTy* Res = 0;
- for (CaseItemIt i = Items.begin(); i != Items.end(); ++i)
- if (i->second == Succ) {
- if (!i->first.isSingleNumber())
- return 0;
- if (Res)
- return 0;
- else
- Res = &(i->first.getLow());
- }
- return Res;
- }
-
- /// Returns true if there is no ranges and values inside.
- bool empty() const { return Items.empty(); }
-
- void clear() {
- Items.clear();
- // Don't reset Sorted flag:
- // 1. For empty mapping it matters nothing.
- // 2. After first item will added Sorted flag will cleared.
- }
-
- // Returns number of clusters
- unsigned size() const {
- return Items.size();
- }
-
- RangeIterator begin() { return Items.begin(); }
- RangeIterator end() { return Items.end(); }
-};
-
-class BasicBlock;
-typedef IntegersSubsetMapping<BasicBlock> IntegersSubsetToBB;
-
-}
-
-#endif /* LLVM_SUPPORT_INTEGERSSUBSETMAPPING_CRSBUILDER_H */
diff --git a/include/llvm/Support/LEB128.h b/include/llvm/Support/LEB128.h
index 802b4f354a5a7..3d7379250af4d 100644
--- a/include/llvm/Support/LEB128.h
+++ b/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/include/llvm/Support/MD5.h b/include/llvm/Support/MD5.h
new file mode 100644
index 0000000000000..b2b8c2d55b875
--- /dev/null
+++ b/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/include/llvm/Support/MachO.h b/include/llvm/Support/MachO.h
index 7f28c3f50021d..897a6112f5010 100644
--- a/include/llvm/Support/MachO.h
+++ b/include/llvm/Support/MachO.h
@@ -14,273 +14,419 @@
#ifndef LLVM_SUPPORT_MACHO_H
#define LLVM_SUPPORT_MACHO_H
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/Host.h"
-// NOTE: The enums in this file are intentially named to be different than those
-// in the headers in /usr/include/mach (on darwin systems) to avoid conflicts
-// with those macros.
namespace llvm {
namespace MachO {
// Enums from <mach-o/loader.h>
- enum {
+ enum LLVM_ENUM_INT_TYPE(uint32_t) {
// Constants for the "magic" field in llvm::MachO::mach_header and
// llvm::MachO::mach_header_64
- HeaderMagic32 = 0xFEEDFACEu, // MH_MAGIC
- HeaderMagic32Swapped = 0xCEFAEDFEu, // MH_CIGAM
- HeaderMagic64 = 0xFEEDFACFu, // MH_MAGIC_64
- HeaderMagic64Swapped = 0xCFFAEDFEu, // MH_CIGAM_64
- UniversalMagic = 0xCAFEBABEu, // FAT_MAGIC
- UniversalMagicSwapped = 0xBEBAFECAu, // FAT_CIGAM
+ MH_MAGIC = 0xFEEDFACEu,
+ MH_CIGAM = 0xCEFAEDFEu,
+ MH_MAGIC_64 = 0xFEEDFACFu,
+ MH_CIGAM_64 = 0xCFFAEDFEu,
+ FAT_MAGIC = 0xCAFEBABEu,
+ FAT_CIGAM = 0xBEBAFECAu
+ };
+ enum HeaderFileType {
// Constants for the "filetype" field in llvm::MachO::mach_header and
// llvm::MachO::mach_header_64
- HeaderFileTypeObject = 0x1u, // MH_OBJECT
- HeaderFileTypeExecutable = 0x2u, // MH_EXECUTE
- HeaderFileTypeFixedVMShlib = 0x3u, // MH_FVMLIB
- HeaderFileTypeCore = 0x4u, // MH_CORE
- HeaderFileTypePreloadedExecutable = 0x5u, // MH_PRELOAD
- HeaderFileTypeDynamicShlib = 0x6u, // MH_DYLIB
- HeaderFileTypeDynamicLinkEditor = 0x7u, // MH_DYLINKER
- HeaderFileTypeBundle = 0x8u, // MH_BUNDLE
- HeaderFileTypeDynamicShlibStub = 0x9u, // MH_DYLIB_STUB
- HeaderFileTypeDSYM = 0xAu, // MH_DSYM
- HeaderFileTypeKextBundle = 0xBu, // MH_KEXT_BUNDLE
+ MH_OBJECT = 0x1u,
+ MH_EXECUTE = 0x2u,
+ MH_FVMLIB = 0x3u,
+ MH_CORE = 0x4u,
+ MH_PRELOAD = 0x5u,
+ MH_DYLIB = 0x6u,
+ MH_DYLINKER = 0x7u,
+ MH_BUNDLE = 0x8u,
+ MH_DYLIB_STUB = 0x9u,
+ MH_DSYM = 0xAu,
+ MH_KEXT_BUNDLE = 0xBu
+ };
+ enum {
// Constant bits for the "flags" field in llvm::MachO::mach_header and
// llvm::MachO::mach_header_64
- HeaderFlagBitNoUndefinedSymbols = 0x00000001u, // MH_NOUNDEFS
- HeaderFlagBitIsIncrementalLinkObject= 0x00000002u, // MH_INCRLINK
- HeaderFlagBitIsDynamicLinkObject = 0x00000004u, // MH_DYLDLINK
- HeaderFlagBitBindAtLoad = 0x00000008u, // MH_BINDATLOAD
- HeaderFlagBitPrebound = 0x00000010u, // MH_PREBOUND
- HeaderFlagBitSplitSegments = 0x00000020u, // MH_SPLIT_SEGS
- HeaderFlagBitLazyInit = 0x00000040u, // MH_LAZY_INIT
- HeaderFlagBitTwoLevelNamespace = 0x00000080u, // MH_TWOLEVEL
- HeaderFlagBitForceFlatNamespace = 0x00000100u, // MH_FORCE_FLAT
- HeaderFlagBitNoMultipleDefintions = 0x00000200u, // MH_NOMULTIDEFS
- HeaderFlagBitNoFixPrebinding = 0x00000400u, // MH_NOFIXPREBINDING
- HeaderFlagBitPrebindable = 0x00000800u, // MH_PREBINDABLE
- HeaderFlagBitAllModulesBound = 0x00001000u, // MH_ALLMODSBOUND
- HeaderFlagBitSubsectionsViaSymbols = 0x00002000u, // MH_SUBSECTIONS_VIA_SYMBOLS
- HeaderFlagBitCanonical = 0x00004000u, // MH_CANONICAL
- HeaderFlagBitWeakDefines = 0x00008000u, // MH_WEAK_DEFINES
- HeaderFlagBitBindsToWeak = 0x00010000u, // MH_BINDS_TO_WEAK
- HeaderFlagBitAllowStackExecution = 0x00020000u, // MH_ALLOW_STACK_EXECUTION
- HeaderFlagBitRootSafe = 0x00040000u, // MH_ROOT_SAFE
- HeaderFlagBitSetUIDSafe = 0x00080000u, // MH_SETUID_SAFE
- HeaderFlagBitNoReexportedDylibs = 0x00100000u, // MH_NO_REEXPORTED_DYLIBS
- HeaderFlagBitPIE = 0x00200000u, // MH_PIE
- HeaderFlagBitDeadStrippableDylib = 0x00400000u, // MH_DEAD_STRIPPABLE_DYLIB
-
+ MH_NOUNDEFS = 0x00000001u,
+ MH_INCRLINK = 0x00000002u,
+ MH_DYLDLINK = 0x00000004u,
+ MH_BINDATLOAD = 0x00000008u,
+ MH_PREBOUND = 0x00000010u,
+ MH_SPLIT_SEGS = 0x00000020u,
+ MH_LAZY_INIT = 0x00000040u,
+ MH_TWOLEVEL = 0x00000080u,
+ MH_FORCE_FLAT = 0x00000100u,
+ MH_NOMULTIDEFS = 0x00000200u,
+ MH_NOFIXPREBINDING = 0x00000400u,
+ MH_PREBINDABLE = 0x00000800u,
+ MH_ALLMODSBOUND = 0x00001000u,
+ MH_SUBSECTIONS_VIA_SYMBOLS = 0x00002000u,
+ MH_CANONICAL = 0x00004000u,
+ MH_WEAK_DEFINES = 0x00008000u,
+ MH_BINDS_TO_WEAK = 0x00010000u,
+ MH_ALLOW_STACK_EXECUTION = 0x00020000u,
+ MH_ROOT_SAFE = 0x00040000u,
+ MH_SETUID_SAFE = 0x00080000u,
+ MH_NO_REEXPORTED_DYLIBS = 0x00100000u,
+ MH_PIE = 0x00200000u,
+ MH_DEAD_STRIPPABLE_DYLIB = 0x00400000u
+ };
+
+ enum LLVM_ENUM_INT_TYPE(uint32_t) {
+ // Flags for the "cmd" field in llvm::MachO::load_command
+ LC_REQ_DYLD = 0x80000000u
+ };
+
+ enum LoadCommandType LLVM_ENUM_INT_TYPE(uint32_t) {
// Constants for the "cmd" field in llvm::MachO::load_command
- LoadCommandDynamicLinkerRequired = 0x80000000u, // LC_REQ_DYLD
- LoadCommandSegment32 = 0x00000001u, // LC_SEGMENT
- LoadCommandSymtab = 0x00000002u, // LC_SYMTAB
- LoadCommandSymSeg = 0x00000003u, // LC_SYMSEG
- LoadCommandThread = 0x00000004u, // LC_THREAD
- LoadCommandUnixThread = 0x00000005u, // LC_UNIXTHREAD
- LoadCommandFixedVMShlibLoad = 0x00000006u, // LC_LOADFVMLIB
- LoadCommandFixedVMShlibIdent = 0x00000007u, // LC_IDFVMLIB
- LoadCommandIdent = 0x00000008u, // LC_IDENT
- LoadCommandFixedVMFileInclusion = 0x00000009u, // LC_FVMFILE
- LoadCommandPrePage = 0x0000000Au, // LC_PREPAGE
- LoadCommandDynamicSymtabInfo = 0x0000000Bu, // LC_DYSYMTAB
- LoadCommandDylibLoad = 0x0000000Cu, // LC_LOAD_DYLIB
- LoadCommandDylibIdent = 0x0000000Du, // LC_ID_DYLIB
- LoadCommandDynamicLinkerLoad = 0x0000000Eu, // LC_LOAD_DYLINKER
- LoadCommandDynamicLinkerIdent = 0x0000000Fu, // LC_ID_DYLINKER
- LoadCommandDylibPrebound = 0x00000010u, // LC_PREBOUND_DYLIB
- LoadCommandRoutines32 = 0x00000011u, // LC_ROUTINES
- LoadCommandSubFramework = 0x00000012u, // LC_SUB_FRAMEWORK
- LoadCommandSubUmbrella = 0x00000013u, // LC_SUB_UMBRELLA
- LoadCommandSubClient = 0x00000014u, // LC_SUB_CLIENT
- LoadCommandSubLibrary = 0x00000015u, // LC_SUB_LIBRARY
- LoadCommandTwoLevelHints = 0x00000016u, // LC_TWOLEVEL_HINTS
- LoadCommandPreBindChecksum = 0x00000017u, // LC_PREBIND_CKSUM
- LoadCommandDylibLoadWeak = 0x80000018u, // LC_LOAD_WEAK_DYLIB
- LoadCommandSegment64 = 0x00000019u, // LC_SEGMENT_64
- LoadCommandRoutines64 = 0x0000001Au, // LC_ROUTINES_64
- LoadCommandUUID = 0x0000001Bu, // LC_UUID
- LoadCommandRunpath = 0x8000001Cu, // LC_RPATH
- LoadCommandCodeSignature = 0x0000001Du, // LC_CODE_SIGNATURE
- LoadCommandSegmentSplitInfo = 0x0000001Eu, // LC_SEGMENT_SPLIT_INFO
- LoadCommandDylibReexport = 0x8000001Fu, // LC_REEXPORT_DYLIB
- LoadCommandDylibLazyLoad = 0x00000020u, // LC_LAZY_LOAD_DYLIB
- LoadCommandEncryptionInfo = 0x00000021u, // LC_ENCRYPTION_INFO
- LoadCommandDynamicLinkerInfo = 0x00000022u, // LC_DYLD_INFO
- LoadCommandDynamicLinkerInfoOnly = 0x80000022u, // LC_DYLD_INFO_ONLY
- LoadCommandDylibLoadUpward = 0x80000023u, // LC_LOAD_UPWARD_DYLIB
- LoadCommandVersionMinMacOSX = 0x00000024u, // LC_VERSION_MIN_MACOSX
- LoadCommandVersionMinIPhoneOS = 0x00000025u, // LC_VERSION_MIN_IPHONEOS
- LoadCommandFunctionStarts = 0x00000026u, // LC_FUNCTION_STARTS
- LoadCommandDyldEnvironment = 0x00000027u, // LC_DYLD_ENVIRONMENT
- LoadCommandMain = 0x80000028u, // LC_MAIN
- LoadCommandDataInCode = 0x00000029u, // LC_DATA_IN_CODE
- LoadCommandSourceVersion = 0x0000002Au, // LC_SOURCE_VERSION
- LoadCommandCodeSignDRs = 0x0000002Bu, // LC_DYLIB_CODE_SIGN_DRS
-
+ LC_SEGMENT = 0x00000001u,
+ LC_SYMTAB = 0x00000002u,
+ LC_SYMSEG = 0x00000003u,
+ LC_THREAD = 0x00000004u,
+ LC_UNIXTHREAD = 0x00000005u,
+ LC_LOADFVMLIB = 0x00000006u,
+ LC_IDFVMLIB = 0x00000007u,
+ LC_IDENT = 0x00000008u,
+ LC_FVMFILE = 0x00000009u,
+ LC_PREPAGE = 0x0000000Au,
+ LC_DYSYMTAB = 0x0000000Bu,
+ LC_LOAD_DYLIB = 0x0000000Cu,
+ LC_ID_DYLIB = 0x0000000Du,
+ LC_LOAD_DYLINKER = 0x0000000Eu,
+ LC_ID_DYLINKER = 0x0000000Fu,
+ LC_PREBOUND_DYLIB = 0x00000010u,
+ LC_ROUTINES = 0x00000011u,
+ LC_SUB_FRAMEWORK = 0x00000012u,
+ LC_SUB_UMBRELLA = 0x00000013u,
+ LC_SUB_CLIENT = 0x00000014u,
+ LC_SUB_LIBRARY = 0x00000015u,
+ LC_TWOLEVEL_HINTS = 0x00000016u,
+ LC_PREBIND_CKSUM = 0x00000017u,
+ LC_LOAD_WEAK_DYLIB = 0x80000018u,
+ LC_SEGMENT_64 = 0x00000019u,
+ LC_ROUTINES_64 = 0x0000001Au,
+ LC_UUID = 0x0000001Bu,
+ LC_RPATH = 0x8000001Cu,
+ LC_CODE_SIGNATURE = 0x0000001Du,
+ LC_SEGMENT_SPLIT_INFO = 0x0000001Eu,
+ LC_REEXPORT_DYLIB = 0x8000001Fu,
+ LC_LAZY_LOAD_DYLIB = 0x00000020u,
+ LC_ENCRYPTION_INFO = 0x00000021u,
+ LC_DYLD_INFO = 0x00000022u,
+ LC_DYLD_INFO_ONLY = 0x80000022u,
+ LC_LOAD_UPWARD_DYLIB = 0x80000023u,
+ LC_VERSION_MIN_MACOSX = 0x00000024u,
+ LC_VERSION_MIN_IPHONEOS = 0x00000025u,
+ LC_FUNCTION_STARTS = 0x00000026u,
+ LC_DYLD_ENVIRONMENT = 0x00000027u,
+ LC_MAIN = 0x80000028u,
+ LC_DATA_IN_CODE = 0x00000029u,
+ LC_SOURCE_VERSION = 0x0000002Au,
+ LC_DYLIB_CODE_SIGN_DRS = 0x0000002Bu,
+ // 0x0000002Cu,
+ LC_LINKER_OPTIONS = 0x0000002Du
+ };
+
+ enum LLVM_ENUM_INT_TYPE(uint32_t) {
// Constant bits for the "flags" field in llvm::MachO::segment_command
- SegmentCommandFlagBitHighVM = 0x1u, // SG_HIGHVM
- SegmentCommandFlagBitFixedVMLibrary = 0x2u, // SG_FVMLIB
- SegmentCommandFlagBitNoRelocations = 0x4u, // SG_NORELOC
- SegmentCommandFlagBitProtectedVersion1 = 0x8u, // SG_PROTECTED_VERSION_1
+ SG_HIGHVM = 0x1u,
+ SG_FVMLIB = 0x2u,
+ SG_NORELOC = 0x4u,
+ SG_PROTECTED_VERSION_1 = 0x8u,
// Constant masks for the "flags" field in llvm::MachO::section and
// llvm::MachO::section_64
- SectionFlagMaskSectionType = 0x000000ffu, // SECTION_TYPE
- SectionFlagMaskAllAttributes = 0xffffff00u, // SECTION_ATTRIBUTES
- SectionFlagMaskUserAttributes = 0xff000000u, // SECTION_ATTRIBUTES_USR
- SectionFlagMaskSystemAttributes = 0x00ffff00u, // SECTION_ATTRIBUTES_SYS
+ SECTION_TYPE = 0x000000ffu, // SECTION_TYPE
+ SECTION_ATTRIBUTES = 0xffffff00u, // SECTION_ATTRIBUTES
+ SECTION_ATTRIBUTES_USR = 0xff000000u, // SECTION_ATTRIBUTES_USR
+ SECTION_ATTRIBUTES_SYS = 0x00ffff00u // SECTION_ATTRIBUTES_SYS
+ };
+ enum SectionType {
// Constant masks for the "flags[7:0]" field in llvm::MachO::section and
// llvm::MachO::section_64 (mask "flags" with SECTION_TYPE)
- SectionTypeRegular = 0x00u, // S_REGULAR
- SectionTypeZeroFill = 0x01u, // S_ZEROFILL
- SectionTypeCStringLiterals = 0x02u, // S_CSTRING_LITERALS
- SectionType4ByteLiterals = 0x03u, // S_4BYTE_LITERALS
- SectionType8ByteLiterals = 0x04u, // S_8BYTE_LITERALS
- SectionTypeLiteralPointers = 0x05u, // S_LITERAL_POINTERS
- SectionTypeNonLazySymbolPointers = 0x06u, // S_NON_LAZY_SYMBOL_POINTERS
- SectionTypeLazySymbolPointers = 0x07u, // S_LAZY_SYMBOL_POINTERS
- SectionTypeSymbolStubs = 0x08u, // S_SYMBOL_STUBS
- SectionTypeModuleInitFunctionPointers = 0x09u, // S_MOD_INIT_FUNC_POINTERS
- SectionTypeModuleTermFunctionPointers = 0x0au, // S_MOD_TERM_FUNC_POINTERS
- SectionTypeCoalesced = 0x0bu, // S_COALESCED
- SectionTypeZeroFillLarge = 0x0cu, // S_GB_ZEROFILL
- SectionTypeInterposing = 0x0du, // S_INTERPOSING
- SectionType16ByteLiterals = 0x0eu, // S_16BYTE_LITERALS
- SectionTypeDTraceObjectFormat = 0x0fu, // S_DTRACE_DOF
- SectionTypeLazyDylibSymbolPointers = 0x10u, // S_LAZY_DYLIB_SYMBOL_POINTERS
-
+ S_REGULAR = 0x00u,
+ S_ZEROFILL = 0x01u,
+ S_CSTRING_LITERALS = 0x02u,
+ S_4BYTE_LITERALS = 0x03u,
+ S_8BYTE_LITERALS = 0x04u,
+ S_LITERAL_POINTERS = 0x05u,
+ S_NON_LAZY_SYMBOL_POINTERS = 0x06u,
+ S_LAZY_SYMBOL_POINTERS = 0x07u,
+ S_SYMBOL_STUBS = 0x08u,
+ S_MOD_INIT_FUNC_POINTERS = 0x09u,
+ S_MOD_TERM_FUNC_POINTERS = 0x0au,
+ S_COALESCED = 0x0bu,
+ S_GB_ZEROFILL = 0x0cu,
+ S_INTERPOSING = 0x0du,
+ S_16BYTE_LITERALS = 0x0eu,
+ S_DTRACE_DOF = 0x0fu,
+ S_LAZY_DYLIB_SYMBOL_POINTERS = 0x10u,
+ S_THREAD_LOCAL_REGULAR = 0x11u,
+ S_THREAD_LOCAL_ZEROFILL = 0x12u,
+ S_THREAD_LOCAL_VARIABLES = 0x13u,
+ S_THREAD_LOCAL_VARIABLE_POINTERS = 0x14u,
+ S_THREAD_LOCAL_INIT_FUNCTION_POINTERS = 0x15u
+ };
+
+ enum LLVM_ENUM_INT_TYPE(uint32_t) {
// Constant masks for the "flags[31:24]" field in llvm::MachO::section and
// llvm::MachO::section_64 (mask "flags" with SECTION_ATTRIBUTES_USR)
- SectionAttrUserPureInstructions = 0x80000000u, // S_ATTR_PURE_INSTRUCTIONS
- SectionAttrUserNoTableOfContents = 0x40000000u, // S_ATTR_NO_TOC
- SectionAttrUserCanStripStaticSymbols = 0x20000000u, // S_ATTR_STRIP_STATIC_SYMS
- SectionAttrUserNoDeadStrip = 0x10000000u, // S_ATTR_NO_DEAD_STRIP
- SectionAttrUserLiveSupport = 0x08000000u, // S_ATTR_LIVE_SUPPORT
- SectionAttrUserSelfModifyingCode = 0x04000000u, // S_ATTR_SELF_MODIFYING_CODE
- SectionAttrUserDebug = 0x02000000u, // S_ATTR_DEBUG
+ S_ATTR_PURE_INSTRUCTIONS = 0x80000000u,
+ S_ATTR_NO_TOC = 0x40000000u,
+ S_ATTR_STRIP_STATIC_SYMS = 0x20000000u,
+ S_ATTR_NO_DEAD_STRIP = 0x10000000u,
+ S_ATTR_LIVE_SUPPORT = 0x08000000u,
+ S_ATTR_SELF_MODIFYING_CODE = 0x04000000u,
+ S_ATTR_DEBUG = 0x02000000u,
// Constant masks for the "flags[23:8]" field in llvm::MachO::section and
// llvm::MachO::section_64 (mask "flags" with SECTION_ATTRIBUTES_SYS)
- SectionAttrSytemSomeInstructions = 0x00000400u, // S_ATTR_SOME_INSTRUCTIONS
- SectionAttrSytemHasExternalRelocations= 0x00000200u, // S_ATTR_EXT_RELOC
- SectionAttrSytemHasLocalRelocations = 0x00000100u, // S_ATTR_LOC_RELOC
-
- IndirectSymbolLocal = 0x80000000u, // INDIRECT_SYMBOL_LOCAL
- IndirectSymbolAbsolute = 0x40000000u, // INDIRECT_SYMBOL_ABS
-
- RebaseTypePointer = 1u, // REBASE_TYPE_POINTER
- RebaseTypeTextAbsolute32 = 2u, // REBASE_TYPE_TEXT_ABSOLUTE32
- RebaseTypeTextPCRelative32 = 3u, // REBASE_TYPE_TEXT_PCREL32
-
- RebaseOpcodeMask = 0xF0u, // REBASE_OPCODE_MASK
- RebaseImmediateMask = 0x0Fu, // REBASE_IMMEDIATE_MASK
- RebaseOpcodeDone = 0x00u, // REBASE_OPCODE_DONE
- RebaseOpcodeSetTypeImmediate = 0x10u, // REBASE_OPCODE_SET_TYPE_IMM
- RebaseOpcodeSetSegmentAndOffsetULEB = 0x20u, // REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB
- RebaseOpcodeAddAddressULEB = 0x30u, // REBASE_OPCODE_ADD_ADDR_ULEB
- RebaseOpcodeAddAddressImmediateScaled = 0x40u, // REBASE_OPCODE_ADD_ADDR_IMM_SCALED
- RebaseOpcodeDoRebaseImmediateTimes = 0x50u, // REBASE_OPCODE_DO_REBASE_IMM_TIMES
- RebaseOpcodeDoRebaseULEBTimes = 0x60u, // REBASE_OPCODE_DO_REBASE_ULEB_TIMES
- RebaseOpcodeDoRebaseAddAddressULEB = 0x70u, // REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB
- RebaseOpcodeDoRebaseULEBTimesSkippingULEB = 0x80u, // REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB
-
-
- BindTypePointer = 1u, // BIND_TYPE_POINTER
- BindTypeTextAbsolute32 = 2u, // BIND_TYPE_TEXT_ABSOLUTE32
- BindTypeTextPCRelative32 = 3u, // BIND_TYPE_TEXT_PCREL32
-
- BindSpecialDylibSelf = 0u, // BIND_SPECIAL_DYLIB_SELF
- BindSpecialDylibMainExecutable = -1u, // BIND_SPECIAL_DYLIB_MAIN_EXECUTABLE
- BindSpecialDylibFlatLookup = -2u, // BIND_SPECIAL_DYLIB_FLAT_LOOKUP
-
- BindSymbolFlagsWeakImport = 0x1u, // BIND_SYMBOL_FLAGS_WEAK_IMPORT
- BindSymbolFlagsNonWeakDefinition = 0x8u, // BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION
-
- BindOpcodeMask = 0xF0u, // BIND_OPCODE_MASK
- BindImmediateMask = 0x0Fu, // BIND_IMMEDIATE_MASK
- BindOpcodeDone = 0x00u, // BIND_OPCODE_DONE
- BindOpcodeSetDylibOrdinalImmediate = 0x10u, // BIND_OPCODE_SET_DYLIB_ORDINAL_IMM
- BindOpcodeSetDylibOrdinalULEB = 0x20u, // BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB
- BindOpcodeSetDylibSpecialImmediate = 0x30u, // BIND_OPCODE_SET_DYLIB_SPECIAL_IMM
- BindOpcodeSetSymbolTrailingFlagsImmediate = 0x40u, // BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM
- BindOpcodeSetTypeImmediate = 0x50u, // BIND_OPCODE_SET_TYPE_IMM
- BindOpcodeSetAppendSLEB = 0x60u, // BIND_OPCODE_SET_ADDEND_SLEB
- BindOpcodeSetSegmentAndOffsetULEB = 0x70u, // BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB
- BindOpcodeAddAddressULEB = 0x80u, // BIND_OPCODE_ADD_ADDR_ULEB
- BindOpcodeDoBind = 0x90u, // BIND_OPCODE_DO_BIND
- BindOpcodeDoBindAddAddressULEB = 0xA0u, // BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB
- BindOpcodeDoBindAddAddressImmediateScaled = 0xB0u, // BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED
- BindOpcodeDoBindULEBTimesSkippingULEB = 0xC0u, // BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB
-
- ExportSymbolFlagsKindMask = 0x03u, // EXPORT_SYMBOL_FLAGS_KIND_MASK
- ExportSymbolFlagsKindRegular = 0x00u, // EXPORT_SYMBOL_FLAGS_KIND_REGULAR
- ExportSymbolFlagsKindThreadLocal = 0x01u, // EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL
- ExportSymbolFlagsWeakDefinition = 0x04u, // EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION
- ExportSymbolFlagsIndirectDefinition = 0x08u, // EXPORT_SYMBOL_FLAGS_INDIRECT_DEFINITION
- ExportSymbolFlagsHasSpecializations = 0x10u, // EXPORT_SYMBOL_FLAGS_HAS_SPECIALIZATIONS
+ S_ATTR_SOME_INSTRUCTIONS = 0x00000400u,
+ S_ATTR_EXT_RELOC = 0x00000200u,
+ S_ATTR_LOC_RELOC = 0x00000100u,
+
+ // Constant masks for the value of an indirect symbol in an indirect
+ // symbol table
+ INDIRECT_SYMBOL_LOCAL = 0x80000000u,
+ INDIRECT_SYMBOL_ABS = 0x40000000u
+ };
+
+ enum DataRegionType {
+ // Constants for the "kind" field in a data_in_code_entry structure
+ DICE_KIND_DATA = 1u,
+ DICE_KIND_JUMP_TABLE8 = 2u,
+ DICE_KIND_JUMP_TABLE16 = 3u,
+ DICE_KIND_JUMP_TABLE32 = 4u,
+ DICE_KIND_ABS_JUMP_TABLE32 = 5u
+ };
+
+ enum RebaseType {
+ REBASE_TYPE_POINTER = 1u,
+ REBASE_TYPE_TEXT_ABSOLUTE32 = 2u,
+ REBASE_TYPE_TEXT_PCREL32 = 3u
+ };
+
+ enum {
+ REBASE_OPCODE_MASK = 0xF0u,
+ REBASE_IMMEDIATE_MASK = 0x0Fu
+ };
+
+ enum RebaseOpcode {
+ REBASE_OPCODE_DONE = 0x00u,
+ REBASE_OPCODE_SET_TYPE_IMM = 0x10u,
+ REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB = 0x20u,
+ REBASE_OPCODE_ADD_ADDR_ULEB = 0x30u,
+ REBASE_OPCODE_ADD_ADDR_IMM_SCALED = 0x40u,
+ REBASE_OPCODE_DO_REBASE_IMM_TIMES = 0x50u,
+ REBASE_OPCODE_DO_REBASE_ULEB_TIMES = 0x60u,
+ REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB = 0x70u,
+ REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB = 0x80u
+ };
+
+ enum BindType {
+ BIND_TYPE_POINTER = 1u,
+ BIND_TYPE_TEXT_ABSOLUTE32 = 2u,
+ BIND_TYPE_TEXT_PCREL32 = 3u
+ };
+ enum BindSpecialDylib {
+ BIND_SPECIAL_DYLIB_SELF = 0,
+ BIND_SPECIAL_DYLIB_MAIN_EXECUTABLE = -1,
+ BIND_SPECIAL_DYLIB_FLAT_LOOKUP = -2
+ };
+
+ enum {
+ BIND_SYMBOL_FLAGS_WEAK_IMPORT = 0x1u,
+ BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION = 0x8u,
+ BIND_OPCODE_MASK = 0xF0u,
+ BIND_IMMEDIATE_MASK = 0x0Fu
+ };
+
+ enum BindOpcode {
+ BIND_OPCODE_DONE = 0x00u,
+ BIND_OPCODE_SET_DYLIB_ORDINAL_IMM = 0x10u,
+ BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB = 0x20u,
+ BIND_OPCODE_SET_DYLIB_SPECIAL_IMM = 0x30u,
+ BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM = 0x40u,
+ BIND_OPCODE_SET_TYPE_IMM = 0x50u,
+ BIND_OPCODE_SET_ADDEND_SLEB = 0x60u,
+ BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB = 0x70u,
+ BIND_OPCODE_ADD_ADDR_ULEB = 0x80u,
+ BIND_OPCODE_DO_BIND = 0x90u,
+ BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB = 0xA0u,
+ BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED = 0xB0u,
+ BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB = 0xC0u
+ };
+
+ enum {
+ EXPORT_SYMBOL_FLAGS_KIND_MASK = 0x03u,
+ EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION = 0x04u,
+ EXPORT_SYMBOL_FLAGS_REEXPORT = 0x08u,
+ EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER = 0x10u
+ };
+
+ enum ExportSymbolKind {
+ EXPORT_SYMBOL_FLAGS_KIND_REGULAR = 0x00u,
+ EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL = 0x01u
+ };
+
+
+ enum {
// Constant masks for the "n_type" field in llvm::MachO::nlist and
// llvm::MachO::nlist_64
- NlistMaskStab = 0xe0, // N_STAB
- NlistMaskPrivateExternal = 0x10, // N_PEXT
- NlistMaskType = 0x0e, // N_TYPE
- NlistMaskExternal = 0x01, // N_EXT
+ N_STAB = 0xe0,
+ N_PEXT = 0x10,
+ N_TYPE = 0x0e,
+ N_EXT = 0x01
+ };
+ enum NListType {
// Constants for the "n_type & N_TYPE" llvm::MachO::nlist and
// llvm::MachO::nlist_64
- NListTypeUndefined = 0x0u, // N_UNDF
- NListTypeAbsolute = 0x2u, // N_ABS
- NListTypeSection = 0xeu, // N_SECT
- NListTypePreboundUndefined = 0xcu, // N_PBUD
- NListTypeIndirect = 0xau, // N_INDR
+ N_UNDF = 0x0u,
+ N_ABS = 0x2u,
+ N_SECT = 0xeu,
+ N_PBUD = 0xcu,
+ N_INDR = 0xau
+ };
- // Constant masks for the "n_sect" field in llvm::MachO::nlist and
+ enum SectionOrdinal {
+ // Constants for the "n_sect" field in llvm::MachO::nlist and
// llvm::MachO::nlist_64
- NListSectionNoSection = 0u, // NO_SECT
- NListSectionMaxSection = 0xffu, // MAX_SECT
+ NO_SECT = 0u,
+ MAX_SECT = 0xffu
+ };
- NListDescWeakRef = 0x40u,
- NListDescWeakDef = 0x80u,
+ enum {
+ // Constant masks for the "n_desc" field in llvm::MachO::nlist and
+ // llvm::MachO::nlist_64
+ N_ARM_THUMB_DEF = 0x0008u,
+ N_NO_DEAD_STRIP = 0x0020u,
+ N_WEAK_REF = 0x0040u,
+ N_WEAK_DEF = 0x0080u,
+ N_SYMBOL_RESOLVER = 0x0100u
+ };
+ enum StabType {
// Constant values for the "n_type" field in llvm::MachO::nlist and
// llvm::MachO::nlist_64 when "(n_type & NlistMaskStab) != 0"
- StabGlobalSymbol = 0x20u, // N_GSYM
- StabFunctionName = 0x22u, // N_FNAME
- StabFunction = 0x24u, // N_FUN
- StabStaticSymbol = 0x26u, // N_STSYM
- StabLocalCommon = 0x28u, // N_LCSYM
- StabBeginSymbol = 0x2Eu, // N_BNSYM
- StabSourceFileOptions = 0x3Cu, // N_OPT
- StabRegisterSymbol = 0x40u, // N_RSYM
- StabSourceLine = 0x44u, // N_SLINE
- StabEndSymbol = 0x4Eu, // N_ENSYM
- StabStructureType = 0x60u, // N_SSYM
- StabSourceFileName = 0x64u, // N_SO
- StabObjectFileName = 0x66u, // N_OSO
- StabLocalSymbol = 0x80u, // N_LSYM
- StabBeginIncludeFileName = 0x82u, // N_BINCL
- StabIncludeFileName = 0x84u, // N_SOL
- StabCompilerParameters = 0x86u, // N_PARAMS
- StabCompilerVersion = 0x88u, // N_VERSION
- StabCompilerOptLevel = 0x8Au, // N_OLEVEL
- StabParameter = 0xA0u, // N_PSYM
- StabEndIncludeFile = 0xA2u, // N_EINCL
- StabAlternateEntry = 0xA4u, // N_ENTRY
- StabLeftBracket = 0xC0u, // N_LBRAC
- StabDeletedIncludeFile = 0xC2u, // N_EXCL
- StabRightBracket = 0xE0u, // N_RBRAC
- StabBeginCommon = 0xE2u, // N_BCOMM
- StabEndCommon = 0xE4u, // N_ECOMM
- StabEndCommonLocal = 0xE8u, // N_ECOML
- StabLength = 0xFEu // N_LENG
-
+ N_GSYM = 0x20u,
+ N_FNAME = 0x22u,
+ N_FUN = 0x24u,
+ N_STSYM = 0x26u,
+ N_LCSYM = 0x28u,
+ N_BNSYM = 0x2Eu,
+ N_OPT = 0x3Cu,
+ N_RSYM = 0x40u,
+ N_SLINE = 0x44u,
+ N_ENSYM = 0x4Eu,
+ N_SSYM = 0x60u,
+ N_SO = 0x64u,
+ N_OSO = 0x66u,
+ N_LSYM = 0x80u,
+ N_BINCL = 0x82u,
+ N_SOL = 0x84u,
+ N_PARAMS = 0x86u,
+ N_VERSION = 0x88u,
+ N_OLEVEL = 0x8Au,
+ N_PSYM = 0xA0u,
+ N_EINCL = 0xA2u,
+ N_ENTRY = 0xA4u,
+ N_LBRAC = 0xC0u,
+ N_EXCL = 0xC2u,
+ N_RBRAC = 0xE0u,
+ N_BCOMM = 0xE2u,
+ N_ECOMM = 0xE4u,
+ N_ECOML = 0xE8u,
+ N_LENG = 0xFEu
+ };
+
+ enum LLVM_ENUM_INT_TYPE(uint32_t) {
+ // Constant values for the r_symbolnum field in an
+ // llvm::MachO::relocation_info structure when r_extern is 0.
+ R_ABS = 0,
+
+ // Constant bits for the r_address field in an
+ // llvm::MachO::relocation_info structure.
+ R_SCATTERED = 0x80000000
+ };
+
+ enum RelocationInfoType {
+ // Constant values for the r_type field in an
+ // llvm::MachO::relocation_info or llvm::MachO::scattered_relocation_info
+ // structure.
+ GENERIC_RELOC_VANILLA = 0,
+ GENERIC_RELOC_PAIR = 1,
+ GENERIC_RELOC_SECTDIFF = 2,
+ GENERIC_RELOC_PB_LA_PTR = 3,
+ GENERIC_RELOC_LOCAL_SECTDIFF = 4,
+ GENERIC_RELOC_TLV = 5,
+
+ // Constant values for the r_type field in a PowerPC architecture
+ // llvm::MachO::relocation_info or llvm::MachO::scattered_relocation_info
+ // structure.
+ PPC_RELOC_VANILLA = GENERIC_RELOC_VANILLA,
+ PPC_RELOC_PAIR = GENERIC_RELOC_PAIR,
+ PPC_RELOC_BR14 = 2,
+ PPC_RELOC_BR24 = 3,
+ PPC_RELOC_HI16 = 4,
+ PPC_RELOC_LO16 = 5,
+ PPC_RELOC_HA16 = 6,
+ PPC_RELOC_LO14 = 7,
+ PPC_RELOC_SECTDIFF = 8,
+ PPC_RELOC_PB_LA_PTR = 9,
+ PPC_RELOC_HI16_SECTDIFF = 10,
+ PPC_RELOC_LO16_SECTDIFF = 11,
+ PPC_RELOC_HA16_SECTDIFF = 12,
+ PPC_RELOC_JBSR = 13,
+ PPC_RELOC_LO14_SECTDIFF = 14,
+ PPC_RELOC_LOCAL_SECTDIFF = 15,
+
+ // Constant values for the r_type field in an ARM architecture
+ // llvm::MachO::relocation_info or llvm::MachO::scattered_relocation_info
+ // structure.
+ ARM_RELOC_VANILLA = GENERIC_RELOC_VANILLA,
+ ARM_RELOC_PAIR = GENERIC_RELOC_PAIR,
+ ARM_RELOC_SECTDIFF = GENERIC_RELOC_SECTDIFF,
+ ARM_RELOC_LOCAL_SECTDIFF = 3,
+ ARM_RELOC_PB_LA_PTR = 4,
+ ARM_RELOC_BR24 = 5,
+ ARM_THUMB_RELOC_BR22 = 6,
+ ARM_THUMB_32BIT_BRANCH = 7, // obsolete
+ ARM_RELOC_HALF = 8,
+ ARM_RELOC_HALF_SECTDIFF = 9,
+
+ // Constant values for the r_type field in an x86_64 architecture
+ // llvm::MachO::relocation_info or llvm::MachO::scattered_relocation_info
+ // structure
+ X86_64_RELOC_UNSIGNED = 0,
+ X86_64_RELOC_SIGNED = 1,
+ X86_64_RELOC_BRANCH = 2,
+ X86_64_RELOC_GOT_LOAD = 3,
+ X86_64_RELOC_GOT = 4,
+ X86_64_RELOC_SUBTRACTOR = 5,
+ X86_64_RELOC_SIGNED_1 = 6,
+ X86_64_RELOC_SIGNED_2 = 7,
+ X86_64_RELOC_SIGNED_4 = 8,
+ X86_64_RELOC_TLV = 9
+ };
+
+ // Values for segment_command.initprot.
+ // From <mach/vm_prot.h>
+ enum {
+ VM_PROT_READ = 0x1,
+ VM_PROT_WRITE = 0x2,
+ VM_PROT_EXECUTE = 0x4
};
+
// Structs from <mach-o/loader.h>
struct mach_header {
@@ -572,6 +718,18 @@ namespace llvm {
uint32_t datasize;
};
+ struct data_in_code_entry {
+ uint32_t offset;
+ uint16_t length;
+ uint16_t kind;
+ };
+
+ struct source_version_command {
+ uint32_t cmd;
+ uint32_t cmdsize;
+ uint64_t version;
+ };
+
struct encryption_info_command {
uint32_t cmd;
uint32_t cmdsize;
@@ -602,6 +760,12 @@ namespace llvm {
uint32_t export_size;
};
+ struct linker_options_command {
+ uint32_t cmd;
+ uint32_t cmdsize;
+ uint32_t count;
+ };
+
struct symseg_command {
uint32_t cmd;
uint32_t cmdsize;
@@ -621,6 +785,31 @@ namespace llvm {
uint32_t header_addr;
};
+ struct tlv_descriptor_32 {
+ uint32_t thunk;
+ uint32_t key;
+ uint32_t offset;
+ };
+
+ struct tlv_descriptor_64 {
+ uint64_t thunk;
+ uint64_t key;
+ uint64_t offset;
+ };
+
+ struct tlv_descriptor {
+ uintptr_t thunk;
+ uintptr_t key;
+ uintptr_t offset;
+ };
+
+ struct entry_point_command {
+ uint32_t cmd;
+ uint32_t cmdsize;
+ uint64_t entryoff;
+ uint64_t stacksize;
+ };
+
// Structs from <mach-o/fat.h>
struct fat_header {
@@ -636,7 +825,39 @@ namespace llvm {
uint32_t align;
};
- // Structs from <mach-o/fat.h>
+ // Structs from <mach-o/reloc.h>
+ struct relocation_info {
+ int32_t r_address;
+ uint32_t r_symbolnum:24,
+ r_pcrel:1,
+ r_length:2,
+ r_extern:1,
+ r_type:4;
+ };
+
+ struct scattered_relocation_info {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && (BYTE_ORDER == BIG_ENDIAN)
+ uint32_t r_scattered:1,
+ r_pcrel:1,
+ r_length:2,
+ r_type:4,
+ r_address:24;
+#else
+ uint32_t r_address:24,
+ r_type:4,
+ r_length:2,
+ r_pcrel:1,
+ r_scattered:1;
+#endif
+ int32_t r_value;
+ };
+
+ // Structs NOT from <mach-o/reloc.h>, but that make LLVM's life easier
+ struct any_relocation_info {
+ uint32_t r_word0, r_word1;
+ };
+
+ // Structs from <mach-o/nlist.h>
struct nlist {
uint32_t n_strx;
uint8_t n_type;
@@ -655,58 +876,132 @@ namespace llvm {
// Get/Set functions from <mach-o/nlist.h>
- static inline uint16_t GET_LIBRARY_ORDINAL(uint16_t n_desc)
- {
+ static inline uint16_t GET_LIBRARY_ORDINAL(uint16_t n_desc) {
return (((n_desc) >> 8u) & 0xffu);
}
- static inline void SET_LIBRARY_ORDINAL(uint16_t &n_desc, uint8_t ordinal)
- {
+ static inline void SET_LIBRARY_ORDINAL(uint16_t &n_desc, uint8_t ordinal) {
n_desc = (((n_desc) & 0x00ff) | (((ordinal) & 0xff) << 8));
}
- static inline uint8_t GET_COMM_ALIGN (uint16_t n_desc)
- {
+ static inline uint8_t GET_COMM_ALIGN (uint16_t n_desc) {
return (n_desc >> 8u) & 0x0fu;
}
- static inline void SET_COMM_ALIGN (uint16_t &n_desc, uint8_t align)
- {
+ static inline void SET_COMM_ALIGN (uint16_t &n_desc, uint8_t align) {
n_desc = ((n_desc & 0xf0ffu) | ((align & 0x0fu) << 8u));
}
// Enums from <mach/machine.h>
- enum {
+ enum LLVM_ENUM_INT_TYPE(uint32_t) {
// Capability bits used in the definition of cpu_type.
- CPUArchMask = 0xff000000, // Mask for architecture bits
- CPUArchABI64 = 0x01000000, // 64 bit ABI
-
- // Constants for the cputype field.
- CPUTypeI386 = 7,
- CPUTypeX86_64 = CPUTypeI386 | CPUArchABI64,
- CPUTypeARM = 12,
- CPUTypeSPARC = 14,
- CPUTypePowerPC = 18,
- CPUTypePowerPC64 = CPUTypePowerPC | CPUArchABI64,
-
-
- // Constants for the cpusubtype field.
-
- // X86
- CPUSubType_I386_ALL = 3,
- CPUSubType_X86_64_ALL = 3,
-
- // ARM
- CPUSubType_ARM_ALL = 0,
- CPUSubType_ARM_V4T = 5,
- CPUSubType_ARM_V5 = 7,
- CPUSubType_ARM_V6 = 6,
- CPUSubType_ARM_V7 = 9,
-
- // PowerPC
- CPUSubType_POWERPC_ALL = 0,
-
- CPUSubType_SPARC_ALL = 0
+ CPU_ARCH_MASK = 0xff000000, // Mask for architecture bits
+ CPU_ARCH_ABI64 = 0x01000000 // 64 bit ABI
+ };
+
+ // Constants for the cputype field.
+ enum CPUType {
+ CPU_TYPE_ANY = -1,
+ CPU_TYPE_X86 = 7,
+ CPU_TYPE_I386 = CPU_TYPE_X86,
+ CPU_TYPE_X86_64 = CPU_TYPE_X86 | CPU_ARCH_ABI64,
+ /* CPU_TYPE_MIPS = 8, */
+ CPU_TYPE_MC98000 = 10, // Old Motorola PowerPC
+ CPU_TYPE_ARM = 12,
+ CPU_TYPE_SPARC = 14,
+ CPU_TYPE_POWERPC = 18,
+ CPU_TYPE_POWERPC64 = CPU_TYPE_POWERPC | CPU_ARCH_ABI64
+ };
+
+ enum LLVM_ENUM_INT_TYPE(uint32_t) {
+ // Capability bits used in the definition of cpusubtype.
+ CPU_SUB_TYPE_MASK = 0xff000000, // Mask for architecture bits
+ CPU_SUB_TYPE_LIB64 = 0x80000000, // 64 bit libraries
+
+ // Special CPU subtype constants.
+ CPU_SUBTYPE_MULTIPLE = ~0u
+ };
+
+ // Constants for the cpusubtype field.
+ enum CPUSubTypeX86 {
+ CPU_SUBTYPE_I386_ALL = 3,
+ CPU_SUBTYPE_386 = 3,
+ CPU_SUBTYPE_486 = 4,
+ CPU_SUBTYPE_486SX = 0x84,
+ CPU_SUBTYPE_586 = 5,
+ CPU_SUBTYPE_PENT = CPU_SUBTYPE_586,
+ CPU_SUBTYPE_PENTPRO = 0x16,
+ CPU_SUBTYPE_PENTII_M3 = 0x36,
+ CPU_SUBTYPE_PENTII_M5 = 0x56,
+ CPU_SUBTYPE_CELERON = 0x67,
+ CPU_SUBTYPE_CELERON_MOBILE = 0x77,
+ CPU_SUBTYPE_PENTIUM_3 = 0x08,
+ CPU_SUBTYPE_PENTIUM_3_M = 0x18,
+ CPU_SUBTYPE_PENTIUM_3_XEON = 0x28,
+ CPU_SUBTYPE_PENTIUM_M = 0x09,
+ CPU_SUBTYPE_PENTIUM_4 = 0x0a,
+ CPU_SUBTYPE_PENTIUM_4_M = 0x1a,
+ CPU_SUBTYPE_ITANIUM = 0x0b,
+ CPU_SUBTYPE_ITANIUM_2 = 0x1b,
+ CPU_SUBTYPE_XEON = 0x0c,
+ CPU_SUBTYPE_XEON_MP = 0x1c,
+
+ CPU_SUBTYPE_X86_ALL = 3,
+ CPU_SUBTYPE_X86_64_ALL = 3,
+ CPU_SUBTYPE_X86_ARCH1 = 4,
+ CPU_SUBTYPE_X86_64_H = 8
+ };
+ static inline int CPU_SUBTYPE_INTEL(int Family, int Model) {
+ return Family | (Model << 4);
+ }
+ static inline int CPU_SUBTYPE_INTEL_FAMILY(CPUSubTypeX86 ST) {
+ return ((int)ST) & 0x0f;
+ }
+ static inline int CPU_SUBTYPE_INTEL_MODEL(CPUSubTypeX86 ST) {
+ return ((int)ST) >> 4;
+ }
+ enum {
+ CPU_SUBTYPE_INTEL_FAMILY_MAX = 15,
+ CPU_SUBTYPE_INTEL_MODEL_ALL = 0
+ };
+
+ enum CPUSubTypeARM {
+ CPU_SUBTYPE_ARM_ALL = 0,
+ CPU_SUBTYPE_ARM_V4T = 5,
+ CPU_SUBTYPE_ARM_V6 = 6,
+ CPU_SUBTYPE_ARM_V5 = 7,
+ CPU_SUBTYPE_ARM_V5TEJ = 7,
+ CPU_SUBTYPE_ARM_XSCALE = 8,
+ CPU_SUBTYPE_ARM_V7 = 9,
+ CPU_SUBTYPE_ARM_V7F = 10,
+ CPU_SUBTYPE_ARM_V7S = 11,
+ CPU_SUBTYPE_ARM_V7K = 12,
+ CPU_SUBTYPE_ARM_V6M = 14,
+ CPU_SUBTYPE_ARM_V7M = 15,
+ CPU_SUBTYPE_ARM_V7EM = 16
+ };
+
+ enum CPUSubTypeSPARC {
+ CPU_SUBTYPE_SPARC_ALL = 0
+ };
+
+ enum CPUSubTypePowerPC {
+ CPU_SUBTYPE_POWERPC_ALL = 0,
+ CPU_SUBTYPE_POWERPC_601 = 1,
+ CPU_SUBTYPE_POWERPC_602 = 2,
+ CPU_SUBTYPE_POWERPC_603 = 3,
+ CPU_SUBTYPE_POWERPC_603e = 4,
+ CPU_SUBTYPE_POWERPC_603ev = 5,
+ CPU_SUBTYPE_POWERPC_604 = 6,
+ CPU_SUBTYPE_POWERPC_604e = 7,
+ CPU_SUBTYPE_POWERPC_620 = 8,
+ CPU_SUBTYPE_POWERPC_750 = 9,
+ CPU_SUBTYPE_POWERPC_7400 = 10,
+ CPU_SUBTYPE_POWERPC_7450 = 11,
+ CPU_SUBTYPE_POWERPC_970 = 100,
+
+ CPU_SUBTYPE_MC980000_ALL = CPU_SUBTYPE_POWERPC_ALL,
+ CPU_SUBTYPE_MC98601 = CPU_SUBTYPE_POWERPC_601
};
} // end namespace MachO
} // end namespace llvm
diff --git a/include/llvm/Support/ManagedStatic.h b/include/llvm/Support/ManagedStatic.h
index 4171d1bec8dce..5587618d11bb6 100644
--- a/include/llvm/Support/ManagedStatic.h
+++ b/include/llvm/Support/ManagedStatic.h
@@ -99,7 +99,6 @@ public:
/// llvm_shutdown - Deallocate and destroy all ManagedStatic variables.
void llvm_shutdown();
-
/// llvm_shutdown_obj - This is a simple helper class that calls
/// llvm_shutdown() when it is destroyed.
struct llvm_shutdown_obj {
diff --git a/include/llvm/Support/MathExtras.h b/include/llvm/Support/MathExtras.h
index d6ae58dc457c3..ff41608f5f517 100644
--- a/include/llvm/Support/MathExtras.h
+++ b/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/include/llvm/Support/MemoryBuffer.h b/include/llvm/Support/MemoryBuffer.h
index 0cce726d4862c..ff22fb67c84eb 100644
--- a/include/llvm/Support/MemoryBuffer.h
+++ b/include/llvm/Support/MemoryBuffer.h
@@ -14,7 +14,7 @@
#ifndef LLVM_SUPPORT_MEMORYBUFFER_H
#define LLVM_SUPPORT_MEMORYBUFFER_H
-#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Twine.h"
#include "llvm/Support/CBindingWrapping.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataTypes.h"
@@ -66,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/include/llvm/Support/MemoryObject.h b/include/llvm/Support/MemoryObject.h
index 732b0f077465d..17aa9d2f675a4 100644
--- a/include/llvm/Support/MemoryObject.h
+++ b/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/include/llvm/Support/PassNameParser.h b/include/llvm/Support/PassNameParser.h
index 317416c97487f..c0914b1f2f080 100644
--- a/include/llvm/Support/PassNameParser.h
+++ b/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/include/llvm/Support/Path.h b/include/llvm/Support/Path.h
index 196eecce81851..b2afe1b8e8ac7 100644
--- a/include/llvm/Support/Path.h
+++ b/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/include/llvm/Support/PathV1.h b/include/llvm/Support/PathV1.h
deleted file mode 100644
index 86328f06ab146..0000000000000
--- a/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/include/llvm/Support/PathV2.h b/include/llvm/Support/PathV2.h
deleted file mode 100644
index ae1a21c7ce582..0000000000000
--- a/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/include/llvm/Support/PatternMatch.h b/include/llvm/Support/PatternMatch.h
index 95d9d782ec043..240bb81d31a79 100644
--- a/include/llvm/Support/PatternMatch.h
+++ b/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/include/llvm/Support/PrettyStackTrace.h b/include/llvm/Support/PrettyStackTrace.h
index 2122e06d53fed..4f68fca24f384 100644
--- a/include/llvm/Support/PrettyStackTrace.h
+++ b/include/llvm/Support/PrettyStackTrace.h
@@ -21,11 +21,7 @@
namespace llvm {
class raw_ostream;
- /// DisablePrettyStackTrace - Set this to true to disable this module. This
- /// might be necessary if the host application installs its own signal
- /// handlers which conflict with the ones installed by this module.
- /// Defaults to false.
- extern bool DisablePrettyStackTrace;
+ void EnablePrettyStackTrace();
/// PrettyStackTraceEntry - This class is used to represent a frame of the
/// "pretty" stack trace that is dumped when a program crashes. You can define
@@ -64,7 +60,9 @@ namespace llvm {
const char *const *ArgV;
public:
PrettyStackTraceProgram(int argc, const char * const*argv)
- : ArgC(argc), ArgV(argv) {}
+ : ArgC(argc), ArgV(argv) {
+ EnablePrettyStackTrace();
+ }
virtual void print(raw_ostream &OS) const LLVM_OVERRIDE;
};
diff --git a/include/llvm/Support/Process.h b/include/llvm/Support/Process.h
index 4256d4a03b9d8..21720367199d0 100644
--- a/include/llvm/Support/Process.h
+++ b/include/llvm/Support/Process.h
@@ -25,11 +25,17 @@
#ifndef LLVM_SUPPORT_PROCESS_H
#define LLVM_SUPPORT_PROCESS_H
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/Config/llvm-config.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/system_error.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/TimeValue.h"
namespace llvm {
+class StringRef;
+
namespace sys {
class self_process;
@@ -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/include/llvm/Support/Program.h b/include/llvm/Support/Program.h
index fb177de97b409..00571a4080162 100644
--- a/include/llvm/Support/Program.h
+++ b/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/include/llvm/Support/RecyclingAllocator.h b/include/llvm/Support/RecyclingAllocator.h
index 34ab874778c91..001d1cf7c3df2 100644
--- a/include/llvm/Support/RecyclingAllocator.h
+++ b/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/include/llvm/Support/Regex.h b/include/llvm/Support/Regex.h
index 82df2c67bd027..3d071bedbd86e 100644
--- a/include/llvm/Support/Regex.h
+++ b/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/include/llvm/Support/Registry.h b/include/llvm/Support/Registry.h
index 29eafb63ca0ee..073becd586aa9 100644
--- a/include/llvm/Support/Registry.h
+++ b/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/include/llvm/Support/Signals.h b/include/llvm/Support/Signals.h
index 465656b94116f..58ed175dc22b8 100644
--- a/include/llvm/Support/Signals.h
+++ b/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/include/llvm/Support/Solaris.h b/include/llvm/Support/Solaris.h
index 6228c4b43b525..b082285324895 100644
--- a/include/llvm/Support/Solaris.h
+++ b/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/include/llvm/Support/SourceMgr.h b/include/llvm/Support/SourceMgr.h
index d67914a1b84ea..dd4897432d9e8 100644
--- a/include/llvm/Support/SourceMgr.h
+++ b/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/include/llvm/Support/StreamableMemoryObject.h b/include/llvm/Support/StreamableMemoryObject.h
index 385548579b1f2..e823d489d3a81 100644
--- a/include/llvm/Support/StreamableMemoryObject.h
+++ b/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/include/llvm/Support/StringRefMemoryObject.h b/include/llvm/Support/StringRefMemoryObject.h
new file mode 100644
index 0000000000000..994fa34b74bb5
--- /dev/null
+++ b/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/include/llvm/Support/SystemUtils.h b/include/llvm/Support/SystemUtils.h
index 399aee51eb7b0..d2d08b234272d 100644
--- a/include/llvm/Support/SystemUtils.h
+++ b/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/include/llvm/Support/TargetRegistry.h b/include/llvm/Support/TargetRegistry.h
index b06676d4d2f55..9ecee3b7c21a1 100644
--- a/include/llvm/Support/TargetRegistry.h
+++ b/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/include/llvm/Support/TimeValue.h b/include/llvm/Support/TimeValue.h
index 4b48b849f20df..27854088f0561 100644
--- a/include/llvm/Support/TimeValue.h
+++ b/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/include/llvm/Support/ToolOutputFile.h b/include/llvm/Support/ToolOutputFile.h
index b3b7c577b7224..a2191ade80cf8 100644
--- a/include/llvm/Support/ToolOutputFile.h
+++ b/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/include/llvm/Support/Unicode.h b/include/llvm/Support/Unicode.h
new file mode 100644
index 0000000000000..e6a52c4c70658
--- /dev/null
+++ b/include/llvm/Support/Unicode.h
@@ -0,0 +1,62 @@
+//===- llvm/Support/Unicode.h - Unicode character properties -*- C++ -*-=====//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines functions that allow querying certain properties of Unicode
+// characters.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/StringRef.h"
+
+namespace llvm {
+namespace sys {
+namespace unicode {
+
+enum ColumnWidthErrors {
+ ErrorInvalidUTF8 = -2,
+ ErrorNonPrintableCharacter = -1
+};
+
+/// Determines if a character is likely to be displayed correctly on the
+/// terminal. Exact implementation would have to depend on the specific
+/// terminal, so we define the semantic that should be suitable for generic case
+/// of a terminal capable to output Unicode characters.
+///
+/// All characters from the Unicode code point range are considered printable
+/// except for:
+/// * C0 and C1 control character ranges;
+/// * default ignorable code points as per 5.21 of
+/// http://www.unicode.org/versions/Unicode6.2.0/UnicodeStandard-6.2.pdf
+/// except for U+00AD SOFT HYPHEN, as it's actually displayed on most
+/// terminals;
+/// * format characters (category = Cf);
+/// * surrogates (category = Cs);
+/// * unassigned characters (category = Cn).
+/// \return true if the character is considered printable.
+bool isPrintable(int UCS);
+
+/// Gets the number of positions the UTF8-encoded \p Text is likely to occupy
+/// when output on a terminal ("character width"). This depends on the
+/// implementation of the terminal, and there's no standard definition of
+/// character width.
+///
+/// The implementation defines it in a way that is expected to be compatible
+/// with a generic Unicode-capable terminal.
+///
+/// \return Character width:
+/// * ErrorNonPrintableCharacter (-1) if \p Text contains non-printable
+/// characters (as identified by isPrintable);
+/// * 0 for each non-spacing and enclosing combining mark;
+/// * 2 for each CJK character excluding halfwidth forms;
+/// * 1 for each of the remaining characters.
+int columnWidthUTF8(StringRef Text);
+
+} // namespace unicode
+} // namespace sys
+} // namespace llvm
diff --git a/include/llvm/Support/UnicodeCharRanges.h b/include/llvm/Support/UnicodeCharRanges.h
new file mode 100644
index 0000000000000..86faa38c0afe2
--- /dev/null
+++ b/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/include/llvm/Support/Valgrind.h b/include/llvm/Support/Valgrind.h
index a1397db8eb2ce..7ae40af754fc0 100644
--- a/include/llvm/Support/Valgrind.h
+++ b/include/llvm/Support/Valgrind.h
@@ -13,8 +13,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SYSTEM_VALGRIND_H
-#define LLVM_SYSTEM_VALGRIND_H
+#ifndef LLVM_SUPPORT_VALGRIND_H
+#define LLVM_SUPPORT_VALGRIND_H
#include "llvm/Config/llvm-config.h"
#include "llvm/Support/Compiler.h"
diff --git a/include/llvm/Support/ValueHandle.h b/include/llvm/Support/ValueHandle.h
index b49341c3ffb66..bc02ba31b9b9a 100644
--- a/include/llvm/Support/ValueHandle.h
+++ b/include/llvm/Support/ValueHandle.h
@@ -339,6 +339,7 @@ public:
/// rearrange itself when the pointer changes). Unlike ValueHandleBase, this
/// class has a vtable and a virtual destructor.
class CallbackVH : public ValueHandleBase {
+ virtual void anchor();
protected:
CallbackVH(const CallbackVH &RHS)
: ValueHandleBase(Callback, RHS) {}
@@ -365,13 +366,13 @@ public:
///
/// All implementations must remove the reference from this object to the
/// Value that's being destroyed.
- virtual void deleted();
+ virtual void deleted() { setValPtr(NULL); }
/// Called when this->getValPtr()->replaceAllUsesWith(new_value) is called,
/// _before_ any of the uses have actually been replaced. If WeakVH were
/// implemented as a CallbackVH, it would use this method to call
/// setValPtr(new_value). AssertingVH would do nothing in this method.
- virtual void allUsesReplacedWith(Value *);
+ virtual void allUsesReplacedWith(Value *) {}
};
} // End llvm namespace
diff --git a/include/llvm/Support/YAMLParser.h b/include/llvm/Support/YAMLParser.h
index 6e4f57f6ab4a8..702044936c626 100644
--- a/include/llvm/Support/YAMLParser.h
+++ b/include/llvm/Support/YAMLParser.h
@@ -43,6 +43,8 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/SMLoc.h"
+
+#include <map>
#include <limits>
#include <utility>
@@ -99,13 +101,11 @@ private:
OwningPtr<Document> CurrentDoc;
friend class Document;
-
- /// @brief Validate a %YAML x.x directive.
- void handleYAMLDirective(const Token &);
};
/// @brief Abstract base class for all Nodes.
class Node {
+ virtual void anchor();
public:
enum NodeKind {
NK_Null,
@@ -116,12 +116,21 @@ public:
NK_Alias
};
- Node(unsigned int Type, OwningPtr<Document>&, StringRef Anchor);
+ Node(unsigned int Type, OwningPtr<Document> &, StringRef Anchor,
+ StringRef Tag);
/// @brief Get the value of the anchor attached to this node. If it does not
/// have one, getAnchor().size() will be 0.
StringRef getAnchor() const { return Anchor; }
+ /// \brief Get the tag as it was written in the document. This does not
+ /// perform tag resolution.
+ StringRef getRawTag() const { return Tag; }
+
+ /// \brief Get the verbatium tag for a given Node. This performs tag resoluton
+ /// and substitution.
+ std::string getVerbatimTag() const;
+
SMRange getSourceRange() const { return SourceRange; }
void setSourceRange(SMRange SR) { SourceRange = SR; }
@@ -158,6 +167,8 @@ protected:
private:
unsigned int TypeID;
StringRef Anchor;
+ /// \brief The tag as typed in the document.
+ StringRef Tag;
};
/// @brief A null value.
@@ -165,8 +176,10 @@ private:
/// Example:
/// !!null null
class NullNode : public Node {
+ virtual void anchor();
public:
- NullNode(OwningPtr<Document> &D) : Node(NK_Null, D, StringRef()) {}
+ NullNode(OwningPtr<Document> &D)
+ : Node(NK_Null, D, StringRef(), StringRef()) {}
static inline bool classof(const Node *N) {
return N->getType() == NK_Null;
@@ -179,10 +192,11 @@ public:
/// Example:
/// Adena
class ScalarNode : public Node {
+ virtual void anchor();
public:
- ScalarNode(OwningPtr<Document> &D, StringRef Anchor, StringRef Val)
- : Node(NK_Scalar, D, Anchor)
- , Value(Val) {
+ ScalarNode(OwningPtr<Document> &D, StringRef Anchor, StringRef Tag,
+ StringRef Val)
+ : Node(NK_Scalar, D, Anchor, Tag), Value(Val) {
SMLoc Start = SMLoc::getFromPointer(Val.begin());
SMLoc End = SMLoc::getFromPointer(Val.end());
SourceRange = SMRange(Start, End);
@@ -220,9 +234,10 @@ private:
/// Example:
/// Section: .text
class KeyValueNode : public Node {
+ virtual void anchor();
public:
KeyValueNode(OwningPtr<Document> &D)
- : Node(NK_KeyValue, D, StringRef())
+ : Node(NK_KeyValue, D, StringRef(), StringRef())
, Key(0)
, Value(0)
{}
@@ -331,6 +346,7 @@ void skip(CollectionType &C) {
/// Name: _main
/// Scope: Global
class MappingNode : public Node {
+ virtual void anchor();
public:
enum MappingType {
MT_Block,
@@ -338,13 +354,10 @@ public:
MT_Inline ///< An inline mapping node is used for "[key: value]".
};
- MappingNode(OwningPtr<Document> &D, StringRef Anchor, MappingType MT)
- : Node(NK_Mapping, D, Anchor)
- , Type(MT)
- , IsAtBeginning(true)
- , IsAtEnd(false)
- , CurrentEntry(0)
- {}
+ MappingNode(OwningPtr<Document> &D, StringRef Anchor, StringRef Tag,
+ MappingType MT)
+ : Node(NK_Mapping, D, Anchor, Tag), Type(MT), IsAtBeginning(true),
+ IsAtEnd(false), CurrentEntry(0) {}
friend class basic_collection_iterator<MappingNode, KeyValueNode>;
typedef basic_collection_iterator<MappingNode, KeyValueNode> iterator;
@@ -383,6 +396,7 @@ private:
/// - Hello
/// - World
class SequenceNode : public Node {
+ virtual void anchor();
public:
enum SequenceType {
ST_Block,
@@ -397,14 +411,12 @@ public:
ST_Indentless
};
- SequenceNode(OwningPtr<Document> &D, StringRef Anchor, SequenceType ST)
- : Node(NK_Sequence, D, Anchor)
- , SeqType(ST)
- , IsAtBeginning(true)
- , IsAtEnd(false)
- , WasPreviousTokenFlowEntry(true) // Start with an imaginary ','.
- , CurrentEntry(0)
- {}
+ SequenceNode(OwningPtr<Document> &D, StringRef Anchor, StringRef Tag,
+ SequenceType ST)
+ : Node(NK_Sequence, D, Anchor, Tag), SeqType(ST), IsAtBeginning(true),
+ IsAtEnd(false),
+ WasPreviousTokenFlowEntry(true), // Start with an imaginary ','.
+ CurrentEntry(0) {}
friend class basic_collection_iterator<SequenceNode, Node>;
typedef basic_collection_iterator<SequenceNode, Node> iterator;
@@ -440,9 +452,10 @@ private:
/// Example:
/// *AnchorName
class AliasNode : public Node {
+ virtual void anchor();
public:
AliasNode(OwningPtr<Document> &D, StringRef Val)
- : Node(NK_Alias, D, StringRef()), Name(Val) {}
+ : Node(NK_Alias, D, StringRef(), StringRef()), Name(Val) {}
StringRef getName() const { return Name; }
Node *getTarget();
@@ -475,6 +488,10 @@ public:
return Root = parseBlockNode();
}
+ const std::map<StringRef, StringRef> &getTagMap() const {
+ return TagMap;
+ }
+
private:
friend class Node;
friend class document_iterator;
@@ -490,18 +507,23 @@ private:
/// document.
Node *Root;
+ /// \brief Maps tag prefixes to their expansion.
+ std::map<StringRef, StringRef> TagMap;
+
Token &peekNext();
Token getNext();
void setError(const Twine &Message, Token &Location) const;
bool failed() const;
- void handleTagDirective(const Token &Tag) {
- // TODO: Track tags.
- }
-
/// @brief Parse %BLAH directives and return true if any were encountered.
bool parseDirectives();
+ /// \brief Parse %YAML
+ void parseYAMLDirective();
+
+ /// \brief Parse %TAG
+ void parseTAGDirective();
+
/// @brief Consume the next token and error if it is not \a TK.
bool expectToken(int TK);
};
@@ -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/include/llvm/Support/YAMLTraits.h b/include/llvm/Support/YAMLTraits.h
index 801868ff1f1f7..c19eb23c5cd02 100644
--- a/include/llvm/Support/YAMLTraits.h
+++ b/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/include/llvm/Support/raw_ostream.h b/include/llvm/Support/raw_ostream.h
index d2b4a2af278a1..ec7e06b535e59 100644
--- a/include/llvm/Support/raw_ostream.h
+++ b/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.