Update all "support" header files to be the latest versions from the llvm
module.
llvm-svn: 44773
diff --git a/support/include/llvm/ADT/APFloat.h b/support/include/llvm/ADT/APFloat.h
new file mode 100644
index 0000000..e4d4c8e
--- /dev/null
+++ b/support/include/llvm/ADT/APFloat.h
@@ -0,0 +1,341 @@
+//== llvm/Support/APFloat.h - Arbitrary Precision Floating Point -*- C++ -*-==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Neil Booth and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares a class to represent arbitrary precision floating
+// point values and provide a variety of arithmetic operations on them.
+//
+//===----------------------------------------------------------------------===//
+
+/* A self-contained host- and target-independent arbitrary-precision
+ floating-point software implementation. It uses bignum integer
+ arithmetic as provided by static functions in the APInt class.
+ The library will work with bignum integers whose parts are any
+ unsigned type at least 16 bits wide, but 64 bits is recommended.
+
+ Written for clarity rather than speed, in particular with a view
+ to use in the front-end of a cross compiler so that target
+ arithmetic can be correctly performed on the host. Performance
+ should nonetheless be reasonable, particularly for its intended
+ use. It may be useful as a base implementation for a run-time
+ library during development of a faster target-specific one.
+
+ All 5 rounding modes in the IEEE-754R draft are handled correctly
+ for all implemented operations. Currently implemented operations
+ are add, subtract, multiply, divide, fused-multiply-add,
+ conversion-to-float, conversion-to-integer and
+ conversion-from-integer. New rounding modes (e.g. away from zero)
+ can be added with three or four lines of code.
+
+ Four formats are built-in: IEEE single precision, double
+ precision, quadruple precision, and x87 80-bit extended double
+ (when operating with full extended precision). Adding a new
+ format that obeys IEEE semantics only requires adding two lines of
+ code: a declaration and definition of the format.
+
+ All operations return the status of that operation as an exception
+ bit-mask, so multiple operations can be done consecutively with
+ their results or-ed together. The returned status can be useful
+ for compiler diagnostics; e.g., inexact, underflow and overflow
+ can be easily diagnosed on constant folding, and compiler
+ optimizers can determine what exceptions would be raised by
+ folding operations and optimize, or perhaps not optimize,
+ accordingly.
+
+ At present, underflow tininess is detected after rounding; it
+ should be straight forward to add support for the before-rounding
+ case too.
+
+ The library reads hexadecimal floating point numbers as per C99,
+ and correctly rounds if necessary according to the specified
+ rounding mode. Syntax is required to have been validated by the
+ caller. It also converts floating point numbers to hexadecimal
+ text as per the C99 %a and %A conversions. The output precision
+ (or alternatively the natural minimal precision) can be specified;
+ if the requested precision is less than the natural precision the
+ output is correctly rounded for the specified rounding mode.
+
+ It also reads decimal floating point numbers and correctly rounds
+ according to the specified rounding mode.
+
+ Conversion to decimal text is not currently implemented.
+
+ Non-zero finite numbers are represented internally as a sign bit,
+ a 16-bit signed exponent, and the significand as an array of
+ integer parts. After normalization of a number of precision P the
+ exponent is within the range of the format, and if the number is
+ not denormal the P-th bit of the significand is set as an explicit
+ integer bit. For denormals the most significant bit is shifted
+ right so that the exponent is maintained at the format's minimum,
+ so that the smallest denormal has just the least significant bit
+ of the significand set. The sign of zeroes and infinities is
+ significant; the exponent and significand of such numbers is not
+ stored, but has a known implicit (deterministic) value: 0 for the
+ significands, 0 for zero exponent, all 1 bits for infinity
+ exponent. For NaNs the sign and significand are deterministic,
+ although not really meaningful, and preserved in non-conversion
+ operations. The exponent is implicitly all 1 bits.
+
+ TODO
+ ====
+
+ Some features that may or may not be worth adding:
+
+ Binary to decimal conversion (hard).
+
+ Optional ability to detect underflow tininess before rounding.
+
+ New formats: x87 in single and double precision mode (IEEE apart
+ from extended exponent range) (hard).
+
+ New operations: sqrt, IEEE remainder, C90 fmod, nextafter,
+ nexttoward.
+*/
+
+#ifndef LLVM_FLOAT_H
+#define LLVM_FLOAT_H
+
+// APInt contains static functions implementing bignum arithmetic.
+#include "llvm/ADT/APInt.h"
+#include "llvm/Bitcode/SerializationFwd.h"
+#include "llvm/CodeGen/ValueTypes.h"
+
+namespace llvm {
+
+ /* Exponents are stored as signed numbers. */
+ typedef signed short exponent_t;
+
+ struct fltSemantics;
+
+ /* When bits of a floating point number are truncated, this enum is
+ used to indicate what fraction of the LSB those bits represented.
+ It essentially combines the roles of guard and sticky bits. */
+ enum lostFraction { // Example of truncated bits:
+ lfExactlyZero, // 000000
+ lfLessThanHalf, // 0xxxxx x's not all zero
+ lfExactlyHalf, // 100000
+ lfMoreThanHalf // 1xxxxx x's not all zero
+ };
+
+ class APFloat {
+ public:
+
+ /* We support the following floating point semantics. */
+ static const fltSemantics IEEEsingle;
+ static const fltSemantics IEEEdouble;
+ static const fltSemantics IEEEquad;
+ static const fltSemantics PPCDoubleDouble;
+ static const fltSemantics x87DoubleExtended;
+ /* And this psuedo, used to construct APFloats that cannot
+ conflict with anything real. */
+ static const fltSemantics Bogus;
+
+ static unsigned int semanticsPrecision(const fltSemantics &);
+
+ /* Floating point numbers have a four-state comparison relation. */
+ enum cmpResult {
+ cmpLessThan,
+ cmpEqual,
+ cmpGreaterThan,
+ cmpUnordered
+ };
+
+ /* IEEE-754R gives five rounding modes. */
+ enum roundingMode {
+ rmNearestTiesToEven,
+ rmTowardPositive,
+ rmTowardNegative,
+ rmTowardZero,
+ rmNearestTiesToAway
+ };
+
+ /* Operation status. opUnderflow or opOverflow are always returned
+ or-ed with opInexact. */
+ enum opStatus {
+ opOK = 0x00,
+ opInvalidOp = 0x01,
+ opDivByZero = 0x02,
+ opOverflow = 0x04,
+ opUnderflow = 0x08,
+ opInexact = 0x10
+ };
+
+ /* Category of internally-represented number. */
+ enum fltCategory {
+ fcInfinity,
+ fcNaN,
+ fcNormal,
+ fcZero
+ };
+
+ /* Constructors. */
+ APFloat(const fltSemantics &, const char *);
+ APFloat(const fltSemantics &, integerPart);
+ APFloat(const fltSemantics &, fltCategory, bool negative);
+ explicit APFloat(double d);
+ explicit APFloat(float f);
+ explicit APFloat(const APInt &, bool isIEEE = false);
+ APFloat(const APFloat &);
+ ~APFloat();
+
+ /// @brief Used by the Bitcode serializer to emit APInts to Bitcode.
+ void Emit(Serializer& S) const;
+
+ /// @brief Used by the Bitcode deserializer to deserialize APInts.
+ static APFloat ReadVal(Deserializer& D);
+
+ /* Arithmetic. */
+ opStatus add(const APFloat &, roundingMode);
+ opStatus subtract(const APFloat &, roundingMode);
+ opStatus multiply(const APFloat &, roundingMode);
+ opStatus divide(const APFloat &, roundingMode);
+ opStatus mod(const APFloat &, roundingMode);
+ opStatus fusedMultiplyAdd(const APFloat &, const APFloat &, roundingMode);
+
+ /* Sign operations. */
+ void changeSign();
+ void clearSign();
+ void copySign(const APFloat &);
+
+ /* Conversions. */
+ opStatus convert(const fltSemantics &, roundingMode);
+ opStatus convertToInteger(integerPart *, unsigned int, bool,
+ roundingMode) const;
+ opStatus convertFromSignExtendedInteger(const integerPart *, unsigned int,
+ bool, roundingMode);
+ opStatus convertFromZeroExtendedInteger(const integerPart *, unsigned int,
+ bool, roundingMode);
+ opStatus convertFromString(const char *, roundingMode);
+ APInt convertToAPInt() const;
+ double convertToDouble() const;
+ float convertToFloat() const;
+
+ /* The definition of equality is not straightforward for floating point,
+ so we won't use operator==. Use one of the following, or write
+ whatever it is you really mean. */
+ // bool operator==(const APFloat &) const; // DO NOT IMPLEMENT
+
+ /* IEEE comparison with another floating point number (NaNs
+ compare unordered, 0==-0). */
+ cmpResult compare(const APFloat &) const;
+
+ /* Write out a hexadecimal representation of the floating point
+ value to DST, which must be of sufficient size, in the C99 form
+ [-]0xh.hhhhp[+-]d. Return the number of characters written,
+ excluding the terminating NUL. */
+ unsigned int convertToHexString(char *dst, unsigned int hexDigits,
+ bool upperCase, roundingMode) const;
+
+ /* Bitwise comparison for equality (QNaNs compare equal, 0!=-0). */
+ bool bitwiseIsEqual(const APFloat &) const;
+
+ /* Simple queries. */
+ fltCategory getCategory() const { return category; }
+ const fltSemantics &getSemantics() const { return *semantics; }
+ bool isZero() const { return category == fcZero; }
+ bool isNonZero() const { return category != fcZero; }
+ bool isNaN() const { return category == fcNaN; }
+ bool isNegative() const { return sign; }
+ bool isPosZero() const { return isZero() && !isNegative(); }
+ bool isNegZero() const { return isZero() && isNegative(); }
+
+ APFloat& operator=(const APFloat &);
+
+ /* Return an arbitrary integer value usable for hashing. */
+ uint32_t getHashValue() const;
+
+ private:
+
+ /* Trivial queries. */
+ integerPart *significandParts();
+ const integerPart *significandParts() const;
+ unsigned int partCount() const;
+
+ /* Significand operations. */
+ integerPart addSignificand(const APFloat &);
+ integerPart subtractSignificand(const APFloat &, integerPart);
+ lostFraction addOrSubtractSignificand(const APFloat &, bool subtract);
+ lostFraction multiplySignificand(const APFloat &, const APFloat *);
+ lostFraction divideSignificand(const APFloat &);
+ void incrementSignificand();
+ void initialize(const fltSemantics *);
+ void shiftSignificandLeft(unsigned int);
+ lostFraction shiftSignificandRight(unsigned int);
+ unsigned int significandLSB() const;
+ unsigned int significandMSB() const;
+ void zeroSignificand();
+
+ /* Arithmetic on special values. */
+ opStatus addOrSubtractSpecials(const APFloat &, bool subtract);
+ opStatus divideSpecials(const APFloat &);
+ opStatus multiplySpecials(const APFloat &);
+
+ /* Miscellany. */
+ void makeNaN(void);
+ opStatus normalize(roundingMode, lostFraction);
+ opStatus addOrSubtract(const APFloat &, roundingMode, bool subtract);
+ cmpResult compareAbsoluteValue(const APFloat &) const;
+ opStatus handleOverflow(roundingMode);
+ bool roundAwayFromZero(roundingMode, lostFraction, unsigned int) const;
+ opStatus convertToSignExtendedInteger(integerPart *, unsigned int, bool,
+ roundingMode) const;
+ opStatus convertFromUnsignedParts(const integerPart *, unsigned int,
+ roundingMode);
+ opStatus convertFromHexadecimalString(const char *, roundingMode);
+ opStatus convertFromDecimalString (const char *, roundingMode);
+ char *convertNormalToHexString(char *, unsigned int, bool,
+ roundingMode) const;
+ opStatus roundSignificandWithExponent(const integerPart *, unsigned int,
+ int, roundingMode);
+
+ APInt convertFloatAPFloatToAPInt() const;
+ APInt convertDoubleAPFloatToAPInt() const;
+ APInt convertF80LongDoubleAPFloatToAPInt() const;
+ APInt convertPPCDoubleDoubleAPFloatToAPInt() const;
+ void initFromAPInt(const APInt& api, bool isIEEE = false);
+ void initFromFloatAPInt(const APInt& api);
+ void initFromDoubleAPInt(const APInt& api);
+ void initFromF80LongDoubleAPInt(const APInt& api);
+ void initFromPPCDoubleDoubleAPInt(const APInt& api);
+
+ void assign(const APFloat &);
+ void copySignificand(const APFloat &);
+ void freeSignificand();
+
+ /* What kind of semantics does this value obey? */
+ const fltSemantics *semantics;
+
+ /* Significand - the fraction with an explicit integer bit. Must be
+ at least one bit wider than the target precision. */
+ union Significand
+ {
+ integerPart part;
+ integerPart *parts;
+ } significand;
+
+ /* The exponent - a signed number. */
+ exponent_t exponent;
+
+ /* What kind of floating point number this is. */
+ /* Only 2 bits are required, but VisualStudio incorrectly sign extends
+ it. Using the extra bit keeps it from failing under VisualStudio */
+ fltCategory category: 3;
+
+ /* The sign bit of this number. */
+ unsigned int sign: 1;
+
+ /* For PPCDoubleDouble, we have a second exponent and sign (the second
+ significand is appended to the first one, although it would be wrong to
+ regard these as a single number for arithmetic purposes). These fields
+ are not meaningful for any other type. */
+ exponent_t exponent2 : 11;
+ unsigned int sign2: 1;
+ };
+} /* namespace llvm */
+
+#endif /* LLVM_FLOAT_H */
diff --git a/support/include/llvm/ADT/APInt.h b/support/include/llvm/ADT/APInt.h
new file mode 100644
index 0000000..7e06d3d
--- /dev/null
+++ b/support/include/llvm/ADT/APInt.h
@@ -0,0 +1,1373 @@
+//===-- llvm/ADT/APInt.h - For Arbitrary Precision Integer -----*- C++ -*--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Sheng Zhou and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a class to represent arbitrary precision integral
+// constant values and operations on them.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_APINT_H
+#define LLVM_APINT_H
+
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Bitcode/SerializationFwd.h"
+#include <cassert>
+#include <string>
+
+#define COMPILE_TIME_ASSERT(cond) extern int CTAssert[(cond) ? 1 : -1]
+
+namespace llvm {
+
+ /* An unsigned host type used as a single part of a multi-part
+ bignum. */
+ typedef uint64_t integerPart;
+
+ const unsigned int host_char_bit = 8;
+ const unsigned int integerPartWidth = host_char_bit * sizeof(integerPart);
+
+//===----------------------------------------------------------------------===//
+// APInt Class
+//===----------------------------------------------------------------------===//
+
+/// APInt - This class represents arbitrary precision constant integral values.
+/// It is a functional replacement for common case unsigned integer type like
+/// "unsigned", "unsigned long" or "uint64_t", but also allows non-byte-width
+/// integer sizes and large integer value types such as 3-bits, 15-bits, or more
+/// than 64-bits of precision. APInt provides a variety of arithmetic operators
+/// and methods to manipulate integer values of any bit-width. It supports both
+/// the typical integer arithmetic and comparison operations as well as bitwise
+/// manipulation.
+///
+/// The class has several invariants worth noting:
+/// * All bit, byte, and word positions are zero-based.
+/// * Once the bit width is set, it doesn't change except by the Truncate,
+/// SignExtend, or ZeroExtend operations.
+/// * All binary operators must be on APInt instances of the same bit width.
+/// Attempting to use these operators on instances with different bit
+/// widths will yield an assertion.
+/// * The value is stored canonically as an unsigned value. For operations
+/// where it makes a difference, there are both signed and unsigned variants
+/// of the operation. For example, sdiv and udiv. However, because the bit
+/// widths must be the same, operations such as Mul and Add produce the same
+/// results regardless of whether the values are interpreted as signed or
+/// not.
+/// * In general, the class tries to follow the style of computation that LLVM
+/// uses in its IR. This simplifies its use for LLVM.
+///
+/// @brief Class for arbitrary precision integers.
+class APInt {
+
+ uint32_t BitWidth; ///< The number of bits in this APInt.
+
+ /// This union is used to store the integer value. When the
+ /// integer bit-width <= 64, it uses VAL, otherwise it uses pVal.
+ union {
+ uint64_t VAL; ///< Used to store the <= 64 bits integer value.
+ uint64_t *pVal; ///< Used to store the >64 bits integer value.
+ };
+
+ /// This enum is used to hold the constants we needed for APInt.
+ enum {
+ APINT_BITS_PER_WORD = sizeof(uint64_t) * 8, ///< Bits in a word
+ APINT_WORD_SIZE = sizeof(uint64_t) ///< Byte size of a word
+ };
+
+ /// This constructor is used only internally for speed of construction of
+ /// temporaries. It is unsafe for general use so it is not public.
+ /// @brief Fast internal constructor
+ APInt(uint64_t* val, uint32_t bits) : BitWidth(bits), pVal(val) { }
+
+ /// @returns true if the number of bits <= 64, false otherwise.
+ /// @brief Determine if this APInt just has one word to store value.
+ inline bool isSingleWord() const {
+ return BitWidth <= APINT_BITS_PER_WORD;
+ }
+
+ /// @returns the word position for the specified bit position.
+ /// @brief Determine which word a bit is in.
+ static inline uint32_t whichWord(uint32_t bitPosition) {
+ return bitPosition / APINT_BITS_PER_WORD;
+ }
+
+ /// @returns the bit position in a word for the specified bit position
+ /// in the APInt.
+ /// @brief Determine which bit in a word a bit is in.
+ static inline uint32_t whichBit(uint32_t bitPosition) {
+ return bitPosition % APINT_BITS_PER_WORD;
+ }
+
+ /// This method generates and returns a uint64_t (word) mask for a single
+ /// bit at a specific bit position. This is used to mask the bit in the
+ /// corresponding word.
+ /// @returns a uint64_t with only bit at "whichBit(bitPosition)" set
+ /// @brief Get a single bit mask.
+ static inline uint64_t maskBit(uint32_t bitPosition) {
+ return 1ULL << whichBit(bitPosition);
+ }
+
+ /// This method is used internally to clear the to "N" bits in the high order
+ /// word that are not used by the APInt. This is needed after the most
+ /// significant word is assigned a value to ensure that those bits are
+ /// zero'd out.
+ /// @brief Clear unused high order bits
+ inline APInt& clearUnusedBits() {
+ // Compute how many bits are used in the final word
+ uint32_t wordBits = BitWidth % APINT_BITS_PER_WORD;
+ if (wordBits == 0)
+ // If all bits are used, we want to leave the value alone. This also
+ // avoids the undefined behavior of >> when the shfit is the same size as
+ // the word size (64).
+ return *this;
+
+ // Mask out the hight bits.
+ uint64_t mask = ~uint64_t(0ULL) >> (APINT_BITS_PER_WORD - wordBits);
+ if (isSingleWord())
+ VAL &= mask;
+ else
+ pVal[getNumWords() - 1] &= mask;
+ return *this;
+ }
+
+ /// @returns the corresponding word for the specified bit position.
+ /// @brief Get the word corresponding to a bit position
+ inline uint64_t getWord(uint32_t bitPosition) const {
+ return isSingleWord() ? VAL : pVal[whichWord(bitPosition)];
+ }
+
+ /// This is used by the constructors that take string arguments.
+ /// @brief Convert a char array into an APInt
+ void fromString(uint32_t numBits, const char *strStart, uint32_t slen,
+ uint8_t radix);
+
+ /// This is used by the toString method to divide by the radix. It simply
+ /// provides a more convenient form of divide for internal use since KnuthDiv
+ /// has specific constraints on its inputs. If those constraints are not met
+ /// then it provides a simpler form of divide.
+ /// @brief An internal division function for dividing APInts.
+ static void divide(const APInt LHS, uint32_t lhsWords,
+ const APInt &RHS, uint32_t rhsWords,
+ APInt *Quotient, APInt *Remainder);
+
+public:
+ /// @name Constructors
+ /// @{
+ /// If isSigned is true then val is treated as if it were a signed value
+ /// (i.e. as an int64_t) and the appropriate sign extension to the bit width
+ /// will be done. Otherwise, no sign extension occurs (high order bits beyond
+ /// the range of val are zero filled).
+ /// @param numBits the bit width of the constructed APInt
+ /// @param val the initial value of the APInt
+ /// @param isSigned how to treat signedness of val
+ /// @brief Create a new APInt of numBits width, initialized as val.
+ APInt(uint32_t numBits, uint64_t val, bool isSigned = false);
+
+ /// Note that numWords can be smaller or larger than the corresponding bit
+ /// width but any extraneous bits will be dropped.
+ /// @param numBits the bit width of the constructed APInt
+ /// @param numWords the number of words in bigVal
+ /// @param bigVal a sequence of words to form the initial value of the APInt
+ /// @brief Construct an APInt of numBits width, initialized as bigVal[].
+ APInt(uint32_t numBits, uint32_t numWords, const uint64_t bigVal[]);
+
+ /// This constructor interprets Val as a string in the given radix. The
+ /// interpretation stops when the first charater that is not suitable for the
+ /// radix is encountered. Acceptable radix values are 2, 8, 10 and 16. It is
+ /// an error for the value implied by the string to require more bits than
+ /// numBits.
+ /// @param numBits the bit width of the constructed APInt
+ /// @param val the string to be interpreted
+ /// @param radix the radix of Val to use for the intepretation
+ /// @brief Construct an APInt from a string representation.
+ APInt(uint32_t numBits, const std::string& val, uint8_t radix);
+
+ /// This constructor interprets the slen characters starting at StrStart as
+ /// a string in the given radix. The interpretation stops when the first
+ /// character that is not suitable for the radix is encountered. Acceptable
+ /// radix values are 2, 8, 10 and 16. It is an error for the value implied by
+ /// the string to require more bits than numBits.
+ /// @param numBits the bit width of the constructed APInt
+ /// @param strStart the start of the string to be interpreted
+ /// @param slen the maximum number of characters to interpret
+ /// @param radix the radix to use for the conversion
+ /// @brief Construct an APInt from a string representation.
+ APInt(uint32_t numBits, const char strStart[], uint32_t slen, uint8_t radix);
+
+ /// Simply makes *this a copy of that.
+ /// @brief Copy Constructor.
+ APInt(const APInt& that);
+
+ /// @brief Destructor.
+ ~APInt();
+
+ /// Default constructor that creates an uninitialized APInt. This is useful
+ /// for object deserialization (pair this with the static method Read).
+ explicit APInt() : BitWidth(1) {}
+
+ /// @brief Used by the Bitcode serializer to emit APInts to Bitcode.
+ void Emit(Serializer& S) const;
+
+ /// @brief Used by the Bitcode deserializer to deserialize APInts.
+ void Read(Deserializer& D);
+
+ /// @}
+ /// @name Value Tests
+ /// @{
+ /// This tests the high bit of this APInt to determine if it is set.
+ /// @returns true if this APInt is negative, false otherwise
+ /// @brief Determine sign of this APInt.
+ bool isNegative() const {
+ return (*this)[BitWidth - 1];
+ }
+
+ /// This tests the high bit of the APInt to determine if it is unset.
+ /// @brief Determine if this APInt Value is positive (not negative).
+ bool isPositive() const {
+ return !isNegative();
+ }
+
+ /// This tests if the value of this APInt is strictly positive (> 0).
+ /// @returns true if this APInt is Positive and not zero.
+ /// @brief Determine if this APInt Value is strictly positive.
+ inline bool isStrictlyPositive() const {
+ return isPositive() && (*this) != 0;
+ }
+
+ /// This checks to see if the value has all bits of the APInt are set or not.
+ /// @brief Determine if all bits are set
+ inline bool isAllOnesValue() const {
+ return countPopulation() == BitWidth;
+ }
+
+ /// This checks to see if the value of this APInt is the maximum unsigned
+ /// value for the APInt's bit width.
+ /// @brief Determine if this is the largest unsigned value.
+ bool isMaxValue() const {
+ return countPopulation() == BitWidth;
+ }
+
+ /// This checks to see if the value of this APInt is the maximum signed
+ /// value for the APInt's bit width.
+ /// @brief Determine if this is the largest signed value.
+ bool isMaxSignedValue() const {
+ return BitWidth == 1 ? VAL == 0 :
+ !isNegative() && countPopulation() == BitWidth - 1;
+ }
+
+ /// This checks to see if the value of this APInt is the minimum unsigned
+ /// value for the APInt's bit width.
+ /// @brief Determine if this is the smallest unsigned value.
+ bool isMinValue() const {
+ return countPopulation() == 0;
+ }
+
+ /// This checks to see if the value of this APInt is the minimum signed
+ /// value for the APInt's bit width.
+ /// @brief Determine if this is the smallest signed value.
+ bool isMinSignedValue() const {
+ return BitWidth == 1 ? VAL == 1 :
+ isNegative() && countPopulation() == 1;
+ }
+
+ /// @brief Check if this APInt has an N-bits integer value.
+ inline bool isIntN(uint32_t N) const {
+ assert(N && "N == 0 ???");
+ if (isSingleWord()) {
+ return VAL == (VAL & (~0ULL >> (64 - N)));
+ } else {
+ APInt Tmp(N, getNumWords(), pVal);
+ return Tmp == (*this);
+ }
+ }
+
+ /// @returns true if the argument APInt value is a power of two > 0.
+ bool isPowerOf2() const;
+
+ /// isSignBit - Return true if this is the value returned by getSignBit.
+ bool isSignBit() const { return isMinSignedValue(); }
+
+ /// This converts the APInt to a boolean value as a test against zero.
+ /// @brief Boolean conversion function.
+ inline bool getBoolValue() const {
+ return *this != 0;
+ }
+
+ /// getLimitedValue - If this value is smaller than the specified limit,
+ /// return it, otherwise return the limit value. This causes the value
+ /// to saturate to the limit.
+ uint64_t getLimitedValue(uint64_t Limit = ~0ULL) const {
+ return (getActiveBits() > 64 || getZExtValue() > Limit) ?
+ Limit : getZExtValue();
+ }
+
+ /// @}
+ /// @name Value Generators
+ /// @{
+ /// @brief Gets maximum unsigned value of APInt for specific bit width.
+ static APInt getMaxValue(uint32_t numBits) {
+ return APInt(numBits, 0).set();
+ }
+
+ /// @brief Gets maximum signed value of APInt for a specific bit width.
+ static APInt getSignedMaxValue(uint32_t numBits) {
+ return APInt(numBits, 0).set().clear(numBits - 1);
+ }
+
+ /// @brief Gets minimum unsigned value of APInt for a specific bit width.
+ static APInt getMinValue(uint32_t numBits) {
+ return APInt(numBits, 0);
+ }
+
+ /// @brief Gets minimum signed value of APInt for a specific bit width.
+ static APInt getSignedMinValue(uint32_t numBits) {
+ return APInt(numBits, 0).set(numBits - 1);
+ }
+
+ /// getSignBit - This is just a wrapper function of getSignedMinValue(), and
+ /// it helps code readability when we want to get a SignBit.
+ /// @brief Get the SignBit for a specific bit width.
+ inline static APInt getSignBit(uint32_t BitWidth) {
+ return getSignedMinValue(BitWidth);
+ }
+
+ /// @returns the all-ones value for an APInt of the specified bit-width.
+ /// @brief Get the all-ones value.
+ static APInt getAllOnesValue(uint32_t numBits) {
+ return APInt(numBits, 0).set();
+ }
+
+ /// @returns the '0' value for an APInt of the specified bit-width.
+ /// @brief Get the '0' value.
+ static APInt getNullValue(uint32_t numBits) {
+ return APInt(numBits, 0);
+ }
+
+ /// Get an APInt with the same BitWidth as this APInt, just zero mask
+ /// the low bits and right shift to the least significant bit.
+ /// @returns the high "numBits" bits of this APInt.
+ APInt getHiBits(uint32_t numBits) const;
+
+ /// Get an APInt with the same BitWidth as this APInt, just zero mask
+ /// the high bits.
+ /// @returns the low "numBits" bits of this APInt.
+ APInt getLoBits(uint32_t numBits) const;
+
+ /// Constructs an APInt value that has a contiguous range of bits set. The
+ /// bits from loBit to hiBit will be set. All other bits will be zero. For
+ /// example, with parameters(32, 15, 0) you would get 0x0000FFFF. If hiBit is
+ /// less than loBit then the set bits "wrap". For example, with
+ /// parameters (32, 3, 28), you would get 0xF000000F.
+ /// @param numBits the intended bit width of the result
+ /// @param loBit the index of the lowest bit set.
+ /// @param hiBit the index of the highest bit set.
+ /// @returns An APInt value with the requested bits set.
+ /// @brief Get a value with a block of bits set.
+ static APInt getBitsSet(uint32_t numBits, uint32_t loBit, uint32_t hiBit) {
+ assert(hiBit < numBits && "hiBit out of range");
+ assert(loBit < numBits && "loBit out of range");
+ if (hiBit < loBit)
+ return getLowBitsSet(numBits, hiBit+1) |
+ getHighBitsSet(numBits, numBits-loBit+1);
+ return getLowBitsSet(numBits, hiBit-loBit+1).shl(loBit);
+ }
+
+ /// Constructs an APInt value that has the top hiBitsSet bits set.
+ /// @param numBits the bitwidth of the result
+ /// @param hiBitsSet the number of high-order bits set in the result.
+ /// @brief Get a value with high bits set
+ static APInt getHighBitsSet(uint32_t numBits, uint32_t hiBitsSet) {
+ assert(hiBitsSet <= numBits && "Too many bits to set!");
+ // Handle a degenerate case, to avoid shifting by word size
+ if (hiBitsSet == 0)
+ return APInt(numBits, 0);
+ uint32_t shiftAmt = numBits - hiBitsSet;
+ // For small values, return quickly
+ if (numBits <= APINT_BITS_PER_WORD)
+ return APInt(numBits, ~0ULL << shiftAmt);
+ return (~APInt(numBits, 0)).shl(shiftAmt);
+ }
+
+ /// Constructs an APInt value that has the bottom loBitsSet bits set.
+ /// @param numBits the bitwidth of the result
+ /// @param loBitsSet the number of low-order bits set in the result.
+ /// @brief Get a value with low bits set
+ static APInt getLowBitsSet(uint32_t numBits, uint32_t loBitsSet) {
+ assert(loBitsSet <= numBits && "Too many bits to set!");
+ // Handle a degenerate case, to avoid shifting by word size
+ if (loBitsSet == 0)
+ return APInt(numBits, 0);
+ if (loBitsSet == APINT_BITS_PER_WORD)
+ return APInt(numBits, -1ULL);
+ // For small values, return quickly
+ if (numBits < APINT_BITS_PER_WORD)
+ return APInt(numBits, (1ULL << loBitsSet) - 1);
+ return (~APInt(numBits, 0)).lshr(numBits - loBitsSet);
+ }
+
+ /// The hash value is computed as the sum of the words and the bit width.
+ /// @returns A hash value computed from the sum of the APInt words.
+ /// @brief Get a hash value based on this APInt
+ uint64_t getHashValue() const;
+
+ /// This function returns a pointer to the internal storage of the APInt.
+ /// This is useful for writing out the APInt in binary form without any
+ /// conversions.
+ inline const uint64_t* getRawData() const {
+ if (isSingleWord())
+ return &VAL;
+ return &pVal[0];
+ }
+
+ /// @}
+ /// @name Unary Operators
+ /// @{
+ /// @returns a new APInt value representing *this incremented by one
+ /// @brief Postfix increment operator.
+ inline const APInt operator++(int) {
+ APInt API(*this);
+ ++(*this);
+ return API;
+ }
+
+ /// @returns *this incremented by one
+ /// @brief Prefix increment operator.
+ APInt& operator++();
+
+ /// @returns a new APInt representing *this decremented by one.
+ /// @brief Postfix decrement operator.
+ inline const APInt operator--(int) {
+ APInt API(*this);
+ --(*this);
+ return API;
+ }
+
+ /// @returns *this decremented by one.
+ /// @brief Prefix decrement operator.
+ APInt& operator--();
+
+ /// Performs a bitwise complement operation on this APInt.
+ /// @returns an APInt that is the bitwise complement of *this
+ /// @brief Unary bitwise complement operator.
+ APInt operator~() const;
+
+ /// Negates *this using two's complement logic.
+ /// @returns An APInt value representing the negation of *this.
+ /// @brief Unary negation operator
+ inline APInt operator-() const {
+ return APInt(BitWidth, 0) - (*this);
+ }
+
+ /// Performs logical negation operation on this APInt.
+ /// @returns true if *this is zero, false otherwise.
+ /// @brief Logical negation operator.
+ bool operator !() const;
+
+ /// @}
+ /// @name Assignment Operators
+ /// @{
+ /// @returns *this after assignment of RHS.
+ /// @brief Copy assignment operator.
+ APInt& operator=(const APInt& RHS);
+
+ /// The RHS value is assigned to *this. If the significant bits in RHS exceed
+ /// the bit width, the excess bits are truncated. If the bit width is larger
+ /// than 64, the value is zero filled in the unspecified high order bits.
+ /// @returns *this after assignment of RHS value.
+ /// @brief Assignment operator.
+ APInt& operator=(uint64_t RHS);
+
+ /// Performs a bitwise AND operation on this APInt and RHS. The result is
+ /// assigned to *this.
+ /// @returns *this after ANDing with RHS.
+ /// @brief Bitwise AND assignment operator.
+ APInt& operator&=(const APInt& RHS);
+
+ /// Performs a bitwise OR operation on this APInt and RHS. The result is
+ /// assigned *this;
+ /// @returns *this after ORing with RHS.
+ /// @brief Bitwise OR assignment operator.
+ APInt& operator|=(const APInt& RHS);
+
+ /// Performs a bitwise XOR operation on this APInt and RHS. The result is
+ /// assigned to *this.
+ /// @returns *this after XORing with RHS.
+ /// @brief Bitwise XOR assignment operator.
+ APInt& operator^=(const APInt& RHS);
+
+ /// Multiplies this APInt by RHS and assigns the result to *this.
+ /// @returns *this
+ /// @brief Multiplication assignment operator.
+ APInt& operator*=(const APInt& RHS);
+
+ /// Adds RHS to *this and assigns the result to *this.
+ /// @returns *this
+ /// @brief Addition assignment operator.
+ APInt& operator+=(const APInt& RHS);
+
+ /// Subtracts RHS from *this and assigns the result to *this.
+ /// @returns *this
+ /// @brief Subtraction assignment operator.
+ APInt& operator-=(const APInt& RHS);
+
+ /// Shifts *this left by shiftAmt and assigns the result to *this.
+ /// @returns *this after shifting left by shiftAmt
+ /// @brief Left-shift assignment function.
+ inline APInt& operator<<=(uint32_t shiftAmt) {
+ *this = shl(shiftAmt);
+ return *this;
+ }
+
+ /// @}
+ /// @name Binary Operators
+ /// @{
+ /// Performs a bitwise AND operation on *this and RHS.
+ /// @returns An APInt value representing the bitwise AND of *this and RHS.
+ /// @brief Bitwise AND operator.
+ APInt operator&(const APInt& RHS) const;
+ APInt And(const APInt& RHS) const {
+ return this->operator&(RHS);
+ }
+
+ /// Performs a bitwise OR operation on *this and RHS.
+ /// @returns An APInt value representing the bitwise OR of *this and RHS.
+ /// @brief Bitwise OR operator.
+ APInt operator|(const APInt& RHS) const;
+ APInt Or(const APInt& RHS) const {
+ return this->operator|(RHS);
+ }
+
+ /// Performs a bitwise XOR operation on *this and RHS.
+ /// @returns An APInt value representing the bitwise XOR of *this and RHS.
+ /// @brief Bitwise XOR operator.
+ APInt operator^(const APInt& RHS) const;
+ APInt Xor(const APInt& RHS) const {
+ return this->operator^(RHS);
+ }
+
+ /// Multiplies this APInt by RHS and returns the result.
+ /// @brief Multiplication operator.
+ APInt operator*(const APInt& RHS) const;
+
+ /// Adds RHS to this APInt and returns the result.
+ /// @brief Addition operator.
+ APInt operator+(const APInt& RHS) const;
+ APInt operator+(uint64_t RHS) const {
+ return (*this) + APInt(BitWidth, RHS);
+ }
+
+ /// Subtracts RHS from this APInt and returns the result.
+ /// @brief Subtraction operator.
+ APInt operator-(const APInt& RHS) const;
+ APInt operator-(uint64_t RHS) const {
+ return (*this) - APInt(BitWidth, RHS);
+ }
+
+ APInt operator<<(unsigned Bits) const {
+ return shl(Bits);
+ }
+
+ /// Arithmetic right-shift this APInt by shiftAmt.
+ /// @brief Arithmetic right-shift function.
+ APInt ashr(uint32_t shiftAmt) const;
+
+ /// Logical right-shift this APInt by shiftAmt.
+ /// @brief Logical right-shift function.
+ APInt lshr(uint32_t shiftAmt) const;
+
+ /// Left-shift this APInt by shiftAmt.
+ /// @brief Left-shift function.
+ APInt shl(uint32_t shiftAmt) const;
+
+ /// @brief Rotate left by rotateAmt.
+ APInt rotl(uint32_t rotateAmt) const;
+
+ /// @brief Rotate right by rotateAmt.
+ APInt rotr(uint32_t rotateAmt) const;
+
+ /// Perform an unsigned divide operation on this APInt by RHS. Both this and
+ /// RHS are treated as unsigned quantities for purposes of this division.
+ /// @returns a new APInt value containing the division result
+ /// @brief Unsigned division operation.
+ APInt udiv(const APInt& RHS) const;
+
+ /// Signed divide this APInt by APInt RHS.
+ /// @brief Signed division function for APInt.
+ inline APInt sdiv(const APInt& RHS) const {
+ if (isNegative())
+ if (RHS.isNegative())
+ return (-(*this)).udiv(-RHS);
+ else
+ return -((-(*this)).udiv(RHS));
+ else if (RHS.isNegative())
+ return -(this->udiv(-RHS));
+ return this->udiv(RHS);
+ }
+
+ /// Perform an unsigned remainder operation on this APInt with RHS being the
+ /// divisor. Both this and RHS are treated as unsigned quantities for purposes
+ /// of this operation. Note that this is a true remainder operation and not
+ /// a modulo operation because the sign follows the sign of the dividend
+ /// which is *this.
+ /// @returns a new APInt value containing the remainder result
+ /// @brief Unsigned remainder operation.
+ APInt urem(const APInt& RHS) const;
+
+ /// Signed remainder operation on APInt.
+ /// @brief Function for signed remainder operation.
+ inline APInt srem(const APInt& RHS) const {
+ if (isNegative())
+ if (RHS.isNegative())
+ return -((-(*this)).urem(-RHS));
+ else
+ return -((-(*this)).urem(RHS));
+ else if (RHS.isNegative())
+ return this->urem(-RHS);
+ return this->urem(RHS);
+ }
+
+ /// Sometimes it is convenient to divide two APInt values and obtain both
+ /// the quotient and remainder. This function does both operations in the
+ /// same computation making it a little more efficient.
+ /// @brief Dual division/remainder interface.
+ static void udivrem(const APInt &LHS, const APInt &RHS,
+ APInt &Quotient, APInt &Remainder);
+
+ static void sdivrem(const APInt &LHS, const APInt &RHS,
+ APInt &Quotient, APInt &Remainder)
+ {
+ if (LHS.isNegative()) {
+ if (RHS.isNegative())
+ APInt::udivrem(-LHS, -RHS, Quotient, Remainder);
+ else
+ APInt::udivrem(-LHS, RHS, Quotient, Remainder);
+ Quotient = -Quotient;
+ Remainder = -Remainder;
+ } else if (RHS.isNegative()) {
+ APInt::udivrem(LHS, -RHS, Quotient, Remainder);
+ Quotient = -Quotient;
+ } else {
+ APInt::udivrem(LHS, RHS, Quotient, Remainder);
+ }
+ }
+
+ /// @returns the bit value at bitPosition
+ /// @brief Array-indexing support.
+ bool operator[](uint32_t bitPosition) const;
+
+ /// @}
+ /// @name Comparison Operators
+ /// @{
+ /// Compares this APInt with RHS for the validity of the equality
+ /// relationship.
+ /// @brief Equality operator.
+ bool operator==(const APInt& RHS) const;
+
+ /// Compares this APInt with a uint64_t for the validity of the equality
+ /// relationship.
+ /// @returns true if *this == Val
+ /// @brief Equality operator.
+ bool operator==(uint64_t Val) const;
+
+ /// Compares this APInt with RHS for the validity of the equality
+ /// relationship.
+ /// @returns true if *this == Val
+ /// @brief Equality comparison.
+ bool eq(const APInt &RHS) const {
+ return (*this) == RHS;
+ }
+
+ /// Compares this APInt with RHS for the validity of the inequality
+ /// relationship.
+ /// @returns true if *this != Val
+ /// @brief Inequality operator.
+ inline bool operator!=(const APInt& RHS) const {
+ return !((*this) == RHS);
+ }
+
+ /// Compares this APInt with a uint64_t for the validity of the inequality
+ /// relationship.
+ /// @returns true if *this != Val
+ /// @brief Inequality operator.
+ inline bool operator!=(uint64_t Val) const {
+ return !((*this) == Val);
+ }
+
+ /// Compares this APInt with RHS for the validity of the inequality
+ /// relationship.
+ /// @returns true if *this != Val
+ /// @brief Inequality comparison
+ bool ne(const APInt &RHS) const {
+ return !((*this) == RHS);
+ }
+
+ /// Regards both *this and RHS as unsigned quantities and compares them for
+ /// the validity of the less-than relationship.
+ /// @returns true if *this < RHS when both are considered unsigned.
+ /// @brief Unsigned less than comparison
+ bool ult(const APInt& RHS) const;
+
+ /// Regards both *this and RHS as signed quantities and compares them for
+ /// validity of the less-than relationship.
+ /// @returns true if *this < RHS when both are considered signed.
+ /// @brief Signed less than comparison
+ bool slt(const APInt& RHS) const;
+
+ /// Regards both *this and RHS as unsigned quantities and compares them for
+ /// validity of the less-or-equal relationship.
+ /// @returns true if *this <= RHS when both are considered unsigned.
+ /// @brief Unsigned less or equal comparison
+ bool ule(const APInt& RHS) const {
+ return ult(RHS) || eq(RHS);
+ }
+
+ /// Regards both *this and RHS as signed quantities and compares them for
+ /// validity of the less-or-equal relationship.
+ /// @returns true if *this <= RHS when both are considered signed.
+ /// @brief Signed less or equal comparison
+ bool sle(const APInt& RHS) const {
+ return slt(RHS) || eq(RHS);
+ }
+
+ /// Regards both *this and RHS as unsigned quantities and compares them for
+ /// the validity of the greater-than relationship.
+ /// @returns true if *this > RHS when both are considered unsigned.
+ /// @brief Unsigned greather than comparison
+ bool ugt(const APInt& RHS) const {
+ return !ult(RHS) && !eq(RHS);
+ }
+
+ /// Regards both *this and RHS as signed quantities and compares them for
+ /// the validity of the greater-than relationship.
+ /// @returns true if *this > RHS when both are considered signed.
+ /// @brief Signed greather than comparison
+ bool sgt(const APInt& RHS) const {
+ return !slt(RHS) && !eq(RHS);
+ }
+
+ /// Regards both *this and RHS as unsigned quantities and compares them for
+ /// validity of the greater-or-equal relationship.
+ /// @returns true if *this >= RHS when both are considered unsigned.
+ /// @brief Unsigned greater or equal comparison
+ bool uge(const APInt& RHS) const {
+ return !ult(RHS);
+ }
+
+ /// Regards both *this and RHS as signed quantities and compares them for
+ /// validity of the greater-or-equal relationship.
+ /// @returns true if *this >= RHS when both are considered signed.
+ /// @brief Signed greather or equal comparison
+ bool sge(const APInt& RHS) const {
+ return !slt(RHS);
+ }
+
+ /// @}
+ /// @name Resizing Operators
+ /// @{
+ /// Truncate the APInt to a specified width. It is an error to specify a width
+ /// that is greater than or equal to the current width.
+ /// @brief Truncate to new width.
+ APInt &trunc(uint32_t width);
+
+ /// This operation sign extends the APInt to a new width. If the high order
+ /// bit is set, the fill on the left will be done with 1 bits, otherwise zero.
+ /// It is an error to specify a width that is less than or equal to the
+ /// current width.
+ /// @brief Sign extend to a new width.
+ APInt &sext(uint32_t width);
+
+ /// This operation zero extends the APInt to a new width. The high order bits
+ /// are filled with 0 bits. It is an error to specify a width that is less
+ /// than or equal to the current width.
+ /// @brief Zero extend to a new width.
+ APInt &zext(uint32_t width);
+
+ /// Make this APInt have the bit width given by \p width. The value is sign
+ /// extended, truncated, or left alone to make it that width.
+ /// @brief Sign extend or truncate to width
+ APInt &sextOrTrunc(uint32_t width);
+
+ /// Make this APInt have the bit width given by \p width. The value is zero
+ /// extended, truncated, or left alone to make it that width.
+ /// @brief Zero extend or truncate to width
+ APInt &zextOrTrunc(uint32_t width);
+
+ /// @}
+ /// @name Bit Manipulation Operators
+ /// @{
+ /// @brief Set every bit to 1.
+ APInt& set();
+
+ /// Set the given bit to 1 whose position is given as "bitPosition".
+ /// @brief Set a given bit to 1.
+ APInt& set(uint32_t bitPosition);
+
+ /// @brief Set every bit to 0.
+ APInt& clear();
+
+ /// Set the given bit to 0 whose position is given as "bitPosition".
+ /// @brief Set a given bit to 0.
+ APInt& clear(uint32_t bitPosition);
+
+ /// @brief Toggle every bit to its opposite value.
+ APInt& flip();
+
+ /// Toggle a given bit to its opposite value whose position is given
+ /// as "bitPosition".
+ /// @brief Toggles a given bit to its opposite value.
+ APInt& flip(uint32_t bitPosition);
+
+ /// @}
+ /// @name Value Characterization Functions
+ /// @{
+
+ /// @returns the total number of bits.
+ inline uint32_t getBitWidth() const {
+ return BitWidth;
+ }
+
+ /// Here one word's bitwidth equals to that of uint64_t.
+ /// @returns the number of words to hold the integer value of this APInt.
+ /// @brief Get the number of words.
+ inline uint32_t getNumWords() const {
+ return (BitWidth + APINT_BITS_PER_WORD - 1) / APINT_BITS_PER_WORD;
+ }
+
+ /// This function returns the number of active bits which is defined as the
+ /// bit width minus the number of leading zeros. This is used in several
+ /// computations to see how "wide" the value is.
+ /// @brief Compute the number of active bits in the value
+ inline uint32_t getActiveBits() const {
+ return BitWidth - countLeadingZeros();
+ }
+
+ /// This function returns the number of active words in the value of this
+ /// APInt. This is used in conjunction with getActiveData to extract the raw
+ /// value of the APInt.
+ inline uint32_t getActiveWords() const {
+ return whichWord(getActiveBits()-1) + 1;
+ }
+
+ /// Computes the minimum bit width for this APInt while considering it to be
+ /// a signed (and probably negative) value. If the value is not negative,
+ /// this function returns the same value as getActiveBits(). Otherwise, it
+ /// returns the smallest bit width that will retain the negative value. For
+ /// example, -1 can be written as 0b1 or 0xFFFFFFFFFF. 0b1 is shorter and so
+ /// for -1, this function will always return 1.
+ /// @brief Get the minimum bit size for this signed APInt
+ inline uint32_t getMinSignedBits() const {
+ if (isNegative())
+ return BitWidth - countLeadingOnes() + 1;
+ return getActiveBits()+1;
+ }
+
+ /// This method attempts to return the value of this APInt as a zero extended
+ /// uint64_t. The bitwidth must be <= 64 or the value must fit within a
+ /// uint64_t. Otherwise an assertion will result.
+ /// @brief Get zero extended value
+ inline uint64_t getZExtValue() const {
+ if (isSingleWord())
+ return VAL;
+ assert(getActiveBits() <= 64 && "Too many bits for uint64_t");
+ return pVal[0];
+ }
+
+ /// This method attempts to return the value of this APInt as a sign extended
+ /// int64_t. The bit width must be <= 64 or the value must fit within an
+ /// int64_t. Otherwise an assertion will result.
+ /// @brief Get sign extended value
+ inline int64_t getSExtValue() const {
+ if (isSingleWord())
+ return int64_t(VAL << (APINT_BITS_PER_WORD - BitWidth)) >>
+ (APINT_BITS_PER_WORD - BitWidth);
+ assert(getActiveBits() <= 64 && "Too many bits for int64_t");
+ return int64_t(pVal[0]);
+ }
+
+ /// This method determines how many bits are required to hold the APInt
+ /// equivalent of the string given by \p str of length \p slen.
+ /// @brief Get bits required for string value.
+ static uint32_t getBitsNeeded(const char* str, uint32_t slen, uint8_t radix);
+
+ /// countLeadingZeros - This function is an APInt version of the
+ /// countLeadingZeros_{32,64} functions in MathExtras.h. It counts the number
+ /// of zeros from the most significant bit to the first one bit.
+ /// @returns BitWidth if the value is zero.
+ /// @returns the number of zeros from the most significant bit to the first
+ /// one bits.
+ uint32_t countLeadingZeros() const;
+
+ /// countLeadingOnes - This function counts the number of contiguous 1 bits
+ /// in the high order bits. The count stops when the first 0 bit is reached.
+ /// @returns 0 if the high order bit is not set
+ /// @returns the number of 1 bits from the most significant to the least
+ /// @brief Count the number of leading one bits.
+ uint32_t countLeadingOnes() const;
+
+ /// countTrailingZeros - This function is an APInt version of the
+ /// countTrailingZoers_{32,64} functions in MathExtras.h. It counts
+ /// the number of zeros from the least significant bit to the first set bit.
+ /// @returns BitWidth if the value is zero.
+ /// @returns the number of zeros from the least significant bit to the first
+ /// one bit.
+ /// @brief Count the number of trailing zero bits.
+ uint32_t countTrailingZeros() const;
+
+ /// countPopulation - This function is an APInt version of the
+ /// countPopulation_{32,64} functions in MathExtras.h. It counts the number
+ /// of 1 bits in the APInt value.
+ /// @returns 0 if the value is zero.
+ /// @returns the number of set bits.
+ /// @brief Count the number of bits set.
+ uint32_t countPopulation() const;
+
+ /// @}
+ /// @name Conversion Functions
+ /// @{
+
+ /// This is used internally to convert an APInt to a string.
+ /// @brief Converts an APInt to a std::string
+ std::string toString(uint8_t radix, bool wantSigned) const;
+
+ /// Considers the APInt to be unsigned and converts it into a string in the
+ /// radix given. The radix can be 2, 8, 10 or 16.
+ /// @returns a character interpretation of the APInt
+ /// @brief Convert unsigned APInt to string representation.
+ inline std::string toStringUnsigned(uint8_t radix = 10) const {
+ return toString(radix, false);
+ }
+
+ /// Considers the APInt to be unsigned and converts it into a string in the
+ /// radix given. The radix can be 2, 8, 10 or 16.
+ /// @returns a character interpretation of the APInt
+ /// @brief Convert unsigned APInt to string representation.
+ inline std::string toStringSigned(uint8_t radix = 10) const {
+ return toString(radix, true);
+ }
+
+ /// @returns a byte-swapped representation of this APInt Value.
+ APInt byteSwap() const;
+
+ /// @brief Converts this APInt to a double value.
+ double roundToDouble(bool isSigned) const;
+
+ /// @brief Converts this unsigned APInt to a double value.
+ double roundToDouble() const {
+ return roundToDouble(false);
+ }
+
+ /// @brief Converts this signed APInt to a double value.
+ double signedRoundToDouble() const {
+ return roundToDouble(true);
+ }
+
+ /// The conversion does not do a translation from integer to double, it just
+ /// re-interprets the bits as a double. Note that it is valid to do this on
+ /// any bit width. Exactly 64 bits will be translated.
+ /// @brief Converts APInt bits to a double
+ double bitsToDouble() const {
+ union {
+ uint64_t I;
+ double D;
+ } T;
+ T.I = (isSingleWord() ? VAL : pVal[0]);
+ return T.D;
+ }
+
+ /// The conversion does not do a translation from integer to float, it just
+ /// re-interprets the bits as a float. Note that it is valid to do this on
+ /// any bit width. Exactly 32 bits will be translated.
+ /// @brief Converts APInt bits to a double
+ float bitsToFloat() const {
+ union {
+ uint32_t I;
+ float F;
+ } T;
+ T.I = uint32_t((isSingleWord() ? VAL : pVal[0]));
+ return T.F;
+ }
+
+ /// The conversion does not do a translation from double to integer, it just
+ /// re-interprets the bits of the double. Note that it is valid to do this on
+ /// any bit width but bits from V may get truncated.
+ /// @brief Converts a double to APInt bits.
+ APInt& doubleToBits(double V) {
+ union {
+ uint64_t I;
+ double D;
+ } T;
+ T.D = V;
+ if (isSingleWord())
+ VAL = T.I;
+ else
+ pVal[0] = T.I;
+ return clearUnusedBits();
+ }
+
+ /// The conversion does not do a translation from float to integer, it just
+ /// re-interprets the bits of the float. Note that it is valid to do this on
+ /// any bit width but bits from V may get truncated.
+ /// @brief Converts a float to APInt bits.
+ APInt& floatToBits(float V) {
+ union {
+ uint32_t I;
+ float F;
+ } T;
+ T.F = V;
+ if (isSingleWord())
+ VAL = T.I;
+ else
+ pVal[0] = T.I;
+ return clearUnusedBits();
+ }
+
+ /// @}
+ /// @name Mathematics Operations
+ /// @{
+
+ /// @returns the floor log base 2 of this APInt.
+ inline uint32_t logBase2() const {
+ return BitWidth - 1 - countLeadingZeros();
+ }
+
+ /// @returns the log base 2 of this APInt if its an exact power of two, -1
+ /// otherwise
+ inline int32_t exactLogBase2() const {
+ if (!isPowerOf2())
+ return -1;
+ return logBase2();
+ }
+
+ /// @brief Compute the square root
+ APInt sqrt() const;
+
+ /// If *this is < 0 then return -(*this), otherwise *this;
+ /// @brief Get the absolute value;
+ APInt abs() const {
+ if (isNegative())
+ return -(*this);
+ return *this;
+ }
+
+ /// @}
+
+ /// @}
+ /// @name Building-block Operations for APInt and APFloat
+ /// @{
+
+ // These building block operations operate on a representation of
+ // arbitrary precision, two's-complement, bignum integer values.
+ // They should be sufficient to implement APInt and APFloat bignum
+ // requirements. Inputs are generally a pointer to the base of an
+ // array of integer parts, representing an unsigned bignum, and a
+ // count of how many parts there are.
+
+ /// Sets the least significant part of a bignum to the input value,
+ /// and zeroes out higher parts. */
+ static void tcSet(integerPart *, integerPart, unsigned int);
+
+ /// Assign one bignum to another.
+ static void tcAssign(integerPart *, const integerPart *, unsigned int);
+
+ /// Returns true if a bignum is zero, false otherwise.
+ static bool tcIsZero(const integerPart *, unsigned int);
+
+ /// Extract the given bit of a bignum; returns 0 or 1. Zero-based.
+ static int tcExtractBit(const integerPart *, unsigned int bit);
+
+ /// Copy the bit vector of width srcBITS from SRC, starting at bit
+ /// srcLSB, to DST, of dstCOUNT parts, such that the bit srcLSB
+ /// becomes the least significant bit of DST. All high bits above
+ /// srcBITS in DST are zero-filled.
+ static void tcExtract(integerPart *, unsigned int dstCount, const integerPart *,
+ unsigned int srcBits, unsigned int srcLSB);
+
+ /// Set the given bit of a bignum. Zero-based.
+ static void tcSetBit(integerPart *, unsigned int bit);
+
+ /// Returns the bit number of the least or most significant set bit
+ /// of a number. If the input number has no bits set -1U is
+ /// returned.
+ static unsigned int tcLSB(const integerPart *, unsigned int);
+ static unsigned int tcMSB(const integerPart *, unsigned int);
+
+ /// Negate a bignum in-place.
+ static void tcNegate(integerPart *, unsigned int);
+
+ /// DST += RHS + CARRY where CARRY is zero or one. Returns the
+ /// carry flag.
+ static integerPart tcAdd(integerPart *, const integerPart *,
+ integerPart carry, unsigned);
+
+ /// DST -= RHS + CARRY where CARRY is zero or one. Returns the
+ /// carry flag.
+ static integerPart tcSubtract(integerPart *, const integerPart *,
+ integerPart carry, unsigned);
+
+ /// DST += SRC * MULTIPLIER + PART if add is true
+ /// DST = SRC * MULTIPLIER + PART if add is false
+ ///
+ /// Requires 0 <= DSTPARTS <= SRCPARTS + 1. If DST overlaps SRC
+ /// they must start at the same point, i.e. DST == SRC.
+ ///
+ /// If DSTPARTS == SRC_PARTS + 1 no overflow occurs and zero is
+ /// returned. Otherwise DST is filled with the least significant
+ /// DSTPARTS parts of the result, and if all of the omitted higher
+ /// parts were zero return zero, otherwise overflow occurred and
+ /// return one.
+ static int tcMultiplyPart(integerPart *dst, const integerPart *src,
+ integerPart multiplier, integerPart carry,
+ unsigned int srcParts, unsigned int dstParts,
+ bool add);
+
+ /// DST = LHS * RHS, where DST has the same width as the operands
+ /// and is filled with the least significant parts of the result.
+ /// Returns one if overflow occurred, otherwise zero. DST must be
+ /// disjoint from both operands.
+ static int tcMultiply(integerPart *, const integerPart *,
+ const integerPart *, unsigned);
+
+ /// DST = LHS * RHS, where DST has width the sum of the widths of
+ /// the operands. No overflow occurs. DST must be disjoint from
+ /// both operands. Returns the number of parts required to hold the
+ /// result.
+ static unsigned int tcFullMultiply(integerPart *, const integerPart *,
+ const integerPart *, unsigned, unsigned);
+
+ /// If RHS is zero LHS and REMAINDER are left unchanged, return one.
+ /// Otherwise set LHS to LHS / RHS with the fractional part
+ /// discarded, set REMAINDER to the remainder, return zero. i.e.
+ ///
+ /// OLD_LHS = RHS * LHS + REMAINDER
+ ///
+ /// SCRATCH is a bignum of the same size as the operands and result
+ /// for use by the routine; its contents need not be initialized
+ /// and are destroyed. LHS, REMAINDER and SCRATCH must be
+ /// distinct.
+ static int tcDivide(integerPart *lhs, const integerPart *rhs,
+ integerPart *remainder, integerPart *scratch,
+ unsigned int parts);
+
+ /// Shift a bignum left COUNT bits. Shifted in bits are zero.
+ /// There are no restrictions on COUNT.
+ static void tcShiftLeft(integerPart *, unsigned int parts,
+ unsigned int count);
+
+ /// Shift a bignum right COUNT bits. Shifted in bits are zero.
+ /// There are no restrictions on COUNT.
+ static void tcShiftRight(integerPart *, unsigned int parts,
+ unsigned int count);
+
+ /// The obvious AND, OR and XOR and complement operations.
+ static void tcAnd(integerPart *, const integerPart *, unsigned int);
+ static void tcOr(integerPart *, const integerPart *, unsigned int);
+ static void tcXor(integerPart *, const integerPart *, unsigned int);
+ static void tcComplement(integerPart *, unsigned int);
+
+ /// Comparison (unsigned) of two bignums.
+ static int tcCompare(const integerPart *, const integerPart *,
+ unsigned int);
+
+ /// Increment a bignum in-place. Return the carry flag.
+ static integerPart tcIncrement(integerPart *, unsigned int);
+
+ /// Set the least significant BITS and clear the rest.
+ static void tcSetLeastSignificantBits(integerPart *, unsigned int,
+ unsigned int bits);
+
+ /// @brief debug method
+ void dump() const;
+
+ /// @}
+};
+
+inline bool operator==(uint64_t V1, const APInt& V2) {
+ return V2 == V1;
+}
+
+inline bool operator!=(uint64_t V1, const APInt& V2) {
+ return V2 != V1;
+}
+
+namespace APIntOps {
+
+/// @brief Determine the smaller of two APInts considered to be signed.
+inline APInt smin(const APInt &A, const APInt &B) {
+ return A.slt(B) ? A : B;
+}
+
+/// @brief Determine the larger of two APInts considered to be signed.
+inline APInt smax(const APInt &A, const APInt &B) {
+ return A.sgt(B) ? A : B;
+}
+
+/// @brief Determine the smaller of two APInts considered to be signed.
+inline APInt umin(const APInt &A, const APInt &B) {
+ return A.ult(B) ? A : B;
+}
+
+/// @brief Determine the larger of two APInts considered to be unsigned.
+inline APInt umax(const APInt &A, const APInt &B) {
+ return A.ugt(B) ? A : B;
+}
+
+/// @brief Check if the specified APInt has a N-bits integer value.
+inline bool isIntN(uint32_t N, const APInt& APIVal) {
+ return APIVal.isIntN(N);
+}
+
+/// @returns true if the argument APInt value is a sequence of ones
+/// starting at the least significant bit with the remainder zero.
+inline bool isMask(uint32_t numBits, const APInt& APIVal) {
+ return APIVal.getBoolValue() && ((APIVal + APInt(numBits,1)) & APIVal) == 0;
+}
+
+/// @returns true if the argument APInt value contains a sequence of ones
+/// with the remainder zero.
+inline bool isShiftedMask(uint32_t numBits, const APInt& APIVal) {
+ return isMask(numBits, (APIVal - APInt(numBits,1)) | APIVal);
+}
+
+/// @returns a byte-swapped representation of the specified APInt Value.
+inline APInt byteSwap(const APInt& APIVal) {
+ return APIVal.byteSwap();
+}
+
+/// @returns the floor log base 2 of the specified APInt value.
+inline uint32_t logBase2(const APInt& APIVal) {
+ return APIVal.logBase2();
+}
+
+/// GreatestCommonDivisor - This function returns the greatest common
+/// divisor of the two APInt values using Enclid's algorithm.
+/// @returns the greatest common divisor of Val1 and Val2
+/// @brief Compute GCD of two APInt values.
+APInt GreatestCommonDivisor(const APInt& Val1, const APInt& Val2);
+
+/// Treats the APInt as an unsigned value for conversion purposes.
+/// @brief Converts the given APInt to a double value.
+inline double RoundAPIntToDouble(const APInt& APIVal) {
+ return APIVal.roundToDouble();
+}
+
+/// Treats the APInt as a signed value for conversion purposes.
+/// @brief Converts the given APInt to a double value.
+inline double RoundSignedAPIntToDouble(const APInt& APIVal) {
+ return APIVal.signedRoundToDouble();
+}
+
+/// @brief Converts the given APInt to a float vlalue.
+inline float RoundAPIntToFloat(const APInt& APIVal) {
+ return float(RoundAPIntToDouble(APIVal));
+}
+
+/// Treast the APInt as a signed value for conversion purposes.
+/// @brief Converts the given APInt to a float value.
+inline float RoundSignedAPIntToFloat(const APInt& APIVal) {
+ return float(APIVal.signedRoundToDouble());
+}
+
+/// RoundDoubleToAPInt - This function convert a double value to an APInt value.
+/// @brief Converts the given double value into a APInt.
+APInt RoundDoubleToAPInt(double Double, uint32_t width);
+
+/// RoundFloatToAPInt - Converts a float value into an APInt value.
+/// @brief Converts a float value into a APInt.
+inline APInt RoundFloatToAPInt(float Float, uint32_t width) {
+ return RoundDoubleToAPInt(double(Float), width);
+}
+
+/// Arithmetic right-shift the APInt by shiftAmt.
+/// @brief Arithmetic right-shift function.
+inline APInt ashr(const APInt& LHS, uint32_t shiftAmt) {
+ return LHS.ashr(shiftAmt);
+}
+
+/// Logical right-shift the APInt by shiftAmt.
+/// @brief Logical right-shift function.
+inline APInt lshr(const APInt& LHS, uint32_t shiftAmt) {
+ return LHS.lshr(shiftAmt);
+}
+
+/// Left-shift the APInt by shiftAmt.
+/// @brief Left-shift function.
+inline APInt shl(const APInt& LHS, uint32_t shiftAmt) {
+ return LHS.shl(shiftAmt);
+}
+
+/// Signed divide APInt LHS by APInt RHS.
+/// @brief Signed division function for APInt.
+inline APInt sdiv(const APInt& LHS, const APInt& RHS) {
+ return LHS.sdiv(RHS);
+}
+
+/// Unsigned divide APInt LHS by APInt RHS.
+/// @brief Unsigned division function for APInt.
+inline APInt udiv(const APInt& LHS, const APInt& RHS) {
+ return LHS.udiv(RHS);
+}
+
+/// Signed remainder operation on APInt.
+/// @brief Function for signed remainder operation.
+inline APInt srem(const APInt& LHS, const APInt& RHS) {
+ return LHS.srem(RHS);
+}
+
+/// Unsigned remainder operation on APInt.
+/// @brief Function for unsigned remainder operation.
+inline APInt urem(const APInt& LHS, const APInt& RHS) {
+ return LHS.urem(RHS);
+}
+
+/// Performs multiplication on APInt values.
+/// @brief Function for multiplication operation.
+inline APInt mul(const APInt& LHS, const APInt& RHS) {
+ return LHS * RHS;
+}
+
+/// Performs addition on APInt values.
+/// @brief Function for addition operation.
+inline APInt add(const APInt& LHS, const APInt& RHS) {
+ return LHS + RHS;
+}
+
+/// Performs subtraction on APInt values.
+/// @brief Function for subtraction operation.
+inline APInt sub(const APInt& LHS, const APInt& RHS) {
+ return LHS - RHS;
+}
+
+/// Performs bitwise AND operation on APInt LHS and
+/// APInt RHS.
+/// @brief Bitwise AND function for APInt.
+inline APInt And(const APInt& LHS, const APInt& RHS) {
+ return LHS & RHS;
+}
+
+/// Performs bitwise OR operation on APInt LHS and APInt RHS.
+/// @brief Bitwise OR function for APInt.
+inline APInt Or(const APInt& LHS, const APInt& RHS) {
+ return LHS | RHS;
+}
+
+/// Performs bitwise XOR operation on APInt.
+/// @brief Bitwise XOR function for APInt.
+inline APInt Xor(const APInt& LHS, const APInt& RHS) {
+ return LHS ^ RHS;
+}
+
+/// Performs a bitwise complement operation on APInt.
+/// @brief Bitwise complement function.
+inline APInt Not(const APInt& APIVal) {
+ return ~APIVal;
+}
+
+} // End of APIntOps namespace
+
+} // End of llvm namespace
+
+#endif
diff --git a/support/include/llvm/ADT/APSInt.h b/support/include/llvm/ADT/APSInt.h
new file mode 100644
index 0000000..4339cd0
--- /dev/null
+++ b/support/include/llvm/ADT/APSInt.h
@@ -0,0 +1,132 @@
+//===-- llvm/ADT/APSInt.h - Arbitrary Precision Signed Int -----*- C++ -*--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the APSInt class, which is a simple class that
+// represents an arbitrary sized integer that knows its signedness.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_APSINT_H
+#define LLVM_APSINT_H
+
+#include "llvm/ADT/APInt.h"
+
+namespace llvm {
+
+
+class APSInt : public APInt {
+ bool IsUnsigned;
+public:
+ /// APSInt ctor - Create an APSInt with the specified width, default to
+ /// unsigned.
+ explicit APSInt(uint32_t BitWidth) : APInt(BitWidth, 0), IsUnsigned(true) {}
+ APSInt(const APInt &I) : APInt(I), IsUnsigned(true) {}
+
+ APSInt &operator=(const APSInt &RHS) {
+ APInt::operator=(RHS);
+ IsUnsigned = RHS.IsUnsigned;
+ return *this;
+ }
+
+ APSInt &operator=(const APInt &RHS) {
+ // Retain our current sign.
+ APInt::operator=(RHS);
+ return *this;
+ }
+
+ APSInt &operator=(uint64_t RHS) {
+ // Retain our current sign.
+ APInt::operator=(RHS);
+ return *this;
+ }
+
+ // Query sign information.
+ bool isSigned() const { return !IsUnsigned; }
+ bool isUnsigned() const { return IsUnsigned; }
+ void setIsUnsigned(bool Val) { IsUnsigned = Val; }
+ void setIsSigned(bool Val) { IsUnsigned = !Val; }
+
+ /// This is used internally to convert an APInt to a string.
+ /// @brief Converts an APInt to a std::string
+ std::string toString(uint8_t Radix = 10) const {
+ return APInt::toString(Radix, isSigned());
+ }
+
+
+ const APSInt &operator%=(const APSInt &RHS) {
+ assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+ if (IsUnsigned)
+ *this = urem(RHS);
+ else
+ *this = srem(RHS);
+ return *this;
+ }
+ const APSInt &operator/=(const APSInt &RHS) {
+ assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+ if (IsUnsigned)
+ *this = udiv(RHS);
+ else
+ *this = sdiv(RHS);
+ return *this;
+ }
+ APSInt operator%(const APSInt &RHS) const {
+ assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+ return IsUnsigned ? urem(RHS) : srem(RHS);
+ }
+ APSInt operator/(const APSInt &RHS) const {
+ assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+ return IsUnsigned ? udiv(RHS) : sdiv(RHS);
+ }
+
+ const APSInt &operator>>=(unsigned Amt) {
+ *this = *this >> Amt;
+ return *this;
+ }
+
+ APSInt& extend(uint32_t width) {
+ if (IsUnsigned)
+ zext(width);
+ else
+ sext(width);
+ return *this;
+ }
+
+ APSInt& extOrTrunc(uint32_t width) {
+ if (IsUnsigned)
+ zextOrTrunc(width);
+ else
+ sextOrTrunc(width);
+ return *this;
+ }
+
+ APSInt operator>>(unsigned Amt) const {
+ return IsUnsigned ? lshr(Amt) : ashr(Amt);
+ }
+
+ inline bool operator<(const APSInt& RHS) const {
+ assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+ return IsUnsigned ? ult(RHS) : slt(RHS);
+ }
+ inline bool operator>(const APSInt& RHS) const {
+ assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+ return IsUnsigned ? ugt(RHS) : sgt(RHS);
+ }
+ inline bool operator<=(const APSInt& RHS) const {
+ assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+ return IsUnsigned ? ule(RHS) : sle(RHS);
+ }
+ inline bool operator>=(const APSInt& RHS) const {
+ assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+ return IsUnsigned ? uge(RHS) : sge(RHS);
+ }
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/support/include/llvm/ADT/BitVector.h b/support/include/llvm/ADT/BitVector.h
new file mode 100644
index 0000000..927cfa9
--- /dev/null
+++ b/support/include/llvm/ADT/BitVector.h
@@ -0,0 +1,404 @@
+//===- llvm/ADT/BitVector.h - Bit vectors -----------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Evan Cheng and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the BitVector class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_BITVECTOR_H
+#define LLVM_ADT_BITVECTOR_H
+
+#include "llvm/Support/MathExtras.h"
+#include <algorithm>
+#include <cstdlib>
+#include <cassert>
+
+namespace llvm {
+
+class BitVector {
+ typedef unsigned long BitWord;
+
+ enum { BITWORD_SIZE = sizeof(BitWord) * 8 };
+
+ BitWord *Bits; // Actual bits.
+ unsigned Size; // Size of bitvector in bits.
+ unsigned Capacity; // Size of allocated memory in BitWord.
+
+public:
+ // Encapsulation of a single bit.
+ class reference {
+ friend class BitVector;
+
+ BitWord *WordRef;
+ unsigned BitPos;
+
+ reference(); // Undefined
+
+ public:
+ reference(BitVector &b, unsigned Idx) {
+ WordRef = &b.Bits[Idx / BITWORD_SIZE];
+ BitPos = Idx % BITWORD_SIZE;
+ }
+
+ ~reference() {}
+
+ reference& operator=(bool t) {
+ if (t)
+ *WordRef |= 1L << BitPos;
+ else
+ *WordRef &= ~(1L << BitPos);
+ return *this;
+ }
+
+ operator bool() const {
+ return ((*WordRef) & (1L << BitPos)) ? true : false;
+ }
+ };
+
+
+ /// BitVector default ctor - Creates an empty bitvector.
+ BitVector() : Size(0), Capacity(0) {
+ Bits = NULL;
+ }
+
+ /// BitVector ctor - Creates a bitvector of specified number of bits. All
+ /// bits are initialized to the specified value.
+ explicit BitVector(unsigned s, bool t = false) : Size(s) {
+ Capacity = NumBitWords(s);
+ Bits = new BitWord[Capacity];
+ init_words(Bits, Capacity, t);
+ if (t)
+ clear_unused_bits();
+ }
+
+ /// BitVector copy ctor.
+ BitVector(const BitVector &RHS) : Size(RHS.size()) {
+ if (Size == 0) {
+ Bits = NULL;
+ Capacity = 0;
+ return;
+ }
+
+ Capacity = NumBitWords(RHS.size());
+ Bits = new BitWord[Capacity];
+ std::copy(RHS.Bits, &RHS.Bits[Capacity], Bits);
+ }
+
+ ~BitVector() {
+ delete[] Bits;
+ }
+
+ /// size - Returns the number of bits in this bitvector.
+ unsigned size() const { return Size; }
+
+ /// count - Returns the number of bits which are set.
+ unsigned count() const {
+ unsigned NumBits = 0;
+ for (unsigned i = 0; i < NumBitWords(size()); ++i)
+ if (sizeof(BitWord) == 4)
+ NumBits += CountPopulation_32(Bits[i]);
+ else if (sizeof(BitWord) == 8)
+ NumBits += CountPopulation_64(Bits[i]);
+ else
+ assert(0 && "Unsupported!");
+ return NumBits;
+ }
+
+ /// any - Returns true if any bit is set.
+ bool any() const {
+ for (unsigned i = 0; i < NumBitWords(size()); ++i)
+ if (Bits[i] != 0)
+ return true;
+ return false;
+ }
+
+ /// none - Returns true if none of the bits are set.
+ bool none() const {
+ return !any();
+ }
+
+ /// find_first - Returns the index of the first set bit, -1 if none
+ /// of the bits are set.
+ int find_first() const {
+ for (unsigned i = 0; i < NumBitWords(size()); ++i)
+ if (Bits[i] != 0) {
+ if (sizeof(BitWord) == 4)
+ return i * BITWORD_SIZE + CountTrailingZeros_32(Bits[i]);
+ else if (sizeof(BitWord) == 8)
+ return i * BITWORD_SIZE + CountTrailingZeros_64(Bits[i]);
+ else
+ assert(0 && "Unsupported!");
+ }
+ return -1;
+ }
+
+ /// find_next - Returns the index of the next set bit following the
+ /// "Prev" bit. Returns -1 if the next set bit is not found.
+ int find_next(unsigned Prev) const {
+ ++Prev;
+ if (Prev >= Size)
+ return -1;
+
+ unsigned WordPos = Prev / BITWORD_SIZE;
+ unsigned BitPos = Prev % BITWORD_SIZE;
+ BitWord Copy = Bits[WordPos];
+ // Mask off previous bits.
+ Copy &= ~0L << BitPos;
+
+ if (Copy != 0) {
+ if (sizeof(BitWord) == 4)
+ return WordPos * BITWORD_SIZE + CountTrailingZeros_32(Copy);
+ else if (sizeof(BitWord) == 8)
+ return WordPos * BITWORD_SIZE + CountTrailingZeros_64(Copy);
+ else
+ assert(0 && "Unsupported!");
+ }
+
+ // Check subsequent words.
+ for (unsigned i = WordPos+1; i < NumBitWords(size()); ++i)
+ if (Bits[i] != 0) {
+ if (sizeof(BitWord) == 4)
+ return i * BITWORD_SIZE + CountTrailingZeros_32(Bits[i]);
+ else if (sizeof(BitWord) == 8)
+ return i * BITWORD_SIZE + CountTrailingZeros_64(Bits[i]);
+ else
+ assert(0 && "Unsupported!");
+ }
+ return -1;
+ }
+
+ /// clear - Clear all bits.
+ void clear() {
+ Size = 0;
+ }
+
+ /// resize - Grow or shrink the bitvector.
+ void resize(unsigned N, bool t = false) {
+ if (N > Capacity * BITWORD_SIZE) {
+ unsigned OldCapacity = Capacity;
+ grow(N);
+ init_words(&Bits[OldCapacity], (Capacity-OldCapacity), t);
+ }
+
+ // Set any old unused bits that are now included in the BitVector. This
+ // may set bits that are not included in the new vector, but we will clear
+ // them back out below.
+ if (N > Size)
+ set_unused_bits(t);
+
+ // Update the size, and clear out any bits that are now unused
+ unsigned OldSize = Size;
+ Size = N;
+ if (t || N < OldSize)
+ clear_unused_bits();
+ }
+
+ void reserve(unsigned N) {
+ if (N > Capacity * BITWORD_SIZE)
+ grow(N);
+ }
+
+ // Set, reset, flip
+ BitVector &set() {
+ init_words(Bits, Capacity, true);
+ clear_unused_bits();
+ return *this;
+ }
+
+ BitVector &set(unsigned Idx) {
+ Bits[Idx / BITWORD_SIZE] |= 1L << (Idx % BITWORD_SIZE);
+ return *this;
+ }
+
+ BitVector &reset() {
+ init_words(Bits, Capacity, false);
+ return *this;
+ }
+
+ BitVector &reset(unsigned Idx) {
+ Bits[Idx / BITWORD_SIZE] &= ~(1L << (Idx % BITWORD_SIZE));
+ return *this;
+ }
+
+ BitVector &flip() {
+ for (unsigned i = 0; i < NumBitWords(size()); ++i)
+ Bits[i] = ~Bits[i];
+ clear_unused_bits();
+ return *this;
+ }
+
+ BitVector &flip(unsigned Idx) {
+ Bits[Idx / BITWORD_SIZE] ^= 1L << (Idx % BITWORD_SIZE);
+ return *this;
+ }
+
+ // No argument flip.
+ BitVector operator~() const {
+ return BitVector(*this).flip();
+ }
+
+ // Indexing.
+ reference operator[](unsigned Idx) {
+ return reference(*this, Idx);
+ }
+
+ bool operator[](unsigned Idx) const {
+ BitWord Mask = 1L << (Idx % BITWORD_SIZE);
+ return (Bits[Idx / BITWORD_SIZE] & Mask) != 0;
+ }
+
+ bool test(unsigned Idx) const {
+ return (*this)[Idx];
+ }
+
+ // Comparison operators.
+ bool operator==(const BitVector &RHS) const {
+ unsigned ThisWords = NumBitWords(size());
+ unsigned RHSWords = NumBitWords(RHS.size());
+ unsigned i;
+ for (i = 0; i != std::min(ThisWords, RHSWords); ++i)
+ if (Bits[i] != RHS.Bits[i])
+ return false;
+
+ // Verify that any extra words are all zeros.
+ if (i != ThisWords) {
+ for (; i != ThisWords; ++i)
+ if (Bits[i])
+ return false;
+ } else if (i != RHSWords) {
+ for (; i != RHSWords; ++i)
+ if (RHS.Bits[i])
+ return false;
+ }
+ return true;
+ }
+
+ bool operator!=(const BitVector &RHS) const {
+ return !(*this == RHS);
+ }
+
+ // Intersection, union, disjoint union.
+ BitVector operator&=(const BitVector &RHS) {
+ unsigned ThisWords = NumBitWords(size());
+ unsigned RHSWords = NumBitWords(RHS.size());
+ unsigned i;
+ for (i = 0; i != std::min(ThisWords, RHSWords); ++i)
+ Bits[i] &= RHS.Bits[i];
+
+ // Any bits that are just in this bitvector become zero, because they aren't
+ // in the RHS bit vector. Any words only in RHS are ignored because they
+ // are already zero in the LHS.
+ for (; i != ThisWords; ++i)
+ Bits[i] = 0;
+
+ return *this;
+ }
+
+ BitVector operator|=(const BitVector &RHS) {
+ assert(Size == RHS.Size && "Illegal operation!");
+ for (unsigned i = 0; i < NumBitWords(size()); ++i)
+ Bits[i] |= RHS.Bits[i];
+ return *this;
+ }
+
+ BitVector operator^=(const BitVector &RHS) {
+ assert(Size == RHS.Size && "Illegal operation!");
+ for (unsigned i = 0; i < NumBitWords(size()); ++i)
+ Bits[i] ^= RHS.Bits[i];
+ return *this;
+ }
+
+ // Assignment operator.
+ const BitVector &operator=(const BitVector &RHS) {
+ if (this == &RHS) return *this;
+
+ Size = RHS.size();
+ unsigned RHSWords = NumBitWords(Size);
+ if (Size <= Capacity * BITWORD_SIZE) {
+ std::copy(RHS.Bits, &RHS.Bits[RHSWords], Bits);
+ clear_unused_bits();
+ return *this;
+ }
+
+ // Grow the bitvector to have enough elements.
+ Capacity = RHSWords;
+ BitWord *NewBits = new BitWord[Capacity];
+ std::copy(RHS.Bits, &RHS.Bits[RHSWords], NewBits);
+
+ // Destroy the old bits.
+ delete[] Bits;
+ Bits = NewBits;
+
+ return *this;
+ }
+
+private:
+ unsigned NumBitWords(unsigned S) const {
+ return (S + BITWORD_SIZE-1) / BITWORD_SIZE;
+ }
+
+ // Set the unused bits in the high words.
+ void set_unused_bits(bool t = true) {
+ // Set high words first.
+ unsigned UsedWords = NumBitWords(Size);
+ if (Capacity > UsedWords)
+ init_words(&Bits[UsedWords], (Capacity-UsedWords), t);
+
+ // Then set any stray high bits of the last used word.
+ unsigned ExtraBits = Size % BITWORD_SIZE;
+ if (ExtraBits) {
+ Bits[UsedWords-1] &= ~(~0L << ExtraBits);
+ Bits[UsedWords-1] |= (0 - (BitWord)t) << ExtraBits;
+ }
+ }
+
+ // Clear the unused bits in the high words.
+ void clear_unused_bits() {
+ set_unused_bits(false);
+ }
+
+ void grow(unsigned NewSize) {
+ unsigned OldCapacity = Capacity;
+ Capacity = NumBitWords(NewSize);
+ BitWord *NewBits = new BitWord[Capacity];
+
+ // Copy the old bits over.
+ if (OldCapacity != 0)
+ std::copy(Bits, &Bits[OldCapacity], NewBits);
+
+ // Destroy the old bits.
+ delete[] Bits;
+ Bits = NewBits;
+ }
+
+ void init_words(BitWord *B, unsigned NumWords, bool t) {
+ memset(B, 0 - (int)t, NumWords*sizeof(BitWord));
+ }
+};
+
+inline BitVector operator&(const BitVector &LHS, const BitVector &RHS) {
+ BitVector Result(LHS);
+ Result &= RHS;
+ return Result;
+}
+
+inline BitVector operator|(const BitVector &LHS, const BitVector &RHS) {
+ BitVector Result(LHS);
+ Result |= RHS;
+ return Result;
+}
+
+inline BitVector operator^(const BitVector &LHS, const BitVector &RHS) {
+ BitVector Result(LHS);
+ Result ^= RHS;
+ return Result;
+}
+
+} // End llvm namespace
+#endif
diff --git a/support/include/llvm/ADT/DenseMap.h b/support/include/llvm/ADT/DenseMap.h
new file mode 100644
index 0000000..7f02dc9
--- /dev/null
+++ b/support/include/llvm/ADT/DenseMap.h
@@ -0,0 +1,458 @@
+//===- llvm/ADT/DenseMap.h - Dense probed hash table ------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the DenseMap class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_DENSEMAP_H
+#define LLVM_ADT_DENSEMAP_H
+
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/MathExtras.h"
+#include <cassert>
+#include <utility>
+
+namespace llvm {
+
+template<typename T>
+struct DenseMapInfo {
+ //static inline T getEmptyKey();
+ //static inline T getTombstoneKey();
+ //static unsigned getHashValue(const T &Val);
+ //static bool isEqual(const T &LHS, const T &RHS);
+ //static bool isPod()
+};
+
+// Provide DenseMapInfo for all pointers.
+template<typename T>
+struct DenseMapInfo<T*> {
+ static inline T* getEmptyKey() { return reinterpret_cast<T*>(-1); }
+ static inline T* getTombstoneKey() { return reinterpret_cast<T*>(-2); }
+ static unsigned getHashValue(const T *PtrVal) {
+ return (unsigned((uintptr_t)PtrVal) >> 4) ^
+ (unsigned((uintptr_t)PtrVal) >> 9);
+ }
+ static bool isEqual(const T *LHS, const T *RHS) { return LHS == RHS; }
+ static bool isPod() { return true; }
+};
+
+template<typename KeyT, typename ValueT,
+ typename KeyInfoT = DenseMapInfo<KeyT>,
+ typename ValueInfoT = DenseMapInfo<ValueT> >
+class DenseMapIterator;
+template<typename KeyT, typename ValueT,
+ typename KeyInfoT = DenseMapInfo<KeyT>,
+ typename ValueInfoT = DenseMapInfo<ValueT> >
+class DenseMapConstIterator;
+
+template<typename KeyT, typename ValueT,
+ typename KeyInfoT = DenseMapInfo<KeyT>,
+ typename ValueInfoT = DenseMapInfo<ValueT> >
+class DenseMap {
+ typedef std::pair<KeyT, ValueT> BucketT;
+ unsigned NumBuckets;
+ BucketT *Buckets;
+
+ unsigned NumEntries;
+ unsigned NumTombstones;
+public:
+ typedef BucketT value_type;
+
+ DenseMap(const DenseMap& other) {
+ NumBuckets = 0;
+ CopyFrom(other);
+ }
+
+ explicit DenseMap(unsigned NumInitBuckets = 64) {
+ init(NumInitBuckets);
+ }
+
+ ~DenseMap() {
+ const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey();
+ for (BucketT *P = Buckets, *E = Buckets+NumBuckets; P != E; ++P) {
+ if (!KeyInfoT::isEqual(P->first, EmptyKey) &&
+ !KeyInfoT::isEqual(P->first, TombstoneKey))
+ P->second.~ValueT();
+ P->first.~KeyT();
+ }
+ delete[] reinterpret_cast<char*>(Buckets);
+ }
+
+ typedef DenseMapIterator<KeyT, ValueT, KeyInfoT> iterator;
+ typedef DenseMapConstIterator<KeyT, ValueT, KeyInfoT> const_iterator;
+ inline iterator begin() {
+ return iterator(Buckets, Buckets+NumBuckets);
+ }
+ inline iterator end() {
+ return iterator(Buckets+NumBuckets, Buckets+NumBuckets);
+ }
+ inline const_iterator begin() const {
+ return const_iterator(Buckets, Buckets+NumBuckets);
+ }
+ inline const_iterator end() const {
+ return const_iterator(Buckets+NumBuckets, Buckets+NumBuckets);
+ }
+
+ bool empty() const { return NumEntries == 0; }
+ unsigned size() const { return NumEntries; }
+
+ /// Grow the densemap so that it has at least Size buckets. Does not shrink
+ void resize(size_t Size) { grow(Size); }
+
+ void clear() {
+ // If the capacity of the array is huge, and the # elements used is small,
+ // shrink the array.
+ if (NumEntries * 4 < NumBuckets && NumBuckets > 64) {
+ shrink_and_clear();
+ return;
+ }
+
+ const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey();
+ for (BucketT *P = Buckets, *E = Buckets+NumBuckets; P != E; ++P) {
+ if (!KeyInfoT::isEqual(P->first, EmptyKey)) {
+ if (!KeyInfoT::isEqual(P->first, TombstoneKey)) {
+ P->second.~ValueT();
+ --NumEntries;
+ }
+ P->first = EmptyKey;
+ }
+ }
+ assert(NumEntries == 0 && "Node count imbalance!");
+ NumTombstones = 0;
+ }
+
+ /// count - Return true if the specified key is in the map.
+ bool count(const KeyT &Val) const {
+ BucketT *TheBucket;
+ return LookupBucketFor(Val, TheBucket);
+ }
+
+ iterator find(const KeyT &Val) {
+ BucketT *TheBucket;
+ if (LookupBucketFor(Val, TheBucket))
+ return iterator(TheBucket, Buckets+NumBuckets);
+ return end();
+ }
+ const_iterator find(const KeyT &Val) const {
+ BucketT *TheBucket;
+ if (LookupBucketFor(Val, TheBucket))
+ return const_iterator(TheBucket, Buckets+NumBuckets);
+ return end();
+ }
+
+ bool insert(const std::pair<KeyT, ValueT> &KV) {
+ BucketT *TheBucket;
+ if (LookupBucketFor(KV.first, TheBucket))
+ return false; // Already in map.
+
+ // Otherwise, insert the new element.
+ InsertIntoBucket(KV.first, KV.second, TheBucket);
+ return true;
+ }
+
+ bool erase(const KeyT &Val) {
+ BucketT *TheBucket;
+ if (!LookupBucketFor(Val, TheBucket))
+ return false; // not in map.
+
+ TheBucket->second.~ValueT();
+ TheBucket->first = getTombstoneKey();
+ --NumEntries;
+ ++NumTombstones;
+ return true;
+ }
+ bool erase(iterator I) {
+ BucketT *TheBucket = &*I;
+ TheBucket->second.~ValueT();
+ TheBucket->first = getTombstoneKey();
+ --NumEntries;
+ ++NumTombstones;
+ return true;
+ }
+
+ value_type& FindAndConstruct(const KeyT &Key) {
+ BucketT *TheBucket;
+ if (LookupBucketFor(Key, TheBucket))
+ return *TheBucket;
+
+ return *InsertIntoBucket(Key, ValueT(), TheBucket);
+ }
+
+ ValueT &operator[](const KeyT &Key) {
+ return FindAndConstruct(Key).second;
+ }
+
+ DenseMap& operator=(const DenseMap& other) {
+ CopyFrom(other);
+ return *this;
+ }
+
+private:
+ void CopyFrom(const DenseMap& other) {
+ if (NumBuckets != 0 && (!KeyInfoT::isPod() || !ValueInfoT::isPod())) {
+ const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey();
+ for (BucketT *P = Buckets, *E = Buckets+NumBuckets; P != E; ++P) {
+ if (!KeyInfoT::isEqual(P->first, EmptyKey) &&
+ !KeyInfoT::isEqual(P->first, TombstoneKey))
+ P->second.~ValueT();
+ P->first.~KeyT();
+ }
+ }
+
+ NumEntries = other.NumEntries;
+ NumTombstones = other.NumTombstones;
+
+ if (NumBuckets)
+ delete[] reinterpret_cast<char*>(Buckets);
+ Buckets = reinterpret_cast<BucketT*>(new char[sizeof(BucketT) *
+ other.NumBuckets]);
+
+ if (KeyInfoT::isPod() && ValueInfoT::isPod())
+ memcpy(Buckets, other.Buckets, other.NumBuckets * sizeof(BucketT));
+ else
+ for (size_t i = 0; i < other.NumBuckets; ++i) {
+ new (Buckets[i].first) KeyT(other.Buckets[i].first);
+ if (!KeyInfoT::isEqual(Buckets[i].first, getEmptyKey()) &&
+ !KeyInfoT::isEqual(Buckets[i].first, getTombstoneKey()))
+ new (&Buckets[i].second) ValueT(other.Buckets[i].second);
+ }
+ NumBuckets = other.NumBuckets;
+ }
+
+ BucketT *InsertIntoBucket(const KeyT &Key, const ValueT &Value,
+ BucketT *TheBucket) {
+ // If the load of the hash table is more than 3/4, or if fewer than 1/8 of
+ // the buckets are empty (meaning that many are filled with tombstones),
+ // grow the table.
+ //
+ // The later case is tricky. For example, if we had one empty bucket with
+ // tons of tombstones, failing lookups (e.g. for insertion) would have to
+ // probe almost the entire table until it found the empty bucket. If the
+ // table completely filled with tombstones, no lookup would ever succeed,
+ // causing infinite loops in lookup.
+ if (NumEntries*4 >= NumBuckets*3 ||
+ NumBuckets-(NumEntries+NumTombstones) < NumBuckets/8) {
+ this->grow(NumBuckets * 2);
+ LookupBucketFor(Key, TheBucket);
+ }
+ ++NumEntries;
+
+ // If we are writing over a tombstone, remember this.
+ if (!KeyInfoT::isEqual(TheBucket->first, getEmptyKey()))
+ --NumTombstones;
+
+ TheBucket->first = Key;
+ new (&TheBucket->second) ValueT(Value);
+ return TheBucket;
+ }
+
+ static unsigned getHashValue(const KeyT &Val) {
+ return KeyInfoT::getHashValue(Val);
+ }
+ static const KeyT getEmptyKey() {
+ return KeyInfoT::getEmptyKey();
+ }
+ static const KeyT getTombstoneKey() {
+ return KeyInfoT::getTombstoneKey();
+ }
+
+ /// LookupBucketFor - Lookup the appropriate bucket for Val, returning it in
+ /// FoundBucket. If the bucket contains the key and a value, this returns
+ /// true, otherwise it returns a bucket with an empty marker or tombstone and
+ /// returns false.
+ bool LookupBucketFor(const KeyT &Val, BucketT *&FoundBucket) const {
+ unsigned BucketNo = getHashValue(Val);
+ unsigned ProbeAmt = 1;
+ BucketT *BucketsPtr = Buckets;
+
+ // FoundTombstone - Keep track of whether we find a tombstone while probing.
+ BucketT *FoundTombstone = 0;
+ const KeyT EmptyKey = getEmptyKey();
+ const KeyT TombstoneKey = getTombstoneKey();
+ assert(!KeyInfoT::isEqual(Val, EmptyKey) &&
+ !KeyInfoT::isEqual(Val, TombstoneKey) &&
+ "Empty/Tombstone value shouldn't be inserted into map!");
+
+ while (1) {
+ BucketT *ThisBucket = BucketsPtr + (BucketNo & (NumBuckets-1));
+ // Found Val's bucket? If so, return it.
+ if (KeyInfoT::isEqual(ThisBucket->first, Val)) {
+ FoundBucket = ThisBucket;
+ return true;
+ }
+
+ // If we found an empty bucket, the key doesn't exist in the set.
+ // Insert it and return the default value.
+ if (KeyInfoT::isEqual(ThisBucket->first, EmptyKey)) {
+ // If we've already seen a tombstone while probing, fill it in instead
+ // of the empty bucket we eventually probed to.
+ if (FoundTombstone) ThisBucket = FoundTombstone;
+ FoundBucket = FoundTombstone ? FoundTombstone : ThisBucket;
+ return false;
+ }
+
+ // If this is a tombstone, remember it. If Val ends up not in the map, we
+ // prefer to return it than something that would require more probing.
+ if (KeyInfoT::isEqual(ThisBucket->first, TombstoneKey) && !FoundTombstone)
+ FoundTombstone = ThisBucket; // Remember the first tombstone found.
+
+ // Otherwise, it's a hash collision or a tombstone, continue quadratic
+ // probing.
+ BucketNo += ProbeAmt++;
+ }
+ }
+
+ void init(unsigned InitBuckets) {
+ NumEntries = 0;
+ NumTombstones = 0;
+ NumBuckets = InitBuckets;
+ assert(InitBuckets && (InitBuckets & InitBuckets-1) == 0 &&
+ "# initial buckets must be a power of two!");
+ Buckets = reinterpret_cast<BucketT*>(new char[sizeof(BucketT)*InitBuckets]);
+ // Initialize all the keys to EmptyKey.
+ const KeyT EmptyKey = getEmptyKey();
+ for (unsigned i = 0; i != InitBuckets; ++i)
+ new (&Buckets[i].first) KeyT(EmptyKey);
+ }
+
+ void grow(unsigned AtLeast) {
+ unsigned OldNumBuckets = NumBuckets;
+ BucketT *OldBuckets = Buckets;
+
+ // Double the number of buckets.
+ while (NumBuckets <= AtLeast)
+ NumBuckets <<= 1;
+ NumTombstones = 0;
+ Buckets = reinterpret_cast<BucketT*>(new char[sizeof(BucketT)*NumBuckets]);
+
+ // Initialize all the keys to EmptyKey.
+ const KeyT EmptyKey = getEmptyKey();
+ for (unsigned i = 0, e = NumBuckets; i != e; ++i)
+ new (&Buckets[i].first) KeyT(EmptyKey);
+
+ // Insert all the old elements.
+ const KeyT TombstoneKey = getTombstoneKey();
+ for (BucketT *B = OldBuckets, *E = OldBuckets+OldNumBuckets; B != E; ++B) {
+ if (!KeyInfoT::isEqual(B->first, EmptyKey) &&
+ !KeyInfoT::isEqual(B->first, TombstoneKey)) {
+ // Insert the key/value into the new table.
+ BucketT *DestBucket;
+ bool FoundVal = LookupBucketFor(B->first, DestBucket);
+ FoundVal = FoundVal; // silence warning.
+ assert(!FoundVal && "Key already in new map?");
+ DestBucket->first = B->first;
+ new (&DestBucket->second) ValueT(B->second);
+
+ // Free the value.
+ B->second.~ValueT();
+ }
+ B->first.~KeyT();
+ }
+
+ // Free the old table.
+ delete[] reinterpret_cast<char*>(OldBuckets);
+ }
+
+ void shrink_and_clear() {
+ unsigned OldNumBuckets = NumBuckets;
+ BucketT *OldBuckets = Buckets;
+
+ // Reduce the number of buckets.
+ NumBuckets = NumEntries > 32 ? 1 << (Log2_32_Ceil(NumEntries) + 1)
+ : 64;
+ NumTombstones = 0;
+ Buckets = reinterpret_cast<BucketT*>(new char[sizeof(BucketT)*NumBuckets]);
+
+ // Initialize all the keys to EmptyKey.
+ const KeyT EmptyKey = getEmptyKey();
+ for (unsigned i = 0, e = NumBuckets; i != e; ++i)
+ new (&Buckets[i].first) KeyT(EmptyKey);
+
+ // Free the old buckets.
+ const KeyT TombstoneKey = getTombstoneKey();
+ for (BucketT *B = OldBuckets, *E = OldBuckets+OldNumBuckets; B != E; ++B) {
+ if (!KeyInfoT::isEqual(B->first, EmptyKey) &&
+ !KeyInfoT::isEqual(B->first, TombstoneKey)) {
+ // Free the value.
+ B->second.~ValueT();
+ }
+ B->first.~KeyT();
+ }
+
+ // Free the old table.
+ delete[] reinterpret_cast<char*>(OldBuckets);
+
+ NumEntries = 0;
+ }
+};
+
+template<typename KeyT, typename ValueT, typename KeyInfoT, typename ValueInfoT>
+class DenseMapIterator {
+ typedef std::pair<KeyT, ValueT> BucketT;
+protected:
+ const BucketT *Ptr, *End;
+public:
+ DenseMapIterator(const BucketT *Pos, const BucketT *E) : Ptr(Pos), End(E) {
+ AdvancePastEmptyBuckets();
+ }
+
+ std::pair<KeyT, ValueT> &operator*() const {
+ return *const_cast<BucketT*>(Ptr);
+ }
+ std::pair<KeyT, ValueT> *operator->() const {
+ return const_cast<BucketT*>(Ptr);
+ }
+
+ bool operator==(const DenseMapIterator &RHS) const {
+ return Ptr == RHS.Ptr;
+ }
+ bool operator!=(const DenseMapIterator &RHS) const {
+ return Ptr != RHS.Ptr;
+ }
+
+ inline DenseMapIterator& operator++() { // Preincrement
+ ++Ptr;
+ AdvancePastEmptyBuckets();
+ return *this;
+ }
+ DenseMapIterator operator++(int) { // Postincrement
+ DenseMapIterator tmp = *this; ++*this; return tmp;
+ }
+
+private:
+ void AdvancePastEmptyBuckets() {
+ const KeyT Empty = KeyInfoT::getEmptyKey();
+ const KeyT Tombstone = KeyInfoT::getTombstoneKey();
+
+ while (Ptr != End &&
+ (KeyInfoT::isEqual(Ptr->first, Empty) ||
+ KeyInfoT::isEqual(Ptr->first, Tombstone)))
+ ++Ptr;
+ }
+};
+
+template<typename KeyT, typename ValueT, typename KeyInfoT, typename ValueInfoT>
+class DenseMapConstIterator : public DenseMapIterator<KeyT, ValueT, KeyInfoT> {
+public:
+ DenseMapConstIterator(const std::pair<KeyT, ValueT> *Pos,
+ const std::pair<KeyT, ValueT> *E)
+ : DenseMapIterator<KeyT, ValueT, KeyInfoT>(Pos, E) {
+ }
+ const std::pair<KeyT, ValueT> &operator*() const {
+ return *this->Ptr;
+ }
+ const std::pair<KeyT, ValueT> *operator->() const {
+ return this->Ptr;
+ }
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/support/include/llvm/ADT/DenseSet.h b/support/include/llvm/ADT/DenseSet.h
new file mode 100644
index 0000000..b19dc5e
--- /dev/null
+++ b/support/include/llvm/ADT/DenseSet.h
@@ -0,0 +1,61 @@
+//===- llvm/ADT/DenseSet.h - Dense probed hash table ------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the DenseSet class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_DENSESET_H
+#define LLVM_ADT_DENSESET_H
+
+#include "llvm/ADT/DenseMap.h"
+
+namespace llvm {
+
+/// DenseSet - This implements a dense probed hash-table based set.
+///
+/// FIXME: This is currently implemented directly in terms of DenseMap, this
+/// should be optimized later if there is a need.
+template<typename ValueT, typename ValueInfoT = DenseMapInfo<ValueT> >
+class DenseSet {
+ DenseMap<ValueT, char, ValueInfoT> TheMap;
+public:
+ DenseSet(const DenseSet &Other) : TheMap(Other.TheMap) {}
+ explicit DenseSet(unsigned NumInitBuckets = 64) : TheMap(NumInitBuckets) {}
+
+ bool empty() const { return TheMap.empty(); }
+ unsigned size() const { return TheMap.size(); }
+
+ // TODO add iterators.
+
+ void clear() {
+ TheMap.clear();
+ }
+
+ bool count(const ValueT &V) const {
+ return TheMap.count(V);
+ }
+
+ void insert(const ValueT &V) {
+ TheMap[V] = 0;
+ }
+
+ void erase(const ValueT &V) {
+ TheMap.erase(V);
+ }
+
+ DenseSet &operator=(const DenseSet &RHS) {
+ TheMap = RHS.TheMap;
+ return *this;
+ }
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/support/include/llvm/ADT/DepthFirstIterator.h b/support/include/llvm/ADT/DepthFirstIterator.h
new file mode 100644
index 0000000..0cdd79b
--- /dev/null
+++ b/support/include/llvm/ADT/DepthFirstIterator.h
@@ -0,0 +1,232 @@
+//===- llvm/ADT/DepthFirstIterator.h - Depth First iterator -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file builds on the ADT/GraphTraits.h file to build generic depth
+// first graph iterator. This file exposes the following functions/types:
+//
+// df_begin/df_end/df_iterator
+// * Normal depth-first iteration - visit a node and then all of its children.
+//
+// idf_begin/idf_end/idf_iterator
+// * Depth-first iteration on the 'inverse' graph.
+//
+// df_ext_begin/df_ext_end/df_ext_iterator
+// * Normal depth-first iteration - visit a node and then all of its children.
+// This iterator stores the 'visited' set in an external set, which allows
+// it to be more efficient, and allows external clients to use the set for
+// other purposes.
+//
+// idf_ext_begin/idf_ext_end/idf_ext_iterator
+// * Depth-first iteration on the 'inverse' graph.
+// This iterator stores the 'visited' set in an external set, which allows
+// it to be more efficient, and allows external clients to use the set for
+// other purposes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_DEPTHFIRSTITERATOR_H
+#define LLVM_ADT_DEPTHFIRSTITERATOR_H
+
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/iterator"
+#include "llvm/ADT/SmallPtrSet.h"
+#include <vector>
+#include <set>
+
+namespace llvm {
+
+// df_iterator_storage - A private class which is used to figure out where to
+// store the visited set.
+template<class SetType, bool External> // Non-external set
+class df_iterator_storage {
+public:
+ SetType Visited;
+};
+
+template<class SetType>
+class df_iterator_storage<SetType, true> {
+public:
+ df_iterator_storage(SetType &VSet) : Visited(VSet) {}
+ df_iterator_storage(const df_iterator_storage &S) : Visited(S.Visited) {}
+ SetType &Visited;
+};
+
+
+// Generic Depth First Iterator
+template<class GraphT,
+class SetType = llvm::SmallPtrSet<typename GraphTraits<GraphT>::NodeType*, 8>,
+ bool ExtStorage = false, class GT = GraphTraits<GraphT> >
+class df_iterator : public forward_iterator<typename GT::NodeType, ptrdiff_t>,
+ public df_iterator_storage<SetType, ExtStorage> {
+ typedef forward_iterator<typename GT::NodeType, ptrdiff_t> super;
+
+ typedef typename GT::NodeType NodeType;
+ typedef typename GT::ChildIteratorType ChildItTy;
+
+ // VisitStack - Used to maintain the ordering. Top = current block
+ // First element is node pointer, second is the 'next child' to visit
+ std::vector<std::pair<NodeType *, ChildItTy> > VisitStack;
+private:
+ inline df_iterator(NodeType *Node) {
+ this->Visited.insert(Node);
+ VisitStack.push_back(std::make_pair(Node, GT::child_begin(Node)));
+ }
+ inline df_iterator() { /* End is when stack is empty */ }
+
+ inline df_iterator(NodeType *Node, SetType &S)
+ : df_iterator_storage<SetType, ExtStorage>(S) {
+ if (!S.count(Node)) {
+ this->Visited.insert(Node);
+ VisitStack.push_back(std::make_pair(Node, GT::child_begin(Node)));
+ }
+ }
+ inline df_iterator(SetType &S)
+ : df_iterator_storage<SetType, ExtStorage>(S) {
+ // End is when stack is empty
+ }
+
+public:
+ typedef typename super::pointer pointer;
+ typedef df_iterator<GraphT, SetType, ExtStorage, GT> _Self;
+
+ // Provide static begin and end methods as our public "constructors"
+ static inline _Self begin(GraphT G) {
+ return _Self(GT::getEntryNode(G));
+ }
+ static inline _Self end(GraphT G) { return _Self(); }
+
+ // Static begin and end methods as our public ctors for external iterators
+ static inline _Self begin(GraphT G, SetType &S) {
+ return _Self(GT::getEntryNode(G), S);
+ }
+ static inline _Self end(GraphT G, SetType &S) { return _Self(S); }
+
+ inline bool operator==(const _Self& x) const {
+ return VisitStack.size() == x.VisitStack.size() &&
+ VisitStack == x.VisitStack;
+ }
+ inline bool operator!=(const _Self& x) const { return !operator==(x); }
+
+ inline pointer operator*() const {
+ return VisitStack.back().first;
+ }
+
+ // This is a nonstandard operator-> that dereferences the pointer an extra
+ // time... so that you can actually call methods ON the Node, because
+ // the contained type is a pointer. This allows BBIt->getTerminator() f.e.
+ //
+ inline NodeType *operator->() const { return operator*(); }
+
+ inline _Self& operator++() { // Preincrement
+ do {
+ std::pair<NodeType *, ChildItTy> &Top = VisitStack.back();
+ NodeType *Node = Top.first;
+ ChildItTy &It = Top.second;
+
+ while (It != GT::child_end(Node)) {
+ NodeType *Next = *It++;
+ if (!this->Visited.count(Next)) { // Has our next sibling been visited?
+ // No, do it now.
+ this->Visited.insert(Next);
+ VisitStack.push_back(std::make_pair(Next, GT::child_begin(Next)));
+ return *this;
+ }
+ }
+
+ // Oops, ran out of successors... go up a level on the stack.
+ VisitStack.pop_back();
+ } while (!VisitStack.empty());
+ return *this;
+ }
+
+ inline _Self operator++(int) { // Postincrement
+ _Self tmp = *this; ++*this; return tmp;
+ }
+
+ // nodeVisited - return true if this iterator has already visited the
+ // specified node. This is public, and will probably be used to iterate over
+ // nodes that a depth first iteration did not find: ie unreachable nodes.
+ //
+ inline bool nodeVisited(NodeType *Node) const {
+ return this->Visited.count(Node) != 0;
+ }
+};
+
+
+// Provide global constructors that automatically figure out correct types...
+//
+template <class T>
+df_iterator<T> df_begin(T G) {
+ return df_iterator<T>::begin(G);
+}
+
+template <class T>
+df_iterator<T> df_end(T G) {
+ return df_iterator<T>::end(G);
+}
+
+// Provide global definitions of external depth first iterators...
+template <class T, class SetTy = std::set<typename GraphTraits<T>::NodeType*> >
+struct df_ext_iterator : public df_iterator<T, SetTy, true> {
+ df_ext_iterator(const df_iterator<T, SetTy, true> &V)
+ : df_iterator<T, SetTy, true>(V) {}
+};
+
+template <class T, class SetTy>
+df_ext_iterator<T, SetTy> df_ext_begin(T G, SetTy &S) {
+ return df_ext_iterator<T, SetTy>::begin(G, S);
+}
+
+template <class T, class SetTy>
+df_ext_iterator<T, SetTy> df_ext_end(T G, SetTy &S) {
+ return df_ext_iterator<T, SetTy>::end(G, S);
+}
+
+
+// Provide global definitions of inverse depth first iterators...
+template <class T,
+ class SetTy = llvm::SmallPtrSet<typename GraphTraits<T>::NodeType*, 8>,
+ bool External = false>
+struct idf_iterator : public df_iterator<Inverse<T>, SetTy, External> {
+ idf_iterator(const df_iterator<Inverse<T>, SetTy, External> &V)
+ : df_iterator<Inverse<T>, SetTy, External>(V) {}
+};
+
+template <class T>
+idf_iterator<T> idf_begin(T G) {
+ return idf_iterator<T>::begin(G);
+}
+
+template <class T>
+idf_iterator<T> idf_end(T G){
+ return idf_iterator<T>::end(G);
+}
+
+// Provide global definitions of external inverse depth first iterators...
+template <class T, class SetTy = std::set<typename GraphTraits<T>::NodeType*> >
+struct idf_ext_iterator : public idf_iterator<T, SetTy, true> {
+ idf_ext_iterator(const idf_iterator<T, SetTy, true> &V)
+ : idf_iterator<T, SetTy, true>(V) {}
+ idf_ext_iterator(const df_iterator<Inverse<T>, SetTy, true> &V)
+ : idf_iterator<T, SetTy, true>(V) {}
+};
+
+template <class T, class SetTy>
+idf_ext_iterator<T, SetTy> idf_ext_begin(T G, SetTy &S) {
+ return idf_ext_iterator<T, SetTy>::begin(G, S);
+}
+
+template <class T, class SetTy>
+idf_ext_iterator<T, SetTy> idf_ext_end(T G, SetTy &S) {
+ return idf_ext_iterator<T, SetTy>::end(G, S);
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/support/include/llvm/ADT/EquivalenceClasses.h b/support/include/llvm/ADT/EquivalenceClasses.h
new file mode 100644
index 0000000..7d305cb
--- /dev/null
+++ b/support/include/llvm/ADT/EquivalenceClasses.h
@@ -0,0 +1,279 @@
+//===-- llvm/ADT/EquivalenceClasses.h - Generic Equiv. Classes --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Generic implementation of equivalence classes through the use Tarjan's
+// efficient union-find algorithm.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_EQUIVALENCECLASSES_H
+#define LLVM_ADT_EQUIVALENCECLASSES_H
+
+#include "llvm/ADT/iterator"
+#include "llvm/Support/DataTypes.h"
+#include <set>
+
+namespace llvm {
+
+/// EquivalenceClasses - This represents a collection of equivalence classes and
+/// supports three efficient operations: insert an element into a class of its
+/// own, union two classes, and find the class for a given element. In
+/// addition to these modification methods, it is possible to iterate over all
+/// of the equivalence classes and all of the elements in a class.
+///
+/// This implementation is an efficient implementation that only stores one copy
+/// of the element being indexed per entry in the set, and allows any arbitrary
+/// type to be indexed (as long as it can be ordered with operator<).
+///
+/// Here is a simple example using integers:
+///
+/// EquivalenceClasses<int> EC;
+/// EC.unionSets(1, 2); // insert 1, 2 into the same set
+/// EC.insert(4); EC.insert(5); // insert 4, 5 into own sets
+/// EC.unionSets(5, 1); // merge the set for 1 with 5's set.
+///
+/// for (EquivalenceClasses<int>::iterator I = EC.begin(), E = EC.end();
+/// I != E; ++I) { // Iterate over all of the equivalence sets.
+/// if (!I->isLeader()) continue; // Ignore non-leader sets.
+/// for (EquivalenceClasses<int>::member_iterator MI = EC.member_begin(I);
+/// MI != EC.member_end(); ++MI) // Loop over members in this set.
+/// cerr << *MI << " "; // Print member.
+/// cerr << "\n"; // Finish set.
+/// }
+///
+/// This example prints:
+/// 4
+/// 5 1 2
+///
+template <class ElemTy>
+class EquivalenceClasses {
+ /// ECValue - The EquivalenceClasses data structure is just a set of these.
+ /// Each of these represents a relation for a value. First it stores the
+ /// value itself, which provides the ordering that the set queries. Next, it
+ /// provides a "next pointer", which is used to enumerate all of the elements
+ /// in the unioned set. Finally, it defines either a "end of list pointer" or
+ /// "leader pointer" depending on whether the value itself is a leader. A
+ /// "leader pointer" points to the node that is the leader for this element,
+ /// if the node is not a leader. A "end of list pointer" points to the last
+ /// node in the list of members of this list. Whether or not a node is a
+ /// leader is determined by a bit stolen from one of the pointers.
+ class ECValue {
+ friend class EquivalenceClasses;
+ mutable const ECValue *Leader, *Next;
+ ElemTy Data;
+ // ECValue ctor - Start out with EndOfList pointing to this node, Next is
+ // Null, isLeader = true.
+ ECValue(const ElemTy &Elt)
+ : Leader(this), Next((ECValue*)(intptr_t)1), Data(Elt) {}
+
+ const ECValue *getLeader() const {
+ if (isLeader()) return this;
+ if (Leader->isLeader()) return Leader;
+ // Path compression.
+ return Leader = Leader->getLeader();
+ }
+ const ECValue *getEndOfList() const {
+ assert(isLeader() && "Cannot get the end of a list for a non-leader!");
+ return Leader;
+ }
+
+ void setNext(const ECValue *NewNext) const {
+ assert(getNext() == 0 && "Already has a next pointer!");
+ Next = (const ECValue*)((intptr_t)NewNext | (intptr_t)isLeader());
+ }
+ public:
+ ECValue(const ECValue &RHS) : Leader(this), Next((ECValue*)(intptr_t)1),
+ Data(RHS.Data) {
+ // Only support copying of singleton nodes.
+ assert(RHS.isLeader() && RHS.getNext() == 0 && "Not a singleton!");
+ }
+
+ bool operator<(const ECValue &UFN) const { return Data < UFN.Data; }
+
+ bool isLeader() const { return (intptr_t)Next & 1; }
+ const ElemTy &getData() const { return Data; }
+
+ const ECValue *getNext() const {
+ return (ECValue*)((intptr_t)Next & ~(intptr_t)1);
+ }
+
+ template<typename T>
+ bool operator<(const T &Val) const { return Data < Val; }
+ };
+
+ /// TheMapping - This implicitly provides a mapping from ElemTy values to the
+ /// ECValues, it just keeps the key as part of the value.
+ std::set<ECValue> TheMapping;
+
+public:
+ EquivalenceClasses() {}
+ EquivalenceClasses(const EquivalenceClasses &RHS) {
+ operator=(RHS);
+ }
+
+ const EquivalenceClasses &operator=(const EquivalenceClasses &RHS) {
+ TheMapping.clear();
+ for (iterator I = RHS.begin(), E = RHS.end(); I != E; ++I)
+ if (I->isLeader()) {
+ member_iterator MI = RHS.member_begin(I);
+ member_iterator LeaderIt = member_begin(insert(*MI));
+ for (++MI; MI != member_end(); ++MI)
+ unionSets(LeaderIt, member_begin(insert(*MI)));
+ }
+ return *this;
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Inspection methods
+ //
+
+ /// iterator* - Provides a way to iterate over all values in the set.
+ typedef typename std::set<ECValue>::const_iterator iterator;
+ iterator begin() const { return TheMapping.begin(); }
+ iterator end() const { return TheMapping.end(); }
+
+ bool empty() const { return TheMapping.empty(); }
+
+ /// member_* Iterate over the members of an equivalence class.
+ ///
+ class member_iterator;
+ member_iterator member_begin(iterator I) const {
+ // Only leaders provide anything to iterate over.
+ return member_iterator(I->isLeader() ? &*I : 0);
+ }
+ member_iterator member_end() const {
+ return member_iterator(0);
+ }
+
+ /// findValue - Return an iterator to the specified value. If it does not
+ /// exist, end() is returned.
+ iterator findValue(const ElemTy &V) const {
+ return TheMapping.find(V);
+ }
+
+ /// getLeaderValue - Return the leader for the specified value that is in the
+ /// set. It is an error to call this method for a value that is not yet in
+ /// the set. For that, call getOrInsertLeaderValue(V).
+ const ElemTy &getLeaderValue(const ElemTy &V) const {
+ member_iterator MI = findLeader(V);
+ assert(MI != member_end() && "Value is not in the set!");
+ return *MI;
+ }
+
+ /// getOrInsertLeaderValue - Return the leader for the specified value that is
+ /// in the set. If the member is not in the set, it is inserted, then
+ /// returned.
+ const ElemTy &getOrInsertLeaderValue(const ElemTy &V) const {
+ member_iterator MI = findLeader(insert(V));
+ assert(MI != member_end() && "Value is not in the set!");
+ return *MI;
+ }
+
+ /// getNumClasses - Return the number of equivalence classes in this set.
+ /// Note that this is a linear time operation.
+ unsigned getNumClasses() const {
+ unsigned NC = 0;
+ for (iterator I = begin(), E = end(); I != E; ++I)
+ if (I->isLeader()) ++NC;
+ return NC;
+ }
+
+
+ //===--------------------------------------------------------------------===//
+ // Mutation methods
+
+ /// insert - Insert a new value into the union/find set, ignoring the request
+ /// if the value already exists.
+ iterator insert(const ElemTy &Data) {
+ return TheMapping.insert(Data).first;
+ }
+
+ /// findLeader - Given a value in the set, return a member iterator for the
+ /// equivalence class it is in. This does the path-compression part that
+ /// makes union-find "union findy". This returns an end iterator if the value
+ /// is not in the equivalence class.
+ ///
+ member_iterator findLeader(iterator I) const {
+ if (I == TheMapping.end()) return member_end();
+ return member_iterator(I->getLeader());
+ }
+ member_iterator findLeader(const ElemTy &V) const {
+ return findLeader(TheMapping.find(V));
+ }
+
+
+ /// union - Merge the two equivalence sets for the specified values, inserting
+ /// them if they do not already exist in the equivalence set.
+ member_iterator unionSets(const ElemTy &V1, const ElemTy &V2) {
+ iterator V1I = insert(V1), V2I = insert(V2);
+ return unionSets(findLeader(V1I), findLeader(V2I));
+ }
+ member_iterator unionSets(member_iterator L1, member_iterator L2) {
+ assert(L1 != member_end() && L2 != member_end() && "Illegal inputs!");
+ if (L1 == L2) return L1; // Unifying the same two sets, noop.
+
+ // Otherwise, this is a real union operation. Set the end of the L1 list to
+ // point to the L2 leader node.
+ const ECValue &L1LV = *L1.Node, &L2LV = *L2.Node;
+ L1LV.getEndOfList()->setNext(&L2LV);
+
+ // Update L1LV's end of list pointer.
+ L1LV.Leader = L2LV.getEndOfList();
+
+ // Clear L2's leader flag:
+ L2LV.Next = L2LV.getNext();
+
+ // L2's leader is now L1.
+ L2LV.Leader = &L1LV;
+ return L1;
+ }
+
+ class member_iterator : public forward_iterator<ElemTy, ptrdiff_t> {
+ typedef forward_iterator<const ElemTy, ptrdiff_t> super;
+ const ECValue *Node;
+ friend class EquivalenceClasses;
+ public:
+ typedef size_t size_type;
+ typedef typename super::pointer pointer;
+ typedef typename super::reference reference;
+
+ explicit member_iterator() {}
+ explicit member_iterator(const ECValue *N) : Node(N) {}
+ member_iterator(const member_iterator &I) : Node(I.Node) {}
+
+ reference operator*() const {
+ assert(Node != 0 && "Dereferencing end()!");
+ return Node->getData();
+ }
+ reference operator->() const { return operator*(); }
+
+ member_iterator &operator++() {
+ assert(Node != 0 && "++'d off the end of the list!");
+ Node = Node->getNext();
+ return *this;
+ }
+
+ member_iterator operator++(int) { // postincrement operators.
+ member_iterator tmp = *this;
+ ++*this;
+ return tmp;
+ }
+
+ bool operator==(const member_iterator &RHS) const {
+ return Node == RHS.Node;
+ }
+ bool operator!=(const member_iterator &RHS) const {
+ return Node != RHS.Node;
+ }
+ };
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/support/include/llvm/ADT/FoldingSet.h b/support/include/llvm/ADT/FoldingSet.h
new file mode 100644
index 0000000..2a7b802
--- /dev/null
+++ b/support/include/llvm/ADT/FoldingSet.h
@@ -0,0 +1,315 @@
+//===-- llvm/ADT/FoldingSet.h - Uniquing Hash Set ---------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by James M. Laskey and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines a hash set that can be used to remove duplication of nodes
+// in a graph. This code was originally created by Chris Lattner for use with
+// SelectionDAGCSEMap, but was isolated to provide use across the llvm code set.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_FOLDINGSET_H
+#define LLVM_ADT_FOLDINGSET_H
+
+#include "llvm/Support/DataTypes.h"
+#include "llvm/ADT/SmallVector.h"
+#include <string>
+
+namespace llvm {
+ class APFloat;
+
+/// This folding set used for two purposes:
+/// 1. Given information about a node we want to create, look up the unique
+/// instance of the node in the set. If the node already exists, return
+/// it, otherwise return the bucket it should be inserted into.
+/// 2. Given a node that has already been created, remove it from the set.
+///
+/// This class is implemented as a single-link chained hash table, where the
+/// "buckets" are actually the nodes themselves (the next pointer is in the
+/// node). The last node points back to the bucket to simplified node removal.
+///
+/// Any node that is to be included in the folding set must be a subclass of
+/// FoldingSetNode. The node class must also define a Profile method used to
+/// establish the unique bits of data for the node. The Profile method is
+/// passed a FoldingSetNodeID object which is used to gather the bits. Just
+/// call one of the Add* functions defined in the FoldingSetImpl::NodeID class.
+/// NOTE: That the folding set does not own the nodes and it is the
+/// responsibility of the user to dispose of the nodes.
+///
+/// Eg.
+/// class MyNode : public FoldingSetNode {
+/// private:
+/// std::string Name;
+/// unsigned Value;
+/// public:
+/// MyNode(const char *N, unsigned V) : Name(N), Value(V) {}
+/// ...
+/// void Profile(FoldingSetNodeID &ID) {
+/// ID.AddString(Name);
+/// ID.AddInteger(Value);
+/// }
+/// ...
+/// };
+///
+/// To define the folding set itself use the FoldingSet template;
+///
+/// Eg.
+/// FoldingSet<MyNode> MyFoldingSet;
+///
+/// Four public methods are available to manipulate the folding set;
+///
+/// 1) If you have an existing node that you want add to the set but unsure
+/// that the node might already exist then call;
+///
+/// MyNode *M = MyFoldingSet.GetOrInsertNode(N);
+///
+/// If The result is equal to the input then the node has been inserted.
+/// Otherwise, the result is the node existing in the folding set, and the
+/// input can be discarded (use the result instead.)
+///
+/// 2) If you are ready to construct a node but want to check if it already
+/// exists, then call FindNodeOrInsertPos with a FoldingSetNodeID of the bits to
+/// check;
+///
+/// FoldingSetNodeID ID;
+/// ID.AddString(Name);
+/// ID.AddInteger(Value);
+/// void *InsertPoint;
+///
+/// MyNode *M = MyFoldingSet.FindNodeOrInsertPos(ID, InsertPoint);
+///
+/// If found then M with be non-NULL, else InsertPoint will point to where it
+/// should be inserted using InsertNode.
+///
+/// 3) If you get a NULL result from FindNodeOrInsertPos then you can as a new
+/// node with FindNodeOrInsertPos;
+///
+/// InsertNode(N, InsertPoint);
+///
+/// 4) Finally, if you want to remove a node from the folding set call;
+///
+/// bool WasRemoved = RemoveNode(N);
+///
+/// The result indicates whether the node existed in the folding set.
+
+
+//===----------------------------------------------------------------------===//
+/// FoldingSetImpl - Implements the folding set functionality. The main
+/// structure is an array of buckets. Each bucket is indexed by the hash of
+/// the nodes it contains. The bucket itself points to the nodes contained
+/// in the bucket via a singly linked list. The last node in the list points
+/// back to the bucket to facilitate node removal.
+///
+class FoldingSetImpl {
+protected:
+ /// Buckets - Array of bucket chains.
+ ///
+ void **Buckets;
+
+ /// NumBuckets - Length of the Buckets array. Always a power of 2.
+ ///
+ unsigned NumBuckets;
+
+ /// NumNodes - Number of nodes in the folding set. Growth occurs when NumNodes
+ /// is greater than twice the number of buckets.
+ unsigned NumNodes;
+
+public:
+ explicit FoldingSetImpl(unsigned Log2InitSize = 6);
+ virtual ~FoldingSetImpl();
+
+ // Forward declaration.
+ class Node;
+
+ //===--------------------------------------------------------------------===//
+ /// NodeID - This class is used to gather all the unique data bits of a
+ /// node. When all the bits are gathered this class is used to produce a
+ /// hash value for the node.
+ ///
+ class NodeID {
+ /// Bits - Vector of all the data bits that make the node unique.
+ /// Use a SmallVector to avoid a heap allocation in the common case.
+ SmallVector<unsigned, 32> Bits;
+
+ public:
+ NodeID() {}
+
+ /// getRawData - Return the ith entry in the Bits data.
+ ///
+ unsigned getRawData(unsigned i) const {
+ return Bits[i];
+ }
+
+ /// Add* - Add various data types to Bit data.
+ ///
+ void AddPointer(const void *Ptr);
+ void AddInteger(signed I);
+ void AddInteger(unsigned I);
+ void AddInteger(int64_t I);
+ void AddInteger(uint64_t I);
+ void AddFloat(float F);
+ void AddDouble(double D);
+ void AddAPFloat(const APFloat& apf);
+ void AddString(const std::string &String);
+
+ /// ComputeHash - Compute a strong hash value for this NodeID, used to
+ /// lookup the node in the FoldingSetImpl.
+ unsigned ComputeHash() const;
+
+ /// operator== - Used to compare two nodes to each other.
+ ///
+ bool operator==(const NodeID &RHS) const;
+ };
+
+ //===--------------------------------------------------------------------===//
+ /// Node - This class is used to maintain the singly linked bucket list in
+ /// a folding set.
+ ///
+ class Node {
+ private:
+ // NextInFoldingSetBucket - next link in the bucket list.
+ void *NextInFoldingSetBucket;
+
+ public:
+
+ Node() : NextInFoldingSetBucket(0) {}
+
+ // Accessors
+ void *getNextInBucket() const { return NextInFoldingSetBucket; }
+ void SetNextInBucket(void *N) { NextInFoldingSetBucket = N; }
+ };
+
+ /// RemoveNode - Remove a node from the folding set, returning true if one
+ /// was removed or false if the node was not in the folding set.
+ bool RemoveNode(Node *N);
+
+ /// GetOrInsertNode - If there is an existing simple Node exactly
+ /// equal to the specified node, return it. Otherwise, insert 'N' and return
+ /// it instead.
+ Node *GetOrInsertNode(Node *N);
+
+ /// FindNodeOrInsertPos - Look up the node specified by ID. If it exists,
+ /// return it. If not, return the insertion token that will make insertion
+ /// faster.
+ Node *FindNodeOrInsertPos(const NodeID &ID, void *&InsertPos);
+
+ /// InsertNode - Insert the specified node into the folding set, knowing that
+ /// it is not already in the folding set. InsertPos must be obtained from
+ /// FindNodeOrInsertPos.
+ void InsertNode(Node *N, void *InsertPos);
+
+ /// size - Returns the number of nodes in the folding set.
+ unsigned size() const { return NumNodes; }
+
+private:
+
+ /// GrowHashTable - Double the size of the hash table and rehash everything.
+ ///
+ void GrowHashTable();
+
+protected:
+
+ /// GetNodeProfile - Instantiations of the FoldingSet template implement
+ /// this function to gather data bits for the given node.
+ virtual void GetNodeProfile(NodeID &ID, Node *N) const = 0;
+};
+
+// Convenience types to hide the implementation of the folding set.
+typedef FoldingSetImpl::Node FoldingSetNode;
+typedef FoldingSetImpl::NodeID FoldingSetNodeID;
+
+template<class T> class FoldingSetIterator;
+
+//===----------------------------------------------------------------------===//
+/// FoldingSet - This template class is used to instantiate a specialized
+/// implementation of the folding set to the node class T. T must be a
+/// subclass of FoldingSetNode and implement a Profile function.
+///
+template<class T> class FoldingSet : public FoldingSetImpl {
+private:
+ /// GetNodeProfile - Each instantiatation of the FoldingSet needs to provide a
+ /// way to convert nodes into a unique specifier.
+ virtual void GetNodeProfile(NodeID &ID, Node *N) const {
+ T *TN = static_cast<T *>(N);
+ TN->Profile(ID);
+ }
+
+public:
+ explicit FoldingSet(unsigned Log2InitSize = 6)
+ : FoldingSetImpl(Log2InitSize)
+ {}
+
+ typedef FoldingSetIterator<T> iterator;
+ iterator begin() { return iterator(Buckets); }
+ iterator end() { return iterator(Buckets+NumBuckets); }
+
+ typedef FoldingSetIterator<const T> const_iterator;
+ const_iterator begin() const { return const_iterator(Buckets); }
+ const_iterator end() const { return const_iterator(Buckets+NumBuckets); }
+
+ /// GetOrInsertNode - If there is an existing simple Node exactly
+ /// equal to the specified node, return it. Otherwise, insert 'N' and
+ /// return it instead.
+ T *GetOrInsertNode(Node *N) {
+ return static_cast<T *>(FoldingSetImpl::GetOrInsertNode(N));
+ }
+
+ /// FindNodeOrInsertPos - Look up the node specified by ID. If it exists,
+ /// return it. If not, return the insertion token that will make insertion
+ /// faster.
+ T *FindNodeOrInsertPos(const FoldingSetNodeID &ID, void *&InsertPos) {
+ return static_cast<T *>(FoldingSetImpl::FindNodeOrInsertPos(ID, InsertPos));
+ }
+};
+
+//===----------------------------------------------------------------------===//
+/// FoldingSetIteratorImpl - This is the common iterator support shared by all
+/// folding sets, which knows how to walk the folding set hash table.
+class FoldingSetIteratorImpl {
+protected:
+ FoldingSetNode *NodePtr;
+ FoldingSetIteratorImpl(void **Bucket);
+ void advance();
+
+public:
+ bool operator==(const FoldingSetIteratorImpl &RHS) const {
+ return NodePtr == RHS.NodePtr;
+ }
+ bool operator!=(const FoldingSetIteratorImpl &RHS) const {
+ return NodePtr != RHS.NodePtr;
+ }
+};
+
+
+template<class T>
+class FoldingSetIterator : public FoldingSetIteratorImpl {
+public:
+ FoldingSetIterator(void **Bucket) : FoldingSetIteratorImpl(Bucket) {}
+
+ T &operator*() const {
+ return *static_cast<T*>(NodePtr);
+ }
+
+ T *operator->() const {
+ return static_cast<T*>(NodePtr);
+ }
+
+ inline FoldingSetIterator& operator++() { // Preincrement
+ advance();
+ return *this;
+ }
+ FoldingSetIterator operator++(int) { // Postincrement
+ FoldingSetIterator tmp = *this; ++*this; return tmp;
+ }
+};
+
+} // End of namespace llvm.
+
+
+#endif
+
diff --git a/support/include/llvm/ADT/GraphTraits.h b/support/include/llvm/ADT/GraphTraits.h
new file mode 100644
index 0000000..853615e
--- /dev/null
+++ b/support/include/llvm/ADT/GraphTraits.h
@@ -0,0 +1,103 @@
+//===-- llvm/ADT/GraphTraits.h - Graph traits template ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the little GraphTraits<X> template class that should be
+// specialized by classes that want to be iteratable by generic graph iterators.
+//
+// This file also defines the marker class Inverse that is used to iterate over
+// graphs in a graph defined, inverse ordering...
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_GRAPHTRAITS_H
+#define LLVM_ADT_GRAPHTRAITS_H
+
+namespace llvm {
+
+// GraphTraits - This class should be specialized by different graph types...
+// which is why the default version is empty.
+//
+template<class GraphType>
+struct GraphTraits {
+ // Elements to provide:
+
+ // typedef NodeType - Type of Node in the graph
+ // typedef ChildIteratorType - Type used to iterate over children in graph
+
+ // static NodeType *getEntryNode(GraphType *)
+ // Return the entry node of the graph
+
+ // static ChildIteratorType child_begin(NodeType *)
+ // static ChildIteratorType child_end (NodeType *)
+ // Return iterators that point to the beginning and ending of the child
+ // node list for the specified node.
+ //
+
+
+ // typedef ...iterator nodes_iterator;
+ // static nodes_iterator nodes_begin(GraphType *G)
+ // static nodes_iterator nodes_end (GraphType *G)
+ //
+ // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
+
+
+ // If anyone tries to use this class without having an appropriate
+ // specialization, make an error. If you get this error, it's because you
+ // need to include the appropriate specialization of GraphTraits<> for your
+ // graph, or you need to define it for a new graph type. Either that or
+ // your argument to XXX_begin(...) is unknown or needs to have the proper .h
+ // file #include'd.
+ //
+ typedef typename GraphType::UnknownGraphTypeError NodeType;
+};
+
+
+// Inverse - This class is used as a little marker class to tell the graph
+// iterator to iterate over the graph in a graph defined "Inverse" ordering.
+// Not all graphs define an inverse ordering, and if they do, it depends on
+// the graph exactly what that is. Here's an example of usage with the
+// df_iterator:
+//
+// idf_iterator<Method*> I = idf_begin(M), E = idf_end(M);
+// for (; I != E; ++I) { ... }
+//
+// Which is equivalent to:
+// df_iterator<Inverse<Method*> > I = idf_begin(M), E = idf_end(M);
+// for (; I != E; ++I) { ... }
+//
+template <class GraphType>
+struct Inverse {
+ GraphType &Graph;
+
+ inline Inverse(GraphType &G) : Graph(G) {}
+};
+
+// Provide a partial specialization of GraphTraits so that the inverse of an inverse
+// falls back to the original graph.
+template<class T>
+struct GraphTraits<Inverse<Inverse<T> > > {
+ typedef typename GraphTraits<T>::NodeType NodeType;
+ typedef typename GraphTraits<T>::ChildIteratorType ChildIteratorType;
+
+ static NodeType *getEntryNode(Inverse<Inverse<T> > *G) {
+ return GraphTraits<T>::getEntryNode(G.Graph.Graph);
+ }
+
+ static ChildIteratorType child_begin(NodeType* N) {
+ return GraphTraits<T>::child_begin(N);
+ }
+
+ static ChildIteratorType child_end(NodeType* N) {
+ return GraphTraits<T>::child_end(N);
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/support/include/llvm/ADT/HashExtras.h b/support/include/llvm/ADT/HashExtras.h
new file mode 100644
index 0000000..9993248
--- /dev/null
+++ b/support/include/llvm/ADT/HashExtras.h
@@ -0,0 +1,41 @@
+//===-- llvm/ADT/HashExtras.h - Useful functions for STL hash ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains some templates that are useful if you are working with the
+// STL Hashed containers.
+//
+// No library is required when using these functinons.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_HASHEXTRAS_H
+#define LLVM_ADT_HASHEXTRAS_H
+
+#include "llvm/ADT/hash_map"
+#include <string>
+
+// Cannot specialize hash template from outside of the std namespace.
+namespace HASH_NAMESPACE {
+
+// Provide a hash function for arbitrary pointers...
+template <class T> struct hash<T *> {
+ inline size_t operator()(const T *Val) const {
+ return reinterpret_cast<size_t>(Val);
+ }
+};
+
+template <> struct hash<std::string> {
+ size_t operator()(std::string const &str) const {
+ return hash<char const *>()(str.c_str());
+ }
+};
+
+} // End namespace std
+
+#endif
diff --git a/support/include/llvm/ADT/ImmutableMap.h b/support/include/llvm/ADT/ImmutableMap.h
new file mode 100644
index 0000000..c9dafda
--- /dev/null
+++ b/support/include/llvm/ADT/ImmutableMap.h
@@ -0,0 +1,163 @@
+//===--- ImmutableMap.h - Immutable (functional) map interface --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Ted Kremenek and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the ImmutableMap class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_IMMAP_H
+#define LLVM_ADT_IMMAP_H
+
+#include "llvm/ADT/ImmutableSet.h"
+
+namespace llvm {
+
+/// ImutKeyValueInfo -Traits class used by ImmutableMap. While both the first and
+/// second elements in a pair are used to generate profile information,
+/// only the first element (the key) is used by isEqual and isLess.
+template <typename T, typename S>
+struct ImutKeyValueInfo {
+ typedef const std::pair<T,S> value_type;
+ typedef const value_type& value_type_ref;
+ typedef const T key_type;
+ typedef const T& key_type_ref;
+ typedef const S data_type;
+ typedef const S& data_type_ref;
+
+ static inline key_type_ref KeyOfValue(value_type_ref V) {
+ return V.first;
+ }
+
+ static inline bool isEqual(key_type_ref L, key_type_ref R) {
+ return ImutContainerInfo<T>::isEqual(L,R);
+ }
+
+ static inline bool isLess(key_type_ref L, key_type_ref R) {
+ return ImutContainerInfo<T>::isLess(L,R);
+ }
+
+ static inline void Profile(FoldingSetNodeID& ID, value_type_ref V) {
+ ImutContainerInfo<T>::Profile(ID, V.first);
+ ImutContainerInfo<S>::Profile(ID, V.second);
+ }
+};
+
+
+template <typename KeyT, typename ValT,
+ typename ValInfo = ImutKeyValueInfo<KeyT,ValT> >
+class ImmutableMap {
+ typedef typename ValInfo::value_type value_type;
+ typedef typename ValInfo::value_type_ref value_type_ref;
+ typedef typename ValInfo::key_type key_type;
+ typedef typename ValInfo::key_type_ref key_type_ref;
+ typedef typename ValInfo::data_type data_type;
+ typedef typename ValInfo::data_type_ref data_type_ref;
+
+private:
+ typedef ImutAVLTree<ValInfo> TreeTy;
+ TreeTy* Root;
+
+ ImmutableMap(TreeTy* R) : Root(R) {}
+
+public:
+
+ class Factory {
+ typename TreeTy::Factory F;
+
+ public:
+ Factory() {}
+
+ ImmutableMap GetEmptyMap() { return ImmutableMap(F.GetEmptyTree()); }
+
+ ImmutableMap Add(ImmutableMap Old, key_type_ref K, data_type_ref D) {
+ return ImmutableMap(F.Add(Old.Root,std::make_pair<key_type,data_type>(K,D)));
+ }
+
+ ImmutableMap Remove(ImmutableMap Old, key_type_ref K) {
+ return ImmutableMap(F.Remove(Old.Root,K));
+ }
+
+ private:
+ Factory(const Factory& RHS) {};
+ void operator=(const Factory& RHS) {};
+ };
+
+ friend class Factory;
+
+ bool contains(key_type_ref K) const {
+ return Root ? Root->contains(K) : false;
+ }
+
+ data_type* find(key_type_ref K) const {
+ if (Root) {
+ TreeTy* T = Root->find(K);
+ if (T) return &T->getValue().second;
+ }
+
+ return NULL;
+ }
+
+ bool operator==(ImmutableMap RHS) const {
+ return Root && RHS.Root ? Root->isEqual(*RHS.Root) : Root == RHS.Root;
+ }
+
+ bool operator!=(ImmutableMap RHS) const {
+ return Root && RHS.Root ? Root->isNotEqual(*RHS.Root) : Root != RHS.Root;
+ }
+
+ bool isEmpty() const { return !Root; }
+
+ //===--------------------------------------------------===//
+ // Foreach - A limited form of map iteration.
+ //===--------------------------------------------------===//
+
+private:
+ template <typename Callback>
+ struct CBWrapper {
+ Callback C;
+ void operator()(value_type_ref V) { C(V.first,V.second); }
+ };
+
+ template <typename Callback>
+ struct CBWrapperRef {
+ Callback &C;
+ CBWrapperRef(Callback& c) : C(c) {}
+
+ void operator()(value_type_ref V) { C(V.first,V.second); }
+ };
+
+public:
+ template <typename Callback>
+ void foreach(Callback& C) {
+ if (Root) {
+ CBWrapperRef<Callback> CB(C);
+ Root->foreach(CB);
+ }
+ }
+
+ template <typename Callback>
+ void foreach() {
+ if (Root) {
+ CBWrapper<Callback> CB;
+ Root->foreach(CB);
+ }
+ }
+
+ //===--------------------------------------------------===//
+ // For testing.
+ //===--------------------------------------------------===//
+
+ void verify() const { if (Root) Root->verify(); }
+ unsigned getHeight() const { return Root ? Root->getHeight() : 0; }
+
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/support/include/llvm/ADT/ImmutableSet.h b/support/include/llvm/ADT/ImmutableSet.h
new file mode 100644
index 0000000..c33717a
--- /dev/null
+++ b/support/include/llvm/ADT/ImmutableSet.h
@@ -0,0 +1,922 @@
+//===--- ImmutableSet.h - Immutable (functional) set interface --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Ted Kremenek and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the ImutAVLTree and ImmutableSet classes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_IMSET_H
+#define LLVM_ADT_IMSET_H
+
+#include "llvm/Support/Allocator.h"
+#include "llvm/ADT/FoldingSet.h"
+#include <cassert>
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+// Immutable AVL-Tree Definition.
+//===----------------------------------------------------------------------===//
+
+template <typename ImutInfo> class ImutAVLFactory;
+
+template <typename ImutInfo> class ImutAVLTreeInOrderIterator;
+
+template <typename ImutInfo >
+class ImutAVLTree : public FoldingSetNode {
+public:
+ typedef typename ImutInfo::key_type_ref key_type_ref;
+ typedef typename ImutInfo::value_type value_type;
+ typedef typename ImutInfo::value_type_ref value_type_ref;
+
+ typedef ImutAVLFactory<ImutInfo> Factory;
+ friend class ImutAVLFactory<ImutInfo>;
+
+ typedef ImutAVLTreeInOrderIterator<ImutInfo> iterator;
+
+ //===----------------------------------------------------===//
+ // Public Interface.
+ //===----------------------------------------------------===//
+
+ /// getLeft - Returns a pointer to the left subtree. This value
+ /// is NULL if there is no left subtree.
+ ImutAVLTree* getLeft() const {
+ assert (!isMutable() && "Node is incorrectly marked mutable.");
+
+ return reinterpret_cast<ImutAVLTree*>(Left);
+ }
+
+ /// getRight - Returns a pointer to the right subtree. This value is
+ /// NULL if there is no right subtree.
+ ImutAVLTree* getRight() const { return Right; }
+
+
+ /// getHeight - Returns the height of the tree. A tree with no subtrees
+ /// has a height of 1.
+ unsigned getHeight() const { return Height; }
+
+ /// getValue - Returns the data value associated with the tree node.
+ const value_type& getValue() const { return Value; }
+
+ /// find - Finds the subtree associated with the specified key value.
+ /// This method returns NULL if no matching subtree is found.
+ ImutAVLTree* find(key_type_ref K) {
+ ImutAVLTree *T = this;
+
+ while (T) {
+ key_type_ref CurrentKey = ImutInfo::KeyOfValue(T->getValue());
+
+ if (ImutInfo::isEqual(K,CurrentKey))
+ return T;
+ else if (ImutInfo::isLess(K,CurrentKey))
+ T = T->getLeft();
+ else
+ T = T->getRight();
+ }
+
+ return NULL;
+ }
+
+ /// size - Returns the number of nodes in the tree, which includes
+ /// both leaves and non-leaf nodes.
+ unsigned size() const {
+ unsigned n = 1;
+
+ if (const ImutAVLTree* L = getLeft()) n += L->size();
+ if (const ImutAVLTree* R = getRight()) n += R->size();
+
+ return n;
+ }
+
+ /// begin - Returns an iterator that iterates over the nodes of the tree
+ /// in an inorder traversal. The returned iterator thus refers to the
+ /// the tree node with the minimum data element.
+ iterator begin() const { return iterator(this); }
+
+ /// end - Returns an iterator for the tree that denotes the end of an
+ /// inorder traversal.
+ iterator end() const { return iterator(); }
+
+ /// isEqual - Compares two trees for structural equality and returns true
+ /// if they are equal. This worst case performance of this operation is
+ // linear in the sizes of the trees.
+ bool isEqual(const ImutAVLTree& RHS) const {
+ if (&RHS == this)
+ return true;
+
+ iterator LItr = begin(), LEnd = end();
+ iterator RItr = RHS.begin(), REnd = RHS.end();
+
+ while (LItr != LEnd && RItr != REnd) {
+ if (*LItr == *RItr) {
+ LItr.SkipSubTree();
+ RItr.SkipSubTree();
+ continue;
+ }
+
+ // FIXME: need to compare data values, not key values, but our
+ // traits don't support this yet.
+ if (!ImutInfo::isEqual(ImutInfo::KeyOfValue(LItr->getValue()),
+ ImutInfo::KeyOfValue(RItr->getValue())))
+ return false;
+
+ ++LItr;
+ ++RItr;
+ }
+
+ return LItr == LEnd && RItr == REnd;
+ }
+
+ /// isNotEqual - Compares two trees for structural inequality. Performance
+ /// is the same is isEqual.
+ bool isNotEqual(const ImutAVLTree& RHS) const { return !isEqual(RHS); }
+
+ /// contains - Returns true if this tree contains a subtree (node) that
+ /// has an data element that matches the specified key. Complexity
+ /// is logarithmic in the size of the tree.
+ bool contains(const key_type_ref K) { return (bool) find(K); }
+
+ /// foreach - A member template the accepts invokes operator() on a functor
+ /// object (specifed by Callback) for every node/subtree in the tree.
+ /// Nodes are visited using an inorder traversal.
+ template <typename Callback>
+ void foreach(Callback& C) {
+ if (ImutAVLTree* L = getLeft()) L->foreach(C);
+
+ C(Value);
+
+ if (ImutAVLTree* R = getRight()) R->foreach(C);
+ }
+
+ /// verify - A utility method that checks that the balancing and
+ /// ordering invariants of the tree are satisifed. It is a recursive
+ /// method that returns the height of the tree, which is then consumed
+ /// by the enclosing verify call. External callers should ignore the
+ /// return value. An invalid tree will cause an assertion to fire in
+ /// a debug build.
+ unsigned verify() const {
+ unsigned HL = getLeft() ? getLeft()->verify() : 0;
+ unsigned HR = getRight() ? getRight()->verify() : 0;
+
+ assert (getHeight() == ( HL > HR ? HL : HR ) + 1
+ && "Height calculation wrong.");
+
+ assert ((HL > HR ? HL-HR : HR-HL) <= 2
+ && "Balancing invariant violated.");
+
+
+ assert (!getLeft()
+ || ImutInfo::isLess(ImutInfo::KeyOfValue(getLeft()->getValue()),
+ ImutInfo::KeyOfValue(getValue()))
+ && "Value in left child is not less that current value.");
+
+
+ assert (!getRight()
+ || ImutInfo::isLess(ImutInfo::KeyOfValue(getValue()),
+ ImutInfo::KeyOfValue(getRight()->getValue()))
+ && "Current value is not less that value of right child.");
+
+ return getHeight();
+ }
+
+ //===----------------------------------------------------===//
+ // Internal Values.
+ //===----------------------------------------------------===//
+
+private:
+ uintptr_t Left;
+ ImutAVLTree* Right;
+ unsigned Height;
+ value_type Value;
+
+ //===----------------------------------------------------===//
+ // Profiling or FoldingSet.
+ //===----------------------------------------------------===//
+
+private:
+
+ /// Profile - Generates a FoldingSet profile for a tree node before it is
+ /// created. This is used by the ImutAVLFactory when creating
+ /// trees.
+ static inline
+ void Profile(FoldingSetNodeID& ID, ImutAVLTree* L, ImutAVLTree* R,
+ value_type_ref V) {
+ ID.AddPointer(L);
+ ID.AddPointer(R);
+ ImutInfo::Profile(ID,V);
+ }
+
+public:
+
+ /// Profile - Generates a FoldingSet profile for an existing tree node.
+ void Profile(FoldingSetNodeID& ID) {
+ Profile(ID,getSafeLeft(),getRight(),getValue());
+ }
+
+ //===----------------------------------------------------===//
+ // Internal methods (node manipulation; used by Factory).
+ //===----------------------------------------------------===//
+
+private:
+
+ enum { Mutable = 0x1 };
+
+ /// ImutAVLTree - Internal constructor that is only called by
+ /// ImutAVLFactory.
+ ImutAVLTree(ImutAVLTree* l, ImutAVLTree* r, value_type_ref v, unsigned height)
+ : Left(reinterpret_cast<uintptr_t>(l) | Mutable),
+ Right(r), Height(height), Value(v) {}
+
+
+ /// isMutable - Returns true if the left and right subtree references
+ /// (as well as height) can be changed. If this method returns false,
+ /// the tree is truly immutable. Trees returned from an ImutAVLFactory
+ /// object should always have this method return true. Further, if this
+ /// method returns false for an instance of ImutAVLTree, all subtrees
+ /// will also have this method return false. The converse is not true.
+ bool isMutable() const { return Left & Mutable; }
+
+ /// getSafeLeft - Returns the pointer to the left tree by always masking
+ /// out the mutable bit. This is used internally by ImutAVLFactory,
+ /// as no trees returned to the client should have the mutable flag set.
+ ImutAVLTree* getSafeLeft() const {
+ return reinterpret_cast<ImutAVLTree*>(Left & ~Mutable);
+ }
+
+ //===----------------------------------------------------===//
+ // Mutating operations. A tree root can be manipulated as
+ // long as its reference has not "escaped" from internal
+ // methods of a factory object (see below). When a tree
+ // pointer is externally viewable by client code, the
+ // internal "mutable bit" is cleared to mark the tree
+ // immutable. Note that a tree that still has its mutable
+ // bit set may have children (subtrees) that are themselves
+ // immutable.
+ //===----------------------------------------------------===//
+
+
+ /// MarkImmutable - Clears the mutable flag for a tree. After this happens,
+ /// it is an error to call setLeft(), setRight(), and setHeight(). It
+ /// is also then safe to call getLeft() instead of getSafeLeft().
+ void MarkImmutable() {
+ assert (isMutable() && "Mutable flag already removed.");
+ Left &= ~Mutable;
+ }
+
+ /// setLeft - Changes the reference of the left subtree. Used internally
+ /// by ImutAVLFactory.
+ void setLeft(ImutAVLTree* NewLeft) {
+ assert (isMutable() &&
+ "Only a mutable tree can have its left subtree changed.");
+
+ Left = reinterpret_cast<uintptr_t>(NewLeft) | Mutable;
+ }
+
+ /// setRight - Changes the reference of the right subtree. Used internally
+ /// by ImutAVLFactory.
+ void setRight(ImutAVLTree* NewRight) {
+ assert (isMutable() &&
+ "Only a mutable tree can have its right subtree changed.");
+
+ Right = NewRight;
+ }
+
+ /// setHeight - Changes the height of the tree. Used internally by
+ /// ImutAVLFactory.
+ void setHeight(unsigned h) {
+ assert (isMutable() && "Only a mutable tree can have its height changed.");
+ Height = h;
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// Immutable AVL-Tree Factory class.
+//===----------------------------------------------------------------------===//
+
+template <typename ImutInfo >
+class ImutAVLFactory {
+ typedef ImutAVLTree<ImutInfo> TreeTy;
+ typedef typename TreeTy::value_type_ref value_type_ref;
+ typedef typename TreeTy::key_type_ref key_type_ref;
+
+ typedef FoldingSet<TreeTy> CacheTy;
+
+ CacheTy Cache;
+ BumpPtrAllocator Allocator;
+
+ //===--------------------------------------------------===//
+ // Public interface.
+ //===--------------------------------------------------===//
+
+public:
+ ImutAVLFactory() {}
+
+ TreeTy* Add(TreeTy* T, value_type_ref V) {
+ T = Add_internal(V,T);
+ MarkImmutable(T);
+ return T;
+ }
+
+ TreeTy* Remove(TreeTy* T, key_type_ref V) {
+ T = Remove_internal(V,T);
+ MarkImmutable(T);
+ return T;
+ }
+
+ TreeTy* GetEmptyTree() const { return NULL; }
+
+ BumpPtrAllocator& getAllocator() { return Allocator; }
+
+ //===--------------------------------------------------===//
+ // A bunch of quick helper functions used for reasoning
+ // about the properties of trees and their children.
+ // These have succinct names so that the balancing code
+ // is as terse (and readable) as possible.
+ //===--------------------------------------------------===//
+private:
+
+ bool isEmpty(TreeTy* T) const { return !T; }
+ unsigned Height(TreeTy* T) const { return T ? T->getHeight() : 0; }
+ TreeTy* Left(TreeTy* T) const { return T->getSafeLeft(); }
+ TreeTy* Right(TreeTy* T) const { return T->getRight(); }
+ value_type_ref Value(TreeTy* T) const { return T->Value; }
+
+ unsigned IncrementHeight(TreeTy* L, TreeTy* R) const {
+ unsigned hl = Height(L);
+ unsigned hr = Height(R);
+ return ( hl > hr ? hl : hr ) + 1;
+ }
+
+ //===--------------------------------------------------===//
+ // "CreateNode" is used to generate new tree roots that link
+ // to other trees. The functon may also simply move links
+ // in an existing root if that root is still marked mutable.
+ // This is necessary because otherwise our balancing code
+ // would leak memory as it would create nodes that are
+ // then discarded later before the finished tree is
+ // returned to the caller.
+ //===--------------------------------------------------===//
+
+ TreeTy* CreateNode(TreeTy* L, value_type_ref V, TreeTy* R) {
+ FoldingSetNodeID ID;
+ TreeTy::Profile(ID,L,R,V);
+ void* InsertPos;
+
+ if (TreeTy* T = Cache.FindNodeOrInsertPos(ID,InsertPos))
+ return T;
+
+ assert (InsertPos != NULL);
+
+ // Allocate the new tree node and insert it into the cache.
+ TreeTy* T = (TreeTy*) Allocator.Allocate<TreeTy>();
+ new (T) TreeTy(L,R,V,IncrementHeight(L,R));
+ Cache.InsertNode(T,InsertPos);
+
+ return T;
+ }
+
+ TreeTy* CreateNode(TreeTy* L, TreeTy* OldTree, TreeTy* R) {
+ assert (!isEmpty(OldTree));
+
+ if (OldTree->isMutable()) {
+ OldTree->setLeft(L);
+ OldTree->setRight(R);
+ OldTree->setHeight(IncrementHeight(L,R));
+ return OldTree;
+ }
+ else return CreateNode(L, Value(OldTree), R);
+ }
+
+ /// Balance - Used by Add_internal and Remove_internal to
+ /// balance a newly created tree.
+ TreeTy* Balance(TreeTy* L, value_type_ref V, TreeTy* R) {
+
+ unsigned hl = Height(L);
+ unsigned hr = Height(R);
+
+ if (hl > hr + 2) {
+ assert (!isEmpty(L) &&
+ "Left tree cannot be empty to have a height >= 2.");
+
+ TreeTy* LL = Left(L);
+ TreeTy* LR = Right(L);
+
+ if (Height(LL) >= Height(LR))
+ return CreateNode(LL, L, CreateNode(LR,V,R));
+
+ assert (!isEmpty(LR) &&
+ "LR cannot be empty because it has a height >= 1.");
+
+ TreeTy* LRL = Left(LR);
+ TreeTy* LRR = Right(LR);
+
+ return CreateNode(CreateNode(LL,L,LRL), LR, CreateNode(LRR,V,R));
+ }
+ else if (hr > hl + 2) {
+ assert (!isEmpty(R) &&
+ "Right tree cannot be empty to have a height >= 2.");
+
+ TreeTy* RL = Left(R);
+ TreeTy* RR = Right(R);
+
+ if (Height(RR) >= Height(RL))
+ return CreateNode(CreateNode(L,V,RL), R, RR);
+
+ assert (!isEmpty(RL) &&
+ "RL cannot be empty because it has a height >= 1.");
+
+ TreeTy* RLL = Left(RL);
+ TreeTy* RLR = Right(RL);
+
+ return CreateNode(CreateNode(L,V,RLL), RL, CreateNode(RLR,R,RR));
+ }
+ else
+ return CreateNode(L,V,R);
+ }
+
+ /// Add_internal - Creates a new tree that includes the specified
+ /// data and the data from the original tree. If the original tree
+ /// already contained the data item, the original tree is returned.
+ TreeTy* Add_internal(value_type_ref V, TreeTy* T) {
+ if (isEmpty(T))
+ return CreateNode(T, V, T);
+
+ assert (!T->isMutable());
+
+ key_type_ref K = ImutInfo::KeyOfValue(V);
+ key_type_ref KCurrent = ImutInfo::KeyOfValue(Value(T));
+
+ if (ImutInfo::isEqual(K,KCurrent))
+ return CreateNode(Left(T), V, Right(T));
+ else if (ImutInfo::isLess(K,KCurrent))
+ return Balance(Add_internal(V,Left(T)), Value(T), Right(T));
+ else
+ return Balance(Left(T), Value(T), Add_internal(V,Right(T)));
+ }
+
+ /// Remove_interal - Creates a new tree that includes all the data
+ /// from the original tree except the specified data. If the
+ /// specified data did not exist in the original tree, the original
+ /// tree is returned.
+ TreeTy* Remove_internal(key_type_ref K, TreeTy* T) {
+ if (isEmpty(T))
+ return T;
+
+ assert (!T->isMutable());
+
+ key_type_ref KCurrent = ImutInfo::KeyOfValue(Value(T));
+
+ if (ImutInfo::isEqual(K,KCurrent))
+ return CombineLeftRightTrees(Left(T),Right(T));
+ else if (ImutInfo::isLess(K,KCurrent))
+ return Balance(Remove_internal(K,Left(T)), Value(T), Right(T));
+ else
+ return Balance(Left(T), Value(T), Remove_internal(K,Right(T)));
+ }
+
+ TreeTy* CombineLeftRightTrees(TreeTy* L, TreeTy* R) {
+ if (isEmpty(L)) return R;
+ if (isEmpty(R)) return L;
+
+ TreeTy* OldNode;
+ TreeTy* NewRight = RemoveMinBinding(R,OldNode);
+ return Balance(L,Value(OldNode),NewRight);
+ }
+
+ TreeTy* RemoveMinBinding(TreeTy* T, TreeTy*& NodeRemoved) {
+ assert (!isEmpty(T));
+
+ if (isEmpty(Left(T))) {
+ NodeRemoved = T;
+ return Right(T);
+ }
+
+ return Balance(RemoveMinBinding(Left(T),NodeRemoved),Value(T),Right(T));
+ }
+
+ /// MarkImmutable - Clears the mutable bits of a root and all of its
+ /// descendants.
+ void MarkImmutable(TreeTy* T) {
+ if (!T || !T->isMutable())
+ return;
+
+ T->MarkImmutable();
+ MarkImmutable(Left(T));
+ MarkImmutable(Right(T));
+ }
+};
+
+
+//===----------------------------------------------------------------------===//
+// Immutable AVL-Tree Iterators.
+//===----------------------------------------------------------------------===//
+
+template <typename ImutInfo>
+class ImutAVLTreeGenericIterator {
+ SmallVector<uintptr_t,20> stack;
+public:
+ enum VisitFlag { VisitedNone=0x0, VisitedLeft=0x1, VisitedRight=0x3,
+ Flags=0x3 };
+
+ typedef ImutAVLTree<ImutInfo> TreeTy;
+ typedef ImutAVLTreeGenericIterator<ImutInfo> _Self;
+
+ inline ImutAVLTreeGenericIterator() {}
+ inline ImutAVLTreeGenericIterator(const TreeTy* Root) {
+ if (Root) stack.push_back(reinterpret_cast<uintptr_t>(Root));
+ }
+
+ TreeTy* operator*() const {
+ assert (!stack.empty());
+ return reinterpret_cast<TreeTy*>(stack.back() & ~Flags);
+ }
+
+ uintptr_t getVisitState() {
+ assert (!stack.empty());
+ return stack.back() & Flags;
+ }
+
+
+ bool AtEnd() const { return stack.empty(); }
+
+ bool AtBeginning() const {
+ return stack.size() == 1 && getVisitState() == VisitedNone;
+ }
+
+ void SkipToParent() {
+ assert (!stack.empty());
+ stack.pop_back();
+
+ if (stack.empty())
+ return;
+
+ switch (getVisitState()) {
+ case VisitedNone:
+ stack.back() |= VisitedLeft;
+ break;
+ case VisitedLeft:
+ stack.back() |= VisitedRight;
+ break;
+ default:
+ assert (false && "Unreachable.");
+ }
+ }
+
+ inline bool operator==(const _Self& x) const {
+ if (stack.size() != x.stack.size())
+ return false;
+
+ for (unsigned i = 0 ; i < stack.size(); i++)
+ if (stack[i] != x.stack[i])
+ return false;
+
+ return true;
+ }
+
+ inline bool operator!=(const _Self& x) const { return !operator==(x); }
+
+ _Self& operator++() {
+ assert (!stack.empty());
+
+ TreeTy* Current = reinterpret_cast<TreeTy*>(stack.back() & ~Flags);
+ assert (Current);
+
+ switch (getVisitState()) {
+ case VisitedNone:
+ if (TreeTy* L = Current->getLeft())
+ stack.push_back(reinterpret_cast<uintptr_t>(L));
+ else
+ stack.back() |= VisitedLeft;
+
+ break;
+
+ case VisitedLeft:
+ if (TreeTy* R = Current->getRight())
+ stack.push_back(reinterpret_cast<uintptr_t>(R));
+ else
+ stack.back() |= VisitedRight;
+
+ break;
+
+ case VisitedRight:
+ SkipToParent();
+ break;
+
+ default:
+ assert (false && "Unreachable.");
+ }
+
+ return *this;
+ }
+
+ _Self& operator--() {
+ assert (!stack.empty());
+
+ TreeTy* Current = reinterpret_cast<TreeTy*>(stack.back() & ~Flags);
+ assert (Current);
+
+ switch (getVisitState()) {
+ case VisitedNone:
+ stack.pop_back();
+ break;
+
+ case VisitedLeft:
+ stack.back() &= ~Flags; // Set state to "VisitedNone."
+
+ if (TreeTy* L = Current->getLeft())
+ stack.push_back(reinterpret_cast<uintptr_t>(L) | VisitedRight);
+
+ break;
+
+ case VisitedRight:
+ stack.back() &= ~Flags;
+ stack.back() |= VisitedLeft;
+
+ if (TreeTy* R = Current->getRight())
+ stack.push_back(reinterpret_cast<uintptr_t>(R) | VisitedRight);
+
+ break;
+
+ default:
+ assert (false && "Unreachable.");
+ }
+
+ return *this;
+ }
+};
+
+template <typename ImutInfo>
+class ImutAVLTreeInOrderIterator {
+ typedef ImutAVLTreeGenericIterator<ImutInfo> InternalIteratorTy;
+ InternalIteratorTy InternalItr;
+
+public:
+ typedef ImutAVLTree<ImutInfo> TreeTy;
+ typedef ImutAVLTreeInOrderIterator<ImutInfo> _Self;
+
+ ImutAVLTreeInOrderIterator(const TreeTy* Root) : InternalItr(Root) {
+ if (Root) operator++(); // Advance to first element.
+ }
+
+ ImutAVLTreeInOrderIterator() : InternalItr() {}
+
+ inline bool operator==(const _Self& x) const {
+ return InternalItr == x.InternalItr;
+ }
+
+ inline bool operator!=(const _Self& x) const { return !operator==(x); }
+
+ inline TreeTy* operator*() const { return *InternalItr; }
+ inline TreeTy* operator->() const { return *InternalItr; }
+
+ inline _Self& operator++() {
+ do ++InternalItr;
+ while (!InternalItr.AtEnd() &&
+ InternalItr.getVisitState() != InternalIteratorTy::VisitedLeft);
+
+ return *this;
+ }
+
+ inline _Self& operator--() {
+ do --InternalItr;
+ while (!InternalItr.AtBeginning() &&
+ InternalItr.getVisitState() != InternalIteratorTy::VisitedLeft);
+
+ return *this;
+ }
+
+ inline void SkipSubTree() {
+ InternalItr.SkipToParent();
+
+ while (!InternalItr.AtEnd() &&
+ InternalItr.getVisitState() != InternalIteratorTy::VisitedLeft)
+ ++InternalItr;
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// Trait classes for Profile information.
+//===----------------------------------------------------------------------===//
+
+/// Generic profile template. The default behavior is to invoke the
+/// profile method of an object. Specializations for primitive integers
+/// and generic handling of pointers is done below.
+template <typename T>
+struct ImutProfileInfo {
+ typedef const T value_type;
+ typedef const T& value_type_ref;
+
+ static inline void Profile(FoldingSetNodeID& ID, value_type_ref X) {
+ X.Profile(ID);
+ }
+};
+
+/// Profile traits for integers.
+template <typename T>
+struct ImutProfileInteger {
+ typedef const T value_type;
+ typedef const T& value_type_ref;
+
+ static inline void Profile(FoldingSetNodeID& ID, value_type_ref X) {
+ ID.AddInteger(X);
+ }
+};
+
+#define PROFILE_INTEGER_INFO(X)\
+template<> struct ImutProfileInfo<X> : ImutProfileInteger<X> {};
+
+PROFILE_INTEGER_INFO(char)
+PROFILE_INTEGER_INFO(unsigned char)
+PROFILE_INTEGER_INFO(short)
+PROFILE_INTEGER_INFO(unsigned short)
+PROFILE_INTEGER_INFO(unsigned)
+PROFILE_INTEGER_INFO(signed)
+PROFILE_INTEGER_INFO(long)
+PROFILE_INTEGER_INFO(unsigned long)
+PROFILE_INTEGER_INFO(long long)
+PROFILE_INTEGER_INFO(unsigned long long)
+
+#undef PROFILE_INTEGER_INFO
+
+/// Generic profile trait for pointer types. We treat pointers as
+/// references to unique objects.
+template <typename T>
+struct ImutProfileInfo<T*> {
+ typedef const T* value_type;
+ typedef value_type value_type_ref;
+
+ static inline void Profile(FoldingSetNodeID &ID, value_type_ref X) {
+ ID.AddPointer(X);
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// Trait classes that contain element comparison operators and type
+// definitions used by ImutAVLTree, ImmutableSet, and ImmutableMap. These
+// inherit from the profile traits (ImutProfileInfo) to include operations
+// for element profiling.
+//===----------------------------------------------------------------------===//
+
+
+/// ImutContainerInfo - Generic definition of comparison operations for
+/// elements of immutable containers that defaults to using
+/// std::equal_to<> and std::less<> to perform comparison of elements.
+template <typename T>
+struct ImutContainerInfo : public ImutProfileInfo<T> {
+ typedef typename ImutProfileInfo<T>::value_type value_type;
+ typedef typename ImutProfileInfo<T>::value_type_ref value_type_ref;
+ typedef value_type key_type;
+ typedef value_type_ref key_type_ref;
+
+ static inline key_type_ref KeyOfValue(value_type_ref D) { return D; }
+
+ static inline bool isEqual(key_type_ref LHS, key_type_ref RHS) {
+ return std::equal_to<key_type>()(LHS,RHS);
+ }
+
+ static inline bool isLess(key_type_ref LHS, key_type_ref RHS) {
+ return std::less<key_type>()(LHS,RHS);
+ }
+};
+
+/// ImutContainerInfo - Specialization for pointer values to treat pointers
+/// as references to unique objects. Pointers are thus compared by
+/// their addresses.
+template <typename T>
+struct ImutContainerInfo<T*> : public ImutProfileInfo<T*> {
+ typedef typename ImutProfileInfo<T*>::value_type value_type;
+ typedef typename ImutProfileInfo<T*>::value_type_ref value_type_ref;
+ typedef value_type key_type;
+ typedef value_type_ref key_type_ref;
+
+ static inline key_type_ref KeyOfValue(value_type_ref D) { return D; }
+
+ static inline bool isEqual(key_type_ref LHS, key_type_ref RHS) {
+ return LHS == RHS;
+ }
+
+ static inline bool isLess(key_type_ref LHS, key_type_ref RHS) {
+ return LHS < RHS;
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// Immutable Set
+//===----------------------------------------------------------------------===//
+
+template <typename ValT, typename ValInfo = ImutContainerInfo<ValT> >
+class ImmutableSet {
+public:
+ typedef typename ValInfo::value_type value_type;
+ typedef typename ValInfo::value_type_ref value_type_ref;
+
+private:
+ typedef ImutAVLTree<ValInfo> TreeTy;
+ TreeTy* Root;
+
+ ImmutableSet(TreeTy* R) : Root(R) {}
+
+public:
+
+ class Factory {
+ typename TreeTy::Factory F;
+
+ public:
+ Factory() {}
+
+ /// GetEmptySet - Returns an immutable set that contains no elements.
+ ImmutableSet GetEmptySet() { return ImmutableSet(F.GetEmptyTree()); }
+
+ /// Add - Creates a new immutable set that contains all of the values
+ /// of the original set with the addition of the specified value. If
+ /// the original set already included the value, then the original set is
+ /// returned and no memory is allocated. The time and space complexity
+ /// of this operation is logarithmic in the size of the original set.
+ /// The memory allocated to represent the set is released when the
+ /// factory object that created the set is destroyed.
+ ImmutableSet Add(ImmutableSet Old, value_type_ref V) {
+ return ImmutableSet(F.Add(Old.Root,V));
+ }
+
+ /// Remove - Creates a new immutable set that contains all of the values
+ /// of the original set with the exception of the specified value. If
+ /// the original set did not contain the value, the original set is
+ /// returned and no memory is allocated. The time and space complexity
+ /// of this operation is logarithmic in the size of the original set.
+ /// The memory allocated to represent the set is released when the
+ /// factory object that created the set is destroyed.
+ ImmutableSet Remove(ImmutableSet Old, value_type_ref V) {
+ return ImmutableSet(F.Remove(Old.Root,V));
+ }
+
+ BumpPtrAllocator& getAllocator() { return F.getAllocator(); }
+
+ private:
+ Factory(const Factory& RHS) {};
+ void operator=(const Factory& RHS) {};
+ };
+
+ friend class Factory;
+
+ /// contains - Returns true if the set contains the specified value.
+ bool contains(const value_type_ref V) const {
+ return Root ? Root->contains(V) : false;
+ }
+
+ bool operator==(ImmutableSet RHS) const {
+ return Root && RHS.Root ? Root->isEqual(*RHS.Root) : Root == RHS.Root;
+ }
+
+ bool operator!=(ImmutableSet RHS) const {
+ return Root && RHS.Root ? Root->isNotEqual(*RHS.Root) : Root != RHS.Root;
+ }
+
+ /// isEmpty - Return true if the set contains no elements.
+ bool isEmpty() const { return !Root; }
+
+ template <typename Callback>
+ void foreach(Callback& C) { if (Root) Root->foreach(C); }
+
+ template <typename Callback>
+ void foreach() { if (Root) { Callback C; Root->foreach(C); } }
+
+ //===--------------------------------------------------===//
+ // Iterators.
+ //===--------------------------------------------------===//
+
+ class iterator {
+ typename TreeTy::iterator itr;
+
+ iterator() {}
+ iterator(TreeTy* t) : itr(t) {}
+ friend class ImmutableSet<ValT,ValInfo>;
+ public:
+ inline value_type_ref operator*() const { return itr->getValue(); }
+ inline iterator& operator++() { ++itr; return *this; }
+ inline iterator operator++(int) { iterator tmp(*this); ++itr; return tmp; }
+ inline iterator& operator--() { --itr; return *this; }
+ inline iterator operator--(int) { iterator tmp(*this); --itr; return tmp; }
+ inline bool operator==(const iterator& RHS) const { return RHS.itr == itr; }
+ inline bool operator!=(const iterator& RHS) const { return RHS.itr != itr; }
+ };
+
+ iterator begin() const { return iterator(Root); }
+ iterator end() const { return iterator(); }
+
+ //===--------------------------------------------------===//
+ // For testing.
+ //===--------------------------------------------------===//
+
+ void verify() const { if (Root) Root->verify(); }
+ unsigned getHeight() const { return Root ? Root->getHeight() : 0; }
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/support/include/llvm/ADT/IndexedMap.h b/support/include/llvm/ADT/IndexedMap.h
new file mode 100644
index 0000000..bc38fdd
--- /dev/null
+++ b/support/include/llvm/ADT/IndexedMap.h
@@ -0,0 +1,75 @@
+//===- llvm/ADT/IndexedMap.h - An index map implementation ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements an indexed map. The index map template takes two
+// types. The first is the mapped type and the second is a functor
+// that maps its argument to a size_t. On instantiation a "null" value
+// can be provided to be used as a "does not exist" indicator in the
+// map. A member function grow() is provided that given the value of
+// the maximally indexed key (the argument of the functor) makes sure
+// the map has enough space for it.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_INDEXEDMAP_H
+#define LLVM_ADT_INDEXEDMAP_H
+
+#include <functional>
+#include <vector>
+#include <cassert>
+
+namespace llvm {
+
+ struct IdentityFunctor : std::unary_function<unsigned, unsigned> {
+ unsigned operator()(unsigned Index) const {
+ return Index;
+ }
+ };
+
+ template <typename T, typename ToIndexT = IdentityFunctor>
+ class IndexedMap {
+ typedef typename ToIndexT::argument_type IndexT;
+ typedef std::vector<T> StorageT;
+ StorageT storage_;
+ T nullVal_;
+ ToIndexT toIndex_;
+
+ public:
+ IndexedMap() : nullVal_(T()) { }
+
+ explicit IndexedMap(const T& val) : nullVal_(val) { }
+
+ typename StorageT::reference operator[](IndexT n) {
+ assert(toIndex_(n) < storage_.size() && "index out of bounds!");
+ return storage_[toIndex_(n)];
+ }
+
+ typename StorageT::const_reference operator[](IndexT n) const {
+ assert(toIndex_(n) < storage_.size() && "index out of bounds!");
+ return storage_[toIndex_(n)];
+ }
+
+ void clear() {
+ storage_.clear();
+ }
+
+ void grow(IndexT n) {
+ unsigned NewSize = toIndex_(n) + 1;
+ if (NewSize > storage_.size())
+ storage_.resize(NewSize, nullVal_);
+ }
+
+ typename StorageT::size_type size() const {
+ return storage_.size();
+ }
+ };
+
+} // End llvm namespace
+
+#endif
diff --git a/support/include/llvm/ADT/PostOrderIterator.h b/support/include/llvm/ADT/PostOrderIterator.h
new file mode 100644
index 0000000..42c8089
--- /dev/null
+++ b/support/include/llvm/ADT/PostOrderIterator.h
@@ -0,0 +1,230 @@
+//===- llvm/ADT/PostOrderIterator.h - PostOrder iterator --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file builds on the ADT/GraphTraits.h file to build a generic graph
+// post order iterator. This should work over any graph type that has a
+// GraphTraits specialization.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_POSTORDERITERATOR_H
+#define LLVM_ADT_POSTORDERITERATOR_H
+
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/iterator"
+#include <stack>
+#include <set>
+#include <vector>
+
+namespace llvm {
+
+template<class SetType, bool External> // Non-external set
+class po_iterator_storage {
+public:
+ SetType Visited;
+};
+
+template<class SetType>
+class po_iterator_storage<SetType, true> {
+public:
+ po_iterator_storage(SetType &VSet) : Visited(VSet) {}
+ po_iterator_storage(const po_iterator_storage &S) : Visited(S.Visited) {}
+ SetType &Visited;
+};
+
+template<class GraphT,
+ class SetType = std::set<typename GraphTraits<GraphT>::NodeType*>,
+ bool ExtStorage = false,
+ class GT = GraphTraits<GraphT> >
+class po_iterator : public forward_iterator<typename GT::NodeType, ptrdiff_t>,
+ public po_iterator_storage<SetType, ExtStorage> {
+ typedef forward_iterator<typename GT::NodeType, ptrdiff_t> super;
+ typedef typename GT::NodeType NodeType;
+ typedef typename GT::ChildIteratorType ChildItTy;
+
+ // VisitStack - Used to maintain the ordering. Top = current block
+ // First element is basic block pointer, second is the 'next child' to visit
+ std::stack<std::pair<NodeType *, ChildItTy> > VisitStack;
+
+ void traverseChild() {
+ while (VisitStack.top().second != GT::child_end(VisitStack.top().first)) {
+ NodeType *BB = *VisitStack.top().second++;
+ if (!this->Visited.count(BB)) { // If the block is not visited...
+ this->Visited.insert(BB);
+ VisitStack.push(std::make_pair(BB, GT::child_begin(BB)));
+ }
+ }
+ }
+
+ inline po_iterator(NodeType *BB) {
+ this->Visited.insert(BB);
+ VisitStack.push(std::make_pair(BB, GT::child_begin(BB)));
+ traverseChild();
+ }
+ inline po_iterator() {} // End is when stack is empty.
+
+ inline po_iterator(NodeType *BB, SetType &S) :
+ po_iterator_storage<SetType, ExtStorage>(&S) {
+ if(!S.count(BB)) {
+ this->Visited.insert(BB);
+ VisitStack.push(std::make_pair(BB, GT::child_begin(BB)));
+ traverseChild();
+ }
+ }
+
+ inline po_iterator(SetType &S) :
+ po_iterator_storage<SetType, ExtStorage>(&S) {
+ } // End is when stack is empty.
+public:
+ typedef typename super::pointer pointer;
+ typedef po_iterator<GraphT, SetType, ExtStorage, GT> _Self;
+
+ // Provide static "constructors"...
+ static inline _Self begin(GraphT G) { return _Self(GT::getEntryNode(G)); }
+ static inline _Self end (GraphT G) { return _Self(); }
+
+ static inline _Self begin(GraphT G, SetType &S) {
+ return _Self(GT::getEntryNode(G), S);
+ }
+ static inline _Self end (GraphT G, SetType &S) { return _Self(S); }
+
+ inline bool operator==(const _Self& x) const {
+ return VisitStack == x.VisitStack;
+ }
+ inline bool operator!=(const _Self& x) const { return !operator==(x); }
+
+ inline pointer operator*() const {
+ return VisitStack.top().first;
+ }
+
+ // This is a nonstandard operator-> that dereferences the pointer an extra
+ // time... so that you can actually call methods ON the BasicBlock, because
+ // the contained type is a pointer. This allows BBIt->getTerminator() f.e.
+ //
+ inline NodeType *operator->() const { return operator*(); }
+
+ inline _Self& operator++() { // Preincrement
+ VisitStack.pop();
+ if (!VisitStack.empty())
+ traverseChild();
+ return *this;
+ }
+
+ inline _Self operator++(int) { // Postincrement
+ _Self tmp = *this; ++*this; return tmp;
+ }
+};
+
+// Provide global constructors that automatically figure out correct types...
+//
+template <class T>
+po_iterator<T> po_begin(T G) { return po_iterator<T>::begin(G); }
+template <class T>
+po_iterator<T> po_end (T G) { return po_iterator<T>::end(G); }
+
+// Provide global definitions of external postorder iterators...
+template<class T, class SetType=std::set<typename GraphTraits<T>::NodeType*> >
+struct po_ext_iterator : public po_iterator<T, SetType, true> {
+ po_ext_iterator(const po_iterator<T, SetType, true> &V) :
+ po_iterator<T, SetType, true>(V) {}
+};
+
+template<class T, class SetType>
+po_ext_iterator<T, SetType> po_ext_begin(T G, SetType &S) {
+ return po_ext_iterator<T, SetType>::begin(G, S);
+}
+
+template<class T, class SetType>
+po_ext_iterator<T, SetType> po_ext_end(T G, SetType &S) {
+ return po_ext_iterator<T, SetType>::end(G, S);
+}
+
+// Provide global definitions of inverse post order iterators...
+template <class T,
+ class SetType = std::set<typename GraphTraits<T>::NodeType*>,
+ bool External = false>
+struct ipo_iterator : public po_iterator<Inverse<T>, SetType, External > {
+ ipo_iterator(const po_iterator<Inverse<T>, SetType, External> &V) :
+ po_iterator<Inverse<T>, SetType, External> (V) {}
+};
+
+template <class T>
+ipo_iterator<T> ipo_begin(T G, bool Reverse = false) {
+ return ipo_iterator<T>::begin(G, Reverse);
+}
+
+template <class T>
+ipo_iterator<T> ipo_end(T G){
+ return ipo_iterator<T>::end(G);
+}
+
+//Provide global definitions of external inverse postorder iterators...
+template <class T, class SetType = std::set<typename GraphTraits<T>::NodeType*> >
+struct ipo_ext_iterator : public ipo_iterator<T, SetType, true> {
+ ipo_ext_iterator(const ipo_iterator<T, SetType, true> &V) :
+ ipo_iterator<T, SetType, true>(&V) {}
+ ipo_ext_iterator(const po_iterator<Inverse<T>, SetType, true> &V) :
+ ipo_iterator<T, SetType, true>(&V) {}
+};
+
+template <class T, class SetType>
+ipo_ext_iterator<T, SetType> ipo_ext_begin(T G, SetType &S) {
+ return ipo_ext_iterator<T, SetType>::begin(G, S);
+}
+
+template <class T, class SetType>
+ipo_ext_iterator<T, SetType> ipo_ext_end(T G, SetType &S) {
+ return ipo_ext_iterator<T, SetType>::end(G, S);
+}
+
+//===--------------------------------------------------------------------===//
+// Reverse Post Order CFG iterator code
+//===--------------------------------------------------------------------===//
+//
+// This is used to visit basic blocks in a method in reverse post order. This
+// class is awkward to use because I don't know a good incremental algorithm to
+// computer RPO from a graph. Because of this, the construction of the
+// ReversePostOrderTraversal object is expensive (it must walk the entire graph
+// with a postorder iterator to build the data structures). The moral of this
+// story is: Don't create more ReversePostOrderTraversal classes than necessary.
+//
+// This class should be used like this:
+// {
+// ReversePostOrderTraversal<Function*> RPOT(FuncPtr); // Expensive to create
+// for (rpo_iterator I = RPOT.begin(); I != RPOT.end(); ++I) {
+// ...
+// }
+// for (rpo_iterator I = RPOT.begin(); I != RPOT.end(); ++I) {
+// ...
+// }
+// }
+//
+
+template<class GraphT, class GT = GraphTraits<GraphT> >
+class ReversePostOrderTraversal {
+ typedef typename GT::NodeType NodeType;
+ std::vector<NodeType*> Blocks; // Block list in normal PO order
+ inline void Initialize(NodeType *BB) {
+ copy(po_begin(BB), po_end(BB), back_inserter(Blocks));
+ }
+public:
+ typedef typename std::vector<NodeType*>::reverse_iterator rpo_iterator;
+
+ inline ReversePostOrderTraversal(GraphT G) {
+ Initialize(GT::getEntryNode(G));
+ }
+
+ // Because we want a reverse post order, use reverse iterators from the vector
+ inline rpo_iterator begin() { return Blocks.rbegin(); }
+ inline rpo_iterator end() { return Blocks.rend(); }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/support/include/llvm/ADT/SCCIterator.h b/support/include/llvm/ADT/SCCIterator.h
new file mode 100644
index 0000000..6b1260d
--- /dev/null
+++ b/support/include/llvm/ADT/SCCIterator.h
@@ -0,0 +1,199 @@
+//===-- Support/SCCIterator.h - Strongly Connected Comp. Iter. --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This builds on the llvm/ADT/GraphTraits.h file to find the strongly connected
+// components (SCCs) of a graph in O(N+E) time using Tarjan's DFS algorithm.
+//
+// The SCC iterator has the important property that if a node in SCC S1 has an
+// edge to a node in SCC S2, then it visits S1 *after* S2.
+//
+// To visit S1 *before* S2, use the scc_iterator on the Inverse graph.
+// (NOTE: This requires some simple wrappers and is not supported yet.)
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_SCCITERATOR_H
+#define LLVM_ADT_SCCITERATOR_H
+
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/iterator"
+#include <vector>
+#include <map>
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+///
+/// scc_iterator - Enumerate the SCCs of a directed graph, in
+/// reverse topological order of the SCC DAG.
+///
+template<class GraphT, class GT = GraphTraits<GraphT> >
+class scc_iterator
+ : public forward_iterator<std::vector<typename GT::NodeType>, ptrdiff_t> {
+ typedef typename GT::NodeType NodeType;
+ typedef typename GT::ChildIteratorType ChildItTy;
+ typedef std::vector<NodeType*> SccTy;
+ typedef forward_iterator<SccTy, ptrdiff_t> super;
+ typedef typename super::reference reference;
+ typedef typename super::pointer pointer;
+
+ // The visit counters used to detect when a complete SCC is on the stack.
+ // visitNum is the global counter.
+ // nodeVisitNumbers are per-node visit numbers, also used as DFS flags.
+ unsigned visitNum;
+ std::map<NodeType *, unsigned> nodeVisitNumbers;
+
+ // SCCNodeStack - Stack holding nodes of the SCC.
+ std::vector<NodeType *> SCCNodeStack;
+
+ // CurrentSCC - The current SCC, retrieved using operator*().
+ SccTy CurrentSCC;
+
+ // VisitStack - Used to maintain the ordering. Top = current block
+ // First element is basic block pointer, second is the 'next child' to visit
+ std::vector<std::pair<NodeType *, ChildItTy> > VisitStack;
+
+ // MinVistNumStack - Stack holding the "min" values for each node in the DFS.
+ // This is used to track the minimum uplink values for all children of
+ // the corresponding node on the VisitStack.
+ std::vector<unsigned> MinVisitNumStack;
+
+ // A single "visit" within the non-recursive DFS traversal.
+ void DFSVisitOne(NodeType* N) {
+ ++visitNum; // Global counter for the visit order
+ nodeVisitNumbers[N] = visitNum;
+ SCCNodeStack.push_back(N);
+ MinVisitNumStack.push_back(visitNum);
+ VisitStack.push_back(std::make_pair(N, GT::child_begin(N)));
+ //DOUT << "TarjanSCC: Node " << N <<
+ // " : visitNum = " << visitNum << "\n";
+ }
+
+ // The stack-based DFS traversal; defined below.
+ void DFSVisitChildren() {
+ assert(!VisitStack.empty());
+ while (VisitStack.back().second != GT::child_end(VisitStack.back().first)) {
+ // TOS has at least one more child so continue DFS
+ NodeType *childN = *VisitStack.back().second++;
+ if (!nodeVisitNumbers.count(childN)) {
+ // this node has never been seen
+ DFSVisitOne(childN);
+ } else {
+ unsigned childNum = nodeVisitNumbers[childN];
+ if (MinVisitNumStack.back() > childNum)
+ MinVisitNumStack.back() = childNum;
+ }
+ }
+ }
+
+ // Compute the next SCC using the DFS traversal.
+ void GetNextSCC() {
+ assert(VisitStack.size() == MinVisitNumStack.size());
+ CurrentSCC.clear(); // Prepare to compute the next SCC
+ while (!VisitStack.empty()) {
+ DFSVisitChildren();
+ assert(VisitStack.back().second ==GT::child_end(VisitStack.back().first));
+ NodeType* visitingN = VisitStack.back().first;
+ unsigned minVisitNum = MinVisitNumStack.back();
+ VisitStack.pop_back();
+ MinVisitNumStack.pop_back();
+ if (!MinVisitNumStack.empty() && MinVisitNumStack.back() > minVisitNum)
+ MinVisitNumStack.back() = minVisitNum;
+
+ //DOUT << "TarjanSCC: Popped node " << visitingN <<
+ // " : minVisitNum = " << minVisitNum << "; Node visit num = " <<
+ // nodeVisitNumbers[visitingN] << "\n";
+
+ if (minVisitNum == nodeVisitNumbers[visitingN]) {
+ // A full SCC is on the SCCNodeStack! It includes all nodes below
+ // visitingN on the stack. Copy those nodes to CurrentSCC,
+ // reset their minVisit values, and return (this suspends
+ // the DFS traversal till the next ++).
+ do {
+ CurrentSCC.push_back(SCCNodeStack.back());
+ SCCNodeStack.pop_back();
+ nodeVisitNumbers[CurrentSCC.back()] = ~0U;
+ } while (CurrentSCC.back() != visitingN);
+ return;
+ }
+ }
+ }
+
+ inline scc_iterator(NodeType *entryN) : visitNum(0) {
+ DFSVisitOne(entryN);
+ GetNextSCC();
+ }
+ inline scc_iterator() { /* End is when DFS stack is empty */ }
+
+public:
+ typedef scc_iterator<GraphT, GT> _Self;
+
+ // Provide static "constructors"...
+ static inline _Self begin(GraphT& G) { return _Self(GT::getEntryNode(G)); }
+ static inline _Self end (GraphT& G) { return _Self(); }
+
+ // Direct loop termination test (I.fini() is more efficient than I == end())
+ inline bool fini() const {
+ assert(!CurrentSCC.empty() || VisitStack.empty());
+ return CurrentSCC.empty();
+ }
+
+ inline bool operator==(const _Self& x) const {
+ return VisitStack == x.VisitStack && CurrentSCC == x.CurrentSCC;
+ }
+ inline bool operator!=(const _Self& x) const { return !operator==(x); }
+
+ // Iterator traversal: forward iteration only
+ inline _Self& operator++() { // Preincrement
+ GetNextSCC();
+ return *this;
+ }
+ inline _Self operator++(int) { // Postincrement
+ _Self tmp = *this; ++*this; return tmp;
+ }
+
+ // Retrieve a reference to the current SCC
+ inline const SccTy &operator*() const {
+ assert(!CurrentSCC.empty() && "Dereferencing END SCC iterator!");
+ return CurrentSCC;
+ }
+ inline SccTy &operator*() {
+ assert(!CurrentSCC.empty() && "Dereferencing END SCC iterator!");
+ return CurrentSCC;
+ }
+
+ // hasLoop() -- Test if the current SCC has a loop. If it has more than one
+ // node, this is trivially true. If not, it may still contain a loop if the
+ // node has an edge back to itself.
+ bool hasLoop() const {
+ assert(!CurrentSCC.empty() && "Dereferencing END SCC iterator!");
+ if (CurrentSCC.size() > 1) return true;
+ NodeType *N = CurrentSCC.front();
+ for (ChildItTy CI = GT::child_begin(N), CE=GT::child_end(N); CI != CE; ++CI)
+ if (*CI == N)
+ return true;
+ return false;
+ }
+};
+
+
+// Global constructor for the SCC iterator.
+template <class T>
+scc_iterator<T> scc_begin(T G) {
+ return scc_iterator<T>::begin(G);
+}
+
+template <class T>
+scc_iterator<T> scc_end(T G) {
+ return scc_iterator<T>::end(G);
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/support/include/llvm/ADT/STLExtras.h b/support/include/llvm/ADT/STLExtras.h
new file mode 100644
index 0000000..9a17e6c
--- /dev/null
+++ b/support/include/llvm/ADT/STLExtras.h
@@ -0,0 +1,223 @@
+//===- llvm/ADT/STLExtras.h - Useful STL related functions ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains some templates that are useful if you are working with the
+// STL at all.
+//
+// No library is required when using these functinons.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_STLEXTRAS_H
+#define LLVM_ADT_STLEXTRAS_H
+
+#include <functional>
+#include <utility> // for std::pair
+#include <cstring> // for std::size_t
+#include "llvm/ADT/iterator"
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+// Extra additions to <functional>
+//===----------------------------------------------------------------------===//
+
+template<class Ty>
+struct greater_ptr : public std::binary_function<Ty, Ty, bool> {
+ bool operator()(const Ty* left, const Ty* right) const {
+ return *right < *left;
+ }
+};
+
+// deleter - Very very very simple method that is used to invoke operator
+// delete on something. It is used like this:
+//
+// for_each(V.begin(), B.end(), deleter<Interval>);
+//
+template <class T>
+static inline void deleter(T *Ptr) {
+ delete Ptr;
+}
+
+
+
+//===----------------------------------------------------------------------===//
+// Extra additions to <iterator>
+//===----------------------------------------------------------------------===//
+
+// mapped_iterator - This is a simple iterator adapter that causes a function to
+// be dereferenced whenever operator* is invoked on the iterator.
+//
+template <class RootIt, class UnaryFunc>
+class mapped_iterator {
+ RootIt current;
+ UnaryFunc Fn;
+public:
+ typedef typename std::iterator_traits<RootIt>::iterator_category
+ iterator_category;
+ typedef typename std::iterator_traits<RootIt>::difference_type
+ difference_type;
+ typedef typename UnaryFunc::result_type value_type;
+
+ typedef void pointer;
+ //typedef typename UnaryFunc::result_type *pointer;
+ typedef void reference; // Can't modify value returned by fn
+
+ typedef RootIt iterator_type;
+ typedef mapped_iterator<RootIt, UnaryFunc> _Self;
+
+ inline const RootIt &getCurrent() const { return current; }
+
+ inline explicit mapped_iterator(const RootIt &I, UnaryFunc F)
+ : current(I), Fn(F) {}
+ inline mapped_iterator(const mapped_iterator &It)
+ : current(It.current), Fn(It.Fn) {}
+
+ inline value_type operator*() const { // All this work to do this
+ return Fn(*current); // little change
+ }
+
+ _Self& operator++() { ++current; return *this; }
+ _Self& operator--() { --current; return *this; }
+ _Self operator++(int) { _Self __tmp = *this; ++current; return __tmp; }
+ _Self operator--(int) { _Self __tmp = *this; --current; return __tmp; }
+ _Self operator+ (difference_type n) const { return _Self(current + n); }
+ _Self& operator+= (difference_type n) { current += n; return *this; }
+ _Self operator- (difference_type n) const { return _Self(current - n); }
+ _Self& operator-= (difference_type n) { current -= n; return *this; }
+ reference operator[](difference_type n) const { return *(*this + n); }
+
+ inline bool operator!=(const _Self &X) const { return !operator==(X); }
+ inline bool operator==(const _Self &X) const { return current == X.current; }
+ inline bool operator< (const _Self &X) const { return current < X.current; }
+
+ inline difference_type operator-(const _Self &X) const {
+ return current - X.current;
+ }
+};
+
+template <class _Iterator, class Func>
+inline mapped_iterator<_Iterator, Func>
+operator+(typename mapped_iterator<_Iterator, Func>::difference_type N,
+ const mapped_iterator<_Iterator, Func>& X) {
+ return mapped_iterator<_Iterator, Func>(X.getCurrent() - N);
+}
+
+
+// map_iterator - Provide a convenient way to create mapped_iterators, just like
+// make_pair is useful for creating pairs...
+//
+template <class ItTy, class FuncTy>
+inline mapped_iterator<ItTy, FuncTy> map_iterator(const ItTy &I, FuncTy F) {
+ return mapped_iterator<ItTy, FuncTy>(I, F);
+}
+
+
+// next/prior - These functions unlike std::advance do not modify the
+// passed iterator but return a copy.
+//
+// next(myIt) returns copy of myIt incremented once
+// next(myIt, n) returns copy of myIt incremented n times
+// prior(myIt) returns copy of myIt decremented once
+// prior(myIt, n) returns copy of myIt decremented n times
+
+template <typename ItTy, typename Dist>
+inline ItTy next(ItTy it, Dist n)
+{
+ std::advance(it, n);
+ return it;
+}
+
+template <typename ItTy>
+inline ItTy next(ItTy it)
+{
+ std::advance(it, 1);
+ return it;
+}
+
+template <typename ItTy, typename Dist>
+inline ItTy prior(ItTy it, Dist n)
+{
+ std::advance(it, -n);
+ return it;
+}
+
+template <typename ItTy>
+inline ItTy prior(ItTy it)
+{
+ std::advance(it, -1);
+ return it;
+}
+
+//===----------------------------------------------------------------------===//
+// Extra additions to <utility>
+//===----------------------------------------------------------------------===//
+
+// tie - this function ties two objects and returns a temporary object
+// that is assignable from a std::pair. This can be used to make code
+// more readable when using values returned from functions bundled in
+// a std::pair. Since an example is worth 1000 words:
+//
+// typedef std::map<int, int> Int2IntMap;
+//
+// Int2IntMap myMap;
+// Int2IntMap::iterator where;
+// bool inserted;
+// tie(where, inserted) = myMap.insert(std::make_pair(123,456));
+//
+// if (inserted)
+// // do stuff
+// else
+// // do other stuff
+
+namespace
+{
+ template <typename T1, typename T2>
+ struct tier {
+ typedef T1 &first_type;
+ typedef T2 &second_type;
+
+ first_type first;
+ second_type second;
+
+ tier(first_type f, second_type s) : first(f), second(s) { }
+ tier& operator=(const std::pair<T1, T2>& p) {
+ first = p.first;
+ second = p.second;
+ return *this;
+ }
+ };
+}
+
+template <typename T1, typename T2>
+inline tier<T1, T2> tie(T1& f, T2& s) {
+ return tier<T1, T2>(f, s);
+}
+
+//===----------------------------------------------------------------------===//
+// Extra additions to arrays
+//===----------------------------------------------------------------------===//
+
+/// Find where an array ends (for ending iterators)
+/// This returns a pointer to the byte immediately
+/// after the end of an array.
+template<class T, std::size_t N>
+inline T *array_endof(T (&x)[N]) {
+ return x+N;
+}
+
+/// Find the length of an array.
+template<class T, std::size_t N>
+inline size_t array_lengthof(T (&x)[N]) {
+ return N;
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/support/include/llvm/ADT/SetOperations.h b/support/include/llvm/ADT/SetOperations.h
new file mode 100644
index 0000000..c37d1e7
--- /dev/null
+++ b/support/include/llvm/ADT/SetOperations.h
@@ -0,0 +1,71 @@
+//===-- llvm/ADT/SetOperations.h - Generic Set Operations -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines generic set operations that may be used on set's of
+// different types, and different element types.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_SETOPERATIONS_H
+#define LLVM_ADT_SETOPERATIONS_H
+
+namespace llvm {
+
+/// set_union(A, B) - Compute A := A u B, return whether A changed.
+///
+template <class S1Ty, class S2Ty>
+bool set_union(S1Ty &S1, const S2Ty &S2) {
+ bool Changed = false;
+
+ for (typename S2Ty::const_iterator SI = S2.begin(), SE = S2.end();
+ SI != SE; ++SI)
+ if (S1.insert(*SI).second)
+ Changed = true;
+
+ return Changed;
+}
+
+/// set_intersect(A, B) - Compute A := A ^ B
+/// Identical to set_intersection, except that it works on set<>'s and
+/// is nicer to use. Functionally, this iterates through S1, removing
+/// elements that are not contained in S2.
+///
+template <class S1Ty, class S2Ty>
+void set_intersect(S1Ty &S1, const S2Ty &S2) {
+ for (typename S1Ty::iterator I = S1.begin(); I != S1.end();) {
+ const typename S1Ty::key_type &E = *I;
+ ++I;
+ if (!S2.count(E)) S1.erase(E); // Erase element if not in S2
+ }
+}
+
+/// set_difference(A, B) - Return A - B
+///
+template <class S1Ty, class S2Ty>
+S1Ty set_difference(const S1Ty &S1, const S2Ty &S2) {
+ S1Ty Result;
+ for (typename S1Ty::const_iterator SI = S1.begin(), SE = S1.end();
+ SI != SE; ++SI)
+ if (!S2.count(*SI)) // if the element is not in set2
+ Result.insert(*SI);
+ return Result;
+}
+
+/// set_subtract(A, B) - Compute A := A - B
+///
+template <class S1Ty, class S2Ty>
+void set_subtract(S1Ty &S1, const S2Ty &S2) {
+ for (typename S2Ty::const_iterator SI = S2.begin(), SE = S2.end();
+ SI != SE; ++SI)
+ S1.erase(*SI);
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/support/include/llvm/ADT/SetVector.h b/support/include/llvm/ADT/SetVector.h
new file mode 100644
index 0000000..7675534
--- /dev/null
+++ b/support/include/llvm/ADT/SetVector.h
@@ -0,0 +1,168 @@
+//===- llvm/ADT/SetVector.h - Set with insert order iteration ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a set that has insertion order iteration
+// characteristics. This is useful for keeping a set of things that need to be
+// visited later but in a deterministic order (insertion order). The interface
+// is purposefully minimal.
+//
+// This file defines SetVector and SmallSetVector, which performs no allocations
+// if the SetVector has less than a certain number of elements.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_SETVECTOR_H
+#define LLVM_ADT_SETVECTOR_H
+
+#include "llvm/ADT/SmallSet.h"
+#include <vector>
+#include <cassert>
+#include <algorithm>
+
+namespace llvm {
+
+/// This adapter class provides a way to keep a set of things that also has the
+/// property of a deterministic iteration order. The order of iteration is the
+/// order of insertion.
+/// @brief A vector that has set insertion semantics.
+template <typename T, typename Vector = std::vector<T>,
+ typename Set = SmallSet<T, 16> >
+class SetVector {
+public:
+ typedef T value_type;
+ typedef T key_type;
+ typedef T& reference;
+ typedef const T& const_reference;
+ typedef Set set_type;
+ typedef Vector vector_type;
+ typedef typename vector_type::const_iterator iterator;
+ typedef typename vector_type::const_iterator const_iterator;
+ typedef typename vector_type::size_type size_type;
+
+ /// @brief Construct an empty SetVector
+ SetVector() {}
+
+ /// @brief Initialize a SetVector with a range of elements
+ template<typename It>
+ SetVector(It Start, It End) {
+ insert(Start, End);
+ }
+
+ /// @brief Determine if the SetVector is empty or not.
+ bool empty() const {
+ return vector_.empty();
+ }
+
+ /// @brief Determine the number of elements in the SetVector.
+ size_type size() const {
+ return vector_.size();
+ }
+
+ /// @brief Get an iterator to the beginning of the SetVector.
+ iterator begin() {
+ return vector_.begin();
+ }
+
+ /// @brief Get a const_iterator to the beginning of the SetVector.
+ const_iterator begin() const {
+ return vector_.begin();
+ }
+
+ /// @brief Get an iterator to the end of the SetVector.
+ iterator end() {
+ return vector_.end();
+ }
+
+ /// @brief Get a const_iterator to the end of the SetVector.
+ const_iterator end() const {
+ return vector_.end();
+ }
+
+ /// @brief Return the last element of the SetVector.
+ const T &back() const {
+ assert(!empty() && "Cannot call back() on empty SetVector!");
+ return vector_.back();
+ }
+
+ /// @brief Index into the SetVector.
+ const_reference operator[](size_type n) const {
+ assert(n < vector_.size() && "SetVector access out of range!");
+ return vector_[n];
+ }
+
+ /// @returns true iff the element was inserted into the SetVector.
+ /// @brief Insert a new element into the SetVector.
+ bool insert(const value_type &X) {
+ bool result = set_.insert(X);
+ if (result)
+ vector_.push_back(X);
+ return result;
+ }
+
+ /// @brief Insert a range of elements into the SetVector.
+ template<typename It>
+ void insert(It Start, It End) {
+ for (; Start != End; ++Start)
+ if (set_.insert(*Start))
+ vector_.push_back(*Start);
+ }
+
+ /// @brief Remove an item from the set vector.
+ void remove(const value_type& X) {
+ if (set_.erase(X)) {
+ typename vector_type::iterator I =
+ std::find(vector_.begin(), vector_.end(), X);
+ assert(I != vector_.end() && "Corrupted SetVector instances!");
+ vector_.erase(I);
+ }
+ }
+
+
+ /// @returns 0 if the element is not in the SetVector, 1 if it is.
+ /// @brief Count the number of elements of a given key in the SetVector.
+ size_type count(const key_type &key) const {
+ return set_.count(key);
+ }
+
+ /// @brief Completely clear the SetVector
+ void clear() {
+ set_.clear();
+ vector_.clear();
+ }
+
+ /// @brief Remove the last element of the SetVector.
+ void pop_back() {
+ assert(!empty() && "Cannot remove an element from an empty SetVector!");
+ set_.erase(back());
+ vector_.pop_back();
+ }
+
+private:
+ set_type set_; ///< The set.
+ vector_type vector_; ///< The vector.
+};
+
+/// SmallSetVector - A SetVector that performs no allocations if smaller than
+/// a certain size.
+template <typename T, unsigned N>
+class SmallSetVector : public SetVector<T, SmallVector<T, N>, SmallSet<T, N> > {
+public:
+ SmallSetVector() {}
+
+ /// @brief Initialize a SmallSetVector with a range of elements
+ template<typename It>
+ SmallSetVector(It Start, It End) {
+ this->insert(Start, End);
+ }
+};
+
+} // End llvm namespace
+
+// vim: sw=2 ai
+#endif
diff --git a/support/include/llvm/ADT/SmallPtrSet.h b/support/include/llvm/ADT/SmallPtrSet.h
new file mode 100644
index 0000000..ec7b78e
--- /dev/null
+++ b/support/include/llvm/ADT/SmallPtrSet.h
@@ -0,0 +1,271 @@
+//===- llvm/ADT/SmallPtrSet.h - 'Normally small' pointer set ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the SmallPtrSet class. See the doxygen comment for
+// SmallPtrSetImpl for more details on the algorithm used.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_SMALLPTRSET_H
+#define LLVM_ADT_SMALLPTRSET_H
+
+#include <cassert>
+#include <cstring>
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+
+/// SmallPtrSetImpl - This is the common code shared among all the
+/// SmallPtrSet<>'s, which is almost everything. SmallPtrSet has two modes, one
+/// for small and one for large sets.
+///
+/// Small sets use an array of pointers allocated in the SmallPtrSet object,
+/// which is treated as a simple array of pointers. When a pointer is added to
+/// the set, the array is scanned to see if the element already exists, if not
+/// the element is 'pushed back' onto the array. If we run out of space in the
+/// array, we grow into the 'large set' case. SmallSet should be used when the
+/// sets are often small. In this case, no memory allocation is used, and only
+/// light-weight and cache-efficient scanning is used.
+///
+/// Large sets use a classic exponentially-probed hash table. Empty buckets are
+/// represented with an illegal pointer value (-1) to allow null pointers to be
+/// inserted. Tombstones are represented with another illegal pointer value
+/// (-2), to allow deletion. The hash table is resized when the table is 3/4 or
+/// more. When this happens, the table is doubled in size.
+///
+class SmallPtrSetImpl {
+protected:
+ /// CurArray - This is the current set of buckets. If it points to
+ /// SmallArray, then the set is in 'small mode'.
+ const void **CurArray;
+ /// CurArraySize - The allocated size of CurArray, always a power of two.
+ /// Note that CurArray points to an array that has CurArraySize+1 elements in
+ /// it, so that the end iterator actually points to valid memory.
+ unsigned CurArraySize;
+
+ // If small, this is # elts allocated consequtively
+ unsigned NumElements;
+ unsigned NumTombstones;
+ const void *SmallArray[1]; // Must be last ivar.
+
+ // Helper to copy construct a SmallPtrSet.
+ SmallPtrSetImpl(const SmallPtrSetImpl& that);
+public:
+ SmallPtrSetImpl(unsigned SmallSize) {
+ assert(SmallSize && (SmallSize & (SmallSize-1)) == 0 &&
+ "Initial size must be a power of two!");
+ CurArray = &SmallArray[0];
+ CurArraySize = SmallSize;
+ // The end pointer, always valid, is set to a valid element to help the
+ // iterator.
+ CurArray[SmallSize] = 0;
+ clear();
+ }
+ ~SmallPtrSetImpl();
+
+ bool empty() const { return size() == 0; }
+ unsigned size() const { return NumElements; }
+
+ static void *getTombstoneMarker() { return reinterpret_cast<void*>(-2); }
+ static void *getEmptyMarker() {
+ // Note that -1 is chosen to make clear() efficiently implementable with
+ // memset and because it's not a valid pointer value.
+ return reinterpret_cast<void*>(-1);
+ }
+
+ void clear() {
+ // If the capacity of the array is huge, and the # elements used is small,
+ // shrink the array.
+ if (!isSmall() && NumElements*4 < CurArraySize && CurArraySize > 32)
+ return shrink_and_clear();
+
+ // Fill the array with empty markers.
+ memset(CurArray, -1, CurArraySize*sizeof(void*));
+ NumElements = 0;
+ NumTombstones = 0;
+ }
+
+protected:
+ /// insert_imp - This returns true if the pointer was new to the set, false if
+ /// it was already in the set. This is hidden from the client so that the
+ /// derived class can check that the right type of pointer is passed in.
+ bool insert_imp(const void * Ptr);
+
+ /// erase_imp - If the set contains the specified pointer, remove it and
+ /// return true, otherwise return false. This is hidden from the client so
+ /// that the derived class can check that the right type of pointer is passed
+ /// in.
+ bool erase_imp(const void * Ptr);
+
+ bool count_imp(const void * Ptr) const {
+ if (isSmall()) {
+ // Linear search for the item.
+ for (const void *const *APtr = SmallArray,
+ *const *E = SmallArray+NumElements; APtr != E; ++APtr)
+ if (*APtr == Ptr)
+ return true;
+ return false;
+ }
+
+ // Big set case.
+ return *FindBucketFor(Ptr) == Ptr;
+ }
+
+private:
+ bool isSmall() const { return CurArray == &SmallArray[0]; }
+
+ unsigned Hash(const void *Ptr) const {
+ return ((uintptr_t)Ptr >> 4) & (CurArraySize-1);
+ }
+ const void * const *FindBucketFor(const void *Ptr) const;
+ void shrink_and_clear();
+
+ /// Grow - Allocate a larger backing store for the buckets and move it over.
+ void Grow();
+
+ void operator=(const SmallPtrSetImpl &RHS); // DO NOT IMPLEMENT.
+protected:
+ void CopyFrom(const SmallPtrSetImpl &RHS);
+};
+
+/// SmallPtrSetIteratorImpl - This is the common base class shared between all
+/// instances of SmallPtrSetIterator.
+class SmallPtrSetIteratorImpl {
+protected:
+ const void *const *Bucket;
+public:
+ SmallPtrSetIteratorImpl(const void *const *BP) : Bucket(BP) {
+ AdvanceIfNotValid();
+ }
+
+ bool operator==(const SmallPtrSetIteratorImpl &RHS) const {
+ return Bucket == RHS.Bucket;
+ }
+ bool operator!=(const SmallPtrSetIteratorImpl &RHS) const {
+ return Bucket != RHS.Bucket;
+ }
+
+protected:
+ /// AdvanceIfNotValid - If the current bucket isn't valid, advance to a bucket
+ /// that is. This is guaranteed to stop because the end() bucket is marked
+ /// valid.
+ void AdvanceIfNotValid() {
+ while (*Bucket == SmallPtrSetImpl::getEmptyMarker() ||
+ *Bucket == SmallPtrSetImpl::getTombstoneMarker())
+ ++Bucket;
+ }
+};
+
+/// SmallPtrSetIterator - This implements a const_iterator for SmallPtrSet.
+template<typename PtrTy>
+class SmallPtrSetIterator : public SmallPtrSetIteratorImpl {
+public:
+ SmallPtrSetIterator(const void *const *BP) : SmallPtrSetIteratorImpl(BP) {}
+
+ // Most methods provided by baseclass.
+
+ const PtrTy operator*() const {
+ return static_cast<const PtrTy>(const_cast<void*>(*Bucket));
+ }
+
+ inline SmallPtrSetIterator& operator++() { // Preincrement
+ ++Bucket;
+ AdvanceIfNotValid();
+ return *this;
+ }
+
+ SmallPtrSetIterator operator++(int) { // Postincrement
+ SmallPtrSetIterator tmp = *this; ++*this; return tmp;
+ }
+};
+
+/// NextPowerOfTwo - This is a helper template that rounds N up to the next
+/// power of two.
+template<unsigned N>
+struct NextPowerOfTwo;
+
+/// NextPowerOfTwoH - If N is not a power of two, increase it. This is a helper
+/// template used to implement NextPowerOfTwo.
+template<unsigned N, bool isPowerTwo>
+struct NextPowerOfTwoH {
+ enum { Val = N };
+};
+template<unsigned N>
+struct NextPowerOfTwoH<N, false> {
+ enum {
+ // We could just use NextVal = N+1, but this converges faster. N|(N-1) sets
+ // the right-most zero bits to one all at once, e.g. 0b0011000 -> 0b0011111.
+ Val = NextPowerOfTwo<(N|(N-1)) + 1>::Val
+ };
+};
+
+template<unsigned N>
+struct NextPowerOfTwo {
+ enum { Val = NextPowerOfTwoH<N, (N&(N-1)) == 0>::Val };
+};
+
+
+/// SmallPtrSet - This class implements a set which is optimizer for holding
+/// SmallSize or less elements. This internally rounds up SmallSize to the next
+/// power of two if it is not already a power of two. See the comments above
+/// SmallPtrSetImpl for details of the algorithm.
+template<class PtrType, unsigned SmallSize>
+class SmallPtrSet : public SmallPtrSetImpl {
+ // Make sure that SmallSize is a power of two, round up if not.
+ enum { SmallSizePowTwo = NextPowerOfTwo<SmallSize>::Val };
+ void *SmallArray[SmallSizePowTwo];
+public:
+ SmallPtrSet() : SmallPtrSetImpl(NextPowerOfTwo<SmallSizePowTwo>::Val) {}
+ SmallPtrSet(const SmallPtrSet &that) : SmallPtrSetImpl(that) {}
+
+ template<typename It>
+ SmallPtrSet(It I, It E)
+ : SmallPtrSetImpl(NextPowerOfTwo<SmallSizePowTwo>::Val) {
+ insert(I, E);
+ }
+
+ /// insert - This returns true if the pointer was new to the set, false if it
+ /// was already in the set.
+ bool insert(PtrType Ptr) { return insert_imp(Ptr); }
+
+ /// erase - If the set contains the specified pointer, remove it and return
+ /// true, otherwise return false.
+ bool erase(PtrType Ptr) { return erase_imp(Ptr); }
+
+ /// count - Return true if the specified pointer is in the set.
+ bool count(PtrType Ptr) const { return count_imp(Ptr); }
+
+ template <typename IterT>
+ void insert(IterT I, IterT E) {
+ for (; I != E; ++I)
+ insert(*I);
+ }
+
+ typedef SmallPtrSetIterator<PtrType> iterator;
+ typedef SmallPtrSetIterator<PtrType> const_iterator;
+ inline iterator begin() const {
+ return iterator(CurArray);
+ }
+ inline iterator end() const {
+ return iterator(CurArray+CurArraySize);
+ }
+
+ // Allow assignment from any smallptrset with the same element type even if it
+ // doesn't have the same smallsize.
+ const SmallPtrSet<PtrType, SmallSize>&
+ operator=(const SmallPtrSet<PtrType, SmallSize> &RHS) {
+ CopyFrom(RHS);
+ return *this;
+ }
+
+};
+
+}
+
+#endif
diff --git a/support/include/llvm/ADT/SmallSet.h b/support/include/llvm/ADT/SmallSet.h
new file mode 100644
index 0000000..30e8ee5
--- /dev/null
+++ b/support/include/llvm/ADT/SmallSet.h
@@ -0,0 +1,112 @@
+//===- llvm/ADT/SmallSet.h - 'Normally small' sets --------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the SmallSet class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_SMALLSET_H
+#define LLVM_ADT_SMALLSET_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include <set>
+
+namespace llvm {
+
+/// SmallSet - This maintains a set of unique values, optimizing for the case
+/// when the set is small (less than N). In this case, the set can be
+/// maintained with no mallocs. If the set gets large, we expand to using an
+/// std::set to maintain reasonable lookup times.
+///
+/// Note that this set does not provide a way to iterate over members in the
+/// set.
+template <typename T, unsigned N>
+class SmallSet {
+ /// Use a SmallVector to hold the elements here (even though it will never
+ /// reach it's 'large' stage) to avoid calling the default ctors of elements
+ /// we will never use.
+ SmallVector<T, N> Vector;
+ std::set<T> Set;
+ typedef typename SmallVector<T, N>::const_iterator VIterator;
+ typedef typename SmallVector<T, N>::iterator mutable_iterator;
+public:
+ SmallSet() {}
+
+ bool empty() const { return Vector.empty() && Set.empty(); }
+ unsigned size() const {
+ return isSmall() ? Vector.size() : Set.size();
+ }
+
+ /// count - Return true if the element is in the set.
+ bool count(const T &V) const {
+ if (isSmall()) {
+ // Since the collection is small, just do a linear search.
+ return vfind(V) != Vector.end();
+ } else {
+ return Set.count(V);
+ }
+ }
+
+ /// insert - Insert an element into the set if it isn't already there.
+ bool insert(const T &V) {
+ if (!isSmall())
+ return Set.insert(V).second;
+
+ VIterator I = vfind(V);
+ if (I != Vector.end()) // Don't reinsert if it already exists.
+ return false;
+ if (Vector.size() < N) {
+ Vector.push_back(V);
+ return true;
+ }
+
+ // Otherwise, grow from vector to set.
+ while (!Vector.empty()) {
+ Set.insert(Vector.back());
+ Vector.pop_back();
+ }
+ Set.insert(V);
+ return true;
+ }
+
+ bool erase(const T &V) {
+ if (!isSmall())
+ return Set.erase(V);
+ for (mutable_iterator I = Vector.begin(), E = Vector.end(); I != E; ++I)
+ if (*I == V) {
+ Vector.erase(I);
+ return true;
+ }
+ return false;
+ }
+
+ void clear() {
+ Vector.clear();
+ Set.clear();
+ }
+private:
+ bool isSmall() const { return Set.empty(); }
+
+ VIterator vfind(const T &V) const {
+ for (VIterator I = Vector.begin(), E = Vector.end(); I != E; ++I)
+ if (*I == V)
+ return I;
+ return Vector.end();
+ }
+};
+
+/// If this set is of pointer values, transparently switch over to using
+/// SmallPtrSet for performance.
+template <typename PointeeType, unsigned N>
+class SmallSet<PointeeType*, N> : public SmallPtrSet<PointeeType*, N> {};
+
+} // end namespace llvm
+
+#endif
diff --git a/support/include/llvm/ADT/SmallString.h b/support/include/llvm/ADT/SmallString.h
new file mode 100644
index 0000000..2818ebb
--- /dev/null
+++ b/support/include/llvm/ADT/SmallString.h
@@ -0,0 +1,62 @@
+//===- llvm/ADT/SmallString.h - 'Normally small' strings --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the SmallString class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_SMALLSTRING_H
+#define LLVM_ADT_SMALLSTRING_H
+
+#include "llvm/ADT/SmallVector.h"
+#include <cstring>
+
+namespace llvm {
+
+/// SmallString - A SmallString is just a SmallVector with methods and accessors
+/// that make it work better as a string (e.g. operator+ etc).
+template<unsigned InternalLen>
+class SmallString : public SmallVector<char, InternalLen> {
+public:
+ // Default ctor - Initialize to empty.
+ SmallString() {}
+
+ // Initialize with a range.
+ template<typename ItTy>
+ SmallString(ItTy S, ItTy E) : SmallVector<char, InternalLen>(S, E) {}
+
+ // Copy ctor.
+ SmallString(const SmallString &RHS) : SmallVector<char, InternalLen>(RHS) {}
+
+
+ // Extra methods.
+ const char *c_str() const {
+ SmallString *This = const_cast<SmallString*>(this);
+ // Ensure that there is a \0 at the end of the string.
+ This->reserve(this->size()+1);
+ This->End[0] = 0;
+ return this->begin();
+ }
+
+ // Extra operators.
+ SmallString &operator+=(const char *RHS) {
+ this->append(RHS, RHS+strlen(RHS));
+ return *this;
+ }
+ SmallString &operator+=(char C) {
+ this->push_back(C);
+ return *this;
+ }
+
+};
+
+
+}
+
+#endif
diff --git a/support/include/llvm/ADT/SmallVector.h b/support/include/llvm/ADT/SmallVector.h
new file mode 100644
index 0000000..eb2ffb9
--- /dev/null
+++ b/support/include/llvm/ADT/SmallVector.h
@@ -0,0 +1,504 @@
+//===- llvm/ADT/SmallVector.h - 'Normally small' vectors --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the SmallVector class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_SMALLVECTOR_H
+#define LLVM_ADT_SMALLVECTOR_H
+
+#include "llvm/ADT/iterator"
+#include <algorithm>
+#include <memory>
+
+#ifdef _MSC_VER
+namespace std {
+#if _MSC_VER <= 1310
+ // Work around flawed VC++ implementation of std::uninitialized_copy. Define
+ // additional overloads so that elements with pointer types are recognized as
+ // scalars and not objects, causing bizarre type conversion errors.
+ template<class T1, class T2>
+ inline _Scalar_ptr_iterator_tag _Ptr_cat(T1 **, T2 **) {
+ _Scalar_ptr_iterator_tag _Cat;
+ return _Cat;
+ }
+
+ template<class T1, class T2>
+ inline _Scalar_ptr_iterator_tag _Ptr_cat(T1* const *, T2 **) {
+ _Scalar_ptr_iterator_tag _Cat;
+ return _Cat;
+ }
+#else
+// FIXME: It is not clear if the problem is fixed in VS 2005. What is clear
+// is that the above hack won't work if it wasn't fixed.
+#endif
+}
+#endif
+
+namespace llvm {
+
+/// SmallVectorImpl - This class consists of common code factored out of the
+/// SmallVector class to reduce code duplication based on the SmallVector 'N'
+/// template parameter.
+template <typename T>
+class SmallVectorImpl {
+protected:
+ T *Begin, *End, *Capacity;
+
+ // Allocate raw space for N elements of type T. If T has a ctor or dtor, we
+ // don't want it to be automatically run, so we need to represent the space as
+ // something else. An array of char would work great, but might not be
+ // aligned sufficiently. Instead, we either use GCC extensions, or some
+ // number of union instances for the space, which guarantee maximal alignment.
+protected:
+#ifdef __GNUC__
+ typedef char U;
+ U FirstEl __attribute__((aligned));
+#else
+ union U {
+ double D;
+ long double LD;
+ long long L;
+ void *P;
+ } FirstEl;
+#endif
+ // Space after 'FirstEl' is clobbered, do not add any instance vars after it.
+public:
+ // Default ctor - Initialize to empty.
+ SmallVectorImpl(unsigned N)
+ : Begin(reinterpret_cast<T*>(&FirstEl)),
+ End(reinterpret_cast<T*>(&FirstEl)),
+ Capacity(reinterpret_cast<T*>(&FirstEl)+N) {
+ }
+
+ ~SmallVectorImpl() {
+ // Destroy the constructed elements in the vector.
+ destroy_range(Begin, End);
+
+ // If this wasn't grown from the inline copy, deallocate the old space.
+ if (!isSmall())
+ delete[] reinterpret_cast<char*>(Begin);
+ }
+
+ typedef size_t size_type;
+ typedef T* iterator;
+ typedef const T* const_iterator;
+
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+ typedef std::reverse_iterator<iterator> reverse_iterator;
+
+ typedef T& reference;
+ typedef const T& const_reference;
+
+ bool empty() const { return Begin == End; }
+ size_type size() const { return End-Begin; }
+
+ // forward iterator creation methods.
+ iterator begin() { return Begin; }
+ const_iterator begin() const { return Begin; }
+ iterator end() { return End; }
+ const_iterator end() const { return End; }
+
+ // reverse iterator creation methods.
+ reverse_iterator rbegin() { return reverse_iterator(end()); }
+ const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); }
+ reverse_iterator rend() { return reverse_iterator(begin()); }
+ const_reverse_iterator rend() const { return const_reverse_iterator(begin());}
+
+
+ reference operator[](unsigned idx) {
+ return Begin[idx];
+ }
+ const_reference operator[](unsigned idx) const {
+ return Begin[idx];
+ }
+
+ reference front() {
+ return begin()[0];
+ }
+ const_reference front() const {
+ return begin()[0];
+ }
+
+ reference back() {
+ return end()[-1];
+ }
+ const_reference back() const {
+ return end()[-1];
+ }
+
+ void push_back(const_reference Elt) {
+ if (End < Capacity) {
+ Retry:
+ new (End) T(Elt);
+ ++End;
+ return;
+ }
+ grow();
+ goto Retry;
+ }
+
+ void pop_back() {
+ --End;
+ End->~T();
+ }
+
+ void clear() {
+ destroy_range(Begin, End);
+ End = Begin;
+ }
+
+ void resize(unsigned N) {
+ if (N < size()) {
+ destroy_range(Begin+N, End);
+ End = Begin+N;
+ } else if (N > size()) {
+ if (unsigned(Capacity-Begin) < N)
+ grow(N);
+ construct_range(End, Begin+N, T());
+ End = Begin+N;
+ }
+ }
+
+ void resize(unsigned N, const T &NV) {
+ if (N < size()) {
+ destroy_range(Begin+N, End);
+ End = Begin+N;
+ } else if (N > size()) {
+ if (unsigned(Capacity-Begin) < N)
+ grow(N);
+ construct_range(End, Begin+N, NV);
+ End = Begin+N;
+ }
+ }
+
+ void reserve(unsigned N) {
+ if (unsigned(Capacity-Begin) < N)
+ grow(N);
+ }
+
+ void swap(SmallVectorImpl &RHS);
+
+ /// append - Add the specified range to the end of the SmallVector.
+ ///
+ template<typename in_iter>
+ void append(in_iter in_start, in_iter in_end) {
+ unsigned NumInputs = std::distance(in_start, in_end);
+ // Grow allocated space if needed.
+ if (End+NumInputs > Capacity)
+ grow(size()+NumInputs);
+
+ // Copy the new elements over.
+ std::uninitialized_copy(in_start, in_end, End);
+ End += NumInputs;
+ }
+
+ void assign(unsigned NumElts, const T &Elt) {
+ clear();
+ if (unsigned(Capacity-Begin) < NumElts)
+ grow(NumElts);
+ End = Begin+NumElts;
+ construct_range(Begin, End, Elt);
+ }
+
+ void erase(iterator I) {
+ // Shift all elts down one.
+ std::copy(I+1, End, I);
+ // Drop the last elt.
+ pop_back();
+ }
+
+ void erase(iterator S, iterator E) {
+ // Shift all elts down.
+ iterator I = std::copy(E, End, S);
+ // Drop the last elts.
+ destroy_range(I, End);
+ End = I;
+ }
+
+ iterator insert(iterator I, const T &Elt) {
+ if (I == End) { // Important special case for empty vector.
+ push_back(Elt);
+ return end()-1;
+ }
+
+ if (End < Capacity) {
+ Retry:
+ new (End) T(back());
+ ++End;
+ // Push everything else over.
+ std::copy_backward(I, End-1, End);
+ *I = Elt;
+ return I;
+ }
+ unsigned EltNo = I-Begin;
+ grow();
+ I = Begin+EltNo;
+ goto Retry;
+ }
+
+ template<typename ItTy>
+ iterator insert(iterator I, ItTy From, ItTy To) {
+ if (I == End) { // Important special case for empty vector.
+ append(From, To);
+ return end()-1;
+ }
+
+ unsigned NumToInsert = std::distance(From, To);
+ // Convert iterator to elt# to avoid invalidating iterator when we reserve()
+ unsigned InsertElt = I-begin();
+
+ // Ensure there is enough space.
+ reserve(size() + NumToInsert);
+
+ // Uninvalidate the iterator.
+ I = begin()+InsertElt;
+
+ // If we already have this many elements in the collection, append the
+ // dest elements at the end, then copy over the appropriate elements. Since
+ // we already reserved space, we know that this won't reallocate the vector.
+ if (size() >= NumToInsert) {
+ T *OldEnd = End;
+ append(End-NumToInsert, End);
+
+ // Copy the existing elements that get replaced.
+ std::copy(I, OldEnd-NumToInsert, I+NumToInsert);
+
+ std::copy(From, To, I);
+ return I;
+ }
+
+ // Otherwise, we're inserting more elements than exist already, and we're
+ // not inserting at the end.
+
+ // Copy over the elements that we're about to overwrite.
+ T *OldEnd = End;
+ End += NumToInsert;
+ unsigned NumOverwritten = OldEnd-I;
+ std::uninitialized_copy(I, OldEnd, End-NumOverwritten);
+
+ // Replace the overwritten part.
+ std::copy(From, From+NumOverwritten, I);
+
+ // Insert the non-overwritten middle part.
+ std::uninitialized_copy(From+NumOverwritten, To, OldEnd);
+ return I;
+ }
+
+ const SmallVectorImpl &operator=(const SmallVectorImpl &RHS);
+
+private:
+ /// isSmall - Return true if this is a smallvector which has not had dynamic
+ /// memory allocated for it.
+ bool isSmall() const {
+ return reinterpret_cast<const void*>(Begin) ==
+ reinterpret_cast<const void*>(&FirstEl);
+ }
+
+ /// grow - double the size of the allocated memory, guaranteeing space for at
+ /// least one more element or MinSize if specified.
+ void grow(unsigned MinSize = 0);
+
+ void construct_range(T *S, T *E, const T &Elt) {
+ for (; S != E; ++S)
+ new (S) T(Elt);
+ }
+
+ void destroy_range(T *S, T *E) {
+ while (S != E) {
+ --E;
+ E->~T();
+ }
+ }
+};
+
+// Define this out-of-line to dissuade the C++ compiler from inlining it.
+template <typename T>
+void SmallVectorImpl<T>::grow(unsigned MinSize) {
+ unsigned CurCapacity = unsigned(Capacity-Begin);
+ unsigned CurSize = unsigned(size());
+ unsigned NewCapacity = 2*CurCapacity;
+ if (NewCapacity < MinSize)
+ NewCapacity = MinSize;
+ T *NewElts = reinterpret_cast<T*>(new char[NewCapacity*sizeof(T)]);
+
+ // Copy the elements over.
+ std::uninitialized_copy(Begin, End, NewElts);
+
+ // Destroy the original elements.
+ destroy_range(Begin, End);
+
+ // If this wasn't grown from the inline copy, deallocate the old space.
+ if (!isSmall())
+ delete[] reinterpret_cast<char*>(Begin);
+
+ Begin = NewElts;
+ End = NewElts+CurSize;
+ Capacity = Begin+NewCapacity;
+}
+
+template <typename T>
+void SmallVectorImpl<T>::swap(SmallVectorImpl<T> &RHS) {
+ if (this == &RHS) return;
+
+ // We can only avoid copying elements if neither vector is small.
+ if (!isSmall() && !RHS.isSmall()) {
+ std::swap(Begin, RHS.Begin);
+ std::swap(End, RHS.End);
+ std::swap(Capacity, RHS.Capacity);
+ return;
+ }
+ if (Begin+RHS.size() > Capacity)
+ grow(RHS.size());
+ if (RHS.begin()+size() > RHS.Capacity)
+ RHS.grow(size());
+
+ // Swap the shared elements.
+ unsigned NumShared = size();
+ if (NumShared > RHS.size()) NumShared = RHS.size();
+ for (unsigned i = 0; i != NumShared; ++i)
+ std::swap(Begin[i], RHS[i]);
+
+ // Copy over the extra elts.
+ if (size() > RHS.size()) {
+ unsigned EltDiff = size() - RHS.size();
+ std::uninitialized_copy(Begin+NumShared, End, RHS.End);
+ RHS.End += EltDiff;
+ destroy_range(Begin+NumShared, End);
+ End = Begin+NumShared;
+ } else if (RHS.size() > size()) {
+ unsigned EltDiff = RHS.size() - size();
+ std::uninitialized_copy(RHS.Begin+NumShared, RHS.End, End);
+ End += EltDiff;
+ destroy_range(RHS.Begin+NumShared, RHS.End);
+ RHS.End = RHS.Begin+NumShared;
+ }
+}
+
+template <typename T>
+const SmallVectorImpl<T> &
+SmallVectorImpl<T>::operator=(const SmallVectorImpl<T> &RHS) {
+ // Avoid self-assignment.
+ if (this == &RHS) return *this;
+
+ // If we already have sufficient space, assign the common elements, then
+ // destroy any excess.
+ unsigned RHSSize = unsigned(RHS.size());
+ unsigned CurSize = unsigned(size());
+ if (CurSize >= RHSSize) {
+ // Assign common elements.
+ iterator NewEnd;
+ if (RHSSize)
+ NewEnd = std::copy(RHS.Begin, RHS.Begin+RHSSize, Begin);
+ else
+ NewEnd = Begin;
+
+ // Destroy excess elements.
+ destroy_range(NewEnd, End);
+
+ // Trim.
+ End = NewEnd;
+ return *this;
+ }
+
+ // If we have to grow to have enough elements, destroy the current elements.
+ // This allows us to avoid copying them during the grow.
+ if (unsigned(Capacity-Begin) < RHSSize) {
+ // Destroy current elements.
+ destroy_range(Begin, End);
+ End = Begin;
+ CurSize = 0;
+ grow(RHSSize);
+ } else if (CurSize) {
+ // Otherwise, use assignment for the already-constructed elements.
+ std::copy(RHS.Begin, RHS.Begin+CurSize, Begin);
+ }
+
+ // Copy construct the new elements in place.
+ std::uninitialized_copy(RHS.Begin+CurSize, RHS.End, Begin+CurSize);
+
+ // Set end.
+ End = Begin+RHSSize;
+ return *this;
+}
+
+/// SmallVector - This is a 'vector' (really, a variable-sized array), optimized
+/// for the case when the array is small. It contains some number of elements
+/// in-place, which allows it to avoid heap allocation when the actual number of
+/// elements is below that threshold. This allows normal "small" cases to be
+/// fast without losing generality for large inputs.
+///
+/// Note that this does not attempt to be exception safe.
+///
+template <typename T, unsigned N>
+class SmallVector : public SmallVectorImpl<T> {
+ /// InlineElts - These are 'N-1' elements that are stored inline in the body
+ /// of the vector. The extra '1' element is stored in SmallVectorImpl.
+ typedef typename SmallVectorImpl<T>::U U;
+ enum {
+ // MinUs - The number of U's require to cover N T's.
+ MinUs = (sizeof(T)*N+sizeof(U)-1)/sizeof(U),
+
+ // NumInlineEltsElts - The number of elements actually in this array. There
+ // is already one in the parent class, and we have to round up to avoid
+ // having a zero-element array.
+ NumInlineEltsElts = (MinUs - 1) > 0 ? (MinUs - 1) : 1,
+
+ // NumTsAvailable - The number of T's we actually have space for, which may
+ // be more than N due to rounding.
+ NumTsAvailable = (NumInlineEltsElts+1)*sizeof(U) / sizeof(T)
+ };
+ U InlineElts[NumInlineEltsElts];
+public:
+ SmallVector() : SmallVectorImpl<T>(NumTsAvailable) {
+ }
+
+ explicit SmallVector(unsigned Size, const T &Value = T())
+ : SmallVectorImpl<T>(NumTsAvailable) {
+ this->reserve(Size);
+ while (Size--)
+ push_back(Value);
+ }
+
+ template<typename ItTy>
+ SmallVector(ItTy S, ItTy E) : SmallVectorImpl<T>(NumTsAvailable) {
+ append(S, E);
+ }
+
+ SmallVector(const SmallVector &RHS) : SmallVectorImpl<T>(NumTsAvailable) {
+ if (!RHS.empty())
+ operator=(RHS);
+ }
+
+ const SmallVector &operator=(const SmallVector &RHS) {
+ SmallVectorImpl<T>::operator=(RHS);
+ return *this;
+ }
+};
+
+} // End llvm namespace
+
+namespace std {
+ /// Implement std::swap in terms of SmallVector swap.
+ template<typename T>
+ inline void
+ swap(llvm::SmallVectorImpl<T> &LHS, llvm::SmallVectorImpl<T> &RHS) {
+ LHS.swap(RHS);
+ }
+
+ /// Implement std::swap in terms of SmallVector swap.
+ template<typename T, unsigned N>
+ inline void
+ swap(llvm::SmallVector<T, N> &LHS, llvm::SmallVector<T, N> &RHS) {
+ LHS.swap(RHS);
+ }
+}
+
+#endif
diff --git a/support/include/llvm/ADT/SparseBitVector.h b/support/include/llvm/ADT/SparseBitVector.h
new file mode 100644
index 0000000..8dbf0c7
--- /dev/null
+++ b/support/include/llvm/ADT/SparseBitVector.h
@@ -0,0 +1,866 @@
+//===- llvm/ADT/SparseBitVector.h - Efficient Sparse BitVector -*- C++ -*- ===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Daniel Berlin and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the SparseBitVector class. See the doxygen comment for
+// SparseBitVector for more details on the algorithm used.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_SPARSEBITVECTOR_H
+#define LLVM_ADT_SPARSEBITVECTOR_H
+
+#include <cassert>
+#include <cstring>
+#include <algorithm>
+#include "llvm/Support/DataTypes.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/ADT/ilist"
+namespace llvm {
+
+/// SparseBitVector is an implementation of a bitvector that is sparse by only
+/// storing the elements that have non-zero bits set. In order to make this
+/// fast for the most common cases, SparseBitVector is implemented as a linked
+/// list of SparseBitVectorElements. We maintain a pointer to the last
+/// SparseBitVectorElement accessed (in the form of a list iterator), in order
+/// to make multiple in-order test/set constant time after the first one is
+/// executed. Note that using vectors to store SparseBitVectorElement's does
+/// not work out very well because it causes insertion in the middle to take
+/// enormous amounts of time with a large amount of bits. Other structures that
+/// have better worst cases for insertion in the middle (various balanced trees,
+/// etc) do not perform as well in practice as a linked list with this iterator
+/// kept up to date. They are also significantly more memory intensive.
+
+
+template <unsigned ElementSize = 128>
+struct SparseBitVectorElement {
+public:
+ typedef unsigned long BitWord;
+ enum {
+ BITWORD_SIZE = sizeof(BitWord) * 8,
+ BITWORDS_PER_ELEMENT = (ElementSize + BITWORD_SIZE - 1) / BITWORD_SIZE,
+ BITS_PER_ELEMENT = ElementSize
+ };
+
+ SparseBitVectorElement<ElementSize> *getNext() const {
+ return Next;
+ }
+ SparseBitVectorElement<ElementSize> *getPrev() const {
+ return Prev;
+ }
+
+ void setNext(SparseBitVectorElement<ElementSize> *RHS) {
+ Next = RHS;
+ }
+ void setPrev(SparseBitVectorElement<ElementSize> *RHS) {
+ Prev = RHS;
+ }
+
+private:
+ SparseBitVectorElement<ElementSize> *Next;
+ SparseBitVectorElement<ElementSize> *Prev;
+ // Index of Element in terms of where first bit starts.
+ unsigned ElementIndex;
+ BitWord Bits[BITWORDS_PER_ELEMENT];
+ // Needed for sentinels
+ SparseBitVectorElement() {
+ ElementIndex = ~0UL;
+ memset(&Bits[0], 0, sizeof (BitWord) * BITWORDS_PER_ELEMENT);
+ }
+
+ friend struct ilist_traits<SparseBitVectorElement<ElementSize> >;
+public:
+ explicit SparseBitVectorElement(unsigned Idx) {
+ ElementIndex = Idx;
+ memset(&Bits[0], 0, sizeof (BitWord) * BITWORDS_PER_ELEMENT);
+ }
+
+ ~SparseBitVectorElement() {
+ }
+
+ // Copy ctor.
+ SparseBitVectorElement(const SparseBitVectorElement &RHS) {
+ ElementIndex = RHS.ElementIndex;
+ std::copy(&RHS.Bits[0], &RHS.Bits[BITWORDS_PER_ELEMENT], Bits);
+ }
+
+ // Comparison.
+ bool operator==(const SparseBitVectorElement &RHS) const {
+ if (ElementIndex != RHS.ElementIndex)
+ return false;
+ for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i)
+ if (Bits[i] != RHS.Bits[i])
+ return false;
+ return true;
+ }
+
+ bool operator!=(const SparseBitVectorElement &RHS) const {
+ return !(*this == RHS);
+ }
+
+ // Return the bits that make up word Idx in our element.
+ BitWord word(unsigned Idx) const {
+ assert (Idx < BITWORDS_PER_ELEMENT);
+ return Bits[Idx];
+ }
+
+ unsigned index() const {
+ return ElementIndex;
+ }
+
+ bool empty() const {
+ for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i)
+ if (Bits[i])
+ return false;
+ return true;
+ }
+
+ void set(unsigned Idx) {
+ Bits[Idx / BITWORD_SIZE] |= 1L << (Idx % BITWORD_SIZE);
+ }
+
+ bool test_and_set (unsigned Idx) {
+ bool old = test(Idx);
+ if (!old) {
+ set(Idx);
+ return true;
+ }
+ return false;
+ }
+
+ void reset(unsigned Idx) {
+ Bits[Idx / BITWORD_SIZE] &= ~(1L << (Idx % BITWORD_SIZE));
+ }
+
+ bool test(unsigned Idx) const {
+ return Bits[Idx / BITWORD_SIZE] & (1L << (Idx % BITWORD_SIZE));
+ }
+
+ unsigned count() const {
+ unsigned NumBits = 0;
+ for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i)
+ if (sizeof(BitWord) == 4)
+ NumBits += CountPopulation_32(Bits[i]);
+ else if (sizeof(BitWord) == 8)
+ NumBits += CountPopulation_64(Bits[i]);
+ else
+ assert(0 && "Unsupported!");
+ return NumBits;
+ }
+
+ /// find_first - Returns the index of the first set bit.
+ int find_first() const {
+ for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i)
+ if (Bits[i] != 0) {
+ if (sizeof(BitWord) == 4)
+ return i * BITWORD_SIZE + CountTrailingZeros_32(Bits[i]);
+ else if (sizeof(BitWord) == 8)
+ return i * BITWORD_SIZE + CountTrailingZeros_64(Bits[i]);
+ else
+ assert(0 && "Unsupported!");
+ }
+ assert(0 && "Illegal empty element");
+ }
+
+ /// find_next - Returns the index of the next set bit starting from the
+ /// "Curr" bit. Returns -1 if the next set bit is not found.
+ int find_next(unsigned Curr) const {
+ if (Curr >= BITS_PER_ELEMENT)
+ return -1;
+
+ unsigned WordPos = Curr / BITWORD_SIZE;
+ unsigned BitPos = Curr % BITWORD_SIZE;
+ BitWord Copy = Bits[WordPos];
+ assert (WordPos <= BITWORDS_PER_ELEMENT
+ && "Word Position outside of element");
+
+ // Mask off previous bits.
+ Copy &= ~0L << BitPos;
+
+ if (Copy != 0) {
+ if (sizeof(BitWord) == 4)
+ return WordPos * BITWORD_SIZE + CountTrailingZeros_32(Copy);
+ else if (sizeof(BitWord) == 8)
+ return WordPos * BITWORD_SIZE + CountTrailingZeros_64(Copy);
+ else
+ assert(0 && "Unsupported!");
+ }
+
+ // Check subsequent words.
+ for (unsigned i = WordPos+1; i < BITWORDS_PER_ELEMENT; ++i)
+ if (Bits[i] != 0) {
+ if (sizeof(BitWord) == 4)
+ return i * BITWORD_SIZE + CountTrailingZeros_32(Bits[i]);
+ else if (sizeof(BitWord) == 8)
+ return i * BITWORD_SIZE + CountTrailingZeros_64(Bits[i]);
+ else
+ assert(0 && "Unsupported!");
+ }
+ return -1;
+ }
+
+ // Union this element with RHS and return true if this one changed.
+ bool unionWith(const SparseBitVectorElement &RHS) {
+ bool changed = false;
+ for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) {
+ BitWord old = changed ? 0 : Bits[i];
+
+ Bits[i] |= RHS.Bits[i];
+ if (!changed && old != Bits[i])
+ changed = true;
+ }
+ return changed;
+ }
+
+ // Return true if we have any bits in common with RHS
+ bool intersects(const SparseBitVectorElement &RHS) const {
+ for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) {
+ if (RHS.Bits[i] & Bits[i])
+ return true;
+ }
+ return false;
+ }
+
+ // Intersect this Element with RHS and return true if this one changed.
+ // BecameZero is set to true if this element became all-zero bits.
+ bool intersectWith(const SparseBitVectorElement &RHS,
+ bool &BecameZero) {
+ bool changed = false;
+ bool allzero = true;
+
+ BecameZero = false;
+ for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) {
+ BitWord old = changed ? 0 : Bits[i];
+
+ Bits[i] &= RHS.Bits[i];
+ if (Bits[i] != 0)
+ allzero = false;
+
+ if (!changed && old != Bits[i])
+ changed = true;
+ }
+ BecameZero = allzero;
+ return changed;
+ }
+ // Intersect this Element with the complement of RHS and return true if this
+ // one changed. BecameZero is set to true if this element became all-zero
+ // bits.
+ bool intersectWithComplement(const SparseBitVectorElement &RHS,
+ bool &BecameZero) {
+ bool changed = false;
+ bool allzero = true;
+
+ BecameZero = false;
+ for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) {
+ BitWord old = changed ? 0 : Bits[i];
+
+ Bits[i] &= ~RHS.Bits[i];
+ if (Bits[i] != 0)
+ allzero = false;
+
+ if (!changed && old != Bits[i])
+ changed = true;
+ }
+ BecameZero = allzero;
+ return changed;
+ }
+ // Three argument version of intersectWithComplement that intersects
+ // RHS1 & ~RHS2 into this element
+ void intersectWithComplement(const SparseBitVectorElement &RHS1,
+ const SparseBitVectorElement &RHS2,
+ bool &BecameZero) {
+ bool allzero = true;
+
+ BecameZero = false;
+ for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) {
+ Bits[i] = RHS1.Bits[i] & ~RHS2.Bits[i];
+ if (Bits[i] != 0)
+ allzero = false;
+ }
+ BecameZero = allzero;
+ }
+
+ // Get a hash value for this element;
+ uint64_t getHashValue() const {
+ uint64_t HashVal = 0;
+ for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) {
+ HashVal ^= Bits[i];
+ }
+ return HashVal;
+ }
+};
+
+template <unsigned ElementSize = 128>
+class SparseBitVector {
+ typedef ilist<SparseBitVectorElement<ElementSize> > ElementList;
+ typedef typename ElementList::iterator ElementListIter;
+ typedef typename ElementList::const_iterator ElementListConstIter;
+ enum {
+ BITWORD_SIZE = SparseBitVectorElement<ElementSize>::BITWORD_SIZE
+ };
+
+ // Pointer to our current Element.
+ ElementListIter CurrElementIter;
+ ElementList Elements;
+
+ // This is like std::lower_bound, except we do linear searching from the
+ // current position.
+ ElementListIter FindLowerBound(unsigned ElementIndex) {
+
+ if (Elements.empty()) {
+ CurrElementIter = Elements.begin();
+ return Elements.begin();
+ }
+
+ // Make sure our current iterator is valid.
+ if (CurrElementIter == Elements.end())
+ --CurrElementIter;
+
+ // Search from our current iterator, either backwards or forwards,
+ // depending on what element we are looking for.
+ ElementListIter ElementIter = CurrElementIter;
+ if (CurrElementIter->index() == ElementIndex) {
+ return ElementIter;
+ } else if (CurrElementIter->index() > ElementIndex) {
+ while (ElementIter != Elements.begin()
+ && ElementIter->index() > ElementIndex)
+ --ElementIter;
+ } else {
+ while (ElementIter != Elements.end() &&
+ ElementIter->index() < ElementIndex)
+ ++ElementIter;
+ }
+ CurrElementIter = ElementIter;
+ return ElementIter;
+ }
+
+ // Iterator to walk set bits in the bitmap. This iterator is a lot uglier
+ // than it would be, in order to be efficient.
+ class SparseBitVectorIterator {
+ private:
+ bool AtEnd;
+
+ const SparseBitVector<ElementSize> *BitVector;
+
+ // Current element inside of bitmap.
+ ElementListConstIter Iter;
+
+ // Current bit number inside of our bitmap.
+ unsigned BitNumber;
+
+ // Current word number inside of our element.
+ unsigned WordNumber;
+
+ // Current bits from the element.
+ typename SparseBitVectorElement<ElementSize>::BitWord Bits;
+
+ // Move our iterator to the first non-zero bit in the bitmap.
+ void AdvanceToFirstNonZero() {
+ if (AtEnd)
+ return;
+ if (BitVector->Elements.empty()) {
+ AtEnd = true;
+ return;
+ }
+ Iter = BitVector->Elements.begin();
+ BitNumber = Iter->index() * ElementSize;
+ unsigned BitPos = Iter->find_first();
+ BitNumber += BitPos;
+ WordNumber = (BitNumber % ElementSize) / BITWORD_SIZE;
+ Bits = Iter->word(WordNumber);
+ Bits >>= BitPos % BITWORD_SIZE;
+ }
+
+ // Move our iterator to the next non-zero bit.
+ void AdvanceToNextNonZero() {
+ if (AtEnd)
+ return;
+
+ while (Bits && !(Bits & 1)) {
+ Bits >>= 1;
+ BitNumber += 1;
+ }
+
+ // See if we ran out of Bits in this word.
+ if (!Bits) {
+ int NextSetBitNumber = Iter->find_next(BitNumber % ElementSize) ;
+ // If we ran out of set bits in this element, move to next element.
+ if (NextSetBitNumber == -1 || (BitNumber % ElementSize == 0)) {
+ ++Iter;
+ WordNumber = 0;
+
+ // We may run out of elements in the bitmap.
+ if (Iter == BitVector->Elements.end()) {
+ AtEnd = true;
+ return;
+ }
+ // Set up for next non zero word in bitmap.
+ BitNumber = Iter->index() * ElementSize;
+ NextSetBitNumber = Iter->find_first();
+ BitNumber += NextSetBitNumber;
+ WordNumber = (BitNumber % ElementSize) / BITWORD_SIZE;
+ Bits = Iter->word(WordNumber);
+ Bits >>= NextSetBitNumber % BITWORD_SIZE;
+ } else {
+ WordNumber = (NextSetBitNumber % ElementSize) / BITWORD_SIZE;
+ Bits = Iter->word(WordNumber);
+ Bits >>= NextSetBitNumber % BITWORD_SIZE;
+ BitNumber = Iter->index() * ElementSize;
+ BitNumber += NextSetBitNumber;
+ }
+ }
+ }
+ public:
+ // Preincrement.
+ inline SparseBitVectorIterator& operator++() {
+ ++BitNumber;
+ Bits >>= 1;
+ AdvanceToNextNonZero();
+ return *this;
+ }
+
+ // Postincrement.
+ inline SparseBitVectorIterator operator++(int) {
+ SparseBitVectorIterator tmp = *this;
+ ++*this;
+ return tmp;
+ }
+
+ // Return the current set bit number.
+ unsigned operator*() const {
+ return BitNumber;
+ }
+
+ bool operator==(const SparseBitVectorIterator &RHS) const {
+ // If they are both at the end, ignore the rest of the fields.
+ if (AtEnd && RHS.AtEnd)
+ return true;
+ // Otherwise they are the same if they have the same bit number and
+ // bitmap.
+ return AtEnd == RHS.AtEnd && RHS.BitNumber == BitNumber;
+ }
+ bool operator!=(const SparseBitVectorIterator &RHS) const {
+ return !(*this == RHS);
+ }
+ SparseBitVectorIterator(): BitVector(NULL) {
+ }
+
+
+ SparseBitVectorIterator(const SparseBitVector<ElementSize> *RHS,
+ bool end = false):BitVector(RHS) {
+ Iter = BitVector->Elements.begin();
+ BitNumber = 0;
+ Bits = 0;
+ WordNumber = ~0;
+ AtEnd = end;
+ AdvanceToFirstNonZero();
+ }
+ };
+public:
+ typedef SparseBitVectorIterator iterator;
+
+ SparseBitVector () {
+ CurrElementIter = Elements.begin ();
+ }
+
+ ~SparseBitVector() {
+ }
+
+ // SparseBitVector copy ctor.
+ SparseBitVector(const SparseBitVector &RHS) {
+ ElementListConstIter ElementIter = RHS.Elements.begin();
+ while (ElementIter != RHS.Elements.end()) {
+ Elements.push_back(SparseBitVectorElement<ElementSize>(*ElementIter));
+ ++ElementIter;
+ }
+
+ CurrElementIter = Elements.begin ();
+ }
+
+ // Test, Reset, and Set a bit in the bitmap.
+ bool test(unsigned Idx) {
+ if (Elements.empty())
+ return false;
+
+ unsigned ElementIndex = Idx / ElementSize;
+ ElementListIter ElementIter = FindLowerBound(ElementIndex);
+
+ // If we can't find an element that is supposed to contain this bit, there
+ // is nothing more to do.
+ if (ElementIter == Elements.end() ||
+ ElementIter->index() != ElementIndex)
+ return false;
+ return ElementIter->test(Idx % ElementSize);
+ }
+
+ void reset(unsigned Idx) {
+ if (Elements.empty())
+ return;
+
+ unsigned ElementIndex = Idx / ElementSize;
+ ElementListIter ElementIter = FindLowerBound(ElementIndex);
+
+ // If we can't find an element that is supposed to contain this bit, there
+ // is nothing more to do.
+ if (ElementIter == Elements.end() ||
+ ElementIter->index() != ElementIndex)
+ return;
+ ElementIter->reset(Idx % ElementSize);
+
+ // When the element is zeroed out, delete it.
+ if (ElementIter->empty()) {
+ ++CurrElementIter;
+ Elements.erase(ElementIter);
+ }
+ }
+
+ void set(unsigned Idx) {
+ unsigned ElementIndex = Idx / ElementSize;
+ SparseBitVectorElement<ElementSize> *Element;
+ ElementListIter ElementIter;
+ if (Elements.empty()) {
+ Element = new SparseBitVectorElement<ElementSize>(ElementIndex);
+ ElementIter = Elements.insert(Elements.end(), Element);
+
+ } else {
+ ElementIter = FindLowerBound(ElementIndex);
+
+ if (ElementIter == Elements.end() ||
+ ElementIter->index() != ElementIndex) {
+ Element = new SparseBitVectorElement<ElementSize>(ElementIndex);
+ // We may have hit the beginning of our SparseBitVector, in which case,
+ // we may need to insert right after this element, which requires moving
+ // the current iterator forward one, because insert does insert before.
+ if (ElementIter != Elements.end() &&
+ ElementIter->index() < ElementIndex)
+ ElementIter = Elements.insert(++ElementIter, Element);
+ else
+ ElementIter = Elements.insert(ElementIter, Element);
+ }
+ }
+ CurrElementIter = ElementIter;
+
+ ElementIter->set(Idx % ElementSize);
+ }
+
+ bool test_and_set (unsigned Idx) {
+ bool old = test(Idx);
+ if (!old) {
+ set(Idx);
+ return true;
+ }
+ return false;
+ }
+
+ bool operator!=(const SparseBitVector &RHS) const {
+ return !(*this == RHS);
+ }
+
+ bool operator==(const SparseBitVector &RHS) const {
+ ElementListConstIter Iter1 = Elements.begin();
+ ElementListConstIter Iter2 = RHS.Elements.begin();
+
+ for (; Iter1 != Elements.end() && Iter2 != RHS.Elements.end();
+ ++Iter1, ++Iter2) {
+ if (*Iter1 != *Iter2)
+ return false;
+ }
+ return Iter1 == Elements.end() && Iter2 == RHS.Elements.end();
+ }
+
+ // Union our bitmap with the RHS and return true if we changed.
+ bool operator|=(const SparseBitVector &RHS) {
+ bool changed = false;
+ ElementListIter Iter1 = Elements.begin();
+ ElementListConstIter Iter2 = RHS.Elements.begin();
+
+ // If RHS is empty, we are done
+ if (RHS.Elements.empty())
+ return false;
+
+ while (Iter2 != RHS.Elements.end()) {
+ if (Iter1 == Elements.end() || Iter1->index() > Iter2->index()) {
+ Elements.insert(Iter1,
+ new SparseBitVectorElement<ElementSize>(*Iter2));
+ ++Iter2;
+ changed = true;
+ } else if (Iter1->index() == Iter2->index()) {
+ changed |= Iter1->unionWith(*Iter2);
+ ++Iter1;
+ ++Iter2;
+ } else {
+ ++Iter1;
+ }
+ }
+ CurrElementIter = Elements.begin();
+ return changed;
+ }
+
+ // Intersect our bitmap with the RHS and return true if ours changed.
+ bool operator&=(const SparseBitVector &RHS) {
+ bool changed = false;
+ ElementListIter Iter1 = Elements.begin();
+ ElementListConstIter Iter2 = RHS.Elements.begin();
+
+ // Check if both bitmaps are empty.
+ if (Elements.empty() && RHS.Elements.empty())
+ return false;
+
+ // Loop through, intersecting as we go, erasing elements when necessary.
+ while (Iter2 != RHS.Elements.end()) {
+ if (Iter1 == Elements.end()) {
+ CurrElementIter = Elements.begin();
+ return changed;
+ }
+
+ if (Iter1->index() > Iter2->index()) {
+ ++Iter2;
+ } else if (Iter1->index() == Iter2->index()) {
+ bool BecameZero;
+ changed |= Iter1->intersectWith(*Iter2, BecameZero);
+ if (BecameZero) {
+ ElementListIter IterTmp = Iter1;
+ ++Iter1;
+ Elements.erase(IterTmp);
+ } else {
+ ++Iter1;
+ }
+ ++Iter2;
+ } else {
+ ElementListIter IterTmp = Iter1;
+ ++Iter1;
+ Elements.erase(IterTmp);
+ }
+ }
+ Elements.erase(Iter1, Elements.end());
+ CurrElementIter = Elements.begin();
+ return changed;
+ }
+
+ // Intersect our bitmap with the complement of the RHS and return true if ours
+ // changed.
+ bool intersectWithComplement(const SparseBitVector &RHS) {
+ bool changed = false;
+ ElementListIter Iter1 = Elements.begin();
+ ElementListConstIter Iter2 = RHS.Elements.begin();
+
+ // If either our bitmap or RHS is empty, we are done
+ if (Elements.empty() || RHS.Elements.empty())
+ return false;
+
+ // Loop through, intersecting as we go, erasing elements when necessary.
+ while (Iter2 != RHS.Elements.end()) {
+ if (Iter1 == Elements.end()) {
+ CurrElementIter = Elements.begin();
+ return changed;
+ }
+
+ if (Iter1->index() > Iter2->index()) {
+ ++Iter2;
+ } else if (Iter1->index() == Iter2->index()) {
+ bool BecameZero;
+ changed |= Iter1->intersectWithComplement(*Iter2, BecameZero);
+ if (BecameZero) {
+ ElementListIter IterTmp = Iter1;
+ ++Iter1;
+ Elements.erase(IterTmp);
+ } else {
+ ++Iter1;
+ }
+ ++Iter2;
+ } else {
+ ++Iter1;
+ }
+ }
+ CurrElementIter = Elements.begin();
+ return changed;
+ }
+
+ bool intersectWithComplement(const SparseBitVector<ElementSize> *RHS) const {
+ return intersectWithComplement(*RHS);
+ }
+
+
+ // Three argument version of intersectWithComplement. Result of RHS1 & ~RHS2
+ // is stored into this bitmap.
+ void intersectWithComplement(const SparseBitVector<ElementSize> &RHS1,
+ const SparseBitVector<ElementSize> &RHS2)
+ {
+ Elements.clear();
+ CurrElementIter = Elements.begin();
+ ElementListConstIter Iter1 = RHS1.Elements.begin();
+ ElementListConstIter Iter2 = RHS2.Elements.begin();
+
+ // If RHS1 is empty, we are done
+ // If RHS2 is empty, we still have to copy RHS1
+ if (RHS1.Elements.empty())
+ return;
+
+ // Loop through, intersecting as we go, erasing elements when necessary.
+ while (Iter2 != RHS2.Elements.end()) {
+ if (Iter1 == RHS1.Elements.end())
+ return;
+
+ if (Iter1->index() > Iter2->index()) {
+ ++Iter2;
+ } else if (Iter1->index() == Iter2->index()) {
+ bool BecameZero = false;
+ SparseBitVectorElement<ElementSize> *NewElement =
+ new SparseBitVectorElement<ElementSize>(Iter1->index());
+ NewElement->intersectWithComplement(*Iter1, *Iter2, BecameZero);
+ if (!BecameZero) {
+ Elements.push_back(NewElement);
+ }
+ else
+ delete NewElement;
+ ++Iter1;
+ ++Iter2;
+ } else {
+ SparseBitVectorElement<ElementSize> *NewElement =
+ new SparseBitVectorElement<ElementSize>(*Iter1);
+ Elements.push_back(NewElement);
+ ++Iter1;
+ }
+ }
+
+ // copy the remaining elements
+ while (Iter1 != RHS1.Elements.end()) {
+ SparseBitVectorElement<ElementSize> *NewElement =
+ new SparseBitVectorElement<ElementSize>(*Iter1);
+ Elements.push_back(NewElement);
+ ++Iter1;
+ }
+
+ return;
+ }
+
+ void intersectWithComplement(const SparseBitVector<ElementSize> *RHS1,
+ const SparseBitVector<ElementSize> *RHS2) {
+ intersectWithComplement(*RHS1, *RHS2);
+ }
+
+ bool intersects(const SparseBitVector<ElementSize> *RHS) const {
+ return intersects(*RHS);
+ }
+
+ // Return true if we share any bits in common with RHS
+ bool intersects(const SparseBitVector<ElementSize> &RHS) const {
+ ElementListConstIter Iter1 = Elements.begin();
+ ElementListConstIter Iter2 = RHS.Elements.begin();
+
+ // Check if both bitmaps are empty.
+ if (Elements.empty() && RHS.Elements.empty())
+ return false;
+
+ // Loop through, intersecting stopping when we hit bits in common.
+ while (Iter2 != RHS.Elements.end()) {
+ if (Iter1 == Elements.end())
+ return false;
+
+ if (Iter1->index() > Iter2->index()) {
+ ++Iter2;
+ } else if (Iter1->index() == Iter2->index()) {
+ if (Iter1->intersects(*Iter2))
+ return true;
+ ++Iter1;
+ ++Iter2;
+ } else {
+ ++Iter1;
+ }
+ }
+ return false;
+ }
+
+ // Return the first set bit in the bitmap. Return -1 if no bits are set.
+ int find_first() const {
+ if (Elements.empty())
+ return -1;
+ const SparseBitVectorElement<ElementSize> &First = *(Elements.begin());
+ return (First.index() * ElementSize) + First.find_first();
+ }
+
+ // Return true if the SparseBitVector is empty
+ bool empty() const {
+ return Elements.empty();
+ }
+
+ unsigned count() const {
+ unsigned BitCount = 0;
+ for (ElementListConstIter Iter = Elements.begin();
+ Iter != Elements.end();
+ ++Iter)
+ BitCount += Iter->count();
+
+ return BitCount;
+ }
+ iterator begin() const {
+ return iterator(this);
+ }
+
+ iterator end() const {
+ return iterator(this, true);
+ }
+
+ // Get a hash value for this bitmap.
+ uint64_t getHashValue() const {
+ uint64_t HashVal = 0;
+ for (ElementListConstIter Iter = Elements.begin();
+ Iter != Elements.end();
+ ++Iter) {
+ HashVal ^= Iter->index();
+ HashVal ^= Iter->getHashValue();
+ }
+ return HashVal;
+ }
+};
+
+// Convenience functions to allow Or and And without dereferencing in the user
+// code.
+
+template <unsigned ElementSize>
+inline bool operator |=(SparseBitVector<ElementSize> &LHS,
+ const SparseBitVector<ElementSize> *RHS) {
+ return LHS |= *RHS;
+}
+
+template <unsigned ElementSize>
+inline bool operator |=(SparseBitVector<ElementSize> *LHS,
+ const SparseBitVector<ElementSize> &RHS) {
+ return LHS->operator|=(RHS);
+}
+
+template <unsigned ElementSize>
+inline bool operator &=(SparseBitVector<ElementSize> *LHS,
+ const SparseBitVector<ElementSize> &RHS) {
+ return LHS->operator&=(RHS);
+}
+
+template <unsigned ElementSize>
+inline bool operator &=(SparseBitVector<ElementSize> &LHS,
+ const SparseBitVector<ElementSize> *RHS) {
+ return LHS &= (*RHS);
+}
+
+
+// Dump a SparseBitVector to a stream
+template <unsigned ElementSize>
+void dump(const SparseBitVector<ElementSize> &LHS, llvm::OStream &out) {
+ out << "[ ";
+
+ typename SparseBitVector<ElementSize>::iterator bi;
+ for (bi = LHS.begin(); bi != LHS.end(); ++bi) {
+ out << *bi << " ";
+ }
+ out << " ]\n";
+}
+}
+
+
+
+#endif
diff --git a/support/include/llvm/ADT/Statistic.h b/support/include/llvm/ADT/Statistic.h
new file mode 100644
index 0000000..ec4fdd6
--- /dev/null
+++ b/support/include/llvm/ADT/Statistic.h
@@ -0,0 +1,75 @@
+//===-- llvm/ADT/Statistic.h - Easy way to expose stats ---------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the 'Statistic' class, which is designed to be an easy way
+// to expose various metrics from passes. These statistics are printed at the
+// end of a run (from llvm_shutdown), when the -stats command line option is
+// passed on the command line.
+//
+// This is useful for reporting information like the number of instructions
+// simplified, optimized or removed by various transformations, like this:
+//
+// static Statistic NumInstsKilled("gcse", "Number of instructions killed");
+//
+// Later, in the code: ++NumInstsKilled;
+//
+// NOTE: Statistics *must* be declared as global variables.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_STATISTIC_H
+#define LLVM_ADT_STATISTIC_H
+
+namespace llvm {
+
+class Statistic {
+public:
+ const char *Name;
+ const char *Desc;
+ unsigned Value : 31;
+ bool Initialized : 1;
+
+ unsigned getValue() const { return Value; }
+ const char *getName() const { return Name; }
+ const char *getDesc() const { return Desc; }
+
+ /// construct - This should only be called for non-global statistics.
+ void construct(const char *name, const char *desc) {
+ Name = name; Desc = desc;
+ Value = 0; Initialized = 0;
+ }
+
+ // Allow use of this class as the value itself.
+ operator unsigned() const { return Value; }
+ const Statistic &operator=(unsigned Val) { Value = Val; return init(); }
+ const Statistic &operator++() { ++Value; return init(); }
+ unsigned operator++(int) { init(); return Value++; }
+ const Statistic &operator--() { --Value; return init(); }
+ unsigned operator--(int) { init(); return Value--; }
+ const Statistic &operator+=(const unsigned &V) { Value += V; return init(); }
+ const Statistic &operator-=(const unsigned &V) { Value -= V; return init(); }
+ const Statistic &operator*=(const unsigned &V) { Value *= V; return init(); }
+ const Statistic &operator/=(const unsigned &V) { Value /= V; return init(); }
+
+protected:
+ Statistic &init() {
+ if (!Initialized) RegisterStatistic();
+ return *this;
+ }
+ void RegisterStatistic();
+};
+
+// STATISTIC - A macro to make definition of statistics really simple. This
+// automatically passes the DEBUG_TYPE of the file into the statistic.
+#define STATISTIC(VARNAME, DESC) \
+ static Statistic VARNAME = { DEBUG_TYPE, DESC, 0, 0 }
+
+} // End llvm namespace
+
+#endif
diff --git a/support/include/llvm/ADT/StringExtras.h b/support/include/llvm/ADT/StringExtras.h
new file mode 100644
index 0000000..ae7960f
--- /dev/null
+++ b/support/include/llvm/ADT/StringExtras.h
@@ -0,0 +1,167 @@
+//===-- llvm/ADT/StringExtras.h - Useful string functions -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains some functions that are useful when dealing with strings.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_STRINGEXTRAS_H
+#define LLVM_ADT_STRINGEXTRAS_H
+
+#include "llvm/Support/DataTypes.h"
+#include "llvm/ADT/APFloat.h"
+#include <cctype>
+#include <cstdio>
+#include <string>
+#include <vector>
+
+namespace llvm {
+
+static inline std::string utohexstr(uint64_t X) {
+ char Buffer[40];
+ char *BufPtr = Buffer+39;
+
+ *BufPtr = 0; // Null terminate buffer...
+ if (X == 0) *--BufPtr = '0'; // Handle special case...
+
+ while (X) {
+ unsigned char Mod = static_cast<unsigned char>(X) & 15;
+ if (Mod < 10)
+ *--BufPtr = '0' + Mod;
+ else
+ *--BufPtr = 'A' + Mod-10;
+ X >>= 4;
+ }
+ return std::string(BufPtr);
+}
+
+static inline std::string utostr_32(uint32_t X, bool isNeg = false) {
+ char Buffer[20];
+ char *BufPtr = Buffer+19;
+
+ *BufPtr = 0; // Null terminate buffer...
+ if (X == 0) *--BufPtr = '0'; // Handle special case...
+
+ while (X) {
+ *--BufPtr = '0' + char(X % 10);
+ X /= 10;
+ }
+
+ if (isNeg) *--BufPtr = '-'; // Add negative sign...
+
+ return std::string(BufPtr);
+}
+
+static inline std::string utostr(uint64_t X, bool isNeg = false) {
+ if (X == uint32_t(X))
+ return utostr_32(uint32_t(X), isNeg);
+
+ char Buffer[40];
+ char *BufPtr = Buffer+39;
+
+ *BufPtr = 0; // Null terminate buffer...
+ if (X == 0) *--BufPtr = '0'; // Handle special case...
+
+ while (X) {
+ *--BufPtr = '0' + char(X % 10);
+ X /= 10;
+ }
+
+ if (isNeg) *--BufPtr = '-'; // Add negative sign...
+ return std::string(BufPtr);
+}
+
+
+static inline std::string itostr(int64_t X) {
+ if (X < 0)
+ return utostr(static_cast<uint64_t>(-X), true);
+ else
+ return utostr(static_cast<uint64_t>(X));
+}
+
+static inline std::string ftostr(double V) {
+ char Buffer[200];
+ sprintf(Buffer, "%20.6e", V);
+ char *B = Buffer;
+ while (*B == ' ') ++B;
+ return B;
+}
+
+static inline std::string ftostr(const APFloat& V) {
+ if (&V.getSemantics() == &APFloat::IEEEdouble)
+ return ftostr(V.convertToDouble());
+ else if (&V.getSemantics() == &APFloat::IEEEsingle)
+ return ftostr((double)V.convertToFloat());
+ return 0; // error
+}
+
+static inline std::string LowercaseString(const std::string &S) {
+ std::string result(S);
+ for (unsigned i = 0; i < S.length(); ++i)
+ if (isupper(result[i]))
+ result[i] = char(tolower(result[i]));
+ return result;
+}
+
+static inline std::string UppercaseString(const std::string &S) {
+ std::string result(S);
+ for (unsigned i = 0; i < S.length(); ++i)
+ if (islower(result[i]))
+ result[i] = char(toupper(result[i]));
+ return result;
+}
+
+/// StringsEqualNoCase - Return true if the two strings are equal, ignoring
+/// case.
+static inline bool StringsEqualNoCase(const std::string &LHS,
+ const std::string &RHS) {
+ if (LHS.size() != RHS.size()) return false;
+ for (unsigned i = 0, e = LHS.size(); i != e; ++i)
+ if (tolower(LHS[i]) != tolower(RHS[i])) return false;
+ return true;
+}
+
+/// StringsEqualNoCase - Return true if the two strings are equal, ignoring
+/// case.
+static inline bool StringsEqualNoCase(const std::string &LHS,
+ const char *RHS) {
+ for (unsigned i = 0, e = LHS.size(); i != e; ++i) {
+ if (RHS[i] == 0) return false; // RHS too short.
+ if (tolower(LHS[i]) != tolower(RHS[i])) return false;
+ }
+ return RHS[LHS.size()] == 0; // Not too long?
+}
+
+/// getToken - This function extracts one token from source, ignoring any
+/// leading characters that appear in the Delimiters string, and ending the
+/// token at any of the characters that appear in the Delimiters string. If
+/// there are no tokens in the source string, an empty string is returned.
+/// The Source source string is updated in place to remove the returned string
+/// and any delimiter prefix from it.
+std::string getToken(std::string &Source,
+ const char *Delimiters = " \t\n\v\f\r");
+
+/// SplitString - Split up the specified string according to the specified
+/// delimiters, appending the result fragments to the output list.
+void SplitString(const std::string &Source,
+ std::vector<std::string> &OutFragments,
+ const char *Delimiters = " \t\n\v\f\r");
+
+/// UnescapeString - Modify the argument string, turning two character sequences
+/// like '\\' 'n' into '\n'. This handles: \e \a \b \f \n \r \t \v \' \\ and
+/// \num (where num is a 1-3 byte octal value).
+void UnescapeString(std::string &Str);
+
+/// EscapeString - Modify the argument string, turning '\\' and anything that
+/// doesn't satisfy std::isprint into an escape sequence.
+void EscapeString(std::string &Str);
+
+} // End llvm namespace
+
+#endif
diff --git a/support/include/llvm/ADT/StringMap.h b/support/include/llvm/ADT/StringMap.h
new file mode 100644
index 0000000..1fa128a
--- /dev/null
+++ b/support/include/llvm/ADT/StringMap.h
@@ -0,0 +1,407 @@
+//===--- StringMap.h - String Hash table map interface ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the StringMap class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_STRINGMAP_H
+#define LLVM_ADT_STRINGMAP_H
+
+#include "llvm/Support/Allocator.h"
+#include <cstring>
+
+namespace llvm {
+ template<typename ValueT>
+ class StringMapConstIterator;
+ template<typename ValueT>
+ class StringMapIterator;
+ template<typename ValueTy>
+ class StringMapEntry;
+
+/// StringMapEntryInitializer - This datatype can be partially specialized for
+/// various datatypes in a stringmap to allow them to be initialized when an
+/// entry is default constructed for the map.
+template<typename ValueTy>
+class StringMapEntryInitializer {
+public:
+ template <typename InitTy>
+ static void Initialize(StringMapEntry<ValueTy> &T, InitTy InitVal) {
+ }
+};
+
+
+/// StringMapEntryBase - Shared base class of StringMapEntry instances.
+class StringMapEntryBase {
+ unsigned StrLen;
+public:
+ explicit StringMapEntryBase(unsigned Len) : StrLen(Len) {}
+
+ unsigned getKeyLength() const { return StrLen; }
+};
+
+/// StringMapImpl - This is the base class of StringMap that is shared among
+/// all of its instantiations.
+class StringMapImpl {
+public:
+ /// ItemBucket - The hash table consists of an array of these. If Item is
+ /// non-null, this is an extant entry, otherwise, it is a hole.
+ struct ItemBucket {
+ /// FullHashValue - This remembers the full hash value of the key for
+ /// easy scanning.
+ unsigned FullHashValue;
+
+ /// Item - This is a pointer to the actual item object.
+ StringMapEntryBase *Item;
+ };
+
+protected:
+ ItemBucket *TheTable;
+ unsigned NumBuckets;
+ unsigned NumItems;
+ unsigned NumTombstones;
+ unsigned ItemSize;
+protected:
+ explicit StringMapImpl(unsigned itemSize) : ItemSize(itemSize) {
+ // Initialize the map with zero buckets to allocation.
+ TheTable = 0;
+ NumBuckets = 0;
+ NumItems = 0;
+ NumTombstones = 0;
+ }
+ StringMapImpl(unsigned InitSize, unsigned ItemSize);
+ void RehashTable();
+
+ /// ShouldRehash - Return true if the table should be rehashed after a new
+ /// element was recently inserted.
+ bool ShouldRehash() const {
+ // If the hash table is now more than 3/4 full, or if fewer than 1/8 of
+ // the buckets are empty (meaning that many are filled with tombstones),
+ // grow the table.
+ return NumItems*4 > NumBuckets*3 ||
+ NumBuckets-(NumItems+NumTombstones) < NumBuckets/8;
+ }
+
+ /// LookupBucketFor - Look up the bucket that the specified string should end
+ /// up in. If it already exists as a key in the map, the Item pointer for the
+ /// specified bucket will be non-null. Otherwise, it will be null. In either
+ /// case, the FullHashValue field of the bucket will be set to the hash value
+ /// of the string.
+ unsigned LookupBucketFor(const char *KeyStart, const char *KeyEnd);
+
+ /// FindKey - Look up the bucket that contains the specified key. If it exists
+ /// in the map, return the bucket number of the key. Otherwise return -1.
+ /// This does not modify the map.
+ int FindKey(const char *KeyStart, const char *KeyEnd) const;
+
+ /// RemoveKey - Remove the specified StringMapEntry from the table, but do not
+ /// delete it. This aborts if the value isn't in the table.
+ void RemoveKey(StringMapEntryBase *V);
+
+ /// RemoveKey - Remove the StringMapEntry for the specified key from the
+ /// table, returning it. If the key is not in the table, this returns null.
+ StringMapEntryBase *RemoveKey(const char *KeyStart, const char *KeyEnd);
+private:
+ void init(unsigned Size);
+public:
+ static StringMapEntryBase *getTombstoneVal() {
+ return (StringMapEntryBase*)-1;
+ }
+
+ unsigned getNumBuckets() const { return NumBuckets; }
+ unsigned getNumItems() const { return NumItems; }
+
+ bool empty() const { return NumItems == 0; }
+ unsigned size() const { return NumItems; }
+};
+
+/// StringMapEntry - This is used to represent one value that is inserted into
+/// a StringMap. It contains the Value itself and the key: the string length
+/// and data.
+template<typename ValueTy>
+class StringMapEntry : public StringMapEntryBase {
+ ValueTy Val;
+public:
+ explicit StringMapEntry(unsigned StrLen)
+ : StringMapEntryBase(StrLen), Val() {}
+ StringMapEntry(unsigned StrLen, const ValueTy &V)
+ : StringMapEntryBase(StrLen), Val(V) {}
+
+ const ValueTy &getValue() const { return Val; }
+ ValueTy &getValue() { return Val; }
+
+ void setValue(const ValueTy &V) { Val = V; }
+
+ /// getKeyData - Return the start of the string data that is the key for this
+ /// value. The string data is always stored immediately after the
+ /// StringMapEntry object.
+ const char *getKeyData() const {return reinterpret_cast<const char*>(this+1);}
+
+ /// Create - Create a StringMapEntry for the specified key and default
+ /// construct the value.
+ template<typename AllocatorTy, typename InitType>
+ static StringMapEntry *Create(const char *KeyStart, const char *KeyEnd,
+ AllocatorTy &Allocator,
+ InitType InitVal) {
+ unsigned KeyLength = KeyEnd-KeyStart;
+
+ // Okay, the item doesn't already exist, and 'Bucket' is the bucket to fill
+ // in. Allocate a new item with space for the string at the end and a null
+ // terminator.
+
+ unsigned AllocSize = sizeof(StringMapEntry)+KeyLength+1;
+ unsigned Alignment = alignof<StringMapEntry>();
+
+ StringMapEntry *NewItem =
+ static_cast<StringMapEntry*>(Allocator.Allocate(AllocSize,Alignment));
+
+ // Default construct the value.
+ new (NewItem) StringMapEntry(KeyLength);
+
+ // Copy the string information.
+ char *StrBuffer = const_cast<char*>(NewItem->getKeyData());
+ memcpy(StrBuffer, KeyStart, KeyLength);
+ StrBuffer[KeyLength] = 0; // Null terminate for convenience of clients.
+
+ // Initialize the value if the client wants to.
+ StringMapEntryInitializer<ValueTy>::Initialize(*NewItem, InitVal);
+ return NewItem;
+ }
+
+ template<typename AllocatorTy>
+ static StringMapEntry *Create(const char *KeyStart, const char *KeyEnd,
+ AllocatorTy &Allocator) {
+ return Create(KeyStart, KeyEnd, Allocator, (void*)0);
+ }
+
+
+ /// Create - Create a StringMapEntry with normal malloc/free.
+ template<typename InitType>
+ static StringMapEntry *Create(const char *KeyStart, const char *KeyEnd,
+ InitType InitVal) {
+ MallocAllocator A;
+ return Create(KeyStart, KeyEnd, A, InitVal);
+ }
+
+ static StringMapEntry *Create(const char *KeyStart, const char *KeyEnd) {
+ return Create(KeyStart, KeyEnd, (void*)0);
+ }
+
+ /// GetStringMapEntryFromValue - Given a value that is known to be embedded
+ /// into a StringMapEntry, return the StringMapEntry itself.
+ static StringMapEntry &GetStringMapEntryFromValue(ValueTy &V) {
+ StringMapEntry *EPtr = 0;
+ char *Ptr = reinterpret_cast<char*>(&V) -
+ (reinterpret_cast<char*>(&EPtr->Val) -
+ reinterpret_cast<char*>(EPtr));
+ return *reinterpret_cast<StringMapEntry*>(Ptr);
+ }
+ static const StringMapEntry &GetStringMapEntryFromValue(const ValueTy &V) {
+ return GetStringMapEntryFromValue(const_cast<ValueTy&>(V));
+ }
+
+ /// Destroy - Destroy this StringMapEntry, releasing memory back to the
+ /// specified allocator.
+ template<typename AllocatorTy>
+ void Destroy(AllocatorTy &Allocator) {
+ // Free memory referenced by the item.
+ this->~StringMapEntry();
+ Allocator.Deallocate(this);
+ }
+
+ /// Destroy this object, releasing memory back to the malloc allocator.
+ void Destroy() {
+ MallocAllocator A;
+ Destroy(A);
+ }
+};
+
+
+/// StringMap - This is an unconventional map that is specialized for handling
+/// keys that are "strings", which are basically ranges of bytes. This does some
+/// funky memory allocation and hashing things to make it extremely efficient,
+/// storing the string data *after* the value in the map.
+template<typename ValueTy, typename AllocatorTy = MallocAllocator>
+class StringMap : public StringMapImpl {
+ AllocatorTy Allocator;
+ typedef StringMapEntry<ValueTy> MapEntryTy;
+public:
+ StringMap() : StringMapImpl(sizeof(MapEntryTy)) {}
+ explicit StringMap(unsigned InitialSize)
+ : StringMapImpl(InitialSize, sizeof(MapEntryTy)) {}
+
+ AllocatorTy &getAllocator() { return Allocator; }
+ const AllocatorTy &getAllocator() const { return Allocator; }
+
+ typedef StringMapConstIterator<ValueTy> const_iterator;
+ typedef StringMapIterator<ValueTy> iterator;
+
+ iterator begin() {
+ return iterator(TheTable, NumBuckets == 0);
+ }
+ iterator end() {
+ return iterator(TheTable+NumBuckets, true);
+ }
+ const_iterator begin() const {
+ return const_iterator(TheTable, NumBuckets == 0);
+ }
+ const_iterator end() const {
+ return const_iterator(TheTable+NumBuckets, true);
+ }
+
+ iterator find(const char *KeyStart, const char *KeyEnd) {
+ int Bucket = FindKey(KeyStart, KeyEnd);
+ if (Bucket == -1) return end();
+ return iterator(TheTable+Bucket);
+ }
+
+ const_iterator find(const char *KeyStart, const char *KeyEnd) const {
+ int Bucket = FindKey(KeyStart, KeyEnd);
+ if (Bucket == -1) return end();
+ return const_iterator(TheTable+Bucket);
+ }
+
+ /// insert - Insert the specified key/value pair into the map. If the key
+ /// already exists in the map, return false and ignore the request, otherwise
+ /// insert it and return true.
+ bool insert(MapEntryTy *KeyValue) {
+ unsigned BucketNo =
+ LookupBucketFor(KeyValue->getKeyData(),
+ KeyValue->getKeyData()+KeyValue->getKeyLength());
+ ItemBucket &Bucket = TheTable[BucketNo];
+ if (Bucket.Item && Bucket.Item != getTombstoneVal())
+ return false; // Already exists in map.
+
+ if (Bucket.Item == getTombstoneVal())
+ --NumTombstones;
+ Bucket.Item = KeyValue;
+ ++NumItems;
+
+ if (ShouldRehash())
+ RehashTable();
+ return true;
+ }
+
+ /// GetOrCreateValue - Look up the specified key in the table. If a value
+ /// exists, return it. Otherwise, default construct a value, insert it, and
+ /// return.
+ template <typename InitTy>
+ StringMapEntry<ValueTy> &GetOrCreateValue(const char *KeyStart,
+ const char *KeyEnd,
+ InitTy Val) {
+ unsigned BucketNo = LookupBucketFor(KeyStart, KeyEnd);
+ ItemBucket &Bucket = TheTable[BucketNo];
+ if (Bucket.Item && Bucket.Item != getTombstoneVal())
+ return *static_cast<MapEntryTy*>(Bucket.Item);
+
+ MapEntryTy *NewItem = MapEntryTy::Create(KeyStart, KeyEnd, Allocator, Val);
+
+ if (Bucket.Item == getTombstoneVal())
+ --NumTombstones;
+ ++NumItems;
+
+ // Fill in the bucket for the hash table. The FullHashValue was already
+ // filled in by LookupBucketFor.
+ Bucket.Item = NewItem;
+
+ if (ShouldRehash())
+ RehashTable();
+ return *NewItem;
+ }
+
+ StringMapEntry<ValueTy> &GetOrCreateValue(const char *KeyStart,
+ const char *KeyEnd) {
+ return GetOrCreateValue(KeyStart, KeyEnd, (void*)0);
+ }
+
+ /// remove - Remove the specified key/value pair from the map, but do not
+ /// erase it. This aborts if the key is not in the map.
+ void remove(MapEntryTy *KeyValue) {
+ RemoveKey(KeyValue);
+ }
+
+ void erase(iterator I) {
+ MapEntryTy &V = *I;
+ remove(&V);
+ V.Destroy(Allocator);
+ }
+
+ ~StringMap() {
+ for (ItemBucket *I = TheTable, *E = TheTable+NumBuckets; I != E; ++I) {
+ if (I->Item && I->Item != getTombstoneVal())
+ static_cast<MapEntryTy*>(I->Item)->Destroy(Allocator);
+ }
+ free(TheTable);
+ }
+private:
+ StringMap(const StringMap &); // FIXME: Implement.
+ void operator=(const StringMap &); // FIXME: Implement.
+};
+
+
+template<typename ValueTy>
+class StringMapConstIterator {
+protected:
+ StringMapImpl::ItemBucket *Ptr;
+public:
+ explicit StringMapConstIterator(StringMapImpl::ItemBucket *Bucket,
+ bool NoAdvance = false)
+ : Ptr(Bucket) {
+ if (!NoAdvance) AdvancePastEmptyBuckets();
+ }
+
+ const StringMapEntry<ValueTy> &operator*() const {
+ return *static_cast<StringMapEntry<ValueTy>*>(Ptr->Item);
+ }
+ const StringMapEntry<ValueTy> *operator->() const {
+ return static_cast<StringMapEntry<ValueTy>*>(Ptr->Item);
+ }
+
+ bool operator==(const StringMapConstIterator &RHS) const {
+ return Ptr == RHS.Ptr;
+ }
+ bool operator!=(const StringMapConstIterator &RHS) const {
+ return Ptr != RHS.Ptr;
+ }
+
+ inline StringMapConstIterator& operator++() { // Preincrement
+ ++Ptr;
+ AdvancePastEmptyBuckets();
+ return *this;
+ }
+ StringMapConstIterator operator++(int) { // Postincrement
+ StringMapConstIterator tmp = *this; ++*this; return tmp;
+ }
+
+private:
+ void AdvancePastEmptyBuckets() {
+ while (Ptr->Item == 0 || Ptr->Item == StringMapImpl::getTombstoneVal())
+ ++Ptr;
+ }
+};
+
+template<typename ValueTy>
+class StringMapIterator : public StringMapConstIterator<ValueTy> {
+public:
+ StringMapIterator(StringMapImpl::ItemBucket *Bucket,
+ bool NoAdvance = false)
+ : StringMapConstIterator<ValueTy>(Bucket, NoAdvance) {
+ }
+ StringMapEntry<ValueTy> &operator*() const {
+ return *static_cast<StringMapEntry<ValueTy>*>(this->Ptr->Item);
+ }
+ StringMapEntry<ValueTy> *operator->() const {
+ return static_cast<StringMapEntry<ValueTy>*>(this->Ptr->Item);
+ }
+};
+
+}
+
+#endif
+
diff --git a/support/include/llvm/ADT/Tree.h b/support/include/llvm/ADT/Tree.h
new file mode 100644
index 0000000..835a001
--- /dev/null
+++ b/support/include/llvm/ADT/Tree.h
@@ -0,0 +1,62 @@
+//===- llvm/ADT/Tree.h - Generic n-way tree structure -----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This class defines a generic N way tree node structure. The tree structure
+// is immutable after creation, but the payload contained within it is not.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_TREE_H
+#define LLVM_ADT_TREE_H
+
+#include <vector>
+
+namespace llvm {
+
+template<class ConcreteTreeNode, class Payload>
+class Tree {
+ std::vector<ConcreteTreeNode*> Children; // This nodes children, if any
+ ConcreteTreeNode *Parent; // Parent of this node...
+ Payload Data; // Data held in this node...
+
+protected:
+ void setChildren(const std::vector<ConcreteTreeNode*> &children) {
+ Children = children;
+ }
+public:
+ inline Tree(ConcreteTreeNode *parent) : Parent(parent) {}
+ inline Tree(const std::vector<ConcreteTreeNode*> &children,
+ ConcreteTreeNode *par) : Children(children), Parent(par) {}
+
+ inline Tree(const std::vector<ConcreteTreeNode*> &children,
+ ConcreteTreeNode *par, const Payload &data)
+ : Children(children), Parent(par), Data(data) {}
+
+ // Tree dtor - Free all children
+ inline ~Tree() {
+ for (unsigned i = Children.size(); i > 0; --i)
+ delete Children[i-1];
+ }
+
+ // Tree manipulation/walking routines...
+ inline ConcreteTreeNode *getParent() const { return Parent; }
+ inline unsigned getNumChildren() const { return Children.size(); }
+ inline ConcreteTreeNode *getChild(unsigned i) const {
+ assert(i < Children.size() && "Tree::getChild with index out of range!");
+ return Children[i];
+ }
+
+ // Payload access...
+ inline Payload &getTreeData() { return Data; }
+ inline const Payload &getTreeData() const { return Data; }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/support/include/llvm/ADT/UniqueVector.h b/support/include/llvm/ADT/UniqueVector.h
new file mode 100644
index 0000000..f3fd7b1
--- /dev/null
+++ b/support/include/llvm/ADT/UniqueVector.h
@@ -0,0 +1,89 @@
+//===-- llvm/ADT/UniqueVector.h ---------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by James M. Laskey and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_UNIQUEVECTOR_H
+#define LLVM_ADT_UNIQUEVECTOR_H
+
+#include <cassert>
+#include <map>
+#include <vector>
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+/// UniqueVector - This class produces a sequential ID number (base 1) for each
+/// unique entry that is added. T is the type of entries in the vector. This
+/// class should have an implementation of operator== and of operator<.
+/// Entries can be fetched using operator[] with the entry ID.
+template<class T> class UniqueVector {
+private:
+ // Map - Used to handle the correspondence of entry to ID.
+ std::map<T, unsigned> Map;
+
+ // Vector - ID ordered vector of entries. Entries can be indexed by ID - 1.
+ //
+ std::vector<T> Vector;
+
+public:
+ /// insert - Append entry to the vector if it doesn't already exist. Returns
+ /// the entry's index + 1 to be used as a unique ID.
+ unsigned insert(const T &Entry) {
+ // Check if the entry is already in the map.
+ unsigned &Val = Map[Entry];
+
+ // See if entry exists, if so return prior ID.
+ if (Val) return Val;
+
+ // Compute ID for entry.
+ Val = Vector.size() + 1;
+
+ // Insert in vector.
+ Vector.push_back(Entry);
+ return Val;
+ }
+
+ /// idFor - return the ID for an existing entry. Returns 0 if the entry is
+ /// not found.
+ unsigned idFor(const T &Entry) const {
+ // Search for entry in the map.
+ typename std::map<T, unsigned>::const_iterator MI = Map.find(Entry);
+
+ // See if entry exists, if so return ID.
+ if (MI != Map.end()) return MI->second;
+
+ // No luck.
+ return 0;
+ }
+
+ /// operator[] - Returns a reference to the entry with the specified ID.
+ ///
+ const T &operator[](unsigned ID) const {
+ assert(ID-1 < size() && "ID is 0 or out of range!");
+ return Vector[ID - 1];
+ }
+
+ /// size - Returns the number of entries in the vector.
+ ///
+ size_t size() const { return Vector.size(); }
+
+ /// empty - Returns true if the vector is empty.
+ ///
+ bool empty() const { return Vector.empty(); }
+
+ /// reset - Clears all the entries.
+ ///
+ void reset() {
+ Map.clear();
+ Vector.resize(0, 0);
+ }
+};
+
+} // End of namespace llvm
+
+#endif // LLVM_ADT_UNIQUEVECTOR_H
diff --git a/support/include/llvm/ADT/VectorExtras.h b/support/include/llvm/ADT/VectorExtras.h
new file mode 100644
index 0000000..bda2ae6
--- /dev/null
+++ b/support/include/llvm/ADT/VectorExtras.h
@@ -0,0 +1,41 @@
+//===-- llvm/ADT/VectorExtras.h - Helpers for std::vector -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains helper functions which are useful for working with the
+// std::vector class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_VECTOREXTRAS_H
+#define LLVM_ADT_VECTOREXTRAS_H
+
+#include <cstdarg>
+#include <vector>
+
+namespace llvm {
+
+/// make_vector - Helper function which is useful for building temporary vectors
+/// to pass into type construction of CallInst ctors. This turns a null
+/// terminated list of pointers (or other value types) into a real live vector.
+///
+template<typename T>
+inline std::vector<T> make_vector(T A, ...) {
+ va_list Args;
+ va_start(Args, A);
+ std::vector<T> Result;
+ Result.push_back(A);
+ while (T Val = va_arg(Args, T))
+ Result.push_back(Val);
+ va_end(Args);
+ return Result;
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/support/include/llvm/ADT/hash_map.in b/support/include/llvm/ADT/hash_map.in
new file mode 100644
index 0000000..fe5c393
--- /dev/null
+++ b/support/include/llvm/ADT/hash_map.in
@@ -0,0 +1,150 @@
+//===-- llvm/ADT/hash_map - "Portable" wrapper around hash_map --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides a wrapper around the mysterious <hash_map> header file
+// that seems to move around between GCC releases into and out of namespaces at
+// will. #including this header will cause hash_map to be available in the
+// global namespace.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_HASH_MAP
+#define LLVM_ADT_HASH_MAP
+
+// Compiler Support Matrix
+//
+// Version Namespace Header File
+// 2.95.x :: hash_map
+// 3.0.4 std ext/hash_map
+// 3.1 __gnu_cxx ext/hash_map
+// HP aCC6 std stdex/rw/hashm*ap.h
+// MS VC++ stdext hash_map
+
+#undef HAVE_GNU_EXT_HASH_MAP
+#undef HAVE_STD_EXT_HASH_MAP
+#undef HAVE_GLOBAL_HASH_MAP
+#undef HAVE_RW_STDEX_HASH_MAP_H
+
+#if HAVE_GNU_EXT_HASH_MAP
+// This is for GCC-3.1+ which puts hash in ext/hash_map
+# include <ext/hash_map>
+# ifndef HASH_NAMESPACE
+# define HASH_NAMESPACE __gnu_cxx
+# endif
+
+// GCC 3.0.x puts hash_map in <ext/hash_map> and in the std namespace.
+#elif HAVE_STD_EXT_HASH_MAP
+# include <ext/hash_map>
+# ifndef HASH_NAMESPACE
+# define HASH_NAMESPACE std
+# endif
+
+// Older compilers such as GCC before version 3.0 do not keep
+// extensions in the `ext' directory, and ignore the `std' namespace.
+#elif HAVE_GLOBAL_HASH_MAP
+# include <hash_map>
+# ifndef HASH_NAMESPACE
+# define HASH_NAMESPACE std
+# endif
+
+// HP aCC doesn't include an SGI-like hash_map. For this platform (or
+// any others using Rogue Wave Software's Tools.h++ library), we wrap
+// around them in std::
+#elif HAVE_RW_STDEX_HASH_MAP_H
+# include <rw/stdex/hashmap.h>
+# include <rw/stdex/hashmmap.h>
+# ifndef HASH_NAMESPACE
+# define HASH_NAMESPACE std
+# endif
+
+// Support Microsoft VC++.
+#elif defined(_MSC_VER)
+# include <hash_map>
+# ifndef HASH_NAMESPACE
+# define HASH_NAMESPACE stdext
+ using std::_Distance;
+# endif
+
+// Give a warning if we couldn't find it, instead of (or in addition to)
+// randomly doing something dumb.
+#else
+# warning "Autoconfiguration failed to find the hash_map header file."
+#endif
+
+// we wrap Rogue Wave Tools.h++ rw_hashmap into something SGI-looking, here:
+#ifdef HAVE_RW_STDEX_HASH_MAP_H
+namespace HASH_NAMESPACE {
+
+template <class DataType> struct hash {
+ unsigned int operator()(const unsigned int& x) const {
+ return x;
+ }
+};
+
+template <typename KeyType,
+ typename ValueType,
+ class _HashFcn = hash<KeyType>,
+ class _EqualKey = equal_to<KeyType>,
+ class _A = allocator <ValueType> >
+class hash_map : public rw_hashmap<KeyType, ValueType, class _HashFcn,
+ class _EqualKey, class _A> {
+};
+
+template <typename KeyType,
+ typename ValueType,
+ class _HashFcn = hash<KeyType>,
+ class _EqualKey = equal_to<KeyType>,
+ class _A = allocator <ValueType> >
+class hash_multimap : public rw_hashmultimap<KeyType, ValueType, class _HashFcn,
+ class _EqualKey, class _A> {
+};
+
+} // end HASH_NAMESPACE;
+#endif
+
+// Include vector because ext/hash_map includes stl_vector.h and leaves
+// out specializations like stl_bvector.h, causing link conflicts.
+#include <vector>
+
+#ifdef _MSC_VER
+
+// GCC and VC++ have differing ways of implementing hash_maps. As it's not
+// standardized, that's to be expected. This adapter class allows VC++
+// hash_map to use GCC's hash classes.
+namespace stdext {
+ template<class Key> struct hash;
+
+ // Provide a hash function for unsigned ints...
+ template<> struct hash<unsigned int> {
+ inline size_t operator()(unsigned int Val) const {
+ return Val;
+ }
+ };
+
+ template<class Key> class hash_compare<Key, std::less<Key> > {
+ std::less<Key> comp;
+ public:
+ enum { bucket_size = 4 };
+ enum { min_buckets = 8 };
+ hash_compare() {}
+ hash_compare(std::less<Key> pred) : comp(pred) {}
+ size_t operator()(const Key& key) const { return hash<Key>()(key); }
+ bool operator()(const Key& k1, const Key& k2) const { return comp(k1, k2); }
+ };
+}
+
+#endif
+
+using HASH_NAMESPACE::hash_map;
+using HASH_NAMESPACE::hash_multimap;
+using HASH_NAMESPACE::hash;
+
+#include "llvm/ADT/HashExtras.h"
+
+#endif
diff --git a/support/include/llvm/ADT/hash_set.in b/support/include/llvm/ADT/hash_set.in
new file mode 100644
index 0000000..aa27e5f
--- /dev/null
+++ b/support/include/llvm/ADT/hash_set.in
@@ -0,0 +1,111 @@
+//===-- llvm/ADT/hash_set - "Portable" wrapper around hash_set --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// vim:ft=cpp
+//
+// This file provides a wrapper around the mysterious <hash_set> header file
+// that seems to move around between GCC releases into and out of namespaces at
+// will. #including this header will cause hash_set to be available in the
+// global namespace.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_HASH_SET
+#define LLVM_ADT_HASH_SET
+
+// Compiler Support Matrix
+//
+// Version Namespace Header File
+// 2.95.x :: hash_set
+// 3.0.4 std ext/hash_set
+// 3.1 __gnu_cxx ext/hash_set
+// HP aCC6 std stdex/rw/hashset.h
+// MS VC++ stdext hash_set
+
+#undef HAVE_GNU_EXT_HASH_SET
+#undef HAVE_STD_EXT_HASH_SET
+#undef HAVE_GLOBAL_HASH_SET
+#undef HAVE_RW_STDEX_HASH_SET_H
+
+// GCC versions 3.1 and later put hash_set in <ext/hash_set> and in
+// the __gnu_cxx namespace.
+#if HAVE_GNU_EXT_HASH_SET
+# include <ext/hash_set>
+# ifndef HASH_NAMESPACE
+# define HASH_NAMESPACE __gnu_cxx
+# endif
+
+// GCC 3.0.x puts hash_set in <ext/hash_set> and in the std namespace.
+#elif HAVE_STD_EXT_HASH_SET
+# include <ext/hash_set>
+# ifndef HASH_NAMESPACE
+# define HASH_NAMESPACE std
+# endif
+
+// Older compilers such as GCC before version 3.0 do not keep
+// extensions in the `ext' directory, and ignore the `std' namespace.
+#elif HAVE_GLOBAL_HASH_SET
+# include <hash_set>
+# ifndef HASH_NAMESPACE
+# define HASH_NAMESPACE std
+# endif
+
+// HP aCC doesn't include an SGI-like hash_set. For this platform (or
+// any others using Rogue Wave Software's Tools.h++ library), we wrap
+// around them in std::
+#elif HAVE_RW_STDEX_HASH_SET_H
+# include <rw/stdex/hashset.h>
+# ifndef HASH_NAMESPACE
+# define HASH_NAMESPACE std
+# endif
+
+// Support Microsoft VC++.
+#elif defined(_MSC_VER)
+# include <hash_set>
+# ifndef HASH_NAMESPACE
+# define HASH_NAMESPACE stdext
+# endif
+
+// Give a warning if we couldn't find it, instead of (or in addition to)
+// randomly doing something dumb.
+#else
+# warning "Autoconfiguration failed to find the hash_set header file."
+#endif
+
+// we wrap Rogue Wave Tools.h++ rw_hashset into something SGI-looking, here:
+#ifdef HAVE_RW_STDEX_HASH_SET_H
+namespace HASH_NAMESPACE {
+
+/*
+template <class DataType> struct hash {
+ unsigned int operator()(const unsigned int& x) const {
+ return x;
+ }
+};
+*/
+
+template <typename ValueType,
+ class _HashFcn = hash<ValueType>,
+ class _EqualKey = equal_to<ValueType>,
+ class _A = allocator <ValueType> >
+class hash_set :
+ public rw_hashset<ValueType, class _HashFcn, class _EqualKey, class _A> {
+};
+
+} // end HASH_NAMESPACE;
+#endif
+
+using HASH_NAMESPACE::hash_set;
+
+// Include vector because ext/hash_set includes stl_vector.h and leaves
+// out specializations like stl_bvector.h, causing link conflicts.
+#include <vector>
+
+#include "llvm/ADT/HashExtras.h"
+
+#endif
diff --git a/support/include/llvm/ADT/ilist b/support/include/llvm/ADT/ilist
new file mode 100644
index 0000000..3b1e8d7
--- /dev/null
+++ b/support/include/llvm/ADT/ilist
@@ -0,0 +1,625 @@
+//===-- llvm/ADT/ilist - Intrusive Linked List Template ---------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines classes to implement an intrusive doubly linked list class
+// (i.e. each node of the list must contain a next and previous field for the
+// list.
+//
+// The ilist_traits trait class is used to gain access to the next and previous
+// fields of the node type that the list is instantiated with. If it is not
+// specialized, the list defaults to using the getPrev(), getNext() method calls
+// to get the next and previous pointers.
+//
+// The ilist class itself, should be a plug in replacement for list, assuming
+// that the nodes contain next/prev pointers. This list replacement does not
+// provides a constant time size() method, so be careful to use empty() when you
+// really want to know if it's empty.
+//
+// The ilist class is implemented by allocating a 'tail' node when the list is
+// created (using ilist_traits<>::createSentinel()). This tail node is
+// absolutely required because the user must be able to compute end()-1. Because
+// of this, users of the direct next/prev links will see an extra link on the
+// end of the list, which should be ignored.
+//
+// Requirements for a user of this list:
+//
+// 1. The user must provide {g|s}et{Next|Prev} methods, or specialize
+// ilist_traits to provide an alternate way of getting and setting next and
+// prev links.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_ILIST
+#define LLVM_ADT_ILIST
+
+#include "llvm/ADT/iterator"
+#include <cassert>
+
+namespace llvm {
+
+template<typename NodeTy, typename Traits> class iplist;
+template<typename NodeTy> class ilist_iterator;
+
+// Template traits for intrusive list. By specializing this template class, you
+// can change what next/prev fields are used to store the links...
+template<typename NodeTy>
+struct ilist_traits {
+ static NodeTy *getPrev(NodeTy *N) { return N->getPrev(); }
+ static NodeTy *getNext(NodeTy *N) { return N->getNext(); }
+ static const NodeTy *getPrev(const NodeTy *N) { return N->getPrev(); }
+ static const NodeTy *getNext(const NodeTy *N) { return N->getNext(); }
+
+ static void setPrev(NodeTy *N, NodeTy *Prev) { N->setPrev(Prev); }
+ static void setNext(NodeTy *N, NodeTy *Next) { N->setNext(Next); }
+
+ static NodeTy *createNode(const NodeTy &V) { return new NodeTy(V); }
+
+ static NodeTy *createSentinel() { return new NodeTy(); }
+ static void destroySentinel(NodeTy *N) { delete N; }
+
+ void addNodeToList(NodeTy *NTy) {}
+ void removeNodeFromList(NodeTy *NTy) {}
+ void transferNodesFromList(iplist<NodeTy, ilist_traits> &L2,
+ ilist_iterator<NodeTy> first,
+ ilist_iterator<NodeTy> last) {}
+};
+
+// Const traits are the same as nonconst traits...
+template<typename Ty>
+struct ilist_traits<const Ty> : public ilist_traits<Ty> {};
+
+
+//===----------------------------------------------------------------------===//
+// ilist_iterator<Node> - Iterator for intrusive list.
+//
+template<typename NodeTy>
+class ilist_iterator
+ : public bidirectional_iterator<NodeTy, ptrdiff_t> {
+ typedef ilist_traits<NodeTy> Traits;
+ typedef bidirectional_iterator<NodeTy, ptrdiff_t> super;
+
+public:
+ typedef size_t size_type;
+ typedef typename super::pointer pointer;
+ typedef typename super::reference reference;
+private:
+ pointer NodePtr;
+public:
+
+ ilist_iterator(pointer NP) : NodePtr(NP) {}
+ ilist_iterator(reference NR) : NodePtr(&NR) {}
+ ilist_iterator() : NodePtr(0) {}
+
+ // This is templated so that we can allow constructing a const iterator from
+ // a nonconst iterator...
+ template<class node_ty>
+ ilist_iterator(const ilist_iterator<node_ty> &RHS)
+ : NodePtr(RHS.getNodePtrUnchecked()) {}
+
+ // This is templated so that we can allow assigning to a const iterator from
+ // a nonconst iterator...
+ template<class node_ty>
+ const ilist_iterator &operator=(const ilist_iterator<node_ty> &RHS) {
+ NodePtr = RHS.getNodePtrUnchecked();
+ return *this;
+ }
+
+ // Accessors...
+ operator pointer() const {
+ assert(Traits::getNext(NodePtr) != 0 && "Dereferencing end()!");
+ return NodePtr;
+ }
+
+ reference operator*() const {
+ assert(Traits::getNext(NodePtr) != 0 && "Dereferencing end()!");
+ return *NodePtr;
+ }
+ pointer operator->() { return &operator*(); }
+ const pointer operator->() const { return &operator*(); }
+
+ // Comparison operators
+ bool operator==(const ilist_iterator &RHS) const {
+ return NodePtr == RHS.NodePtr;
+ }
+ bool operator!=(const ilist_iterator &RHS) const {
+ return NodePtr != RHS.NodePtr;
+ }
+
+ // Increment and decrement operators...
+ ilist_iterator &operator--() { // predecrement - Back up
+ NodePtr = Traits::getPrev(NodePtr);
+ assert(Traits::getNext(NodePtr) && "--'d off the beginning of an ilist!");
+ return *this;
+ }
+ ilist_iterator &operator++() { // preincrement - Advance
+ NodePtr = Traits::getNext(NodePtr);
+ assert(NodePtr && "++'d off the end of an ilist!");
+ return *this;
+ }
+ ilist_iterator operator--(int) { // postdecrement operators...
+ ilist_iterator tmp = *this;
+ --*this;
+ return tmp;
+ }
+ ilist_iterator operator++(int) { // postincrement operators...
+ ilist_iterator tmp = *this;
+ ++*this;
+ return tmp;
+ }
+
+ // Internal interface, do not use...
+ pointer getNodePtrUnchecked() const { return NodePtr; }
+};
+
+// do not implement. this is to catch errors when people try to use
+// them as random access iterators
+template<typename T>
+void operator-(int, ilist_iterator<T>);
+template<typename T>
+void operator-(ilist_iterator<T>,int);
+
+template<typename T>
+void operator+(int, ilist_iterator<T>);
+template<typename T>
+void operator+(ilist_iterator<T>,int);
+
+// operator!=/operator== - Allow mixed comparisons without dereferencing
+// the iterator, which could very likely be pointing to end().
+template<typename T>
+bool operator!=(const T* LHS, const ilist_iterator<const T> &RHS) {
+ return LHS != RHS.getNodePtrUnchecked();
+}
+template<typename T>
+bool operator==(const T* LHS, const ilist_iterator<const T> &RHS) {
+ return LHS == RHS.getNodePtrUnchecked();
+}
+template<typename T>
+bool operator!=(T* LHS, const ilist_iterator<T> &RHS) {
+ return LHS != RHS.getNodePtrUnchecked();
+}
+template<typename T>
+bool operator==(T* LHS, const ilist_iterator<T> &RHS) {
+ return LHS == RHS.getNodePtrUnchecked();
+}
+
+
+// Allow ilist_iterators to convert into pointers to a node automatically when
+// used by the dyn_cast, cast, isa mechanisms...
+
+template<typename From> struct simplify_type;
+
+template<typename NodeTy> struct simplify_type<ilist_iterator<NodeTy> > {
+ typedef NodeTy* SimpleType;
+
+ static SimpleType getSimplifiedValue(const ilist_iterator<NodeTy> &Node) {
+ return &*Node;
+ }
+};
+template<typename NodeTy> struct simplify_type<const ilist_iterator<NodeTy> > {
+ typedef NodeTy* SimpleType;
+
+ static SimpleType getSimplifiedValue(const ilist_iterator<NodeTy> &Node) {
+ return &*Node;
+ }
+};
+
+
+//===----------------------------------------------------------------------===//
+//
+/// iplist - The subset of list functionality that can safely be used on nodes
+/// of polymorphic types, i.e. a heterogenous list with a common base class that
+/// holds the next/prev pointers. The only state of the list itself is a single
+/// pointer to the head of the list.
+///
+/// This list can be in one of three interesting states:
+/// 1. The list may be completely unconstructed. In this case, the head
+/// pointer is null. When in this form, any query for an iterator (e.g.
+/// begin() or end()) causes the list to transparently change to state #2.
+/// 2. The list may be empty, but contain a sentinal for the end iterator. This
+/// sentinal is created by the Traits::createSentinel method and is a link
+/// in the list. When the list is empty, the pointer in the iplist points
+/// to the sentinal. Once the sentinal is constructed, it
+/// is not destroyed until the list is.
+/// 3. The list may contain actual objects in it, which are stored as a doubly
+/// linked list of nodes. One invariant of the list is that the predecessor
+/// of the first node in the list always points to the last node in the list,
+/// and the successor pointer for the sentinal (which always stays at the
+/// end of the list) is always null.
+///
+template<typename NodeTy, typename Traits=ilist_traits<NodeTy> >
+class iplist : public Traits {
+ mutable NodeTy *Head;
+
+ // Use the prev node pointer of 'head' as the tail pointer. This is really a
+ // circularly linked list where we snip the 'next' link from the sentinel node
+ // back to the first node in the list (to preserve assertions about going off
+ // the end of the list).
+ NodeTy *getTail() { return getPrev(Head); }
+ const NodeTy *getTail() const { return getPrev(Head); }
+ void setTail(NodeTy *N) const { setPrev(Head, N); }
+
+ /// CreateLazySentinal - This method verifies whether the sentinal for the
+ /// list has been created and lazily makes it if not.
+ void CreateLazySentinal() const {
+ if (Head != 0) return;
+ Head = Traits::createSentinel();
+ setNext(Head, 0);
+ setTail(Head);
+ }
+
+ static bool op_less(NodeTy &L, NodeTy &R) { return L < R; }
+ static bool op_equal(NodeTy &L, NodeTy &R) { return L == R; }
+public:
+ typedef NodeTy *pointer;
+ typedef const NodeTy *const_pointer;
+ typedef NodeTy &reference;
+ typedef const NodeTy &const_reference;
+ typedef NodeTy value_type;
+ typedef ilist_iterator<NodeTy> iterator;
+ typedef ilist_iterator<const NodeTy> const_iterator;
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+ typedef std::reverse_iterator<iterator> reverse_iterator;
+
+ iplist() : Head(0) {}
+ ~iplist() {
+ if (!Head) return;
+ clear();
+ Traits::destroySentinel(getTail());
+ }
+
+ // Iterator creation methods.
+ iterator begin() {
+ CreateLazySentinal();
+ return iterator(Head);
+ }
+ const_iterator begin() const {
+ CreateLazySentinal();
+ return const_iterator(Head);
+ }
+ iterator end() {
+ CreateLazySentinal();
+ return iterator(getTail());
+ }
+ const_iterator end() const {
+ CreateLazySentinal();
+ return const_iterator(getTail());
+ }
+
+ // reverse iterator creation methods.
+ reverse_iterator rbegin() { return reverse_iterator(end()); }
+ const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); }
+ reverse_iterator rend() { return reverse_iterator(begin()); }
+ const_reverse_iterator rend() const { return const_reverse_iterator(begin());}
+
+
+ // Miscellaneous inspection routines.
+ size_type max_size() const { return size_type(-1); }
+ bool empty() const { return Head == 0 || Head == getTail(); }
+
+ // Front and back accessor functions...
+ reference front() {
+ assert(!empty() && "Called front() on empty list!");
+ return *Head;
+ }
+ const_reference front() const {
+ assert(!empty() && "Called front() on empty list!");
+ return *Head;
+ }
+ reference back() {
+ assert(!empty() && "Called back() on empty list!");
+ return *getPrev(getTail());
+ }
+ const_reference back() const {
+ assert(!empty() && "Called back() on empty list!");
+ return *getPrev(getTail());
+ }
+
+ void swap(iplist &RHS) {
+ abort(); // Swap does not use list traits callback correctly yet!
+ std::swap(Head, RHS.Head);
+ }
+
+ iterator insert(iterator where, NodeTy *New) {
+ NodeTy *CurNode = where.getNodePtrUnchecked(), *PrevNode = getPrev(CurNode);
+ setNext(New, CurNode);
+ setPrev(New, PrevNode);
+
+ if (CurNode != Head) // Is PrevNode off the beginning of the list?
+ setNext(PrevNode, New);
+ else
+ Head = New;
+ setPrev(CurNode, New);
+
+ addNodeToList(New); // Notify traits that we added a node...
+ return New;
+ }
+
+ NodeTy *remove(iterator &IT) {
+ assert(IT != end() && "Cannot remove end of list!");
+ NodeTy *Node = &*IT;
+ NodeTy *NextNode = getNext(Node);
+ NodeTy *PrevNode = getPrev(Node);
+
+ if (Node != Head) // Is PrevNode off the beginning of the list?
+ setNext(PrevNode, NextNode);
+ else
+ Head = NextNode;
+ setPrev(NextNode, PrevNode);
+ IT = NextNode;
+ removeNodeFromList(Node); // Notify traits that we removed a node...
+ return Node;
+ }
+
+ NodeTy *remove(const iterator &IT) {
+ iterator MutIt = IT;
+ return remove(MutIt);
+ }
+
+ // erase - remove a node from the controlled sequence... and delete it.
+ iterator erase(iterator where) {
+ delete remove(where);
+ return where;
+ }
+
+
+private:
+ // transfer - The heart of the splice function. Move linked list nodes from
+ // [first, last) into position.
+ //
+ void transfer(iterator position, iplist &L2, iterator first, iterator last) {
+ assert(first != last && "Should be checked by callers");
+
+ if (position != last) {
+ // Note: we have to be careful about the case when we move the first node
+ // in the list. This node is the list sentinel node and we can't move it.
+ NodeTy *ThisSentinel = getTail();
+ setTail(0);
+ NodeTy *L2Sentinel = L2.getTail();
+ L2.setTail(0);
+
+ // Remove [first, last) from its old position.
+ NodeTy *First = &*first, *Prev = getPrev(First);
+ NodeTy *Next = last.getNodePtrUnchecked(), *Last = getPrev(Next);
+ if (Prev)
+ setNext(Prev, Next);
+ else
+ L2.Head = Next;
+ setPrev(Next, Prev);
+
+ // Splice [first, last) into its new position.
+ NodeTy *PosNext = position.getNodePtrUnchecked();
+ NodeTy *PosPrev = getPrev(PosNext);
+
+ // Fix head of list...
+ if (PosPrev)
+ setNext(PosPrev, First);
+ else
+ Head = First;
+ setPrev(First, PosPrev);
+
+ // Fix end of list...
+ setNext(Last, PosNext);
+ setPrev(PosNext, Last);
+
+ transferNodesFromList(L2, First, PosNext);
+
+ // Now that everything is set, restore the pointers to the list sentinals.
+ L2.setTail(L2Sentinel);
+ setTail(ThisSentinel);
+ }
+ }
+
+public:
+
+ //===----------------------------------------------------------------------===
+ // Functionality derived from other functions defined above...
+ //
+
+ size_type size() const {
+ if (Head == 0) return 0; // Don't require construction of sentinal if empty.
+#if __GNUC__ == 2
+ // GCC 2.95 has a broken std::distance
+ size_type Result = 0;
+ std::distance(begin(), end(), Result);
+ return Result;
+#else
+ return std::distance(begin(), end());
+#endif
+ }
+
+ iterator erase(iterator first, iterator last) {
+ while (first != last)
+ first = erase(first);
+ return last;
+ }
+
+ void clear() { if (Head) erase(begin(), end()); }
+
+ // Front and back inserters...
+ void push_front(NodeTy *val) { insert(begin(), val); }
+ void push_back(NodeTy *val) { insert(end(), val); }
+ void pop_front() {
+ assert(!empty() && "pop_front() on empty list!");
+ erase(begin());
+ }
+ void pop_back() {
+ assert(!empty() && "pop_back() on empty list!");
+ iterator t = end(); erase(--t);
+ }
+
+ // Special forms of insert...
+ template<class InIt> void insert(iterator where, InIt first, InIt last) {
+ for (; first != last; ++first) insert(where, *first);
+ }
+
+ // Splice members - defined in terms of transfer...
+ void splice(iterator where, iplist &L2) {
+ if (!L2.empty())
+ transfer(where, L2, L2.begin(), L2.end());
+ }
+ void splice(iterator where, iplist &L2, iterator first) {
+ iterator last = first; ++last;
+ if (where == first || where == last) return; // No change
+ transfer(where, L2, first, last);
+ }
+ void splice(iterator where, iplist &L2, iterator first, iterator last) {
+ if (first != last) transfer(where, L2, first, last);
+ }
+
+
+
+ //===----------------------------------------------------------------------===
+ // High-Level Functionality that shouldn't really be here, but is part of list
+ //
+
+ // These two functions are actually called remove/remove_if in list<>, but
+ // they actually do the job of erase, rename them accordingly.
+ //
+ void erase(const NodeTy &val) {
+ for (iterator I = begin(), E = end(); I != E; ) {
+ iterator next = I; ++next;
+ if (*I == val) erase(I);
+ I = next;
+ }
+ }
+ template<class Pr1> void erase_if(Pr1 pred) {
+ for (iterator I = begin(), E = end(); I != E; ) {
+ iterator next = I; ++next;
+ if (pred(*I)) erase(I);
+ I = next;
+ }
+ }
+
+ template<class Pr2> void unique(Pr2 pred) {
+ if (empty()) return;
+ for (iterator I = begin(), E = end(), Next = begin(); ++Next != E;) {
+ if (pred(*I))
+ erase(Next);
+ else
+ I = Next;
+ Next = I;
+ }
+ }
+ void unique() { unique(op_equal); }
+
+ template<class Pr3> void merge(iplist &right, Pr3 pred) {
+ iterator first1 = begin(), last1 = end();
+ iterator first2 = right.begin(), last2 = right.end();
+ while (first1 != last1 && first2 != last2)
+ if (pred(*first2, *first1)) {
+ iterator next = first2;
+ transfer(first1, right, first2, ++next);
+ first2 = next;
+ } else {
+ ++first1;
+ }
+ if (first2 != last2) transfer(last1, right, first2, last2);
+ }
+ void merge(iplist &right) { return merge(right, op_less); }
+
+ template<class Pr3> void sort(Pr3 pred);
+ void sort() { sort(op_less); }
+ void reverse();
+};
+
+
+template<typename NodeTy>
+struct ilist : public iplist<NodeTy> {
+ typedef typename iplist<NodeTy>::size_type size_type;
+ typedef typename iplist<NodeTy>::iterator iterator;
+
+ ilist() {}
+ ilist(const ilist &right) {
+ insert(this->begin(), right.begin(), right.end());
+ }
+ explicit ilist(size_type count) {
+ insert(this->begin(), count, NodeTy());
+ }
+ ilist(size_type count, const NodeTy &val) {
+ insert(this->begin(), count, val);
+ }
+ template<class InIt> ilist(InIt first, InIt last) {
+ insert(this->begin(), first, last);
+ }
+
+
+ // Forwarding functions: A workaround for GCC 2.95 which does not correctly
+ // support 'using' declarations to bring a hidden member into scope.
+ //
+ iterator insert(iterator a, NodeTy *b){ return iplist<NodeTy>::insert(a, b); }
+ void push_front(NodeTy *a) { iplist<NodeTy>::push_front(a); }
+ void push_back(NodeTy *a) { iplist<NodeTy>::push_back(a); }
+
+
+ // Main implementation here - Insert for a node passed by value...
+ iterator insert(iterator where, const NodeTy &val) {
+ return insert(where, createNode(val));
+ }
+
+
+ // Front and back inserters...
+ void push_front(const NodeTy &val) { insert(this->begin(), val); }
+ void push_back(const NodeTy &val) { insert(this->end(), val); }
+
+ // Special forms of insert...
+ template<class InIt> void insert(iterator where, InIt first, InIt last) {
+ for (; first != last; ++first) insert(where, *first);
+ }
+ void insert(iterator where, size_type count, const NodeTy &val) {
+ for (; count != 0; --count) insert(where, val);
+ }
+
+ // Assign special forms...
+ void assign(size_type count, const NodeTy &val) {
+ iterator I = this->begin();
+ for (; I != this->end() && count != 0; ++I, --count)
+ *I = val;
+ if (count != 0)
+ insert(this->end(), val, val);
+ else
+ erase(I, this->end());
+ }
+ template<class InIt> void assign(InIt first1, InIt last1) {
+ iterator first2 = this->begin(), last2 = this->end();
+ for ( ; first1 != last1 && first2 != last2; ++first1, ++first2)
+ *first1 = *first2;
+ if (first2 == last2)
+ erase(first1, last1);
+ else
+ insert(last1, first2, last2);
+ }
+
+
+ // Resize members...
+ void resize(size_type newsize, NodeTy val) {
+ iterator i = this->begin();
+ size_type len = 0;
+ for ( ; i != this->end() && len < newsize; ++i, ++len) /* empty*/ ;
+
+ if (len == newsize)
+ erase(i, this->end());
+ else // i == end()
+ insert(this->end(), newsize - len, val);
+ }
+ void resize(size_type newsize) { resize(newsize, NodeTy()); }
+};
+
+} // End llvm namespace
+
+namespace std {
+ // Ensure that swap uses the fast list swap...
+ template<class Ty>
+ void swap(llvm::iplist<Ty> &Left, llvm::iplist<Ty> &Right) {
+ Left.swap(Right);
+ }
+} // End 'std' extensions...
+
+#endif
diff --git a/support/include/llvm/ADT/iterator.in b/support/include/llvm/ADT/iterator.in
new file mode 100644
index 0000000..47f70d1
--- /dev/null
+++ b/support/include/llvm/ADT/iterator.in
@@ -0,0 +1,76 @@
+//===-- llvm/ADT/iterator - Portable wrapper around <iterator> --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides a wrapper around the mysterious <iterator> header file.
+// In GCC 2.95.3, the file defines a bidirectional_iterator class (and other
+// friends), instead of the standard iterator class. In GCC 3.1, the
+// bidirectional_iterator class got moved out and the new, standards compliant,
+// iterator<> class was added. Because there is nothing that we can do to get
+// correct behavior on both compilers, we have this header with #ifdef's. Gross
+// huh?
+//
+// By #includ'ing this file, you get the contents of <iterator> plus the
+// following classes in the global namespace:
+//
+// 1. bidirectional_iterator
+// 2. forward_iterator
+//
+// The #if directives' expressions are filled in by Autoconf.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_ITERATOR
+#define LLVM_ADT_ITERATOR
+
+#include <iterator>
+
+#undef HAVE_BI_ITERATOR
+#undef HAVE_STD_ITERATOR
+#undef HAVE_FWD_ITERATOR
+
+#ifdef _MSC_VER
+# define HAVE_BI_ITERATOR 0
+# define HAVE_STD_ITERATOR 1
+# define HAVE_FWD_ITERATOR 0
+#endif
+
+#if !HAVE_BI_ITERATOR
+# if HAVE_STD_ITERATOR
+/// If the bidirectional iterator is not defined, we attempt to define it in
+/// terms of the C++ standard iterator. Otherwise, we import it with a "using"
+/// statement.
+///
+template<class Ty, class PtrDiffTy>
+struct bidirectional_iterator
+ : public std::iterator<std::bidirectional_iterator_tag, Ty, PtrDiffTy> {
+};
+# else
+# error "Need to have standard iterator to define bidirectional iterator!"
+# endif
+#else
+using std::bidirectional_iterator;
+#endif
+
+#if !HAVE_FWD_ITERATOR
+# if HAVE_STD_ITERATOR
+/// If the forward iterator is not defined, attempt to define it in terms of
+/// the C++ standard iterator. Otherwise, we import it with a "using" statement.
+///
+template<class Ty, class PtrDiffTy>
+struct forward_iterator
+ : public std::iterator<std::forward_iterator_tag, Ty, PtrDiffTy> {
+};
+# else
+# error "Need to have standard iterator to define forward iterator!"
+# endif
+#else
+using std::forward_iterator;
+#endif
+
+#endif
diff --git a/support/include/llvm/ADT/scoped_ptr.h b/support/include/llvm/ADT/scoped_ptr.h
new file mode 100644
index 0000000..a95a6ef
--- /dev/null
+++ b/support/include/llvm/ADT/scoped_ptr.h
@@ -0,0 +1,129 @@
+//===- llvm/ADT/scoped_ptr.h - basic smart pointer --------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the scoped_ptr smart pointer: scoped_ptr mimics a built-in
+// pointer except that it guarantees deletion of the object pointed to, either
+// on destruction of the scoped_ptr or via an explicit reset(). scoped_ptr is a
+// simple solution for simple needs.
+//
+//===----------------------------------------------------------------------===//
+//
+// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
+// Copyright (c) 2001, 2002 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file llvm/docs/BOOST_LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt )
+//
+// http://www.boost.org/libs/smart_ptr/scoped_ptr.htm
+//
+
+#ifndef LLVM_SCOPED_PTR_HPP_INCLUDED
+#define LLVM_SCOPED_PTR_HPP_INCLUDED
+
+#include <cassert>
+
+namespace llvm {
+
+// verify that types are complete for increased safety
+template<class T> inline void checked_delete(T * x) {
+ // intentionally complex - simplification causes regressions
+ typedef char type_must_be_complete[ sizeof(T)? 1: -1 ];
+ (void) sizeof(type_must_be_complete);
+ delete x;
+}
+
+// scoped_ptr mimics a built-in pointer except that it guarantees deletion
+// of the object pointed to, either on destruction of the scoped_ptr or via
+// an explicit reset(). scoped_ptr is a simple solution for simple needs;
+// use shared_ptr or std::auto_ptr if your needs are more complex.
+
+template<class T> class scoped_ptr // noncopyable
+{
+private:
+
+ T * ptr;
+
+ scoped_ptr(scoped_ptr const &);
+ scoped_ptr & operator=(scoped_ptr const &);
+
+ typedef scoped_ptr<T> this_type;
+
+public:
+
+ typedef T element_type;
+
+ explicit scoped_ptr(T * p = 0): ptr(p) // never throws
+ {
+ }
+
+ ~scoped_ptr() // never throws
+ {
+ llvm::checked_delete(ptr);
+ }
+
+ void reset(T * p = 0) // never throws
+ {
+ assert( (p == 0 || p != ptr) && "scoped_ptr: self-reset error"); // catch self-reset errors
+ this_type(p).swap(*this);
+ }
+
+ T & operator*() const // never throws
+ {
+ assert(ptr != 0 && "scoped_ptr: Trying to dereference a null pointeur");
+ return *ptr;
+ }
+
+ T * operator->() const // never throws
+ {
+ assert(ptr != 0 && "scoped_ptr: Trying to dereference a null pointeur");
+ return ptr;
+ }
+
+ T * get() const // never throws
+ {
+ return ptr;
+ }
+
+ // implicit conversion to "bool"
+ typedef T * this_type::*unspecified_bool_type;
+
+ operator unspecified_bool_type() const // never throws
+ {
+ return ptr == 0? 0: &this_type::ptr;
+ }
+
+ bool operator! () const // never throws
+ {
+ return ptr == 0;
+ }
+
+ void swap(scoped_ptr & b) // never throws
+ {
+ T * tmp = b.ptr;
+ b.ptr = ptr;
+ ptr = tmp;
+ }
+};
+
+template<class T> inline void swap(scoped_ptr<T> & a, scoped_ptr<T> & b) // never throws
+{
+ a.swap(b);
+}
+
+// get_pointer(p) is a generic way to say p.get()
+
+template<class T> inline T * get_pointer(scoped_ptr<T> const & p)
+{
+ return p.get();
+}
+
+} // namespace llvm
+
+#endif // #ifndef LLVM_SCOPED_PTR_HPP_INCLUDED
diff --git a/support/include/llvm/Config/alloca.h b/support/include/llvm/Config/alloca.h
new file mode 100644
index 0000000..10fa74d
--- /dev/null
+++ b/support/include/llvm/Config/alloca.h
@@ -0,0 +1,50 @@
+/*
+ * The LLVM Compiler Infrastructure
+ *
+ * This file was developed by the LLVM research group and is distributed under
+ * the University of Illinois Open Source License. See LICENSE.TXT for details.
+ *
+ ******************************************************************************
+ *
+ * Description:
+ * This header file includes the infamous alloc.h header file if the
+ * autoconf system has found it. It hides all of the autoconf details
+ * from the rest of the application source code.
+ */
+
+#ifndef _CONFIG_ALLOC_H
+#define _CONFIG_ALLOC_H
+
+#include "llvm/Config/config.h"
+
+/*
+ * This is a modified version of that suggested by the Autoconf manual.
+ * 1) The #pragma is indented so that pre-ANSI C compilers ignore it.
+ * 2) If alloca.h cannot be found, then try stdlib.h. Some platforms
+ * (notably FreeBSD) defined alloca() there.
+ */
+#ifdef _MSC_VER
+#include <malloc.h>
+#define alloca _alloca
+#elif defined(HAVE_ALLOCA_H)
+#include <alloca.h>
+#elif defined(__MINGW32__) && defined(HAVE_MALLOC_H)
+#include <malloc.h>
+#elif !defined(__GNUC__)
+# ifdef _AIX
+# pragma alloca
+# else
+# ifndef alloca
+ char * alloca ();
+# endif
+# endif
+#else
+# ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+# else
+# error "The function alloca() is required but not found!"
+# endif
+#endif
+
+#endif
+
diff --git a/support/include/llvm/Config/config.h.in b/support/include/llvm/Config/config.h.in
new file mode 100644
index 0000000..32e154a
--- /dev/null
+++ b/support/include/llvm/Config/config.h.in
@@ -0,0 +1,576 @@
+/* include/llvm/Config/config.h.in. Generated from autoconf/configure.ac by autoheader. */
+
+/* Define if dlopen(0) will open the symbols of the program */
+#undef CAN_DLOPEN_SELF
+
+/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
+ systems. This function is required for `alloca.c' support on those systems.
+ */
+#undef CRAY_STACKSEG_END
+
+/* Define to 1 if using `alloca.c'. */
+#undef C_ALLOCA
+
+/* Define if CBE is enabled for printf %a output */
+#undef ENABLE_CBE_PRINTF_A
+
+/* Define if position independent code is enabled */
+#undef ENABLE_PIC
+
+/* Define if threads enabled */
+#undef ENABLE_THREADS
+
+/* Define to 1 if you have `alloca', as a function or macro. */
+#undef HAVE_ALLOCA
+
+/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
+ */
+#undef HAVE_ALLOCA_H
+
+/* Define to 1 if you have the `argz_append' function. */
+#undef HAVE_ARGZ_APPEND
+
+/* Define to 1 if you have the `argz_create_sep' function. */
+#undef HAVE_ARGZ_CREATE_SEP
+
+/* Define to 1 if you have the <argz.h> header file. */
+#undef HAVE_ARGZ_H
+
+/* Define to 1 if you have the `argz_insert' function. */
+#undef HAVE_ARGZ_INSERT
+
+/* Define to 1 if you have the `argz_next' function. */
+#undef HAVE_ARGZ_NEXT
+
+/* Define to 1 if you have the `argz_stringify' function. */
+#undef HAVE_ARGZ_STRINGIFY
+
+/* Define to 1 if you have the <assert.h> header file. */
+#undef HAVE_ASSERT_H
+
+/* Define to 1 if you have the `backtrace' function. */
+#undef HAVE_BACKTRACE
+
+/* Define to 1 if you have the `bcopy' function. */
+#undef HAVE_BCOPY
+
+/* Does not have bi-directional iterator */
+#undef HAVE_BI_ITERATOR
+
+/* Define to 1 if you have the `ceilf' function. */
+#undef HAVE_CEILF
+
+/* Define to 1 if you have the `closedir' function. */
+#undef HAVE_CLOSEDIR
+
+/* Define to 1 if you have the <ctype.h> header file. */
+#undef HAVE_CTYPE_H
+
+/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
+ */
+#undef HAVE_DIRENT_H
+
+/* Define if you have the GNU dld library. */
+#undef HAVE_DLD
+
+/* Define to 1 if you have the <dld.h> header file. */
+#undef HAVE_DLD_H
+
+/* Define to 1 if you have the `dlerror' function. */
+#undef HAVE_DLERROR
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define if dlopen() is available on this platform. */
+#undef HAVE_DLOPEN
+
+/* Define to 1 if you have the <dl.h> header file. */
+#undef HAVE_DL_H
+
+/* Define if the dot program is available */
+#undef HAVE_DOT
+
+/* Define if the dotty program is available */
+#undef HAVE_DOTTY
+
+/* Define if you have the _dyld_func_lookup function. */
+#undef HAVE_DYLD
+
+/* Define to 1 if you have the <errno.h> header file. */
+#undef HAVE_ERRNO_H
+
+/* Define to 1 if the system has the type `error_t'. */
+#undef HAVE_ERROR_T
+
+/* Define to 1 if you have the <execinfo.h> header file. */
+#undef HAVE_EXECINFO_H
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#undef HAVE_FCNTL_H
+
+/* Set to 1 if the finite function is found in <ieeefp.h> */
+#undef HAVE_FINITE_IN_IEEEFP_H
+
+/* Define to 1 if you have the `floorf' function. */
+#undef HAVE_FLOORF
+
+/* Define to 1 if you have the `fmodf' function. */
+#undef HAVE_FMODF
+
+/* Does not have forward iterator */
+#undef HAVE_FWD_ITERATOR
+
+/* Define to 1 if you have the `getcwd' function. */
+#undef HAVE_GETCWD
+
+/* Define to 1 if you have the `getpagesize' function. */
+#undef HAVE_GETPAGESIZE
+
+/* Define to 1 if you have the `getrlimit' function. */
+#undef HAVE_GETRLIMIT
+
+/* Define to 1 if you have the `getrusage' function. */
+#undef HAVE_GETRUSAGE
+
+/* Define to 1 if you have the `gettimeofday' function. */
+#undef HAVE_GETTIMEOFDAY
+
+/* Does not have <hash_map> */
+#undef HAVE_GLOBAL_HASH_MAP
+
+/* Does not have hash_set in global namespace */
+#undef HAVE_GLOBAL_HASH_SET
+
+/* Does not have ext/hash_map */
+#undef HAVE_GNU_EXT_HASH_MAP
+
+/* Does not have hash_set in gnu namespace */
+#undef HAVE_GNU_EXT_HASH_SET
+
+/* Define if the Graphviz program is available */
+#undef HAVE_GRAPHVIZ
+
+/* Define if the gv program is available */
+#undef HAVE_GV
+
+/* Define to 1 if you have the `index' function. */
+#undef HAVE_INDEX
+
+/* Define to 1 if the system has the type `int64_t'. */
+#undef HAVE_INT64_T
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the `isatty' function. */
+#undef HAVE_ISATTY
+
+/* Set to 1 if the isinf function is found in <cmath> */
+#undef HAVE_ISINF_IN_CMATH
+
+/* Set to 1 if the isinf function is found in <math.h> */
+#undef HAVE_ISINF_IN_MATH_H
+
+/* Set to 1 if the isnan function is found in <cmath> */
+#undef HAVE_ISNAN_IN_CMATH
+
+/* Set to 1 if the isnan function is found in <math.h> */
+#undef HAVE_ISNAN_IN_MATH_H
+
+/* Define if you have the libdl library or equivalent. */
+#undef HAVE_LIBDL
+
+/* Define to 1 if you have the `elf' library (-lelf). */
+#undef HAVE_LIBELF
+
+/* Define to 1 if you have the `imagehlp' library (-limagehlp). */
+#undef HAVE_LIBIMAGEHLP
+
+/* Define to 1 if you have the `m' library (-lm). */
+#undef HAVE_LIBM
+
+/* Define to 1 if you have the `psapi' library (-lpsapi). */
+#undef HAVE_LIBPSAPI
+
+/* Define to 1 if you have the `pthread' library (-lpthread). */
+#undef HAVE_LIBPTHREAD
+
+/* Define to 1 if you have the `udis86' library (-ludis86). */
+#undef HAVE_LIBUDIS86
+
+/* Define to 1 if you have the <limits.h> header file. */
+#undef HAVE_LIMITS_H
+
+/* Define to 1 if you have the <link.h> header file. */
+#undef HAVE_LINK_H
+
+/* Define if you can use -Wl,-R. to pass -R. to the linker, in order to add
+ the current directory to the dynamic linker search path. */
+#undef HAVE_LINK_R
+
+/* Define to 1 if you have the `longjmp' function. */
+#undef HAVE_LONGJMP
+
+/* Define if lt_dlopen() is available on this platform */
+#undef HAVE_LT_DLOPEN
+
+/* Define to 1 if you have the <mach/mach.h> header file. */
+#undef HAVE_MACH_MACH_H
+
+/* Define to 1 if you have the <mach-o/dyld.h> header file. */
+#undef HAVE_MACH_O_DYLD_H
+
+/* Define if mallinfo() is available on this platform. */
+#undef HAVE_MALLINFO
+
+/* Define to 1 if you have the <malloc.h> header file. */
+#undef HAVE_MALLOC_H
+
+/* Define to 1 if you have the <malloc/malloc.h> header file. */
+#undef HAVE_MALLOC_MALLOC_H
+
+/* Define to 1 if you have the `malloc_zone_statistics' function. */
+#undef HAVE_MALLOC_ZONE_STATISTICS
+
+/* Define to 1 if you have the `memcpy' function. */
+#undef HAVE_MEMCPY
+
+/* Define to 1 if you have the `memmove' function. */
+#undef HAVE_MEMMOVE
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the `mkdtemp' function. */
+#undef HAVE_MKDTEMP
+
+/* Define to 1 if you have the `mkstemp' function. */
+#undef HAVE_MKSTEMP
+
+/* Define to 1 if you have the `mktemp' function. */
+#undef HAVE_MKTEMP
+
+/* Define to 1 if you have a working `mmap' system call. */
+#undef HAVE_MMAP
+
+/* Define if mmap() uses MAP_ANONYMOUS to map anonymous pages, or undefine if
+ it uses MAP_ANON */
+#undef HAVE_MMAP_ANONYMOUS
+
+/* Define if mmap() can map files into memory */
+#undef HAVE_MMAP_FILE
+
+/* define if the compiler implements namespaces */
+#undef HAVE_NAMESPACES
+
+/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
+#undef HAVE_NDIR_H
+
+/* Define to 1 if you have the `nearbyintf' function. */
+#undef HAVE_NEARBYINTF
+
+/* Define to 1 if you have the `opendir' function. */
+#undef HAVE_OPENDIR
+
+/* Define to 1 if you have the `powf' function. */
+#undef HAVE_POWF
+
+/* Define if libtool can extract symbol lists from object files. */
+#undef HAVE_PRELOADED_SYMBOLS
+
+/* Define to have the %a format string */
+#undef HAVE_PRINTF_A
+
+/* Define to 1 if you have the <pthread.h> header file. */
+#undef HAVE_PTHREAD_H
+
+/* Have pthread_mutex_lock */
+#undef HAVE_PTHREAD_MUTEX_LOCK
+
+/* Define to 1 if srand48/lrand48/drand48 exist in <stdlib.h> */
+#undef HAVE_RAND48
+
+/* Define to 1 if you have the `readdir' function. */
+#undef HAVE_READDIR
+
+/* Define to 1 if you have the `realpath' function. */
+#undef HAVE_REALPATH
+
+/* Define to 1 if you have the `rindex' function. */
+#undef HAVE_RINDEX
+
+/* Define to 1 if you have the `rintf' function. */
+#undef HAVE_RINTF
+
+/* Define to 1 if you have the `round' function. */
+#undef HAVE_ROUND
+
+/* Define to 1 if you have the `roundf' function. */
+#undef HAVE_ROUNDF
+
+/* Define to 1 if you have the `sbrk' function. */
+#undef HAVE_SBRK
+
+/* Define to 1 if you have the `setjmp' function. */
+#undef HAVE_SETJMP
+
+/* Define to 1 if you have the <setjmp.h> header file. */
+#undef HAVE_SETJMP_H
+
+/* Define to 1 if you have the `setrlimit' function. */
+#undef HAVE_SETRLIMIT
+
+/* Define if you have the shl_load function. */
+#undef HAVE_SHL_LOAD
+
+/* Define to 1 if you have the `siglongjmp' function. */
+#undef HAVE_SIGLONGJMP
+
+/* Define to 1 if you have the <signal.h> header file. */
+#undef HAVE_SIGNAL_H
+
+/* Define to 1 if you have the `sigsetjmp' function. */
+#undef HAVE_SIGSETJMP
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdio.h> header file. */
+#undef HAVE_STDIO_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Does not have ext/hash_map> */
+#undef HAVE_STD_EXT_HASH_MAP
+
+/* Does not have hash_set in std namespace */
+#undef HAVE_STD_EXT_HASH_SET
+
+/* Set to 1 if the std::isinf function is found in <cmath> */
+#undef HAVE_STD_ISINF_IN_CMATH
+
+/* Set to 1 if the std::isnan function is found in <cmath> */
+#undef HAVE_STD_ISNAN_IN_CMATH
+
+/* Does not have std namespace iterator */
+#undef HAVE_STD_ITERATOR
+
+/* Define to 1 if you have the `strchr' function. */
+#undef HAVE_STRCHR
+
+/* Define to 1 if you have the `strcmp' function. */
+#undef HAVE_STRCMP
+
+/* Define to 1 if you have the `strdup' function. */
+#undef HAVE_STRDUP
+
+/* Define to 1 if you have the `strerror' function. */
+#undef HAVE_STRERROR
+
+/* Define to 1 if you have the `strerror_r' function. */
+#undef HAVE_STRERROR_R
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the `strrchr' function. */
+#undef HAVE_STRRCHR
+
+/* Define to 1 if you have the `strtof' function. */
+#undef HAVE_STRTOF
+
+/* Define to 1 if you have the `strtoll' function. */
+#undef HAVE_STRTOLL
+
+/* Define to 1 if you have the `strtoq' function. */
+#undef HAVE_STRTOQ
+
+/* Define to 1 if you have the `sysconf' function. */
+#undef HAVE_SYSCONF
+
+/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
+ */
+#undef HAVE_SYS_DIR_H
+
+/* Define to 1 if you have the <sys/dl.h> header file. */
+#undef HAVE_SYS_DL_H
+
+/* Define to 1 if you have the <sys/mman.h> header file. */
+#undef HAVE_SYS_MMAN_H
+
+/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
+ */
+#undef HAVE_SYS_NDIR_H
+
+/* Define to 1 if you have the <sys/param.h> header file. */
+#undef HAVE_SYS_PARAM_H
+
+/* Define to 1 if you have the <sys/resource.h> header file. */
+#undef HAVE_SYS_RESOURCE_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#undef HAVE_SYS_TIME_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
+#undef HAVE_SYS_WAIT_H
+
+/* Define to 1 if the system has the type `uint64_t'. */
+#undef HAVE_UINT64_T
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to 1 if you have the <utime.h> header file. */
+#undef HAVE_UTIME_H
+
+/* Define to 1 if the system has the type `u_int64_t'. */
+#undef HAVE_U_INT64_T
+
+/* Define to 1 if you have the <windows.h> header file. */
+#undef HAVE_WINDOWS_H
+
+/* Define to 1 if you have the `__dso_handle' function. */
+#undef HAVE___DSO_HANDLE
+
+/* Installation directory for binary executables */
+#undef LLVM_BINDIR
+
+/* Time at which LLVM was configured */
+#undef LLVM_CONFIGTIME
+
+/* Installation directory for data files */
+#undef LLVM_DATADIR
+
+/* Installation directory for documentation */
+#undef LLVM_DOCSDIR
+
+/* Installation directory for config files */
+#undef LLVM_ETCDIR
+
+/* Host triple we were built on */
+#undef LLVM_HOSTTRIPLE
+
+/* Installation directory for include files */
+#undef LLVM_INCLUDEDIR
+
+/* Installation directory for .info files */
+#undef LLVM_INFODIR
+
+/* Installation directory for libraries */
+#undef LLVM_LIBDIR
+
+/* Installation directory for man pages */
+#undef LLVM_MANDIR
+
+/* Define if this is Unixish platform */
+#undef LLVM_ON_UNIX
+
+/* Define if this is Win32ish platform */
+#undef LLVM_ON_WIN32
+
+/* Define to path to dot program if found or 'echo dot' otherwise */
+#undef LLVM_PATH_DOT
+
+/* Define to path to dotty program if found or 'echo dotty' otherwise */
+#undef LLVM_PATH_DOTTY
+
+/* Define to path to Graphviz program if found or 'echo Graphviz' otherwise */
+#undef LLVM_PATH_GRAPHVIZ
+
+/* Define to path to gv program if found or 'echo gv' otherwise */
+#undef LLVM_PATH_GV
+
+/* Installation prefix directory */
+#undef LLVM_PREFIX
+
+/* Define if the OS needs help to load dependent libraries for dlopen(). */
+#undef LTDL_DLOPEN_DEPLIBS
+
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+ */
+#undef LTDL_OBJDIR
+
+/* Define to the name of the environment variable that determines the dynamic
+ library search path. */
+#undef LTDL_SHLIBPATH_VAR
+
+/* Define to the extension used for shared libraries, say, ".so". */
+#undef LTDL_SHLIB_EXT
+
+/* Define to the system default library search path. */
+#undef LTDL_SYSSEARCHPATH
+
+/* Define if /dev/zero should be used when mapping RWX memory, or undefine if
+ its not necessary */
+#undef NEED_DEV_ZERO_FOR_MMAP
+
+/* Define if dlsym() requires a leading underscore in symbol names. */
+#undef NEED_USCORE
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define as the return type of signal handlers (`int' or `void'). */
+#undef RETSIGTYPE
+
+/* If using the C implementation of alloca, define if you know the
+ direction of stack growth for your system; otherwise it will be
+ automatically deduced at runtime.
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown */
+#undef STACK_DIRECTION
+
+/* Define to 1 if the `S_IS*' macros in <sys/stat.h> do not work properly. */
+#undef STAT_MACROS_BROKEN
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+#undef TIME_WITH_SYS_TIME
+
+/* Define to 1 if your <sys/time.h> declares `struct tm'. */
+#undef TM_IN_SYS_TIME
+
+/* Define if use udis86 library */
+#undef USE_UDIS86
+
+/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a
+ `char[]'. */
+#undef YYTEXT_POINTER
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* Define to a type to use for `error_t' if it is not otherwise available. */
+#undef error_t
+
+/* Define to `int' if <sys/types.h> does not define. */
+#undef pid_t
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+#undef size_t
diff --git a/support/include/llvm/Support/AIXDataTypesFix.h b/support/include/llvm/Support/AIXDataTypesFix.h
new file mode 100644
index 0000000..256e45f
--- /dev/null
+++ b/support/include/llvm/Support/AIXDataTypesFix.h
@@ -0,0 +1,25 @@
+//===-- llvm/Support/AIXDataTypesFix.h - Fix datatype defs ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file overrides default system-defined types and limits which cannot be
+// done in DataTypes.h.in because it is processed by autoheader first, which
+// comments out any #undef statement
+//
+//===----------------------------------------------------------------------===//
+
+// No include guards desired!
+
+#ifndef SUPPORT_DATATYPES_H
+#error "AIXDataTypesFix.h must only be included via DataTypes.h!"
+#endif
+
+// GCC is strict about defining large constants: they must have LL modifier.
+// These will be defined properly at the end of DataTypes.h
+#undef INT64_MAX
+#undef INT64_MIN
diff --git a/support/include/llvm/Support/AlignOf.h b/support/include/llvm/Support/AlignOf.h
new file mode 100644
index 0000000..4ee5ea2
--- /dev/null
+++ b/support/include/llvm/Support/AlignOf.h
@@ -0,0 +1,48 @@
+//===--- AlignOf.h - Portable calculation of type alignment -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Ted Kremenek and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the AlignOf function that computes alignments for
+// arbitrary types.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_ALIGNOF_H
+#define LLVM_SUPPORT_ALIGNOF_H
+
+namespace llvm {
+
+template <typename T>
+struct AlignmentCalcImpl {
+ char x;
+ T t;
+private:
+ AlignmentCalcImpl() {} // Never instantiate.
+};
+
+/// AlignOf - A templated class that contains an enum value representing
+/// the alignment of the template argument. For example,
+/// AlignOf<int>::Alignment represents the alignment of type "int". The
+/// alignment calculated is the minimum alignment, and not necessarily
+/// the "desired" alignment returned by GCC's __alignof__ (for example). Note
+/// that because the alignment is an enum value, it can be used as a
+/// compile-time constant (e.g., for template instantiation).
+template <typename T>
+struct AlignOf {
+ enum { Alignment = sizeof(AlignmentCalcImpl<T>) - sizeof(T) };
+};
+
+/// alignof - A templated function that returns the mininum alignment of
+/// of a type. This provides no extra functionality beyond the AlignOf
+/// class besides some cosmetic cleanliness. Example usage:
+/// alignof<int>() returns the alignment of an int.
+template <typename T>
+static inline unsigned alignof() { return AlignOf<T>::Alignment; }
+
+} // end namespace llvm
+#endif
diff --git a/support/include/llvm/Support/Allocator.h b/support/include/llvm/Support/Allocator.h
new file mode 100644
index 0000000..729cc67
--- /dev/null
+++ b/support/include/llvm/Support/Allocator.h
@@ -0,0 +1,62 @@
+//===--- Allocator.h - Simple memory allocation abstraction -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the MallocAllocator and BumpPtrAllocator interfaces.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_ALLOCATOR_H
+#define LLVM_SUPPORT_ALLOCATOR_H
+
+#include "llvm/Support/AlignOf.h"
+#include <cstdlib>
+
+namespace llvm {
+
+class MallocAllocator {
+public:
+ MallocAllocator() {}
+ ~MallocAllocator() {}
+
+ void Reset() {}
+ void *Allocate(unsigned Size, unsigned Alignment) { return malloc(Size); }
+
+ template <typename T>
+ void *Allocate() { return reinterpret_cast<T*>(malloc(sizeof(T))); }
+
+ void Deallocate(void *Ptr) { free(Ptr); }
+ void PrintStats() const {}
+};
+
+/// BumpPtrAllocator - This allocator is useful for containers that need very
+/// simple memory allocation strategies. In particular, this just keeps
+/// allocating memory, and never deletes it until the entire block is dead. This
+/// makes allocation speedy, but must only be used when the trade-off is ok.
+class BumpPtrAllocator {
+ void *TheMemory;
+public:
+ BumpPtrAllocator();
+ ~BumpPtrAllocator();
+
+ void Reset();
+ void *Allocate(unsigned Size, unsigned Alignment);
+
+ template <typename T>
+ void *Allocate() {
+ return reinterpret_cast<T*>(Allocate(sizeof(T),AlignOf<T>::Alignment));
+ }
+
+
+ void Deallocate(void *Ptr) {}
+ void PrintStats() const;
+};
+
+} // end namespace clang
+
+#endif
diff --git a/support/include/llvm/Support/Annotation.h b/support/include/llvm/Support/Annotation.h
new file mode 100644
index 0000000..f9d9f60
--- /dev/null
+++ b/support/include/llvm/Support/Annotation.h
@@ -0,0 +1,216 @@
+//===-- llvm/Support/Annotation.h - Annotation classes ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declarations for two classes: Annotation & Annotable.
+// Using these two simple classes, anything that derives from Annotable can have
+// Annotation subclasses attached to them, ready for easy retrieval.
+//
+// Annotations are designed to be easily attachable to various classes.
+//
+// The AnnotationManager class is essential for using these classes. It is
+// responsible for turning Annotation name strings into tokens [unique id #'s]
+// that may be used to search for and create annotations.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_ANNOTATION_H
+#define LLVM_SUPPORT_ANNOTATION_H
+
+#include <string>
+#include <cassert>
+
+namespace llvm {
+
+class AnnotationID;
+class Annotation;
+class Annotable;
+struct AnnotationManager;
+
+//===----------------------------------------------------------------------===//
+//
+// AnnotationID - This class is a thin wrapper around an unsigned integer that
+// is used to hopefully prevent errors using AnnotationID's. They may be copied
+// freely around and passed byvalue with little or no overhead.
+//
+class AnnotationID {
+ friend struct AnnotationManager;
+ unsigned ID;
+
+ AnnotationID(); // Default ctor is disabled
+ inline AnnotationID(unsigned i) : ID(i) {} // Only creatable from AnnMgr
+public:
+ inline AnnotationID(const AnnotationID &A) : ID(A.ID) {}
+
+ inline bool operator==(const AnnotationID &A) const {
+ return A.ID == ID;
+ }
+ inline bool operator<(const AnnotationID &A) const {
+ return ID < A.ID;
+ }
+};
+
+
+//===----------------------------------------------------------------------===//
+//
+// Annotation Class - This class serves as a base class for any specific
+// annotations that you might need. Simply subclass this to add extra
+// information to the annotations.
+//
+class Annotation {
+ friend class Annotable; // Annotable manipulates Next list
+ AnnotationID ID; // ID number, as obtained from AnnotationManager
+ Annotation *Next; // The next annotation in the linked list
+public:
+ inline Annotation(AnnotationID id) : ID(id), Next(0) {}
+ virtual ~Annotation(); // Designed to be subclassed
+
+ // getID - Return the unique ID# of this annotation
+ inline AnnotationID getID() const { return ID; }
+
+ // getNext - Return the next annotation in the list...
+ inline Annotation *getNext() const { return Next; }
+};
+
+
+//===----------------------------------------------------------------------===//
+//
+// Annotable - This class is used as a base class for all objects that would
+// like to have annotation capability.
+//
+// Annotable objects keep their annotation list sorted as annotations are
+// inserted and deleted. This is used to ensure that annotations with identical
+// ID#'s are stored sequentially.
+//
+class Annotable {
+ mutable Annotation *AnnotationList;
+
+ Annotable(const Annotable &); // Do not implement
+ void operator=(const Annotable &); // Do not implement
+public:
+ Annotable() : AnnotationList(0) {}
+ ~Annotable();
+
+ // getAnnotation - Search the list for annotations of the specified ID. The
+ // pointer returned is either null (if no annotations of the specified ID
+ // exist), or it points to the first element of a potentially list of elements
+ // with identical ID #'s.
+ //
+ Annotation *getAnnotation(AnnotationID ID) const {
+ for (Annotation *A = AnnotationList; A; A = A->getNext())
+ if (A->getID() == ID) return A;
+ return 0;
+ }
+
+ // getOrCreateAnnotation - Search through the annotation list, if there is
+ // no annotation with the specified ID, then use the AnnotationManager to
+ // create one.
+ //
+ inline Annotation *getOrCreateAnnotation(AnnotationID ID) const;
+
+ // addAnnotation - Insert the annotation into the list in a sorted location.
+ //
+ void addAnnotation(Annotation *A) const {
+ assert(A->Next == 0 && "Annotation already in list?!?");
+
+ Annotation **AL = &AnnotationList;
+ while (*AL && (*AL)->ID < A->getID()) // Find where to insert annotation
+ AL = &((*AL)->Next);
+ A->Next = *AL; // Link the annotation in
+ *AL = A;
+ }
+
+ // unlinkAnnotation - Remove the first annotation of the specified ID... and
+ // then return the unlinked annotation. The annotation object is not deleted.
+ //
+ inline Annotation *unlinkAnnotation(AnnotationID ID) const {
+ for (Annotation **A = &AnnotationList; *A; A = &((*A)->Next))
+ if ((*A)->getID() == ID) {
+ Annotation *Ret = *A;
+ *A = Ret->Next;
+ Ret->Next = 0;
+ return Ret;
+ }
+ return 0;
+ }
+
+ // deleteAnnotation - Delete the first annotation of the specified ID in the
+ // list. Unlink unlinkAnnotation, this actually deletes the annotation object
+ //
+ bool deleteAnnotation(AnnotationID ID) const {
+ Annotation *A = unlinkAnnotation(ID);
+ delete A;
+ return A != 0;
+ }
+};
+
+
+//===----------------------------------------------------------------------===//
+//
+// AnnotationManager - This class is primarily responsible for maintaining a
+// one-to-one mapping between string Annotation names and Annotation ID numbers.
+//
+// Compared to the rest of the Annotation system, these mapping methods are
+// relatively slow, so they should be avoided by locally caching Annotation
+// ID #'s. These methods are safe to call at any time, even by static ctors, so
+// they should be used by static ctors most of the time.
+//
+// This class also provides support for annotations that are created on demand
+// by the Annotable::getOrCreateAnnotation method. To get this to work, simply
+// register an annotation handler
+//
+struct AnnotationManager {
+ typedef Annotation *(*Factory)(AnnotationID, const Annotable *, void*);
+
+ //===--------------------------------------------------------------------===//
+ // Basic ID <-> Name map functionality
+
+ static AnnotationID getID(const std::string &Name); // Name -> ID
+ static const std::string &getName(AnnotationID ID); // ID -> Name
+
+ // getID - Name -> ID + registration of a factory function for demand driven
+ // annotation support.
+ static AnnotationID getID(const std::string &Name, Factory Fact,
+ void *Data = 0);
+
+ //===--------------------------------------------------------------------===//
+ // Annotation creation on demand support...
+
+ // registerAnnotationFactory - This method is used to register a callback
+ // function used to create an annotation on demand if it is needed by the
+ // Annotable::getOrCreateAnnotation method.
+ //
+ static void registerAnnotationFactory(AnnotationID ID, Factory Func,
+ void *ExtraData = 0);
+
+ // createAnnotation - Create an annotation of the specified ID for the
+ // specified object, using a register annotation creation function.
+ //
+ static Annotation *createAnnotation(AnnotationID ID, const Annotable *Obj);
+};
+
+
+
+// getOrCreateAnnotation - Search through the annotation list, if there is
+// no annotation with the specified ID, then use the AnnotationManager to
+// create one.
+//
+inline Annotation *Annotable::getOrCreateAnnotation(AnnotationID ID) const {
+ Annotation *A = getAnnotation(ID); // Fast path, check for preexisting ann
+ if (A) return A;
+
+ // No annotation found, ask the annotation manager to create an annotation...
+ A = AnnotationManager::createAnnotation(ID, this);
+ assert(A && "AnnotationManager could not create annotation!");
+ addAnnotation(A);
+ return A;
+}
+
+} // End namespace llvm
+
+#endif
diff --git a/support/include/llvm/Support/CFG.h b/support/include/llvm/Support/CFG.h
new file mode 100644
index 0000000..a2cc22c
--- /dev/null
+++ b/support/include/llvm/Support/CFG.h
@@ -0,0 +1,265 @@
+//===-- llvm/Support/CFG.h - Process LLVM structures as graphs --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines specializations of GraphTraits that allow Function and
+// BasicBlock graphs to be treated as proper graphs for generic algorithms.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_CFG_H
+#define LLVM_SUPPORT_CFG_H
+
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/Function.h"
+#include "llvm/InstrTypes.h"
+#include "llvm/ADT/iterator"
+
+namespace llvm {
+
+//===--------------------------------------------------------------------===//
+// BasicBlock pred_iterator definition
+//===--------------------------------------------------------------------===//
+
+template <class _Ptr, class _USE_iterator> // Predecessor Iterator
+class PredIterator : public forward_iterator<_Ptr, ptrdiff_t> {
+ typedef forward_iterator<_Ptr, ptrdiff_t> super;
+ _USE_iterator It;
+public:
+ typedef PredIterator<_Ptr,_USE_iterator> _Self;
+ typedef typename super::pointer pointer;
+
+ inline void advancePastNonTerminators() {
+ // Loop to ignore non terminator uses (for example PHI nodes)...
+ while (!It.atEnd() && !isa<TerminatorInst>(*It))
+ ++It;
+ }
+
+ inline PredIterator(_Ptr *bb) : It(bb->use_begin()) {
+ advancePastNonTerminators();
+ }
+ inline PredIterator(_Ptr *bb, bool) : It(bb->use_end()) {}
+
+ inline bool operator==(const _Self& x) const { return It == x.It; }
+ inline bool operator!=(const _Self& x) const { return !operator==(x); }
+
+ inline pointer operator*() const {
+ assert(!It.atEnd() && "pred_iterator out of range!");
+ return cast<TerminatorInst>(*It)->getParent();
+ }
+ inline pointer *operator->() const { return &(operator*()); }
+
+ inline _Self& operator++() { // Preincrement
+ assert(!It.atEnd() && "pred_iterator out of range!");
+ ++It; advancePastNonTerminators();
+ return *this;
+ }
+
+ inline _Self operator++(int) { // Postincrement
+ _Self tmp = *this; ++*this; return tmp;
+ }
+};
+
+typedef PredIterator<BasicBlock, Value::use_iterator> pred_iterator;
+typedef PredIterator<const BasicBlock,
+ Value::use_const_iterator> pred_const_iterator;
+
+inline pred_iterator pred_begin(BasicBlock *BB) { return pred_iterator(BB); }
+inline pred_const_iterator pred_begin(const BasicBlock *BB) {
+ return pred_const_iterator(BB);
+}
+inline pred_iterator pred_end(BasicBlock *BB) { return pred_iterator(BB, true);}
+inline pred_const_iterator pred_end(const BasicBlock *BB) {
+ return pred_const_iterator(BB, true);
+}
+
+
+
+//===--------------------------------------------------------------------===//
+// BasicBlock succ_iterator definition
+//===--------------------------------------------------------------------===//
+
+template <class Term_, class BB_> // Successor Iterator
+class SuccIterator : public bidirectional_iterator<BB_, ptrdiff_t> {
+ const Term_ Term;
+ unsigned idx;
+ typedef bidirectional_iterator<BB_, ptrdiff_t> super;
+public:
+ typedef SuccIterator<Term_, BB_> _Self;
+ typedef typename super::pointer pointer;
+ // TODO: This can be random access iterator, need operator+ and stuff tho
+
+ inline SuccIterator(Term_ T) : Term(T), idx(0) { // begin iterator
+ assert(T && "getTerminator returned null!");
+ }
+ inline SuccIterator(Term_ T, bool) // end iterator
+ : Term(T), idx(Term->getNumSuccessors()) {
+ assert(T && "getTerminator returned null!");
+ }
+
+ inline const _Self &operator=(const _Self &I) {
+ assert(Term == I.Term &&"Cannot assign iterators to two different blocks!");
+ idx = I.idx;
+ return *this;
+ }
+
+ /// getSuccessorIndex - This is used to interface between code that wants to
+ /// operate on terminator instructions directly.
+ unsigned getSuccessorIndex() const { return idx; }
+
+ inline bool operator==(const _Self& x) const { return idx == x.idx; }
+ inline bool operator!=(const _Self& x) const { return !operator==(x); }
+
+ inline pointer operator*() const { return Term->getSuccessor(idx); }
+ inline pointer operator->() const { return operator*(); }
+
+ inline _Self& operator++() { ++idx; return *this; } // Preincrement
+ inline _Self operator++(int) { // Postincrement
+ _Self tmp = *this; ++*this; return tmp;
+ }
+
+ inline _Self& operator--() { --idx; return *this; } // Predecrement
+ inline _Self operator--(int) { // Postdecrement
+ _Self tmp = *this; --*this; return tmp;
+ }
+};
+
+typedef SuccIterator<TerminatorInst*, BasicBlock> succ_iterator;
+typedef SuccIterator<const TerminatorInst*,
+ const BasicBlock> succ_const_iterator;
+
+inline succ_iterator succ_begin(BasicBlock *BB) {
+ return succ_iterator(BB->getTerminator());
+}
+inline succ_const_iterator succ_begin(const BasicBlock *BB) {
+ return succ_const_iterator(BB->getTerminator());
+}
+inline succ_iterator succ_end(BasicBlock *BB) {
+ return succ_iterator(BB->getTerminator(), true);
+}
+inline succ_const_iterator succ_end(const BasicBlock *BB) {
+ return succ_const_iterator(BB->getTerminator(), true);
+}
+
+
+
+//===--------------------------------------------------------------------===//
+// GraphTraits specializations for basic block graphs (CFGs)
+//===--------------------------------------------------------------------===//
+
+// Provide specializations of GraphTraits to be able to treat a function as a
+// graph of basic blocks...
+
+template <> struct GraphTraits<BasicBlock*> {
+ typedef BasicBlock NodeType;
+ typedef succ_iterator ChildIteratorType;
+
+ static NodeType *getEntryNode(BasicBlock *BB) { return BB; }
+ static inline ChildIteratorType child_begin(NodeType *N) {
+ return succ_begin(N);
+ }
+ static inline ChildIteratorType child_end(NodeType *N) {
+ return succ_end(N);
+ }
+};
+
+template <> struct GraphTraits<const BasicBlock*> {
+ typedef const BasicBlock NodeType;
+ typedef succ_const_iterator ChildIteratorType;
+
+ static NodeType *getEntryNode(const BasicBlock *BB) { return BB; }
+
+ static inline ChildIteratorType child_begin(NodeType *N) {
+ return succ_begin(N);
+ }
+ static inline ChildIteratorType child_end(NodeType *N) {
+ return succ_end(N);
+ }
+};
+
+// Provide specializations of GraphTraits to be able to treat a function as a
+// graph of basic blocks... and to walk it in inverse order. Inverse order for
+// a function is considered to be when traversing the predecessor edges of a BB
+// instead of the successor edges.
+//
+template <> struct GraphTraits<Inverse<BasicBlock*> > {
+ typedef BasicBlock NodeType;
+ typedef pred_iterator ChildIteratorType;
+ static NodeType *getEntryNode(Inverse<BasicBlock *> G) { return G.Graph; }
+ static inline ChildIteratorType child_begin(NodeType *N) {
+ return pred_begin(N);
+ }
+ static inline ChildIteratorType child_end(NodeType *N) {
+ return pred_end(N);
+ }
+};
+
+template <> struct GraphTraits<Inverse<const BasicBlock*> > {
+ typedef const BasicBlock NodeType;
+ typedef pred_const_iterator ChildIteratorType;
+ static NodeType *getEntryNode(Inverse<const BasicBlock*> G) {
+ return G.Graph;
+ }
+ static inline ChildIteratorType child_begin(NodeType *N) {
+ return pred_begin(N);
+ }
+ static inline ChildIteratorType child_end(NodeType *N) {
+ return pred_end(N);
+ }
+};
+
+
+
+//===--------------------------------------------------------------------===//
+// GraphTraits specializations for function basic block graphs (CFGs)
+//===--------------------------------------------------------------------===//
+
+// Provide specializations of GraphTraits to be able to treat a function as a
+// graph of basic blocks... these are the same as the basic block iterators,
+// except that the root node is implicitly the first node of the function.
+//
+template <> struct GraphTraits<Function*> : public GraphTraits<BasicBlock*> {
+ static NodeType *getEntryNode(Function *F) { return &F->getEntryBlock(); }
+
+ // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
+ 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(); }
+};
+template <> struct GraphTraits<const Function*> :
+ public GraphTraits<const BasicBlock*> {
+ static NodeType *getEntryNode(const Function *F) {return &F->getEntryBlock();}
+
+ // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
+ 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(); }
+};
+
+
+// Provide specializations of GraphTraits to be able to treat a function as a
+// graph of basic blocks... and to walk it in inverse order. Inverse order for
+// a function is considered to be when traversing the predecessor edges of a BB
+// instead of the successor edges.
+//
+template <> struct GraphTraits<Inverse<Function*> > :
+ public GraphTraits<Inverse<BasicBlock*> > {
+ static NodeType *getEntryNode(Inverse<Function*> G) {
+ return &G.Graph->getEntryBlock();
+ }
+};
+template <> struct GraphTraits<Inverse<const Function*> > :
+ public GraphTraits<Inverse<const BasicBlock*> > {
+ static NodeType *getEntryNode(Inverse<const Function *> G) {
+ return &G.Graph->getEntryBlock();
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/support/include/llvm/Support/CallSite.h b/support/include/llvm/Support/CallSite.h
new file mode 100644
index 0000000..5bb60a8
--- /dev/null
+++ b/support/include/llvm/Support/CallSite.h
@@ -0,0 +1,139 @@
+//===-- llvm/Support/CallSite.h - Abstract Call & Invoke instrs -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the CallSite class, which is a handy wrapper for code that
+// wants to treat Call and Invoke instructions in a generic way.
+//
+// NOTE: This class is supposed to have "value semantics". So it should be
+// passed by value, not by reference; it should not be "new"ed or "delete"d. It
+// is efficiently copyable, assignable and constructable, with cost equivalent
+// to copying a pointer (notice that it has only a single data member).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_CALLSITE_H
+#define LLVM_SUPPORT_CALLSITE_H
+
+#include "llvm/Instruction.h"
+#include "llvm/BasicBlock.h"
+#include "llvm/ParameterAttributes.h"
+
+namespace llvm {
+
+class CallInst;
+class InvokeInst;
+class ParamAttrsList;
+
+class CallSite {
+ Instruction *I;
+public:
+ CallSite() : I(0) {}
+ CallSite(CallInst *CI) : I(reinterpret_cast<Instruction*>(CI)) {}
+ CallSite(InvokeInst *II) : I(reinterpret_cast<Instruction*>(II)) {}
+ CallSite(const CallSite &CS) : I(CS.I) {}
+ CallSite &operator=(const CallSite &CS) { I = CS.I; return *this; }
+
+ /// CallSite::get - This static method is sort of like a constructor. It will
+ /// create an appropriate call site for a Call or Invoke instruction, but it
+ /// can also create a null initialized CallSite object for something which is
+ /// NOT a call site.
+ ///
+ static CallSite get(Value *V) {
+ if (Instruction *I = dyn_cast<Instruction>(V)) {
+ if (I->getOpcode() == Instruction::Call)
+ return CallSite(reinterpret_cast<CallInst*>(I));
+ else if (I->getOpcode() == Instruction::Invoke)
+ return CallSite(reinterpret_cast<InvokeInst*>(I));
+ }
+ return CallSite();
+ }
+
+ /// getCallingConv/setCallingConv - get or set the calling convention of the
+ /// call.
+ unsigned getCallingConv() const;
+ void setCallingConv(unsigned CC);
+
+ /// getParamAttrs/setParamAttrs - get or set the parameter attributes of
+ /// the call.
+ const ParamAttrsList *getParamAttrs() const;
+ void setParamAttrs(const ParamAttrsList *PAL);
+
+ /// paramHasAttr - whether the call or the callee has the given attribute.
+ bool paramHasAttr(uint16_t i, ParameterAttributes attr) const;
+
+ /// @brief Determine if the call does not access memory.
+ bool doesNotAccessMemory() const;
+
+ /// @brief Determine if the call does not access or only reads memory.
+ bool onlyReadsMemory() const;
+
+ /// getType - Return the type of the instruction that generated this call site
+ ///
+ const Type *getType() const { return I->getType(); }
+
+ /// getInstruction - Return the instruction this call site corresponds to
+ ///
+ Instruction *getInstruction() const { return I; }
+
+ /// getCaller - Return the caller function for this call site
+ ///
+ Function *getCaller() const { return I->getParent()->getParent(); }
+
+ /// getCalledValue - Return the pointer to function that is being called...
+ ///
+ Value *getCalledValue() const {
+ assert(I && "Not a call or invoke instruction!");
+ return I->getOperand(0);
+ }
+
+ /// getCalledFunction - Return the function being called if this is a direct
+ /// call, otherwise return null (if it's an indirect call).
+ ///
+ Function *getCalledFunction() const {
+ return dyn_cast<Function>(getCalledValue());
+ }
+
+ /// setCalledFunction - Set the callee to the specified value...
+ ///
+ void setCalledFunction(Value *V) {
+ assert(I && "Not a call or invoke instruction!");
+ I->setOperand(0, V);
+ }
+
+ Value *getArgument(unsigned ArgNo) const {
+ assert(arg_begin() + ArgNo < arg_end() && "Argument # out of range!");
+ return *(arg_begin()+ArgNo);
+ }
+
+ /// arg_iterator - The type of iterator to use when looping over actual
+ /// arguments at this call site...
+ typedef User::op_iterator arg_iterator;
+
+ /// arg_begin/arg_end - Return iterators corresponding to the actual argument
+ /// list for a call site.
+ ///
+ arg_iterator arg_begin() const {
+ assert(I && "Not a call or invoke instruction!");
+ if (I->getOpcode() == Instruction::Call)
+ return I->op_begin()+1; // Skip Function
+ else
+ return I->op_begin()+3; // Skip Function, BB, BB
+ }
+ arg_iterator arg_end() const { return I->op_end(); }
+ bool arg_empty() const { return arg_end() == arg_begin(); }
+ unsigned arg_size() const { return unsigned(arg_end() - arg_begin()); }
+
+ bool operator<(const CallSite &CS) const {
+ return getInstruction() < CS.getInstruction();
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/support/include/llvm/Support/Casting.h b/support/include/llvm/Support/Casting.h
new file mode 100644
index 0000000..dc31839
--- /dev/null
+++ b/support/include/llvm/Support/Casting.h
@@ -0,0 +1,303 @@
+//===-- llvm/Support/Casting.h - Allow flexible, checked, casts -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the isa<X>(), cast<X>(), dyn_cast<X>(), cast_or_null<X>(),
+// and dyn_cast_or_null<X>() templates.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_CASTING_H
+#define LLVM_SUPPORT_CASTING_H
+
+#include <cassert>
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+// isa<x> Support Templates
+//===----------------------------------------------------------------------===//
+
+template<typename FromCl> struct isa_impl_cl;
+
+// Define a template that can be specialized by smart pointers to reflect the
+// fact that they are automatically dereferenced, and are not involved with the
+// template selection process... the default implementation is a noop.
+//
+template<typename From> struct simplify_type {
+ typedef From SimpleType; // The real type this represents...
+
+ // An accessor to get the real value...
+ static SimpleType &getSimplifiedValue(From &Val) { return Val; }
+};
+
+template<typename From> struct simplify_type<const From> {
+ typedef const From SimpleType;
+ static SimpleType &getSimplifiedValue(const From &Val) {
+ return simplify_type<From>::getSimplifiedValue(static_cast<From&>(Val));
+ }
+};
+
+
+// isa<X> - Return true if the parameter to the template is an instance of the
+// template type argument. Used like this:
+//
+// if (isa<Type*>(myVal)) { ... }
+//
+template <typename To, typename From>
+inline bool isa_impl(const From &Val) {
+ return To::classof(&Val);
+}
+
+template<typename To, typename From, typename SimpleType>
+struct isa_impl_wrap {
+ // When From != SimplifiedType, we can simplify the type some more by using
+ // the simplify_type template.
+ static bool doit(const From &Val) {
+ return isa_impl_cl<const SimpleType>::template
+ isa<To>(simplify_type<const From>::getSimplifiedValue(Val));
+ }
+};
+
+template<typename To, typename FromTy>
+struct isa_impl_wrap<To, const FromTy, const FromTy> {
+ // When From == SimpleType, we are as simple as we are going to get.
+ static bool doit(const FromTy &Val) {
+ return isa_impl<To,FromTy>(Val);
+ }
+};
+
+// isa_impl_cl - Use class partial specialization to transform types to a single
+// canonical form for isa_impl.
+//
+template<typename FromCl>
+struct isa_impl_cl {
+ template<class ToCl>
+ static bool isa(const FromCl &Val) {
+ return isa_impl_wrap<ToCl,const FromCl,
+ typename simplify_type<const FromCl>::SimpleType>::doit(Val);
+ }
+};
+
+// Specialization used to strip const qualifiers off of the FromCl type...
+template<typename FromCl>
+struct isa_impl_cl<const FromCl> {
+ template<class ToCl>
+ static bool isa(const FromCl &Val) {
+ return isa_impl_cl<FromCl>::template isa<ToCl>(Val);
+ }
+};
+
+// Define pointer traits in terms of base traits...
+template<class FromCl>
+struct isa_impl_cl<FromCl*> {
+ template<class ToCl>
+ static bool isa(FromCl *Val) {
+ return isa_impl_cl<FromCl>::template isa<ToCl>(*Val);
+ }
+};
+
+// Define reference traits in terms of base traits...
+template<class FromCl>
+struct isa_impl_cl<FromCl&> {
+ template<class ToCl>
+ static bool isa(FromCl &Val) {
+ return isa_impl_cl<FromCl>::template isa<ToCl>(&Val);
+ }
+};
+
+template <class X, class Y>
+inline bool isa(const Y &Val) {
+ return isa_impl_cl<Y>::template isa<X>(Val);
+}
+
+//===----------------------------------------------------------------------===//
+// cast<x> Support Templates
+//===----------------------------------------------------------------------===//
+
+template<class To, class From> struct cast_retty;
+
+
+// Calculate what type the 'cast' function should return, based on a requested
+// type of To and a source type of From.
+template<class To, class From> struct cast_retty_impl {
+ typedef To& ret_type; // Normal case, return Ty&
+};
+template<class To, class From> struct cast_retty_impl<To, const From> {
+ typedef const To &ret_type; // Normal case, return Ty&
+};
+
+template<class To, class From> struct cast_retty_impl<To, From*> {
+ typedef To* ret_type; // Pointer arg case, return Ty*
+};
+
+template<class To, class From> struct cast_retty_impl<To, const From*> {
+ typedef const To* ret_type; // Constant pointer arg case, return const Ty*
+};
+
+template<class To, class From> struct cast_retty_impl<To, const From*const> {
+ typedef const To* ret_type; // Constant pointer arg case, return const Ty*
+};
+
+
+template<class To, class From, class SimpleFrom>
+struct cast_retty_wrap {
+ // When the simplified type and the from type are not the same, use the type
+ // simplifier to reduce the type, then reuse cast_retty_impl to get the
+ // resultant type.
+ typedef typename cast_retty<To, SimpleFrom>::ret_type ret_type;
+};
+
+template<class To, class FromTy>
+struct cast_retty_wrap<To, FromTy, FromTy> {
+ // When the simplified type is equal to the from type, use it directly.
+ typedef typename cast_retty_impl<To,FromTy>::ret_type ret_type;
+};
+
+template<class To, class From>
+struct cast_retty {
+ typedef typename cast_retty_wrap<To, From,
+ typename simplify_type<From>::SimpleType>::ret_type ret_type;
+};
+
+// Ensure the non-simple values are converted using the simplify_type template
+// that may be specialized by smart pointers...
+//
+template<class To, class From, class SimpleFrom> struct cast_convert_val {
+ // This is not a simple type, use the template to simplify it...
+ static typename cast_retty<To, From>::ret_type doit(const From &Val) {
+ return cast_convert_val<To, SimpleFrom,
+ typename simplify_type<SimpleFrom>::SimpleType>::doit(
+ simplify_type<From>::getSimplifiedValue(Val));
+ }
+};
+
+template<class To, class FromTy> struct cast_convert_val<To,FromTy,FromTy> {
+ // This _is_ a simple type, just cast it.
+ static typename cast_retty<To, FromTy>::ret_type doit(const FromTy &Val) {
+ return reinterpret_cast<typename cast_retty<To, FromTy>::ret_type>(
+ const_cast<FromTy&>(Val));
+ }
+};
+
+
+
+// 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
+// on failure. But it will correctly return NULL when the input is NULL.
+// Used Like this:
+//
+// cast<Instruction>(myVal)->getParent()
+//
+template <class X, class Y>
+inline typename cast_retty<X, Y>::ret_type cast(const 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);
+}
+
+// cast_or_null<X> - Functionally identical to cast, except that a null value is
+// accepted.
+//
+template <class X, class Y>
+inline typename cast_retty<X, Y*>::ret_type cast_or_null(Y *Val) {
+ if (Val == 0) return 0;
+ assert(isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!");
+ return cast<X>(Val);
+}
+
+
+// dyn_cast<X> - Return the argument parameter cast to the specified type. This
+// casting operator returns null if the argument is of the wrong type, so it can
+// be used to test for a type as well as cast if successful. This should be
+// used in the context of an if statement like this:
+//
+// if (const Instruction *I = dyn_cast<Instruction>(myVal)) { ... }
+//
+
+template <class X, class Y>
+inline typename cast_retty<X, Y>::ret_type dyn_cast(Y Val) {
+ return isa<X>(Val) ? cast<X, Y>(Val) : 0;
+}
+
+// dyn_cast_or_null<X> - Functionally identical to dyn_cast, except that a null
+// value is accepted.
+//
+template <class X, class Y>
+inline typename cast_retty<X, Y>::ret_type dyn_cast_or_null(Y Val) {
+ return (Val && isa<X>(Val)) ? cast<X, Y>(Val) : 0;
+}
+
+
+#ifdef DEBUG_CAST_OPERATORS
+#include "llvm/Support/Debug.h"
+
+struct bar {
+ bar() {}
+private:
+ bar(const bar &);
+};
+struct foo {
+ void ext() const;
+ /* static bool classof(const bar *X) {
+ cerr << "Classof: " << X << "\n";
+ return true;
+ }*/
+};
+
+template <> inline bool isa_impl<foo,bar>(const bar &Val) {
+ cerr << "Classof: " << &Val << "\n";
+ return true;
+}
+
+
+bar *fub();
+void test(bar &B1, const bar *B2) {
+ // test various configurations of const
+ const bar &B3 = B1;
+ const bar *const B4 = B2;
+
+ // test isa
+ if (!isa<foo>(B1)) return;
+ if (!isa<foo>(B2)) return;
+ if (!isa<foo>(B3)) return;
+ if (!isa<foo>(B4)) return;
+
+ // test cast
+ foo &F1 = cast<foo>(B1);
+ const foo *F3 = cast<foo>(B2);
+ const foo *F4 = cast<foo>(B2);
+ const foo &F8 = cast<foo>(B3);
+ const foo *F9 = cast<foo>(B4);
+ foo *F10 = cast<foo>(fub());
+
+ // test cast_or_null
+ const foo *F11 = cast_or_null<foo>(B2);
+ const foo *F12 = cast_or_null<foo>(B2);
+ const foo *F13 = cast_or_null<foo>(B4);
+ const foo *F14 = cast_or_null<foo>(fub()); // Shouldn't print.
+
+ // These lines are errors...
+ //foo *F20 = cast<foo>(B2); // Yields const foo*
+ //foo &F21 = cast<foo>(B3); // Yields const foo&
+ //foo *F22 = cast<foo>(B4); // Yields const foo*
+ //foo &F23 = cast_or_null<foo>(B1);
+ //const foo &F24 = cast_or_null<foo>(B3);
+}
+
+bar *fub() { return 0; }
+void main() {
+ bar B;
+ test(B, &B);
+}
+
+#endif
+
+} // End llvm namespace
+
+#endif
diff --git a/support/include/llvm/Support/CommandLine.h b/support/include/llvm/Support/CommandLine.h
new file mode 100644
index 0000000..005861e
--- /dev/null
+++ b/support/include/llvm/Support/CommandLine.h
@@ -0,0 +1,1331 @@
+//===- llvm/Support/CommandLine.h - Command line handler --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This class implements a command line argument processor that is useful when
+// creating a tool. It provides a simple, minimalistic interface that is easily
+// extensible and supports nonlocal (library) command line options.
+//
+// Note that rather than trying to figure out what this code does, you should
+// read the library documentation located in docs/CommandLine.html or looks at
+// the many example usages in tools/*/*.cpp
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_COMMANDLINE_H
+#define LLVM_SUPPORT_COMMANDLINE_H
+
+#include "llvm/Support/type_traits.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/ADT/SmallVector.h"
+#include <string>
+#include <vector>
+#include <utility>
+#include <cstdarg>
+#include <cassert>
+
+namespace llvm {
+
+/// cl Namespace - This namespace contains all of the command line option
+/// processing machinery. It is intentionally a short name to make qualified
+/// usage concise.
+namespace cl {
+
+//===----------------------------------------------------------------------===//
+// ParseCommandLineOptions - Command line option processing entry point.
+//
+void ParseCommandLineOptions(int argc, char **argv,
+ const char *Overview = 0);
+
+//===----------------------------------------------------------------------===//
+// ParseEnvironmentOptions - Environment variable option processing alternate
+// entry point.
+//
+void ParseEnvironmentOptions(const char *progName, const char *envvar,
+ const char *Overview = 0);
+
+///===---------------------------------------------------------------------===//
+/// SetVersionPrinter - Override the default (LLVM specific) version printer
+/// used to print out the version when --version is given
+/// on the command line. This allows other systems using the
+/// CommandLine utilities to print their own version string.
+void SetVersionPrinter(void (*func)());
+
+
+// MarkOptionsChanged - Internal helper function.
+void MarkOptionsChanged();
+
+//===----------------------------------------------------------------------===//
+// Flags permitted to be passed to command line arguments
+//
+
+enum NumOccurrences { // Flags for the number of occurrences allowed
+ Optional = 0x01, // Zero or One occurrence
+ ZeroOrMore = 0x02, // Zero or more occurrences allowed
+ Required = 0x03, // One occurrence required
+ OneOrMore = 0x04, // One or more occurrences required
+
+ // ConsumeAfter - Indicates that this option is fed anything that follows the
+ // last positional argument required by the application (it is an error if
+ // there are zero positional arguments, and a ConsumeAfter option is used).
+ // Thus, for example, all arguments to LLI are processed until a filename is
+ // found. Once a filename is found, all of the succeeding arguments are
+ // passed, unprocessed, to the ConsumeAfter option.
+ //
+ ConsumeAfter = 0x05,
+
+ OccurrencesMask = 0x07
+};
+
+enum ValueExpected { // Is a value required for the option?
+ ValueOptional = 0x08, // The value can appear... or not
+ ValueRequired = 0x10, // The value is required to appear!
+ ValueDisallowed = 0x18, // A value may not be specified (for flags)
+ ValueMask = 0x18
+};
+
+enum OptionHidden { // Control whether -help shows this option
+ NotHidden = 0x20, // Option included in --help & --help-hidden
+ Hidden = 0x40, // -help doesn't, but --help-hidden does
+ ReallyHidden = 0x60, // Neither --help nor --help-hidden show this arg
+ HiddenMask = 0x60
+};
+
+// Formatting flags - This controls special features that the option might have
+// that cause it to be parsed differently...
+//
+// Prefix - This option allows arguments that are otherwise unrecognized to be
+// matched by options that are a prefix of the actual value. This is useful for
+// cases like a linker, where options are typically of the form '-lfoo' or
+// '-L../../include' where -l or -L are the actual flags. When prefix is
+// enabled, and used, the value for the flag comes from the suffix of the
+// argument.
+//
+// Grouping - With this option enabled, multiple letter options are allowed to
+// bunch together with only a single hyphen for the whole group. This allows
+// emulation of the behavior that ls uses for example: ls -la === ls -l -a
+//
+
+enum FormattingFlags {
+ NormalFormatting = 0x000, // Nothing special
+ Positional = 0x080, // Is a positional argument, no '-' required
+ Prefix = 0x100, // Can this option directly prefix its value?
+ Grouping = 0x180, // Can this option group with other options?
+ FormattingMask = 0x180 // Union of the above flags.
+};
+
+enum MiscFlags { // Miscellaneous flags to adjust argument
+ CommaSeparated = 0x200, // Should this cl::list split between commas?
+ PositionalEatsArgs = 0x400, // Should this positional cl::list eat -args?
+ MiscMask = 0x600 // Union of the above flags.
+};
+
+
+
+//===----------------------------------------------------------------------===//
+// Option Base class
+//
+class alias;
+class Option {
+ friend class alias;
+
+ // handleOccurrences - Overriden by subclasses to handle the value passed into
+ // an argument. Should return true if there was an error processing the
+ // argument and the program should exit.
+ //
+ virtual bool handleOccurrence(unsigned pos, const char *ArgName,
+ const std::string &Arg) = 0;
+
+ virtual enum ValueExpected getValueExpectedFlagDefault() const {
+ return ValueOptional;
+ }
+
+ // Out of line virtual function to provide home for the class.
+ virtual void anchor();
+
+ int NumOccurrences; // The number of times specified
+ int Flags; // Flags for the argument
+ unsigned Position; // Position of last occurrence of the option
+ Option *NextRegistered; // Singly linked list of registered options.
+public:
+ const char *ArgStr; // The argument string itself (ex: "help", "o")
+ const char *HelpStr; // The descriptive text message for --help
+ const char *ValueStr; // String describing what the value of this option is
+
+ inline enum NumOccurrences getNumOccurrencesFlag() const {
+ return static_cast<enum NumOccurrences>(Flags & OccurrencesMask);
+ }
+ inline enum ValueExpected getValueExpectedFlag() const {
+ int VE = Flags & ValueMask;
+ return VE ? static_cast<enum ValueExpected>(VE)
+ : getValueExpectedFlagDefault();
+ }
+ inline enum OptionHidden getOptionHiddenFlag() const {
+ return static_cast<enum OptionHidden>(Flags & HiddenMask);
+ }
+ inline enum FormattingFlags getFormattingFlag() const {
+ return static_cast<enum FormattingFlags>(Flags & FormattingMask);
+ }
+ inline unsigned getMiscFlags() const {
+ return Flags & MiscMask;
+ }
+ inline unsigned getPosition() const { return Position; }
+
+ // hasArgStr - Return true if the argstr != ""
+ bool hasArgStr() const { return ArgStr[0] != 0; }
+
+ //-------------------------------------------------------------------------===
+ // Accessor functions set by OptionModifiers
+ //
+ void setArgStr(const char *S) { ArgStr = S; }
+ void setDescription(const char *S) { HelpStr = S; }
+ void setValueStr(const char *S) { ValueStr = S; }
+
+ void setFlag(unsigned Flag, unsigned FlagMask) {
+ Flags &= ~FlagMask;
+ Flags |= Flag;
+ }
+
+ void setNumOccurrencesFlag(enum NumOccurrences Val) {
+ setFlag(Val, OccurrencesMask);
+ }
+ void setValueExpectedFlag(enum ValueExpected Val) { setFlag(Val, ValueMask); }
+ void setHiddenFlag(enum OptionHidden Val) { setFlag(Val, HiddenMask); }
+ void setFormattingFlag(enum FormattingFlags V) { setFlag(V, FormattingMask); }
+ void setMiscFlag(enum MiscFlags M) { setFlag(M, M); }
+ void setPosition(unsigned pos) { Position = pos; }
+protected:
+ explicit Option(unsigned DefaultFlags)
+ : NumOccurrences(0), Flags(DefaultFlags | NormalFormatting), Position(0),
+ NextRegistered(0), ArgStr(""), HelpStr(""), ValueStr("") {
+ assert(getNumOccurrencesFlag() != 0 &&
+ getOptionHiddenFlag() != 0 && "Not all default flags specified!");
+ }
+
+public:
+ // addArgument - Register this argument with the commandline system.
+ //
+ void addArgument();
+
+ Option *getNextRegisteredOption() const { return NextRegistered; }
+
+ // Return the width of the option tag for printing...
+ virtual unsigned getOptionWidth() const = 0;
+
+ // printOptionInfo - Print out information about this option. The
+ // to-be-maintained width is specified.
+ //
+ virtual void printOptionInfo(unsigned GlobalWidth) const = 0;
+
+ virtual void getExtraOptionNames(std::vector<const char*> &OptionNames) {}
+
+ // addOccurrence - Wrapper around handleOccurrence that enforces Flags
+ //
+ bool addOccurrence(unsigned pos, const char *ArgName,
+ const std::string &Value);
+
+ // Prints option name followed by message. Always returns true.
+ bool error(std::string Message, const char *ArgName = 0);
+
+public:
+ inline int getNumOccurrences() const { return NumOccurrences; }
+ virtual ~Option() {}
+};
+
+
+//===----------------------------------------------------------------------===//
+// Command line option modifiers that can be used to modify the behavior of
+// command line option parsers...
+//
+
+// desc - Modifier to set the description shown in the --help output...
+struct desc {
+ const char *Desc;
+ desc(const char *Str) : Desc(Str) {}
+ void apply(Option &O) const { O.setDescription(Desc); }
+};
+
+// value_desc - Modifier to set the value description shown in the --help
+// output...
+struct value_desc {
+ const char *Desc;
+ value_desc(const char *Str) : Desc(Str) {}
+ void apply(Option &O) const { O.setValueStr(Desc); }
+};
+
+// init - Specify a default (initial) value for the command line argument, if
+// the default constructor for the argument type does not give you what you
+// want. This is only valid on "opt" arguments, not on "list" arguments.
+//
+template<class Ty>
+struct initializer {
+ const Ty &Init;
+ initializer(const Ty &Val) : Init(Val) {}
+
+ template<class Opt>
+ void apply(Opt &O) const { O.setInitialValue(Init); }
+};
+
+template<class Ty>
+initializer<Ty> init(const Ty &Val) {
+ return initializer<Ty>(Val);
+}
+
+
+// location - Allow the user to specify which external variable they want to
+// store the results of the command line argument processing into, if they don't
+// want to store it in the option itself.
+//
+template<class Ty>
+struct LocationClass {
+ Ty &Loc;
+ LocationClass(Ty &L) : Loc(L) {}
+
+ template<class Opt>
+ void apply(Opt &O) const { O.setLocation(O, Loc); }
+};
+
+template<class Ty>
+LocationClass<Ty> location(Ty &L) { return LocationClass<Ty>(L); }
+
+
+//===----------------------------------------------------------------------===//
+// Enum valued command line option
+//
+#define clEnumVal(ENUMVAL, DESC) #ENUMVAL, int(ENUMVAL), DESC
+#define clEnumValN(ENUMVAL, FLAGNAME, DESC) FLAGNAME, int(ENUMVAL), DESC
+#define clEnumValEnd (reinterpret_cast<void*>(0))
+
+// values - For custom data types, allow specifying a group of values together
+// as the values that go into the mapping that the option handler uses. Note
+// that the values list must always have a 0 at the end of the list to indicate
+// that the list has ended.
+//
+template<class DataType>
+class ValuesClass {
+ // Use a vector instead of a map, because the lists should be short,
+ // the overhead is less, and most importantly, it keeps them in the order
+ // inserted so we can print our option out nicely.
+ SmallVector<std::pair<const char *, std::pair<int, const char *> >,4> Values;
+ void processValues(va_list Vals);
+public:
+ ValuesClass(const char *EnumName, DataType Val, const char *Desc,
+ va_list ValueArgs) {
+ // Insert the first value, which is required.
+ Values.push_back(std::make_pair(EnumName, std::make_pair(Val, Desc)));
+
+ // Process the varargs portion of the values...
+ while (const char *EnumName = va_arg(ValueArgs, const char *)) {
+ DataType EnumVal = static_cast<DataType>(va_arg(ValueArgs, int));
+ const char *EnumDesc = va_arg(ValueArgs, const char *);
+ Values.push_back(std::make_pair(EnumName, // Add value to value map
+ std::make_pair(EnumVal, EnumDesc)));
+ }
+ }
+
+ template<class Opt>
+ void apply(Opt &O) const {
+ for (unsigned i = 0, e = Values.size(); i != e; ++i)
+ O.getParser().addLiteralOption(Values[i].first, Values[i].second.first,
+ Values[i].second.second);
+ }
+};
+
+template<class DataType>
+ValuesClass<DataType> END_WITH_NULL values(const char *Arg, DataType Val,
+ const char *Desc, ...) {
+ va_list ValueArgs;
+ va_start(ValueArgs, Desc);
+ ValuesClass<DataType> Vals(Arg, Val, Desc, ValueArgs);
+ va_end(ValueArgs);
+ return Vals;
+}
+
+
+//===----------------------------------------------------------------------===//
+// parser class - Parameterizable parser for different data types. By default,
+// known data types (string, int, bool) have specialized parsers, that do what
+// you would expect. The default parser, used for data types that are not
+// built-in, uses a mapping table to map specific options to values, which is
+// used, among other things, to handle enum types.
+
+//--------------------------------------------------
+// generic_parser_base - This class holds all the non-generic code that we do
+// not need replicated for every instance of the generic parser. This also
+// allows us to put stuff into CommandLine.cpp
+//
+struct generic_parser_base {
+ virtual ~generic_parser_base() {} // Base class should have virtual-dtor
+
+ // getNumOptions - Virtual function implemented by generic subclass to
+ // indicate how many entries are in Values.
+ //
+ virtual unsigned getNumOptions() const = 0;
+
+ // getOption - Return option name N.
+ virtual const char *getOption(unsigned N) const = 0;
+
+ // getDescription - Return description N
+ virtual const char *getDescription(unsigned N) const = 0;
+
+ // Return the width of the option tag for printing...
+ virtual unsigned getOptionWidth(const Option &O) const;
+
+ // printOptionInfo - Print out information about this option. The
+ // to-be-maintained width is specified.
+ //
+ virtual void printOptionInfo(const Option &O, unsigned GlobalWidth) const;
+
+ void initialize(Option &O) {
+ // All of the modifiers for the option have been processed by now, so the
+ // argstr field should be stable, copy it down now.
+ //
+ hasArgStr = O.hasArgStr();
+ }
+
+ void getExtraOptionNames(std::vector<const char*> &OptionNames) {
+ // If there has been no argstr specified, that means that we need to add an
+ // argument for every possible option. This ensures that our options are
+ // vectored to us.
+ if (!hasArgStr)
+ for (unsigned i = 0, e = getNumOptions(); i != e; ++i)
+ OptionNames.push_back(getOption(i));
+ }
+
+
+ enum ValueExpected getValueExpectedFlagDefault() const {
+ // If there is an ArgStr specified, then we are of the form:
+ //
+ // -opt=O2 or -opt O2 or -optO2
+ //
+ // In which case, the value is required. Otherwise if an arg str has not
+ // been specified, we are of the form:
+ //
+ // -O2 or O2 or -la (where -l and -a are separate options)
+ //
+ // If this is the case, we cannot allow a value.
+ //
+ if (hasArgStr)
+ return ValueRequired;
+ else
+ return ValueDisallowed;
+ }
+
+ // findOption - Return the option number corresponding to the specified
+ // argument string. If the option is not found, getNumOptions() is returned.
+ //
+ unsigned findOption(const char *Name);
+
+protected:
+ bool hasArgStr;
+};
+
+// Default parser implementation - This implementation depends on having a
+// mapping of recognized options to values of some sort. In addition to this,
+// each entry in the mapping also tracks a help message that is printed with the
+// command line option for --help. Because this is a simple mapping parser, the
+// data type can be any unsupported type.
+//
+template <class DataType>
+class parser : public generic_parser_base {
+protected:
+ SmallVector<std::pair<const char *,
+ std::pair<DataType, const char *> >, 8> Values;
+public:
+ typedef DataType parser_data_type;
+
+ // Implement virtual functions needed by generic_parser_base
+ unsigned getNumOptions() const { return unsigned(Values.size()); }
+ const char *getOption(unsigned N) const { return Values[N].first; }
+ const char *getDescription(unsigned N) const {
+ return Values[N].second.second;
+ }
+
+ // parse - Return true on error.
+ bool parse(Option &O, const char *ArgName, const std::string &Arg,
+ DataType &V) {
+ std::string ArgVal;
+ if (hasArgStr)
+ ArgVal = Arg;
+ else
+ ArgVal = ArgName;
+
+ for (unsigned i = 0, e = Values.size(); i != e; ++i)
+ if (ArgVal == Values[i].first) {
+ V = Values[i].second.first;
+ return false;
+ }
+
+ return O.error(": Cannot find option named '" + ArgVal + "'!");
+ }
+
+ /// addLiteralOption - Add an entry to the mapping table.
+ ///
+ template <class DT>
+ void addLiteralOption(const char *Name, const DT &V, const char *HelpStr) {
+ assert(findOption(Name) == Values.size() && "Option already exists!");
+ Values.push_back(std::make_pair(Name,
+ std::make_pair(static_cast<DataType>(V),HelpStr)));
+ MarkOptionsChanged();
+ }
+
+ /// removeLiteralOption - Remove the specified option.
+ ///
+ void removeLiteralOption(const char *Name) {
+ unsigned N = findOption(Name);
+ assert(N != Values.size() && "Option not found!");
+ Values.erase(Values.begin()+N);
+ }
+};
+
+//--------------------------------------------------
+// basic_parser - Super class of parsers to provide boilerplate code
+//
+struct basic_parser_impl { // non-template implementation of basic_parser<t>
+ virtual ~basic_parser_impl() {}
+
+ enum ValueExpected getValueExpectedFlagDefault() const {
+ return ValueRequired;
+ }
+
+ void getExtraOptionNames(std::vector<const char*> &OptionNames) {}
+
+ void initialize(Option &O) {}
+
+ // Return the width of the option tag for printing...
+ unsigned getOptionWidth(const Option &O) const;
+
+ // printOptionInfo - Print out information about this option. The
+ // to-be-maintained width is specified.
+ //
+ void printOptionInfo(const Option &O, unsigned GlobalWidth) const;
+
+ // getValueName - Overload in subclass to provide a better default value.
+ virtual const char *getValueName() const { return "value"; }
+
+ // An out-of-line virtual method to provide a 'home' for this class.
+ virtual void anchor();
+};
+
+// basic_parser - The real basic parser is just a template wrapper that provides
+// a typedef for the provided data type.
+//
+template<class DataType>
+struct basic_parser : public basic_parser_impl {
+ typedef DataType parser_data_type;
+};
+
+//--------------------------------------------------
+// parser<bool>
+//
+template<>
+class parser<bool> : public basic_parser<bool> {
+public:
+ // parse - Return true on error.
+ bool parse(Option &O, const char *ArgName, const std::string &Arg, bool &Val);
+
+ enum ValueExpected getValueExpectedFlagDefault() const {
+ return ValueOptional;
+ }
+
+ // getValueName - Do not print =<value> at all.
+ virtual const char *getValueName() const { return 0; }
+
+ // An out-of-line virtual method to provide a 'home' for this class.
+ virtual void anchor();
+};
+
+EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<bool>);
+
+//--------------------------------------------------
+// parser<boolOrDefault>
+enum boolOrDefault { BOU_UNSET, BOU_TRUE, BOU_FALSE };
+template<>
+class parser<boolOrDefault> : public basic_parser<boolOrDefault> {
+public:
+ // parse - Return true on error.
+ bool parse(Option &O, const char *ArgName, const std::string &Arg,
+ boolOrDefault &Val);
+
+ enum ValueExpected getValueExpectedFlagDefault() const {
+ return ValueOptional;
+ }
+
+ // getValueName - Do not print =<value> at all.
+ virtual const char *getValueName() const { return 0; }
+
+ // An out-of-line virtual method to provide a 'home' for this class.
+ virtual void anchor();
+};
+
+EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<boolOrDefault>);
+
+//--------------------------------------------------
+// parser<int>
+//
+template<>
+class parser<int> : public basic_parser<int> {
+public:
+ // parse - Return true on error.
+ bool parse(Option &O, const char *ArgName, const std::string &Arg, int &Val);
+
+ // getValueName - Overload in subclass to provide a better default value.
+ virtual const char *getValueName() const { return "int"; }
+
+ // An out-of-line virtual method to provide a 'home' for this class.
+ virtual void anchor();
+};
+
+EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<int>);
+
+
+//--------------------------------------------------
+// parser<unsigned>
+//
+template<>
+class parser<unsigned> : public basic_parser<unsigned> {
+public:
+ // parse - Return true on error.
+ bool parse(Option &O, const char *AN, const std::string &Arg, unsigned &Val);
+
+ // getValueName - Overload in subclass to provide a better default value.
+ virtual const char *getValueName() const { return "uint"; }
+
+ // An out-of-line virtual method to provide a 'home' for this class.
+ virtual void anchor();
+};
+
+EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<unsigned>);
+
+//--------------------------------------------------
+// parser<double>
+//
+template<>
+class parser<double> : public basic_parser<double> {
+public:
+ // parse - Return true on error.
+ bool parse(Option &O, const char *AN, const std::string &Arg, double &Val);
+
+ // getValueName - Overload in subclass to provide a better default value.
+ virtual const char *getValueName() const { return "number"; }
+
+ // An out-of-line virtual method to provide a 'home' for this class.
+ virtual void anchor();
+};
+
+EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<double>);
+
+//--------------------------------------------------
+// parser<float>
+//
+template<>
+class parser<float> : public basic_parser<float> {
+public:
+ // parse - Return true on error.
+ bool parse(Option &O, const char *AN, const std::string &Arg, float &Val);
+
+ // getValueName - Overload in subclass to provide a better default value.
+ virtual const char *getValueName() const { return "number"; }
+
+ // An out-of-line virtual method to provide a 'home' for this class.
+ virtual void anchor();
+};
+
+EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<float>);
+
+//--------------------------------------------------
+// parser<std::string>
+//
+template<>
+class parser<std::string> : public basic_parser<std::string> {
+public:
+ // parse - Return true on error.
+ bool parse(Option &O, const char *AN, const std::string &Arg,
+ std::string &Value) {
+ Value = Arg;
+ return false;
+ }
+
+ // getValueName - Overload in subclass to provide a better default value.
+ virtual const char *getValueName() const { return "string"; }
+
+ // An out-of-line virtual method to provide a 'home' for this class.
+ virtual void anchor();
+};
+
+EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<std::string>);
+
+//===----------------------------------------------------------------------===//
+// applicator class - This class is used because we must use partial
+// specialization to handle literal string arguments specially (const char* does
+// not correctly respond to the apply method). Because the syntax to use this
+// is a pain, we have the 'apply' method below to handle the nastiness...
+//
+template<class Mod> struct applicator {
+ template<class Opt>
+ static void opt(const Mod &M, Opt &O) { M.apply(O); }
+};
+
+// Handle const char* as a special case...
+template<unsigned n> struct applicator<char[n]> {
+ template<class Opt>
+ static void opt(const char *Str, Opt &O) { O.setArgStr(Str); }
+};
+template<unsigned n> struct applicator<const char[n]> {
+ template<class Opt>
+ static void opt(const char *Str, Opt &O) { O.setArgStr(Str); }
+};
+template<> struct applicator<const char*> {
+ template<class Opt>
+ static void opt(const char *Str, Opt &O) { O.setArgStr(Str); }
+};
+
+template<> struct applicator<NumOccurrences> {
+ static void opt(NumOccurrences NO, Option &O) { O.setNumOccurrencesFlag(NO); }
+};
+template<> struct applicator<ValueExpected> {
+ static void opt(ValueExpected VE, Option &O) { O.setValueExpectedFlag(VE); }
+};
+template<> struct applicator<OptionHidden> {
+ static void opt(OptionHidden OH, Option &O) { O.setHiddenFlag(OH); }
+};
+template<> struct applicator<FormattingFlags> {
+ static void opt(FormattingFlags FF, Option &O) { O.setFormattingFlag(FF); }
+};
+template<> struct applicator<MiscFlags> {
+ static void opt(MiscFlags MF, Option &O) { O.setMiscFlag(MF); }
+};
+
+// apply method - Apply a modifier to an option in a type safe way.
+template<class Mod, class Opt>
+void apply(const Mod &M, Opt *O) {
+ applicator<Mod>::opt(M, *O);
+}
+
+
+//===----------------------------------------------------------------------===//
+// opt_storage class
+
+// Default storage class definition: external storage. This implementation
+// assumes the user will specify a variable to store the data into with the
+// cl::location(x) modifier.
+//
+template<class DataType, bool ExternalStorage, bool isClass>
+class opt_storage {
+ DataType *Location; // Where to store the object...
+
+ void check() {
+ assert(Location != 0 && "cl::location(...) not specified for a command "
+ "line option with external storage, "
+ "or cl::init specified before cl::location()!!");
+ }
+public:
+ opt_storage() : Location(0) {}
+
+ bool setLocation(Option &O, DataType &L) {
+ if (Location)
+ return O.error(": cl::location(x) specified more than once!");
+ Location = &L;
+ return false;
+ }
+
+ template<class T>
+ void setValue(const T &V) {
+ check();
+ *Location = V;
+ }
+
+ DataType &getValue() { check(); return *Location; }
+ const DataType &getValue() const { check(); return *Location; }
+};
+
+
+// Define how to hold a class type object, such as a string. Since we can
+// inherit from a class, we do so. This makes us exactly compatible with the
+// object in all cases that it is used.
+//
+template<class DataType>
+class opt_storage<DataType,false,true> : public DataType {
+public:
+ template<class T>
+ void setValue(const T &V) { DataType::operator=(V); }
+
+ DataType &getValue() { return *this; }
+ const DataType &getValue() const { return *this; }
+};
+
+// Define a partial specialization to handle things we cannot inherit from. In
+// this case, we store an instance through containment, and overload operators
+// to get at the value.
+//
+template<class DataType>
+class opt_storage<DataType, false, false> {
+public:
+ DataType Value;
+
+ // Make sure we initialize the value with the default constructor for the
+ // type.
+ opt_storage() : Value(DataType()) {}
+
+ template<class T>
+ void setValue(const T &V) { Value = V; }
+ DataType &getValue() { return Value; }
+ DataType getValue() const { return Value; }
+
+ // If the datatype is a pointer, support -> on it.
+ DataType operator->() const { return Value; }
+};
+
+
+//===----------------------------------------------------------------------===//
+// opt - A scalar command line option.
+//
+template <class DataType, bool ExternalStorage = false,
+ class ParserClass = parser<DataType> >
+class opt : public Option,
+ public opt_storage<DataType, ExternalStorage,
+ is_class<DataType>::value> {
+ ParserClass Parser;
+
+ virtual bool handleOccurrence(unsigned pos, const char *ArgName,
+ const std::string &Arg) {
+ typename ParserClass::parser_data_type Val =
+ typename ParserClass::parser_data_type();
+ if (Parser.parse(*this, ArgName, Arg, Val))
+ return true; // Parse error!
+ setValue(Val);
+ setPosition(pos);
+ return false;
+ }
+
+ virtual enum ValueExpected getValueExpectedFlagDefault() const {
+ return Parser.getValueExpectedFlagDefault();
+ }
+ virtual void getExtraOptionNames(std::vector<const char*> &OptionNames) {
+ return Parser.getExtraOptionNames(OptionNames);
+ }
+
+ // Forward printing stuff to the parser...
+ virtual unsigned getOptionWidth() const {return Parser.getOptionWidth(*this);}
+ virtual void printOptionInfo(unsigned GlobalWidth) const {
+ Parser.printOptionInfo(*this, GlobalWidth);
+ }
+
+ void done() {
+ addArgument();
+ Parser.initialize(*this);
+ }
+public:
+ // setInitialValue - Used by the cl::init modifier...
+ void setInitialValue(const DataType &V) { this->setValue(V); }
+
+ ParserClass &getParser() { return Parser; }
+
+ operator DataType() const { return this->getValue(); }
+
+ template<class T>
+ DataType &operator=(const T &Val) {
+ this->setValue(Val);
+ return this->getValue();
+ }
+
+ // One option...
+ template<class M0t>
+ explicit opt(const M0t &M0) : Option(Optional | NotHidden) {
+ apply(M0, this);
+ done();
+ }
+
+ // Two options...
+ template<class M0t, class M1t>
+ opt(const M0t &M0, const M1t &M1) : Option(Optional | NotHidden) {
+ apply(M0, this); apply(M1, this);
+ done();
+ }
+
+ // Three options...
+ template<class M0t, class M1t, class M2t>
+ opt(const M0t &M0, const M1t &M1,
+ const M2t &M2) : Option(Optional | NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this);
+ done();
+ }
+ // Four options...
+ template<class M0t, class M1t, class M2t, class M3t>
+ opt(const M0t &M0, const M1t &M1, const M2t &M2,
+ const M3t &M3) : Option(Optional | NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ done();
+ }
+ // Five options...
+ template<class M0t, class M1t, class M2t, class M3t, class M4t>
+ opt(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
+ const M4t &M4) : Option(Optional | NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ apply(M4, this);
+ done();
+ }
+ // Six options...
+ template<class M0t, class M1t, class M2t, class M3t,
+ class M4t, class M5t>
+ opt(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
+ const M4t &M4, const M5t &M5) : Option(Optional | NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ apply(M4, this); apply(M5, this);
+ done();
+ }
+ // Seven options...
+ template<class M0t, class M1t, class M2t, class M3t,
+ class M4t, class M5t, class M6t>
+ opt(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
+ const M4t &M4, const M5t &M5,
+ const M6t &M6) : Option(Optional | NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ apply(M4, this); apply(M5, this); apply(M6, this);
+ done();
+ }
+ // Eight options...
+ template<class M0t, class M1t, class M2t, class M3t,
+ class M4t, class M5t, class M6t, class M7t>
+ opt(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
+ const M4t &M4, const M5t &M5, const M6t &M6,
+ const M7t &M7) : Option(Optional | NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ apply(M4, this); apply(M5, this); apply(M6, this); apply(M7, this);
+ done();
+ }
+};
+
+EXTERN_TEMPLATE_INSTANTIATION(class opt<unsigned>);
+EXTERN_TEMPLATE_INSTANTIATION(class opt<int>);
+EXTERN_TEMPLATE_INSTANTIATION(class opt<std::string>);
+EXTERN_TEMPLATE_INSTANTIATION(class opt<bool>);
+
+//===----------------------------------------------------------------------===//
+// list_storage class
+
+// Default storage class definition: external storage. This implementation
+// assumes the user will specify a variable to store the data into with the
+// cl::location(x) modifier.
+//
+template<class DataType, class StorageClass>
+class list_storage {
+ StorageClass *Location; // Where to store the object...
+
+public:
+ list_storage() : Location(0) {}
+
+ bool setLocation(Option &O, StorageClass &L) {
+ if (Location)
+ return O.error(": cl::location(x) specified more than once!");
+ Location = &L;
+ return false;
+ }
+
+ template<class T>
+ void addValue(const T &V) {
+ assert(Location != 0 && "cl::location(...) not specified for a command "
+ "line option with external storage!");
+ Location->push_back(V);
+ }
+};
+
+
+// Define how to hold a class type object, such as a string. Since we can
+// inherit from a class, we do so. This makes us exactly compatible with the
+// object in all cases that it is used.
+//
+template<class DataType>
+class list_storage<DataType, bool> : public std::vector<DataType> {
+public:
+ template<class T>
+ void addValue(const T &V) { push_back(V); }
+};
+
+
+//===----------------------------------------------------------------------===//
+// list - A list of command line options.
+//
+template <class DataType, class Storage = bool,
+ class ParserClass = parser<DataType> >
+class list : public Option, public list_storage<DataType, Storage> {
+ std::vector<unsigned> Positions;
+ ParserClass Parser;
+
+ virtual enum ValueExpected getValueExpectedFlagDefault() const {
+ return Parser.getValueExpectedFlagDefault();
+ }
+ virtual void getExtraOptionNames(std::vector<const char*> &OptionNames) {
+ return Parser.getExtraOptionNames(OptionNames);
+ }
+
+ virtual bool handleOccurrence(unsigned pos, const char *ArgName,
+ const std::string &Arg) {
+ typename ParserClass::parser_data_type Val =
+ typename ParserClass::parser_data_type();
+ if (Parser.parse(*this, ArgName, Arg, Val))
+ return true; // Parse Error!
+ addValue(Val);
+ setPosition(pos);
+ Positions.push_back(pos);
+ return false;
+ }
+
+ // Forward printing stuff to the parser...
+ virtual unsigned getOptionWidth() const {return Parser.getOptionWidth(*this);}
+ virtual void printOptionInfo(unsigned GlobalWidth) const {
+ Parser.printOptionInfo(*this, GlobalWidth);
+ }
+
+ void done() {
+ addArgument();
+ Parser.initialize(*this);
+ }
+public:
+ ParserClass &getParser() { return Parser; }
+
+ unsigned getPosition(unsigned optnum) const {
+ assert(optnum < this->size() && "Invalid option index");
+ return Positions[optnum];
+ }
+
+ // One option...
+ template<class M0t>
+ explicit list(const M0t &M0) : Option(ZeroOrMore | NotHidden) {
+ apply(M0, this);
+ done();
+ }
+ // Two options...
+ template<class M0t, class M1t>
+ list(const M0t &M0, const M1t &M1) : Option(ZeroOrMore | NotHidden) {
+ apply(M0, this); apply(M1, this);
+ done();
+ }
+ // Three options...
+ template<class M0t, class M1t, class M2t>
+ list(const M0t &M0, const M1t &M1, const M2t &M2)
+ : Option(ZeroOrMore | NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this);
+ done();
+ }
+ // Four options...
+ template<class M0t, class M1t, class M2t, class M3t>
+ list(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3)
+ : Option(ZeroOrMore | NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ done();
+ }
+ // Five options...
+ template<class M0t, class M1t, class M2t, class M3t, class M4t>
+ list(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
+ const M4t &M4) : Option(ZeroOrMore | NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ apply(M4, this);
+ done();
+ }
+ // Six options...
+ template<class M0t, class M1t, class M2t, class M3t,
+ class M4t, class M5t>
+ list(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
+ const M4t &M4, const M5t &M5) : Option(ZeroOrMore | NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ apply(M4, this); apply(M5, this);
+ done();
+ }
+ // Seven options...
+ template<class M0t, class M1t, class M2t, class M3t,
+ class M4t, class M5t, class M6t>
+ list(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
+ const M4t &M4, const M5t &M5, const M6t &M6)
+ : Option(ZeroOrMore | NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ apply(M4, this); apply(M5, this); apply(M6, this);
+ done();
+ }
+ // Eight options...
+ template<class M0t, class M1t, class M2t, class M3t,
+ class M4t, class M5t, class M6t, class M7t>
+ list(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
+ const M4t &M4, const M5t &M5, const M6t &M6,
+ const M7t &M7) : Option(ZeroOrMore | NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ apply(M4, this); apply(M5, this); apply(M6, this); apply(M7, this);
+ done();
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// bits_storage class
+
+// Default storage class definition: external storage. This implementation
+// assumes the user will specify a variable to store the data into with the
+// cl::location(x) modifier.
+//
+template<class DataType, class StorageClass>
+class bits_storage {
+ unsigned *Location; // Where to store the bits...
+
+ template<class T>
+ static unsigned Bit(const T &V) {
+ unsigned BitPos = reinterpret_cast<unsigned>(V);
+ assert(BitPos < sizeof(unsigned) * 8 &&
+ "enum exceeds width of bit vector!");
+ return 1 << BitPos;
+ }
+
+public:
+ bits_storage() : Location(0) {}
+
+ bool setLocation(Option &O, unsigned &L) {
+ if (Location)
+ return O.error(": cl::location(x) specified more than once!");
+ Location = &L;
+ return false;
+ }
+
+ template<class T>
+ void addValue(const T &V) {
+ assert(Location != 0 && "cl::location(...) not specified for a command "
+ "line option with external storage!");
+ *Location |= Bit(V);
+ }
+
+ unsigned getBits() { return *Location; }
+
+ template<class T>
+ bool isSet(const T &V) {
+ return (*Location & Bit(V)) != 0;
+ }
+};
+
+
+// Define how to hold bits. Since we can inherit from a class, we do so.
+// This makes us exactly compatible with the bits in all cases that it is used.
+//
+template<class DataType>
+class bits_storage<DataType, bool> {
+ unsigned Bits; // Where to store the bits...
+
+ template<class T>
+ static unsigned Bit(const T &V) {
+ unsigned BitPos = reinterpret_cast<unsigned>(V);
+ assert(BitPos < sizeof(unsigned) * 8 &&
+ "enum exceeds width of bit vector!");
+ return 1 << BitPos;
+ }
+
+public:
+ template<class T>
+ void addValue(const T &V) {
+ Bits |= Bit(V);
+ }
+
+ unsigned getBits() { return Bits; }
+
+ template<class T>
+ bool isSet(const T &V) {
+ return (Bits & Bit(V)) != 0;
+ }
+};
+
+
+//===----------------------------------------------------------------------===//
+// bits - A bit vector of command options.
+//
+template <class DataType, class Storage = bool,
+ class ParserClass = parser<DataType> >
+class bits : public Option, public bits_storage<DataType, Storage> {
+ std::vector<unsigned> Positions;
+ ParserClass Parser;
+
+ virtual enum ValueExpected getValueExpectedFlagDefault() const {
+ return Parser.getValueExpectedFlagDefault();
+ }
+ virtual void getExtraOptionNames(std::vector<const char*> &OptionNames) {
+ return Parser.getExtraOptionNames(OptionNames);
+ }
+
+ virtual bool handleOccurrence(unsigned pos, const char *ArgName,
+ const std::string &Arg) {
+ typename ParserClass::parser_data_type Val =
+ typename ParserClass::parser_data_type();
+ if (Parser.parse(*this, ArgName, Arg, Val))
+ return true; // Parse Error!
+ addValue(Val);
+ setPosition(pos);
+ Positions.push_back(pos);
+ return false;
+ }
+
+ // Forward printing stuff to the parser...
+ virtual unsigned getOptionWidth() const {return Parser.getOptionWidth(*this);}
+ virtual void printOptionInfo(unsigned GlobalWidth) const {
+ Parser.printOptionInfo(*this, GlobalWidth);
+ }
+
+ void done() {
+ addArgument();
+ Parser.initialize(*this);
+ }
+public:
+ ParserClass &getParser() { return Parser; }
+
+ unsigned getPosition(unsigned optnum) const {
+ assert(optnum < this->size() && "Invalid option index");
+ return Positions[optnum];
+ }
+
+ // One option...
+ template<class M0t>
+ explicit bits(const M0t &M0) : Option(ZeroOrMore | NotHidden) {
+ apply(M0, this);
+ done();
+ }
+ // Two options...
+ template<class M0t, class M1t>
+ bits(const M0t &M0, const M1t &M1) : Option(ZeroOrMore | NotHidden) {
+ apply(M0, this); apply(M1, this);
+ done();
+ }
+ // Three options...
+ template<class M0t, class M1t, class M2t>
+ bits(const M0t &M0, const M1t &M1, const M2t &M2)
+ : Option(ZeroOrMore | NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this);
+ done();
+ }
+ // Four options...
+ template<class M0t, class M1t, class M2t, class M3t>
+ bits(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3)
+ : Option(ZeroOrMore | NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ done();
+ }
+ // Five options...
+ template<class M0t, class M1t, class M2t, class M3t, class M4t>
+ bits(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
+ const M4t &M4) : Option(ZeroOrMore | NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ apply(M4, this);
+ done();
+ }
+ // Six options...
+ template<class M0t, class M1t, class M2t, class M3t,
+ class M4t, class M5t>
+ bits(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
+ const M4t &M4, const M5t &M5) : Option(ZeroOrMore | NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ apply(M4, this); apply(M5, this);
+ done();
+ }
+ // Seven options...
+ template<class M0t, class M1t, class M2t, class M3t,
+ class M4t, class M5t, class M6t>
+ bits(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
+ const M4t &M4, const M5t &M5, const M6t &M6)
+ : Option(ZeroOrMore | NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ apply(M4, this); apply(M5, this); apply(M6, this);
+ done();
+ }
+ // Eight options...
+ template<class M0t, class M1t, class M2t, class M3t,
+ class M4t, class M5t, class M6t, class M7t>
+ bits(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
+ const M4t &M4, const M5t &M5, const M6t &M6,
+ const M7t &M7) : Option(ZeroOrMore | NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ apply(M4, this); apply(M5, this); apply(M6, this); apply(M7, this);
+ done();
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// Aliased command line option (alias this name to a preexisting name)
+//
+
+class alias : public Option {
+ Option *AliasFor;
+ virtual bool handleOccurrence(unsigned pos, const char *ArgName,
+ const std::string &Arg) {
+ return AliasFor->handleOccurrence(pos, AliasFor->ArgStr, Arg);
+ }
+ // Handle printing stuff...
+ virtual unsigned getOptionWidth() const;
+ virtual void printOptionInfo(unsigned GlobalWidth) const;
+
+ void done() {
+ if (!hasArgStr())
+ error(": cl::alias must have argument name specified!");
+ if (AliasFor == 0)
+ error(": cl::alias must have an cl::aliasopt(option) specified!");
+ addArgument();
+ }
+public:
+ void setAliasFor(Option &O) {
+ if (AliasFor)
+ error(": cl::alias must only have one cl::aliasopt(...) specified!");
+ AliasFor = &O;
+ }
+
+ // One option...
+ template<class M0t>
+ explicit alias(const M0t &M0) : Option(Optional | Hidden), AliasFor(0) {
+ apply(M0, this);
+ done();
+ }
+ // Two options...
+ template<class M0t, class M1t>
+ alias(const M0t &M0, const M1t &M1) : Option(Optional | Hidden), AliasFor(0) {
+ apply(M0, this); apply(M1, this);
+ done();
+ }
+ // Three options...
+ template<class M0t, class M1t, class M2t>
+ alias(const M0t &M0, const M1t &M1, const M2t &M2)
+ : Option(Optional | Hidden), AliasFor(0) {
+ apply(M0, this); apply(M1, this); apply(M2, this);
+ done();
+ }
+ // Four options...
+ template<class M0t, class M1t, class M2t, class M3t>
+ alias(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3)
+ : Option(Optional | Hidden), AliasFor(0) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ done();
+ }
+};
+
+// aliasfor - Modifier to set the option an alias aliases.
+struct aliasopt {
+ Option &Opt;
+ explicit aliasopt(Option &O) : Opt(O) {}
+ void apply(alias &A) const { A.setAliasFor(Opt); }
+};
+
+// extrahelp - provide additional help at the end of the normal help
+// output. All occurrences of cl::extrahelp will be accumulated and
+// printed to std::cerr at the end of the regular help, just before
+// exit is called.
+struct extrahelp {
+ const char * morehelp;
+ extrahelp(const char* help);
+};
+
+void PrintVersionMessage();
+// This function just prints the help message, exactly the same way as if the
+// --help option had been given on the command line.
+// NOTE: THIS FUNCTION TERMINATES THE PROGRAM!
+void PrintHelpMessage();
+
+} // End namespace cl
+
+} // End namespace llvm
+
+#endif
diff --git a/support/include/llvm/Support/Compiler.h b/support/include/llvm/Support/Compiler.h
new file mode 100644
index 0000000..06be685
--- /dev/null
+++ b/support/include/llvm/Support/Compiler.h
@@ -0,0 +1,48 @@
+//===-- llvm/Support/Compiler.h - Compiler abstraction support --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines several macros, based on the current compiler. This allows
+// use of compiler-specific features in a way that remains portable.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_COMPILER_H
+#define LLVM_SUPPORT_COMPILER_H
+
+// The VISIBILITY_HIDDEN macro, used for marking classes with the GCC-specific
+// visibility("hidden") attribute.
+#if __GNUC__ >= 4
+#define VISIBILITY_HIDDEN __attribute__ ((visibility("hidden")))
+#else
+#define VISIBILITY_HIDDEN
+#endif
+
+
+// C++ doesn't support 'extern template' of template specializations. GCC does,
+// but requires __extension__ before it. In the header, use this:
+// EXTERN_TEMPLATE_INSTANTIATION(class foo<bar>);
+// in the .cpp file, use this:
+// TEMPLATE_INSTANTIATION(class foo<bar>);
+#ifdef __GNUC__
+#define EXTERN_TEMPLATE_INSTANTIATION(X) __extension__ extern template X
+#define TEMPLATE_INSTANTIATION(X) template X
+#else
+#define EXTERN_TEMPLATE_INSTANTIATION(X)
+#define TEMPLATE_INSTANTIATION(X)
+#endif
+
+// DISABLE_INLINE - On compilers where we have a directive to do so, mark a
+// method "not for inlining".
+#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
+#define DISABLE_INLINE __attribute__((noinline))
+#else
+#define DISABLE_INLINE
+#endif
+
+#endif
diff --git a/support/include/llvm/Support/ConstantRange.h b/support/include/llvm/Support/ConstantRange.h
new file mode 100644
index 0000000..778827c
--- /dev/null
+++ b/support/include/llvm/Support/ConstantRange.h
@@ -0,0 +1,198 @@
+//===-- llvm/Support/ConstantRange.h - Represent a range --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Represent a range of possible values that may occur when the program is run
+// for an integral value. This keeps track of a lower and upper bound for the
+// constant, which MAY wrap around the end of the numeric range. To do this, it
+// keeps track of a [lower, upper) bound, which specifies an interval just like
+// STL iterators. When used with boolean values, the following are important
+// ranges: :
+//
+// [F, F) = {} = Empty set
+// [T, F) = {T}
+// [F, T) = {F}
+// [T, T) = {F, T} = Full set
+//
+// The other integral ranges use min/max values for special range values. For
+// example, for 8-bit types, it uses:
+// [0, 0) = {} = Empty set
+// [255, 255) = {0..255} = Full Set
+//
+// Note that ConstantRange always keeps unsigned values.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_CONSTANT_RANGE_H
+#define LLVM_SUPPORT_CONSTANT_RANGE_H
+
+#include "llvm/ADT/APInt.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/Streams.h"
+#include <iosfwd>
+
+namespace llvm {
+
+class ConstantRange {
+ APInt Lower, Upper;
+ static ConstantRange intersect1Wrapped(const ConstantRange &LHS,
+ const ConstantRange &RHS);
+ public:
+ /// Initialize a full (the default) or empty set for the specified bit width.
+ ///
+ ConstantRange(uint32_t BitWidth, bool isFullSet = true);
+
+ /// Initialize a range to hold the single specified value.
+ ///
+ ConstantRange(const APInt &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);
+
+ /// getLower - Return the lower value for this range...
+ ///
+ const APInt &getLower() const { return Lower; }
+
+ /// getUpper - Return the upper value for this range...
+ ///
+ const APInt &getUpper() const { return Upper; }
+
+ /// getBitWidth - get the bit width of this ConstantRange
+ ///
+ uint32_t getBitWidth() const { return Lower.getBitWidth(); }
+
+ /// isFullSet - Return true if this set contains all of the elements possible
+ /// for this data-type
+ ///
+ bool isFullSet() const;
+
+ /// isEmptySet - Return true if this set contains no members.
+ ///
+ bool isEmptySet() const;
+
+ /// isWrappedSet - Return true if this set wraps around the top of the range,
+ /// for example: [100, 8)
+ ///
+ bool isWrappedSet() const;
+
+ /// contains - Return true if the specified value is in the set.
+ ///
+ bool contains(const APInt &Val) const;
+
+ /// getSingleElement - If this set contains a single element, return it,
+ /// otherwise return null.
+ ///
+ const APInt *getSingleElement() const {
+ if (Upper == Lower + 1)
+ return &Lower;
+ return 0;
+ }
+
+ /// isSingleElement - Return true if this set contains exactly one member.
+ ///
+ bool isSingleElement() const { return getSingleElement() != 0; }
+
+ /// getSetSize - Return the number of elements in this set.
+ ///
+ APInt getSetSize() const;
+
+ /// getUnsignedMax - Return the largest unsigned value contained in the
+ /// ConstantRange.
+ ///
+ APInt getUnsignedMax() const;
+
+ /// getUnsignedMin - Return the smallest unsigned value contained in the
+ /// ConstantRange.
+ ///
+ APInt getUnsignedMin() const;
+
+ /// getSignedMax - Return the largest signed value contained in the
+ /// ConstantRange.
+ ///
+ APInt getSignedMax() const;
+
+ /// getSignedMin - Return the smallest signed value contained in the
+ /// ConstantRange.
+ ///
+ APInt getSignedMin() const;
+
+ /// operator== - Return true if this range is equal to another range.
+ ///
+ bool operator==(const ConstantRange &CR) const {
+ return Lower == CR.Lower && Upper == CR.Upper;
+ }
+ bool operator!=(const ConstantRange &CR) const {
+ return !operator==(CR);
+ }
+
+ /// subtract - Subtract the specified constant from the endpoints of this
+ /// constant range.
+ ConstantRange subtract(const APInt &CI) const;
+
+ /// intersectWith - Return the range that results from the intersection of
+ /// this range with another range. The resultant range is pruned as much as
+ /// possible, but there may be cases where elements are included that are in
+ /// one of the sets but not the other. For example: [100, 8) intersect [3,
+ /// 120) yields [3, 120)
+ ///
+ ConstantRange intersectWith(const ConstantRange &CR) const;
+
+ /// maximalIntersectWith - Return the range that results from the intersection
+ /// of this range with another range. The resultant range is guaranteed to
+ /// include all elements contained in both input ranges, and to have the
+ /// smallest possible set size that does so. Because there may be two
+ /// intersections with the same set size, A.maximalIntersectWith(B) might not
+ /// be equal to B.maximalIntersectWith(A).
+ ///
+ ConstantRange maximalIntersectWith(const ConstantRange &CR) const;
+
+ /// unionWith - Return the range that results from the union of this range
+ /// with another range. The resultant range is guaranteed to include the
+ /// elements of both sets, but may contain more. For example, [3, 9) union
+ /// [12,15) is [3, 15), which includes 9, 10, and 11, which were not included
+ /// in either set before.
+ ///
+ ConstantRange unionWith(const ConstantRange &CR) const;
+
+ /// zeroExtend - Return a new range in the specified integer type, which must
+ /// be strictly larger than the current type. The returned range will
+ /// correspond to the possible range of values if the source range had been
+ /// zero extended to BitWidth.
+ ConstantRange zeroExtend(uint32_t BitWidth) const;
+
+ /// signExtend - Return a new range in the specified integer type, which must
+ /// be strictly larger than the current type. The returned range will
+ /// correspond to the possible range of values if the source range had been
+ /// sign extended to BitWidth.
+ ConstantRange signExtend(uint32_t BitWidth) const;
+
+ /// truncate - Return a new range in the specified integer type, which must be
+ /// strictly smaller than the current type. The returned range will
+ /// correspond to the possible range of values if the source range had been
+ /// truncated to the specified type.
+ ConstantRange truncate(uint32_t BitWidth) const;
+
+ /// print - Print out the bounds to a stream...
+ ///
+ void print(std::ostream &OS) const;
+ void print(std::ostream *OS) const { if (OS) print(*OS); }
+
+ /// dump - Allow printing from a debugger easily...
+ ///
+ void dump() const;
+};
+
+inline std::ostream &operator<<(std::ostream &OS, const ConstantRange &CR) {
+ CR.print(OS);
+ return OS;
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/support/include/llvm/Support/DOTGraphTraits.h b/support/include/llvm/Support/DOTGraphTraits.h
new file mode 100644
index 0000000..ed59303
--- /dev/null
+++ b/support/include/llvm/Support/DOTGraphTraits.h
@@ -0,0 +1,122 @@
+//===-- llvm/Support/DotGraphTraits.h - Customize .dot output ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines a template class that can be used to customize dot output
+// graphs generated by the GraphWriter.h file. The default implementation of
+// this file will produce a simple, but not very polished graph. By
+// specializing this template, lots of customization opportunities are possible.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_DOTGRAPHTRAITS_H
+#define LLVM_SUPPORT_DOTGRAPHTRAITS_H
+
+#include <string>
+
+namespace llvm {
+
+/// DefaultDOTGraphTraits - This class provides the default implementations of
+/// all of the DOTGraphTraits methods. If a specialization does not need to
+/// override all methods here it should inherit so that it can get the default
+/// implementations.
+///
+struct DefaultDOTGraphTraits {
+ /// getGraphName - Return the label for the graph as a whole. Printed at the
+ /// top of the graph.
+ ///
+ template<typename GraphType>
+ static std::string getGraphName(GraphType Graph) { return ""; }
+
+ /// getGraphProperties - Return any custom properties that should be included
+ /// in the top level graph structure for dot.
+ ///
+ template<typename GraphType>
+ static std::string getGraphProperties(GraphType Graph) {
+ return "";
+ }
+
+ /// renderGraphFromBottomUp - If this function returns true, the graph is
+ /// emitted bottom-up instead of top-down. This requires graphviz 2.0 to work
+ /// though.
+ static bool renderGraphFromBottomUp() {
+ return false;
+ }
+
+ /// getNodeLabel - Given a node and a pointer to the top level graph, return
+ /// the label to print in the node.
+ template<typename GraphType>
+ static std::string getNodeLabel(const void *Node, GraphType Graph) {
+ return "";
+ }
+
+ /// hasNodeAddressLabel - If this method returns true, the address of the node
+ /// is added to the label of the node.
+ template<typename GraphType>
+ static bool hasNodeAddressLabel(const void *Node, GraphType Graph) {
+ return false;
+ }
+
+ /// If you want to specify custom node attributes, this is the place to do so
+ ///
+ template<typename GraphType>
+ static std::string getNodeAttributes(const void *Node, GraphType Graph) {
+ return "";
+ }
+
+ /// If you want to override the dot attributes printed for a particular edge,
+ /// override this method.
+ template<typename EdgeIter>
+ static std::string getEdgeAttributes(const void *Node, EdgeIter EI) {
+ return "";
+ }
+
+ /// getEdgeSourceLabel - If you want to label the edge source itself,
+ /// implement this method.
+ template<typename EdgeIter>
+ static std::string getEdgeSourceLabel(const void *Node, EdgeIter I) {
+ return "";
+ }
+
+ /// edgeTargetsEdgeSource - This method returns true if this outgoing edge
+ /// should actually target another edge source, not a node. If this method is
+ /// implemented, getEdgeTarget should be implemented.
+ template<typename EdgeIter>
+ static bool edgeTargetsEdgeSource(const void *Node, EdgeIter I) {
+ return false;
+ }
+
+ /// getEdgeTarget - If edgeTargetsEdgeSource returns true, this method is
+ /// called to determine which outgoing edge of Node is the target of this
+ /// edge.
+ template<typename EdgeIter>
+ static EdgeIter getEdgeTarget(const void *Node, EdgeIter I) {
+ return I;
+ }
+
+ /// addCustomGraphFeatures - If a graph is made up of more than just
+ /// straight-forward nodes and edges, this is the place to put all of the
+ /// custom stuff necessary. The GraphWriter object, instantiated with your
+ /// GraphType is passed in as an argument. You may call arbitrary methods on
+ /// it to add things to the output graph.
+ ///
+ template<typename GraphType, typename GraphWriter>
+ static void addCustomGraphFeatures(GraphType Graph, GraphWriter &GW) {}
+};
+
+
+/// DOTGraphTraits - Template class that can be specialized to customize how
+/// graphs are converted to 'dot' graphs. When specializing, you may inherit
+/// from DefaultDOTGraphTraits if you don't need to override everything.
+///
+template <typename Ty>
+struct DOTGraphTraits : public DefaultDOTGraphTraits {};
+
+} // End llvm namespace
+
+#endif
diff --git a/support/include/llvm/Support/DataTypes.h.in b/support/include/llvm/Support/DataTypes.h.in
new file mode 100644
index 0000000..dcf7bfc
--- /dev/null
+++ b/support/include/llvm/Support/DataTypes.h.in
@@ -0,0 +1,131 @@
+//===-- include/Support/DataTypes.h - Define fixed size types ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains definitions to figure out the size of _HOST_ data types.
+// This file is important because different host OS's define different macros,
+// which makes portability tough. This file exports the following definitions:
+//
+// [u]int(32|64)_t : typedefs for signed and unsigned 32/64 bit system types
+// [U]INT(8|16|32|64)_(MIN|MAX) : Constants for the min and max values.
+//
+// No library is required when using these functinons.
+//
+//===----------------------------------------------------------------------===//
+
+#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
+#undef HAVE_U_INT64_T
+
+#ifndef _MSC_VER
+
+// Note that this header's correct operation depends on __STDC_LIMIT_MACROS
+// being defined. We would define it here, but in order to prevent Bad Things
+// happening when system headers or C++ STL headers include stdint.h before
+// we define it here, we define it on the g++ command line (in Makefile.rules).
+#if !defined(__STDC_LIMIT_MACROS)
+# error "Must #define __STDC_LIMIT_MACROS before #including Support/DataTypes.h"
+#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>
+#endif
+
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+#ifdef __cplusplus
+#include <cmath>
+#else
+#include <math.h>
+#endif
+
+#ifdef _AIX
+#include "llvm/Support/AIXDataTypesFix.h"
+#endif
+
+// Handle incorrect definition of uint64_t as u_int64_t
+#ifndef HAVE_UINT64_T
+#ifdef HAVE_U_INT64_T
+typedef u_int64_t uint64_t;
+#else
+# error "Don't have a definition for uint64_t on this platform"
+#endif
+#endif
+
+#ifdef _OpenBSD_
+#define INT8_MAX 127
+#define INT8_MIN -128
+#define UINT8_MAX 255
+#define INT16_MAX 32767
+#define INT16_MIN -32768
+#define UINT16_MAX 65535
+#define INT32_MAX 2147483647
+#define INT32_MIN -2147483648
+#define UINT32_MAX 4294967295U
+#endif
+
+#else /* _MSC_VER */
+// Visual C++ doesn't provide standard integer headers, but it does provide
+// built-in data types.
+#include <stdlib.h>
+#include <stddef.h>
+#include <sys/types.h>
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+typedef signed int int32_t;
+typedef unsigned int uint32_t;
+typedef short int16_t;
+typedef unsigned short uint16_t;
+typedef signed char int8_t;
+typedef unsigned char uint8_t;
+typedef signed int ssize_t;
+#define INT8_MAX 127
+#define INT8_MIN -128
+#define UINT8_MAX 255
+#define INT16_MAX 32767
+#define INT16_MIN -32768
+#define UINT16_MAX 65535
+#define INT32_MAX 2147483647
+#define INT32_MIN -2147483648
+#define UINT32_MAX 4294967295U
+#endif /* _MSC_VER */
+
+/* Set defaults for constants which we cannot find. */
+#if !defined(INT64_MAX)
+# define INT64_MAX 9223372036854775807LL
+#endif
+#if !defined(INT64_MIN)
+# define INT64_MIN ((-INT64_MAX)-1)
+#endif
+#if !defined(UINT64_MAX)
+# define UINT64_MAX 0xffffffffffffffffULL
+#endif
+
+#if __GNUC__ > 3
+#define END_WITH_NULL __attribute__((sentinel))
+#else
+#define END_WITH_NULL
+#endif
+
+#ifndef HUGE_VALF
+#define HUGE_VALF (float)HUGE_VAL
+#endif
+
+#endif /* SUPPORT_DATATYPES_H */
diff --git a/support/include/llvm/Support/Debug.h b/support/include/llvm/Support/Debug.h
new file mode 100644
index 0000000..cbfaf15
--- /dev/null
+++ b/support/include/llvm/Support/Debug.h
@@ -0,0 +1,78 @@
+//===- llvm/Support/Debug.h - Easy way to add debug output ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a handy way of adding debugging information to your
+// code, without it being enabled all of the time, and without having to add
+// command line options to enable it.
+//
+// In particular, just wrap your code with the DEBUG() macro, and it will be
+// enabled automatically if you specify '-debug' on the command-line.
+// Alternatively, you can also use the SET_DEBUG_TYPE("foo") macro to specify
+// that your debug code belongs to class "foo". Then, on the command line, you
+// can specify '-debug-only=foo' to enable JUST the debug information for the
+// foo class.
+//
+// When compiling in release mode, the -debug-* options and all code in DEBUG()
+// statements disappears, so it does not effect the runtime of the code.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_DEBUG_H
+#define LLVM_SUPPORT_DEBUG_H
+
+#include "llvm/Support/Streams.h"
+
+namespace llvm {
+
+// DebugFlag - This boolean is set to true if the '-debug' command line option
+// is specified. This should probably not be referenced directly, instead, use
+// the DEBUG macro below.
+//
+extern bool DebugFlag;
+
+// isCurrentDebugType - Return true if the specified string is the debug type
+// specified on the command line, or if none was specified on the command line
+// with the -debug-only=X option.
+//
+bool isCurrentDebugType(const char *Type);
+
+// DEBUG macro - This macro should be used by passes to emit debug information.
+// In the '-debug' option is specified on the commandline, and if this is a
+// debug build, then the code specified as the option to the macro will be
+// executed. Otherwise it will not be. Example:
+//
+// DEBUG(cerr << "Bitset contains: " << Bitset << "\n");
+//
+
+#ifndef DEBUG_TYPE
+#define DEBUG_TYPE ""
+#endif
+
+#ifdef NDEBUG
+#define DEBUG(X)
+#else
+#define DEBUG(X) \
+ do { if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) { X; } } while (0)
+#endif
+
+/// getErrorOutputStream - Returns the error output stream (std::cerr). This
+/// places the std::c* I/O streams into one .cpp file and relieves the whole
+/// program from having to have hundreds of static c'tor/d'tors for them.
+///
+OStream &getErrorOutputStream(const char *DebugType);
+
+#ifdef NDEBUG
+#define DOUT llvm::OStream(0)
+#else
+#define DOUT llvm::getErrorOutputStream(DEBUG_TYPE)
+#endif
+
+} // End llvm namespace
+
+#endif
diff --git a/support/include/llvm/Support/Dwarf.h b/support/include/llvm/Support/Dwarf.h
new file mode 100644
index 0000000..21f49f6
--- /dev/null
+++ b/support/include/llvm/Support/Dwarf.h
@@ -0,0 +1,572 @@
+//===-- llvm/Support/Dwarf.h ---Dwarf Constants------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by James M. Laskey and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains constants used for implementing Dwarf debug support. For
+// Details on the Dwarf 3 specfication see DWARF Debugging Information Format
+// V.3 reference manual http://dwarf.freestandards.org ,
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_DWARF_H
+#define LLVM_SUPPORT_DWARF_H
+
+#include "llvm/System/IncludeFile.h"
+
+namespace llvm {
+
+namespace dwarf {
+
+//===----------------------------------------------------------------------===//
+// Dwarf constants as gleaned from the DWARF Debugging Information Format V.3
+// 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 {
+ // llvm mock tags
+ DW_TAG_invalid = ~0U, // Tag for invalid results.
+
+ DW_TAG_anchor = 0, // Tag for descriptor anchors.
+ DW_TAG_auto_variable = 0x100, // Tag for local (auto) variables.
+ DW_TAG_arg_variable = 0x101, // Tag for argument variables.
+ DW_TAG_return_variable = 0x102, // Tag for return variables.
+
+ DW_TAG_vector_type = 0x103, // Tag for vector types.
+
+ DW_TAG_user_base = 0x1000, // Recommended base for user tags.
+
+ DW_CIE_VERSION = 1, // Common frame information version.
+ DW_CIE_ID = 0xffffffff // Common frame information mark.
+};
+
+enum dwarf_constants {
+ DWARF_VERSION = 2,
+
+ // Tags
+ DW_TAG_array_type = 0x01,
+ DW_TAG_class_type = 0x02,
+ DW_TAG_entry_point = 0x03,
+ DW_TAG_enumeration_type = 0x04,
+ DW_TAG_formal_parameter = 0x05,
+ DW_TAG_imported_declaration = 0x08,
+ DW_TAG_label = 0x0a,
+ DW_TAG_lexical_block = 0x0b,
+ DW_TAG_member = 0x0d,
+ DW_TAG_pointer_type = 0x0f,
+ DW_TAG_reference_type = 0x10,
+ DW_TAG_compile_unit = 0x11,
+ DW_TAG_string_type = 0x12,
+ DW_TAG_structure_type = 0x13,
+ DW_TAG_subroutine_type = 0x15,
+ DW_TAG_typedef = 0x16,
+ DW_TAG_union_type = 0x17,
+ DW_TAG_unspecified_parameters = 0x18,
+ DW_TAG_variant = 0x19,
+ DW_TAG_common_block = 0x1a,
+ DW_TAG_common_inclusion = 0x1b,
+ DW_TAG_inheritance = 0x1c,
+ DW_TAG_inlined_subroutine = 0x1d,
+ DW_TAG_module = 0x1e,
+ DW_TAG_ptr_to_member_type = 0x1f,
+ DW_TAG_set_type = 0x20,
+ DW_TAG_subrange_type = 0x21,
+ DW_TAG_with_stmt = 0x22,
+ DW_TAG_access_declaration = 0x23,
+ DW_TAG_base_type = 0x24,
+ DW_TAG_catch_block = 0x25,
+ DW_TAG_const_type = 0x26,
+ DW_TAG_constant = 0x27,
+ DW_TAG_enumerator = 0x28,
+ DW_TAG_file_type = 0x29,
+ DW_TAG_friend = 0x2a,
+ DW_TAG_namelist = 0x2b,
+ DW_TAG_namelist_item = 0x2c,
+ DW_TAG_packed_type = 0x2d,
+ DW_TAG_subprogram = 0x2e,
+ DW_TAG_template_type_parameter = 0x2f,
+ DW_TAG_template_value_parameter = 0x30,
+ DW_TAG_thrown_type = 0x31,
+ DW_TAG_try_block = 0x32,
+ DW_TAG_variant_part = 0x33,
+ DW_TAG_variable = 0x34,
+ DW_TAG_volatile_type = 0x35,
+ DW_TAG_dwarf_procedure = 0x36,
+ DW_TAG_restrict_type = 0x37,
+ DW_TAG_interface_type = 0x38,
+ DW_TAG_namespace = 0x39,
+ DW_TAG_imported_module = 0x3a,
+ DW_TAG_unspecified_type = 0x3b,
+ DW_TAG_partial_unit = 0x3c,
+ DW_TAG_imported_unit = 0x3d,
+ DW_TAG_condition = 0x3f,
+ DW_TAG_shared_type = 0x40,
+ DW_TAG_lo_user = 0x4080,
+ DW_TAG_hi_user = 0xffff,
+
+ // Children flag
+ DW_CHILDREN_no = 0x00,
+ DW_CHILDREN_yes = 0x01,
+
+ // Attributes
+ DW_AT_sibling = 0x01,
+ DW_AT_location = 0x02,
+ DW_AT_name = 0x03,
+ DW_AT_ordering = 0x09,
+ DW_AT_byte_size = 0x0b,
+ DW_AT_bit_offset = 0x0c,
+ DW_AT_bit_size = 0x0d,
+ DW_AT_stmt_list = 0x10,
+ DW_AT_low_pc = 0x11,
+ DW_AT_high_pc = 0x12,
+ DW_AT_language = 0x13,
+ DW_AT_discr = 0x15,
+ DW_AT_discr_value = 0x16,
+ DW_AT_visibility = 0x17,
+ DW_AT_import = 0x18,
+ DW_AT_string_length = 0x19,
+ DW_AT_common_reference = 0x1a,
+ DW_AT_comp_dir = 0x1b,
+ DW_AT_const_value = 0x1c,
+ DW_AT_containing_type = 0x1d,
+ DW_AT_default_value = 0x1e,
+ DW_AT_inline = 0x20,
+ DW_AT_is_optional = 0x21,
+ DW_AT_lower_bound = 0x22,
+ DW_AT_producer = 0x25,
+ DW_AT_prototyped = 0x27,
+ DW_AT_return_addr = 0x2a,
+ DW_AT_start_scope = 0x2c,
+ DW_AT_bit_stride = 0x2e,
+ DW_AT_upper_bound = 0x2f,
+ DW_AT_abstract_origin = 0x31,
+ DW_AT_accessibility = 0x32,
+ DW_AT_address_class = 0x33,
+ DW_AT_artificial = 0x34,
+ DW_AT_base_types = 0x35,
+ DW_AT_calling_convention = 0x36,
+ DW_AT_count = 0x37,
+ DW_AT_data_member_location = 0x38,
+ DW_AT_decl_column = 0x39,
+ DW_AT_decl_file = 0x3a,
+ DW_AT_decl_line = 0x3b,
+ DW_AT_declaration = 0x3c,
+ DW_AT_discr_list = 0x3d,
+ DW_AT_encoding = 0x3e,
+ DW_AT_external = 0x3f,
+ DW_AT_frame_base = 0x40,
+ DW_AT_friend = 0x41,
+ DW_AT_identifier_case = 0x42,
+ DW_AT_macro_info = 0x43,
+ DW_AT_namelist_item = 0x44,
+ DW_AT_priority = 0x45,
+ DW_AT_segment = 0x46,
+ DW_AT_specification = 0x47,
+ DW_AT_static_link = 0x48,
+ DW_AT_type = 0x49,
+ DW_AT_use_location = 0x4a,
+ DW_AT_variable_parameter = 0x4b,
+ DW_AT_virtuality = 0x4c,
+ DW_AT_vtable_elem_location = 0x4d,
+ DW_AT_allocated = 0x4e,
+ DW_AT_associated = 0x4f,
+ DW_AT_data_location = 0x50,
+ DW_AT_byte_stride = 0x51,
+ DW_AT_entry_pc = 0x52,
+ DW_AT_use_UTF8 = 0x53,
+ DW_AT_extension = 0x54,
+ DW_AT_ranges = 0x55,
+ DW_AT_trampoline = 0x56,
+ DW_AT_call_column = 0x57,
+ DW_AT_call_file = 0x58,
+ DW_AT_call_line = 0x59,
+ DW_AT_description = 0x5a,
+ DW_AT_binary_scale = 0x5b,
+ DW_AT_decimal_scale = 0x5c,
+ DW_AT_small = 0x5d,
+ DW_AT_decimal_sign = 0x5e,
+ DW_AT_digit_count = 0x5f,
+ DW_AT_picture_string = 0x60,
+ DW_AT_mutable = 0x61,
+ DW_AT_threads_scaled = 0x62,
+ DW_AT_explicit = 0x63,
+ DW_AT_object_pointer = 0x64,
+ DW_AT_endianity = 0x65,
+ DW_AT_elemental = 0x66,
+ DW_AT_pure = 0x67,
+ DW_AT_recursive = 0x68,
+ DW_AT_MIPS_linkage_name = 0x2007,
+ DW_AT_sf_names = 0x2101,
+ DW_AT_src_info = 0x2102,
+ DW_AT_mac_info = 0x2103,
+ DW_AT_src_coords = 0x2104,
+ DW_AT_body_begin = 0x2105,
+ DW_AT_body_end = 0x2106,
+ DW_AT_GNU_vector = 0x2107,
+ DW_AT_lo_user = 0x2000,
+ DW_AT_hi_user = 0x3fff,
+
+ // Attribute form encodings
+ DW_FORM_addr = 0x01,
+ DW_FORM_block2 = 0x03,
+ DW_FORM_block4 = 0x04,
+ DW_FORM_data2 = 0x05,
+ DW_FORM_data4 = 0x06,
+ DW_FORM_data8 = 0x07,
+ DW_FORM_string = 0x08,
+ DW_FORM_block = 0x09,
+ DW_FORM_block1 = 0x0a,
+ DW_FORM_data1 = 0x0b,
+ DW_FORM_flag = 0x0c,
+ DW_FORM_sdata = 0x0d,
+ DW_FORM_strp = 0x0e,
+ DW_FORM_udata = 0x0f,
+ DW_FORM_ref_addr = 0x10,
+ DW_FORM_ref1 = 0x11,
+ DW_FORM_ref2 = 0x12,
+ DW_FORM_ref4 = 0x13,
+ DW_FORM_ref8 = 0x14,
+ DW_FORM_ref_udata = 0x15,
+ DW_FORM_indirect = 0x16,
+
+ // Operation encodings
+ DW_OP_addr = 0x03,
+ DW_OP_deref = 0x06,
+ DW_OP_const1u = 0x08,
+ DW_OP_const1s = 0x09,
+ DW_OP_const2u = 0x0a,
+ DW_OP_const2s = 0x0b,
+ DW_OP_const4u = 0x0c,
+ DW_OP_const4s = 0x0d,
+ DW_OP_const8u = 0x0e,
+ DW_OP_const8s = 0x0f,
+ DW_OP_constu = 0x10,
+ DW_OP_consts = 0x11,
+ DW_OP_dup = 0x12,
+ DW_OP_drop = 0x13,
+ DW_OP_over = 0x14,
+ DW_OP_pick = 0x15,
+ DW_OP_swap = 0x16,
+ DW_OP_rot = 0x17,
+ DW_OP_xderef = 0x18,
+ DW_OP_abs = 0x19,
+ DW_OP_and = 0x1a,
+ DW_OP_div = 0x1b,
+ DW_OP_minus = 0x1c,
+ DW_OP_mod = 0x1d,
+ DW_OP_mul = 0x1e,
+ DW_OP_neg = 0x1f,
+ DW_OP_not = 0x20,
+ DW_OP_or = 0x21,
+ DW_OP_plus = 0x22,
+ DW_OP_plus_uconst = 0x23,
+ DW_OP_shl = 0x24,
+ DW_OP_shr = 0x25,
+ DW_OP_shra = 0x26,
+ DW_OP_xor = 0x27,
+ DW_OP_skip = 0x2f,
+ DW_OP_bra = 0x28,
+ DW_OP_eq = 0x29,
+ DW_OP_ge = 0x2a,
+ DW_OP_gt = 0x2b,
+ DW_OP_le = 0x2c,
+ DW_OP_lt = 0x2d,
+ DW_OP_ne = 0x2e,
+ DW_OP_lit0 = 0x30,
+ DW_OP_lit1 = 0x31,
+ DW_OP_lit31 = 0x4f,
+ DW_OP_reg0 = 0x50,
+ DW_OP_reg1 = 0x51,
+ DW_OP_reg31 = 0x6f,
+ DW_OP_breg0 = 0x70,
+ DW_OP_breg1 = 0x71,
+ DW_OP_breg31 = 0x8f,
+ DW_OP_regx = 0x90,
+ DW_OP_fbreg = 0x91,
+ DW_OP_bregx = 0x92,
+ DW_OP_piece = 0x93,
+ DW_OP_deref_size = 0x94,
+ DW_OP_xderef_size = 0x95,
+ DW_OP_nop = 0x96,
+ DW_OP_push_object_address = 0x97,
+ DW_OP_call2 = 0x98,
+ DW_OP_call4 = 0x99,
+ DW_OP_call_ref = 0x9a,
+ DW_OP_form_tls_address = 0x9b,
+ DW_OP_call_frame_cfa = 0x9c,
+ DW_OP_lo_user = 0xe0,
+ DW_OP_hi_user = 0xff,
+
+ // Encoding attribute values
+ DW_ATE_address = 0x01,
+ DW_ATE_boolean = 0x02,
+ DW_ATE_complex_float = 0x03,
+ DW_ATE_float = 0x04,
+ DW_ATE_signed = 0x05,
+ DW_ATE_signed_char = 0x06,
+ DW_ATE_unsigned = 0x07,
+ DW_ATE_unsigned_char = 0x08,
+ DW_ATE_imaginary_float = 0x09,
+ DW_ATE_packed_decimal = 0x0a,
+ DW_ATE_numeric_string = 0x0b,
+ DW_ATE_edited = 0x0c,
+ DW_ATE_signed_fixed = 0x0d,
+ DW_ATE_unsigned_fixed = 0x0e,
+ DW_ATE_decimal_float = 0x0f,
+ DW_ATE_lo_user = 0x80,
+ DW_ATE_hi_user = 0xff,
+
+ // 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,
+
+ // 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,
+
+ // Accessibility codes
+ DW_ACCESS_public = 0x01,
+ DW_ACCESS_protected = 0x02,
+ DW_ACCESS_private = 0x03,
+
+ // Visibility codes
+ DW_VIS_local = 0x01,
+ DW_VIS_exported = 0x02,
+ DW_VIS_qualified = 0x03,
+
+ // Virtuality codes
+ DW_VIRTUALITY_none = 0x00,
+ DW_VIRTUALITY_virtual = 0x01,
+ DW_VIRTUALITY_pure_virtual = 0x02,
+
+ // Language names
+ DW_LANG_C89 = 0x0001,
+ DW_LANG_C = 0x0002,
+ DW_LANG_Ada83 = 0x0003,
+ DW_LANG_C_plus_plus = 0x0004,
+ DW_LANG_Cobol74 = 0x0005,
+ DW_LANG_Cobol85 = 0x0006,
+ DW_LANG_Fortran77 = 0x0007,
+ DW_LANG_Fortran90 = 0x0008,
+ DW_LANG_Pascal83 = 0x0009,
+ DW_LANG_Modula2 = 0x000a,
+ DW_LANG_Java = 0x000b,
+ DW_LANG_C99 = 0x000c,
+ DW_LANG_Ada95 = 0x000d,
+ DW_LANG_Fortran95 = 0x000e,
+ DW_LANG_PLI = 0x000f,
+ DW_LANG_ObjC = 0x0010,
+ DW_LANG_ObjC_plus_plus = 0x0011,
+ DW_LANG_UPC = 0x0012,
+ DW_LANG_D = 0x0013,
+ DW_LANG_lo_user = 0x8000,
+ DW_LANG_hi_user = 0xffff,
+
+ // Identifier case codes
+ DW_ID_case_sensitive = 0x00,
+ DW_ID_up_case = 0x01,
+ DW_ID_down_case = 0x02,
+ DW_ID_case_insensitive = 0x03,
+
+ // 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,
+
+ // Inline codes
+ DW_INL_not_inlined = 0x00,
+ DW_INL_inlined = 0x01,
+ DW_INL_declared_not_inlined = 0x02,
+ DW_INL_declared_inlined = 0x03,
+
+ // Array ordering
+ DW_ORD_row_major = 0x00,
+ DW_ORD_col_major = 0x01,
+
+ // Discriminant descriptor values
+ DW_DSC_label = 0x00,
+ DW_DSC_range = 0x01,
+
+ // Line Number Standard Opcode Encodings
+ DW_LNS_copy = 0x01,
+ DW_LNS_advance_pc = 0x02,
+ DW_LNS_advance_line = 0x03,
+ DW_LNS_set_file = 0x04,
+ DW_LNS_set_column = 0x05,
+ DW_LNS_negate_stmt = 0x06,
+ DW_LNS_set_basic_block = 0x07,
+ DW_LNS_const_add_pc = 0x08,
+ DW_LNS_fixed_advance_pc = 0x09,
+ DW_LNS_set_prologue_end = 0x0a,
+ DW_LNS_set_epilogue_begin = 0x0b,
+ DW_LNS_set_isa = 0x0c,
+
+ // Line Number Extended Opcode Encodings
+ DW_LNE_end_sequence = 0x01,
+ DW_LNE_set_address = 0x02,
+ DW_LNE_define_file = 0x03,
+ DW_LNE_lo_user = 0x80,
+ DW_LNE_hi_user = 0xff,
+
+ // 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,
+
+ // Call frame instruction encodings
+ DW_CFA_extended = 0x00,
+ DW_CFA_advance_loc = 0x40,
+ DW_CFA_offset = 0x80,
+ DW_CFA_restore = 0xc0,
+ DW_CFA_set_loc = 0x01,
+ DW_CFA_advance_loc1 = 0x02,
+ DW_CFA_advance_loc2 = 0x03,
+ DW_CFA_advance_loc4 = 0x04,
+ DW_CFA_offset_extended = 0x05,
+ DW_CFA_restore_extended = 0x06,
+ DW_CFA_undefined = 0x07,
+ DW_CFA_same_value = 0x08,
+ DW_CFA_register = 0x09,
+ DW_CFA_remember_state = 0x0a,
+ DW_CFA_restore_state = 0x0b,
+ DW_CFA_def_cfa = 0x0c,
+ DW_CFA_def_cfa_register = 0x0d,
+ DW_CFA_def_cfa_offset = 0x0e,
+ DW_CFA_def_cfa_expression = 0x0f,
+ DW_CFA_expression = 0x10,
+ DW_CFA_offset_extended_sf = 0x11,
+ DW_CFA_def_cfa_sf = 0x12,
+ DW_CFA_def_cfa_offset_sf = 0x13,
+ DW_CFA_val_offset = 0x14,
+ DW_CFA_val_offset_sf = 0x15,
+ DW_CFA_val_expression = 0x16,
+ DW_CFA_lo_user = 0x1c,
+ DW_CFA_hi_user = 0x3f,
+
+ DW_EH_PE_absptr = 0x00,
+ DW_EH_PE_omit = 0xff,
+ DW_EH_PE_uleb128 = 0x01,
+ DW_EH_PE_udata2 = 0x02,
+ DW_EH_PE_udata4 = 0x03,
+ DW_EH_PE_udata8 = 0x04,
+ DW_EH_PE_sleb128 = 0x09,
+ DW_EH_PE_sdata2 = 0x0A,
+ DW_EH_PE_sdata4 = 0x0B,
+ DW_EH_PE_sdata8 = 0x0C,
+ DW_EH_PE_signed = 0x08,
+ DW_EH_PE_pcrel = 0x10,
+ DW_EH_PE_textrel = 0x20,
+ DW_EH_PE_datarel = 0x30,
+ DW_EH_PE_funcrel = 0x40,
+ DW_EH_PE_aligned = 0x50,
+ DW_EH_PE_indirect = 0x80
+};
+
+/// TagString - Return the string for the specified tag.
+///
+const char *TagString(unsigned Tag);
+
+/// ChildrenString - Return the string for the specified children flag.
+///
+const char *ChildrenString(unsigned Children);
+
+/// AttributeString - Return the string for the specified attribute.
+///
+const char *AttributeString(unsigned Attribute);
+
+/// FormEncodingString - Return the string for the specified form encoding.
+///
+const char *FormEncodingString(unsigned Encoding);
+
+/// OperationEncodingString - Return the string for the specified operation
+/// encoding.
+const char *OperationEncodingString(unsigned Encoding);
+
+/// AttributeEncodingString - Return the string for the specified attribute
+/// encoding.
+const char *AttributeEncodingString(unsigned Encoding);
+
+/// DecimalSignString - Return the string for the specified decimal sign
+/// attribute.
+const char *DecimalSignString(unsigned Sign);
+
+/// EndianityString - Return the string for the specified endianity.
+///
+const char *EndianityString(unsigned Endian);
+
+/// AccessibilityString - Return the string for the specified accessibility.
+///
+const char *AccessibilityString(unsigned Access);
+
+/// VisibilityString - Return the string for the specified visibility.
+///
+const char *VisibilityString(unsigned Visibility);
+
+/// VirtualityString - Return the string for the specified virtuality.
+///
+const char *VirtualityString(unsigned Virtuality);
+
+/// LanguageString - Return the string for the specified language.
+///
+const char *LanguageString(unsigned Language);
+
+/// CaseString - Return the string for the specified identifier case.
+///
+const char *CaseString(unsigned Case);
+
+/// ConventionString - Return the string for the specified calling convention.
+///
+const char *ConventionString(unsigned Convention);
+
+/// InlineCodeString - Return the string for the specified inline code.
+///
+const char *InlineCodeString(unsigned Code);
+
+/// ArrayOrderString - Return the string for the specified array order.
+///
+const char *ArrayOrderString(unsigned Order);
+
+/// DiscriminantString - Return the string for the specified discriminant
+/// descriptor.
+const char *DiscriminantString(unsigned Discriminant);
+
+/// LNStandardString - Return the string for the specified line number standard.
+///
+const char *LNStandardString(unsigned Standard);
+
+/// LNExtendedString - Return the string for the specified line number extended
+/// opcode encodings.
+const char *LNExtendedString(unsigned Encoding);
+
+/// MacinfoString - Return the string for the specified macinfo type encodings.
+///
+const char *MacinfoString(unsigned Encoding);
+
+/// CallFrameString - Return the string for the specified call frame instruction
+/// encodings.
+const char *CallFrameString(unsigned Encoding);
+
+} // End of namespace dwarf
+
+} // End of namespace llvm
+
+FORCE_DEFINING_FILE_TO_BE_LINKED(SupportDwarf)
+
+#endif
diff --git a/support/include/llvm/Support/DynamicLinker.h b/support/include/llvm/Support/DynamicLinker.h
new file mode 100644
index 0000000..e996b0f
--- /dev/null
+++ b/support/include/llvm/Support/DynamicLinker.h
@@ -0,0 +1,40 @@
+//===-- llvm/Support/DynamicLinker.h - Portable Dynamic Linker --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Lightweight interface to dynamic library linking and loading, and dynamic
+// symbol lookup functionality, in whatever form the operating system
+// provides it.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_DYNAMICLINKER_H
+#define LLVM_SUPPORT_DYNAMICLINKER_H
+
+#include <string>
+
+namespace llvm {
+
+/// LinkDynamicObject - Load the named file as a dynamic library
+/// and link it with the currently running process. Returns false
+/// on success, true if there is an error (and sets ErrorMessage
+/// if it is not NULL). Analogous to dlopen().
+///
+bool LinkDynamicObject (const char *filename, std::string *ErrorMessage);
+
+/// GetAddressOfSymbol - Returns the address of the named symbol in
+/// the currently running process, as reported by the dynamic linker,
+/// or NULL if the symbol does not exist or some other error has
+/// occurred.
+///
+void *GetAddressOfSymbol (const char *symbolName);
+void *GetAddressOfSymbol (const std::string &symbolName);
+
+} // End llvm namespace
+
+#endif // SUPPORT_DYNAMICLINKER_H
diff --git a/support/include/llvm/Support/ELF.h b/support/include/llvm/Support/ELF.h
new file mode 100644
index 0000000..cd811f2
--- /dev/null
+++ b/support/include/llvm/Support/ELF.h
@@ -0,0 +1,300 @@
+//===-- llvm/Support/ELF.h - ELF constants and data structures --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header contains common, non-processor-specific data structures and
+// constants for the ELF file format.
+//
+// The details of the ELF32 bits in this file are largely based on
+// the Tool Interface Standard (TIS) Executable and Linking Format
+// (ELF) Specification Version 1.2, May 1995. The ELF64 stuff is not
+// standardized, as far as I can tell. It was largely based on information
+// I found in OpenBSD header files.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_ELF_H
+#define LLVM_SUPPORT_ELF_H
+
+#include "llvm/Support/DataTypes.h"
+#include <cstring>
+#include <cstdlib>
+
+namespace llvm {
+
+namespace ELF {
+
+typedef uint32_t Elf32_Addr; // Program address
+typedef uint16_t Elf32_Half;
+typedef uint32_t Elf32_Off; // File offset
+typedef int32_t Elf32_Sword;
+typedef uint32_t Elf32_Word;
+
+typedef uint64_t Elf64_Addr;
+typedef uint64_t Elf64_Off;
+typedef int32_t Elf64_Shalf;
+typedef int32_t Elf64_Sword;
+typedef uint32_t Elf64_Word;
+typedef int64_t Elf64_Sxword;
+typedef uint64_t Elf64_Xword;
+typedef uint32_t Elf64_Half;
+typedef uint16_t Elf64_Quarter;
+
+// Object file magic string.
+static const char ElfMagic[] = { 0x7f, 'E', 'L', 'F', '\0' };
+
+struct Elf32_Ehdr {
+ unsigned char e_ident[16]; // ELF Identification bytes
+ Elf32_Half e_type; // Type of file (see ET_* below)
+ Elf32_Half e_machine; // Required architecture for this file (see EM_*)
+ Elf32_Word e_version; // Must be equal to 1
+ Elf32_Addr e_entry; // Address to jump to in order to start program
+ Elf32_Off e_phoff; // Program header table's file offset, in bytes
+ Elf32_Off e_shoff; // Section header table's file offset, in bytes
+ Elf32_Word e_flags; // Processor-specific flags
+ Elf32_Half e_ehsize; // Size of ELF header, in bytes
+ Elf32_Half e_phentsize; // Size of an entry in the program header table
+ Elf32_Half e_phnum; // Number of entries in the program header table
+ Elf32_Half e_shentsize; // Size of an entry in the section header table
+ Elf32_Half e_shnum; // Number of entries in the section header table
+ Elf32_Half e_shstrndx; // Sect hdr table index of sect name string table
+ bool checkMagic () const {
+ return (memcmp (e_ident, ElfMagic, strlen (ElfMagic))) == 0;
+ }
+ unsigned char getFileClass () const { return e_ident[4]; }
+ unsigned char getDataEncoding () { return e_ident[5]; }
+};
+
+// 64-bit ELF header. Fields are the same as for ELF32, but with different
+// types (see above).
+struct Elf64_Ehdr {
+ unsigned char e_ident[16];
+ Elf64_Quarter e_type;
+ Elf64_Quarter e_machine;
+ Elf64_Half e_version;
+ Elf64_Addr e_entry;
+ Elf64_Off e_phoff;
+ Elf64_Off e_shoff;
+ Elf64_Half e_flags;
+ Elf64_Quarter e_ehsize;
+ Elf64_Quarter e_phentsize;
+ Elf64_Quarter e_phnum;
+ Elf64_Quarter e_shentsize;
+ Elf64_Quarter e_shnum;
+ Elf64_Quarter e_shstrndx;
+};
+
+// File types
+enum {
+ ET_NONE = 0, // No file type
+ ET_REL = 1, // Relocatable file
+ ET_EXEC = 2, // Executable file
+ ET_DYN = 3, // Shared object file
+ ET_CORE = 4, // Core file
+ ET_LOPROC = 0xff00, // Beginning of processor-specific codes
+ ET_HIPROC = 0xffff // Processor-specific
+};
+
+// Machine architectures
+enum {
+ EM_NONE = 0, // No machine
+ EM_M32 = 1, // AT&T WE 32100
+ EM_SPARC = 2, // SPARC
+ EM_386 = 3, // Intel 386
+ EM_68K = 4, // Motorola 68000
+ EM_88K = 5, // Motorola 88000
+ EM_486 = 6, // Intel 486 (deprecated)
+ EM_860 = 7, // Intel 80860
+ EM_MIPS = 8, // MIPS R3000
+ EM_PPC = 20, // PowerPC
+ EM_ARM = 40, // ARM
+ EM_ALPHA = 41, // DEC Alpha
+ EM_SPARCV9 = 43 // SPARC V9
+};
+
+// Object file classes.
+enum {
+ ELFCLASS32 = 1, // 32-bit object file
+ ELFCLASS64 = 2 // 64-bit object file
+};
+
+// Object file byte orderings.
+enum {
+ ELFDATA2LSB = 1, // Little-endian object file
+ ELFDATA2MSB = 2 // Big-endian object file
+};
+
+// Section header.
+struct Elf32_Shdr {
+ Elf32_Word sh_name; // Section name (index into string table)
+ Elf32_Word sh_type; // Section type (SHT_*)
+ Elf32_Word sh_flags; // Section flags (SHF_*)
+ Elf32_Addr sh_addr; // Address where section is to be loaded
+ Elf32_Off sh_offset; // File offset of section data, in bytes
+ Elf32_Word sh_size; // Size of section, in bytes
+ Elf32_Word sh_link; // Section type-specific header table index link
+ Elf32_Word sh_info; // Section type-specific extra information
+ Elf32_Word sh_addralign; // Section address alignment
+ Elf32_Word sh_entsize; // Size of records contained within the section
+};
+
+// Section header for ELF64 - same fields as ELF32, different types.
+struct Elf64_Shdr {
+ Elf64_Half sh_name;
+ Elf64_Half sh_type;
+ Elf64_Xword sh_flags;
+ Elf64_Addr sh_addr;
+ Elf64_Off sh_offset;
+ Elf64_Xword sh_size;
+ Elf64_Half sh_link;
+ Elf64_Half sh_info;
+ Elf64_Xword sh_addralign;
+ Elf64_Xword sh_entsize;
+};
+
+// Special section indices.
+enum {
+ SHN_UNDEF = 0, // Undefined, missing, irrelevant, or meaningless
+ SHN_LORESERVE = 0xff00, // Lowest reserved index
+ SHN_LOPROC = 0xff00, // Lowest processor-specific index
+ SHN_HIPROC = 0xff1f, // Highest processor-specific index
+ SHN_ABS = 0xfff1, // Symbol has absolute value; does not need relocation
+ SHN_COMMON = 0xfff2, // FORTRAN COMMON or C external global variables
+ SHN_HIRESERVE = 0xffff // Highest reserved index
+};
+
+// Section types.
+enum {
+ SHT_NULL = 0, // No associated section (inactive entry).
+ SHT_PROGBITS = 1, // Program-defined contents.
+ SHT_SYMTAB = 2, // Symbol table.
+ SHT_STRTAB = 3, // String table.
+ SHT_RELA = 4, // Relocation entries; explicit addends.
+ SHT_HASH = 5, // Symbol hash table.
+ SHT_DYNAMIC = 6, // Information for dynamic linking.
+ SHT_NOTE = 7, // Information about the file.
+ SHT_NOBITS = 8, // Data occupies no space in the file.
+ SHT_REL = 9, // Relocation entries; no explicit addends.
+ SHT_SHLIB = 10, // Reserved.
+ SHT_DYNSYM = 11, // Symbol table.
+ SHT_LOPROC = 0x70000000, // Lowest processor architecture-specific type.
+ SHT_HIPROC = 0x7fffffff, // Highest processor architecture-specific type.
+ SHT_LOUSER = 0x80000000, // Lowest type reserved for applications.
+ SHT_HIUSER = 0xffffffff // Highest type reserved for applications.
+};
+
+// Section flags.
+enum {
+ SHF_WRITE = 0x1, // Section data should be writable during execution.
+ SHF_ALLOC = 0x2, // Section occupies memory during program execution.
+ SHF_EXECINSTR = 0x4, // Section contains executable machine instructions.
+ SHF_MASKPROC = 0xf0000000 // Bits indicating processor-specific flags.
+};
+
+// Symbol table entries.
+struct Elf32_Sym {
+ Elf32_Word st_name; // Symbol name (index into string table)
+ Elf32_Addr st_value; // Value or address associated with the symbol
+ Elf32_Word st_size; // Size of the symbol
+ unsigned char st_info; // Symbol's type and binding attributes
+ unsigned char st_other; // Must be zero; reserved
+ Elf32_Half st_shndx; // Which section (header table index) it's defined in
+
+ // These accessors and mutators correspond to the ELF32_ST_BIND,
+ // ELF32_ST_TYPE, and ELF32_ST_INFO macros defined in the ELF specification:
+ unsigned char getBinding () const { return st_info >> 4; }
+ unsigned char getType () const { return st_info & 0x0f; }
+ void setBinding (unsigned char b) { setBindingAndType (b, getType ()); }
+ void setType (unsigned char t) { setBindingAndType (getBinding (), t); }
+ void setBindingAndType (unsigned char b, unsigned char t) {
+ st_info = (b << 4) + (t & 0x0f);
+ }
+};
+
+// Symbol bindings.
+enum {
+ STB_LOCAL = 0, // Local symbol, not visible outside obj file containing def
+ STB_GLOBAL = 1, // Global symbol, visible to all object files being combined
+ STB_WEAK = 2, // Weak symbol, like global but lower-precedence
+ STB_LOPROC = 13, // Lowest processor-specific binding type
+ STB_HIPROC = 15 // Highest processor-specific binding type
+};
+
+// Symbol types.
+enum {
+ STT_NOTYPE = 0, // Symbol's type is not specified
+ STT_OBJECT = 1, // Symbol is a data object (variable, array, etc.)
+ STT_FUNC = 2, // Symbol is executable code (function, etc.)
+ STT_SECTION = 3, // Symbol refers to a section
+ STT_FILE = 4, // Local, absolute symbol that refers to a file
+ STT_LOPROC = 13, // Lowest processor-specific symbol type
+ STT_HIPROC = 15 // Highest processor-specific symbol type
+};
+
+// Relocation entry, without explicit addend.
+struct Elf32_Rel {
+ Elf32_Addr r_offset; // Location (file byte offset, or program virtual addr)
+ Elf32_Word r_info; // Symbol table index and type of relocation to apply
+
+ // These accessors and mutators correspond to the ELF32_R_SYM, ELF32_R_TYPE,
+ // and ELF32_R_INFO macros defined in the ELF specification:
+ Elf32_Word getSymbol () const { return (r_info >> 8); }
+ unsigned char getType () const { return (unsigned char) (r_info & 0x0ff); }
+ void setSymbol (Elf32_Word s) { setSymbolAndType (s, getType ()); }
+ void setType (unsigned char t) { setSymbolAndType (getSymbol(), t); }
+ void setSymbolAndType (Elf32_Word s, unsigned char t) {
+ r_info = (s << 8) + t;
+ };
+};
+
+// Relocation entry with explicit addend.
+struct Elf32_Rela {
+ Elf32_Addr r_offset; // Location (file byte offset, or program virtual addr)
+ Elf32_Word r_info; // Symbol table index and type of relocation to apply
+ Elf32_Sword r_addend; // Compute value for relocatable field by adding this
+
+ // These accessors and mutators correspond to the ELF32_R_SYM, ELF32_R_TYPE,
+ // and ELF32_R_INFO macros defined in the ELF specification:
+ Elf32_Word getSymbol () const { return (r_info >> 8); }
+ unsigned char getType () const { return (unsigned char) (r_info & 0x0ff); }
+ void setSymbol (Elf32_Word s) { setSymbolAndType (s, getType ()); }
+ void setType (unsigned char t) { setSymbolAndType (getSymbol(), t); }
+ void setSymbolAndType (Elf32_Word s, unsigned char t) {
+ r_info = (s << 8) + t;
+ };
+};
+
+// Program header.
+struct Elf32_Phdr {
+ Elf32_Word p_type; // Type of segment
+ Elf32_Off p_offset; // File offset where segment is located, in bytes
+ Elf32_Addr p_vaddr; // Virtual address of beginning of segment
+ Elf32_Addr p_paddr; // Physical address of beginning of segment (OS-specific)
+ Elf32_Word p_filesz; // Num. of bytes in file image of segment (may be zero)
+ Elf32_Word p_memsz; // Num. of bytes in mem image of segment (may be zero)
+ Elf32_Word p_flags; // Segment flags
+ Elf32_Word p_align; // Segment alignment constraint
+};
+
+enum {
+ PT_NULL = 0, // Unused segment.
+ PT_LOAD = 1, // Loadable segment.
+ PT_DYNAMIC = 2, // Dynamic linking information.
+ PT_INTERP = 3, // Interpreter pathname.
+ PT_NOTE = 4, // Auxiliary information.
+ PT_SHLIB = 5, // Reserved.
+ PT_PHDR = 6, // The program header table itself.
+ PT_LOPROC = 0x70000000, // Lowest processor-specific program hdr entry type.
+ PT_HIPROC = 0x7fffffff // Highest processor-specific program hdr entry type.
+};
+
+} // end namespace ELF
+
+} // end namespace llvm
+
+#endif
diff --git a/support/include/llvm/Support/FileUtilities.h b/support/include/llvm/Support/FileUtilities.h
new file mode 100644
index 0000000..950516d
--- /dev/null
+++ b/support/include/llvm/Support/FileUtilities.h
@@ -0,0 +1,59 @@
+//===- llvm/Support/FileUtilities.h - File System Utilities -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines a family of utility functions which are useful for doing
+// various things with files.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_FILEUTILITIES_H
+#define LLVM_SUPPORT_FILEUTILITIES_H
+
+#include "llvm/System/Path.h"
+
+namespace llvm {
+
+ /// DiffFilesWithTolerance - Compare the two files specified, returning 0 if
+ /// the files match, 1 if they are different, and 2 if there is a file error.
+ /// This function allows you to specify an absolete and relative FP error that
+ /// is allowed to exist. If you specify a string to fill in for the error
+ /// 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,
+ double AbsTol, double RelTol,
+ std::string *Error = 0);
+
+
+ /// FileRemover - This class is a simple object meant to be stack allocated.
+ /// If an exception is thrown from a region, the object removes the filename
+ /// specified (if deleteIt is true).
+ ///
+ class FileRemover {
+ sys::Path Filename;
+ bool DeleteIt;
+ public:
+ explicit FileRemover(const sys::Path &filename, bool deleteIt = true)
+ : Filename(filename), DeleteIt(deleteIt) {}
+
+ ~FileRemover() {
+ if (DeleteIt) {
+ // Ignore problems deleting the file.
+ Filename.eraseFromDisk();
+ }
+ }
+
+ /// releaseFile - Take ownership of the file away from the FileRemover so it
+ /// will not be removed when the object is destroyed.
+ void releaseFile() { DeleteIt = false; }
+ };
+} // End llvm namespace
+
+#endif
diff --git a/support/include/llvm/Support/GetElementPtrTypeIterator.h b/support/include/llvm/Support/GetElementPtrTypeIterator.h
new file mode 100644
index 0000000..846332e
--- /dev/null
+++ b/support/include/llvm/Support/GetElementPtrTypeIterator.h
@@ -0,0 +1,112 @@
+//===- llvm/Support/GetElementPtrTypeIterator.h -----------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements an iterator for walking through the types indexed by
+// getelementptr instructions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_GETELEMENTPTRTYPE_H
+#define LLVM_SUPPORT_GETELEMENTPTRTYPE_H
+
+#include "llvm/User.h"
+#include "llvm/DerivedTypes.h"
+
+namespace llvm {
+ template<typename ItTy = User::const_op_iterator>
+ class generic_gep_type_iterator
+ : public forward_iterator<const Type *, ptrdiff_t> {
+ typedef forward_iterator<const Type*, ptrdiff_t> super;
+
+ ItTy OpIt;
+ const Type *CurTy;
+ generic_gep_type_iterator() {}
+ public:
+
+ static generic_gep_type_iterator begin(const Type *Ty, ItTy It) {
+ generic_gep_type_iterator I;
+ I.CurTy = Ty;
+ I.OpIt = It;
+ return I;
+ }
+ static generic_gep_type_iterator end(ItTy It) {
+ generic_gep_type_iterator I;
+ I.CurTy = 0;
+ I.OpIt = It;
+ return I;
+ }
+
+ bool operator==(const generic_gep_type_iterator& x) const {
+ return OpIt == x.OpIt;
+ }
+ bool operator!=(const generic_gep_type_iterator& x) const {
+ return !operator==(x);
+ }
+
+ const Type *operator*() const {
+ return CurTy;
+ }
+
+ const Type *getIndexedType() const {
+ const CompositeType *CT = cast<CompositeType>(CurTy);
+ return CT->getTypeAtIndex(getOperand());
+ }
+
+ // This is a non-standard operator->. It allows you to call methods on the
+ // current type directly.
+ const Type *operator->() const { return operator*(); }
+
+ Value *getOperand() const { return *OpIt; }
+
+ generic_gep_type_iterator& operator++() { // Preincrement
+ if (const CompositeType *CT = dyn_cast<CompositeType>(CurTy)) {
+ CurTy = CT->getTypeAtIndex(getOperand());
+ } else {
+ CurTy = 0;
+ }
+ ++OpIt;
+ return *this;
+ }
+
+ generic_gep_type_iterator operator++(int) { // Postincrement
+ generic_gep_type_iterator tmp = *this; ++*this; return tmp;
+ }
+ };
+
+ typedef generic_gep_type_iterator<> gep_type_iterator;
+
+ inline gep_type_iterator gep_type_begin(const User *GEP) {
+ return gep_type_iterator::begin(GEP->getOperand(0)->getType(),
+ GEP->op_begin()+1);
+ }
+ inline gep_type_iterator gep_type_end(const User *GEP) {
+ return gep_type_iterator::end(GEP->op_end());
+ }
+ inline gep_type_iterator gep_type_begin(const User &GEP) {
+ return gep_type_iterator::begin(GEP.getOperand(0)->getType(),
+ GEP.op_begin()+1);
+ }
+ inline gep_type_iterator gep_type_end(const User &GEP) {
+ return gep_type_iterator::end(GEP.op_end());
+ }
+
+ template<typename ItTy>
+ inline generic_gep_type_iterator<ItTy>
+ gep_type_begin(const Type *Op0, ItTy I, ItTy E) {
+ return generic_gep_type_iterator<ItTy>::begin(Op0, I);
+ }
+
+ template<typename ItTy>
+ inline generic_gep_type_iterator<ItTy>
+ gep_type_end(const Type *Op0, ItTy I, ItTy E) {
+ return generic_gep_type_iterator<ItTy>::end(E);
+ }
+} // end namespace llvm
+
+#endif
diff --git a/support/include/llvm/Support/GraphWriter.h b/support/include/llvm/Support/GraphWriter.h
new file mode 100644
index 0000000..85cf718
--- /dev/null
+++ b/support/include/llvm/Support/GraphWriter.h
@@ -0,0 +1,312 @@
+//===-- llvm/Support/GraphWriter.h - Write graph to a .dot file -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines a simple interface that can be used to print out generic
+// LLVM graphs to ".dot" files. "dot" is a tool that is part of the AT&T
+// graphviz package (http://www.research.att.com/sw/tools/graphviz/) which can
+// be used to turn the files output by this interface into a variety of
+// different graphics formats.
+//
+// Graphs do not need to implement any interface past what is already required
+// by the GraphTraits template, but they can choose to implement specializations
+// of the DOTGraphTraits template if they want to customize the graphs output in
+// any way.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_GRAPHWRITER_H
+#define LLVM_SUPPORT_GRAPHWRITER_H
+
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/DOTGraphTraits.h"
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/System/Path.h"
+#include <fstream>
+#include <vector>
+
+namespace llvm {
+
+namespace DOT { // Private functions...
+ inline std::string EscapeString(const std::string &Label) {
+ std::string Str(Label);
+ for (unsigned i = 0; i != Str.length(); ++i)
+ switch (Str[i]) {
+ case '\n':
+ Str.insert(Str.begin()+i, '\\'); // Escape character...
+ ++i;
+ Str[i] = 'n';
+ break;
+ case '\t':
+ Str.insert(Str.begin()+i, ' '); // Convert to two spaces
+ ++i;
+ Str[i] = ' ';
+ break;
+ case '\\':
+ if (i+1 != Str.length() && Str[i+1] == 'l')
+ break; // don't disturb \l
+ case '{': case '}':
+ case '<': case '>':
+ case '|': case '"':
+ Str.insert(Str.begin()+i, '\\'); // Escape character...
+ ++i; // don't infinite loop
+ break;
+ }
+ return Str;
+ }
+}
+
+void DisplayGraph(const sys::Path& Filename);
+
+template<typename GraphType>
+class GraphWriter {
+ std::ostream &O;
+ const GraphType &G;
+
+ typedef DOTGraphTraits<GraphType> DOTTraits;
+ typedef GraphTraits<GraphType> GTraits;
+ typedef typename GTraits::NodeType NodeType;
+ typedef typename GTraits::nodes_iterator node_iterator;
+ typedef typename GTraits::ChildIteratorType child_iterator;
+public:
+ GraphWriter(std::ostream &o, const GraphType &g) : O(o), G(g) {}
+
+ void writeHeader(const std::string &Name) {
+ if (Name.empty())
+ O << "digraph foo {\n"; // Graph name doesn't matter
+ else
+ O << "digraph " << Name << " {\n";
+
+ if (DOTTraits::renderGraphFromBottomUp())
+ O << "\trankdir=\"BT\";\n";
+
+ std::string GraphName = DOTTraits::getGraphName(G);
+ if (!GraphName.empty())
+ O << "\tlabel=\"" << DOT::EscapeString(GraphName) << "\";\n";
+ O << DOTTraits::getGraphProperties(G);
+ O << "\n";
+ }
+
+ void writeFooter() {
+ // Finish off the graph
+ O << "}\n";
+ }
+
+ void writeNodes() {
+ // Loop over the graph, printing it out...
+ for (node_iterator I = GTraits::nodes_begin(G), E = GTraits::nodes_end(G);
+ I != E; ++I)
+ writeNode(*I);
+ }
+
+ void writeNode(NodeType& Node) {
+ writeNode(&Node);
+ }
+
+ void writeNode(NodeType *const *Node) {
+ writeNode(*Node);
+ }
+
+ void writeNode(NodeType *Node) {
+ std::string NodeAttributes = DOTTraits::getNodeAttributes(Node, G);
+
+ O << "\tNode" << reinterpret_cast<const void*>(Node) << " [shape=record,";
+ if (!NodeAttributes.empty()) O << NodeAttributes << ",";
+ O << "label=\"{";
+
+ if (!DOTTraits::renderGraphFromBottomUp()) {
+ O << DOT::EscapeString(DOTTraits::getNodeLabel(Node, G));
+
+ // If we should include the address of the node in the label, do so now.
+ if (DOTTraits::hasNodeAddressLabel(Node, G))
+ O << "|" << (void*)Node;
+ }
+
+ // Print out the fields of the current node...
+ child_iterator EI = GTraits::child_begin(Node);
+ child_iterator EE = GTraits::child_end(Node);
+ if (EI != EE) {
+ if (!DOTTraits::renderGraphFromBottomUp()) O << "|";
+ O << "{";
+
+ for (unsigned i = 0; EI != EE && i != 64; ++EI, ++i) {
+ if (i) O << "|";
+ O << "<g" << i << ">" << DOTTraits::getEdgeSourceLabel(Node, EI);
+ }
+
+ if (EI != EE)
+ O << "|<g64>truncated...";
+ O << "}";
+ if (DOTTraits::renderGraphFromBottomUp()) O << "|";
+ }
+
+ if (DOTTraits::renderGraphFromBottomUp()) {
+ O << DOT::EscapeString(DOTTraits::getNodeLabel(Node, G));
+
+ // If we should include the address of the node in the label, do so now.
+ if (DOTTraits::hasNodeAddressLabel(Node, G))
+ O << "|" << (void*)Node;
+ }
+
+ O << "}\"];\n"; // Finish printing the "node" line
+
+ // Output all of the edges now
+ EI = GTraits::child_begin(Node);
+ for (unsigned i = 0; EI != EE && i != 64; ++EI, ++i)
+ writeEdge(Node, i, EI);
+ for (; EI != EE; ++EI)
+ writeEdge(Node, 64, EI);
+ }
+
+ void writeEdge(NodeType *Node, unsigned edgeidx, child_iterator EI) {
+ if (NodeType *TargetNode = *EI) {
+ int DestPort = -1;
+ if (DOTTraits::edgeTargetsEdgeSource(Node, EI)) {
+ child_iterator TargetIt = DOTTraits::getEdgeTarget(Node, EI);
+
+ // Figure out which edge this targets...
+ unsigned Offset = std::distance(GTraits::child_begin(TargetNode),
+ TargetIt);
+ DestPort = static_cast<int>(Offset);
+ }
+
+ emitEdge(reinterpret_cast<const void*>(Node), edgeidx,
+ reinterpret_cast<const void*>(TargetNode), DestPort,
+ DOTTraits::getEdgeAttributes(Node, EI));
+ }
+ }
+
+ /// emitSimpleNode - Outputs a simple (non-record) node
+ void emitSimpleNode(const void *ID, const std::string &Attr,
+ const std::string &Label, unsigned NumEdgeSources = 0,
+ const std::vector<std::string> *EdgeSourceLabels = 0) {
+ O << "\tNode" << ID << "[ ";
+ if (!Attr.empty())
+ O << Attr << ",";
+ O << " label =\"";
+ if (NumEdgeSources) O << "{";
+ O << DOT::EscapeString(Label);
+ if (NumEdgeSources) {
+ O << "|{";
+
+ for (unsigned i = 0; i != NumEdgeSources; ++i) {
+ if (i) O << "|";
+ O << "<g" << i << ">";
+ if (EdgeSourceLabels) O << (*EdgeSourceLabels)[i];
+ }
+ O << "}}";
+ }
+ O << "\"];\n";
+ }
+
+ /// emitEdge - Output an edge from a simple node into the graph...
+ void emitEdge(const void *SrcNodeID, int SrcNodePort,
+ const void *DestNodeID, int DestNodePort,
+ const std::string &Attrs) {
+ if (SrcNodePort > 64) return; // Eminating from truncated part?
+ if (DestNodePort > 64) DestNodePort = 64; // Targetting the truncated part?
+
+ O << "\tNode" << SrcNodeID;
+ if (SrcNodePort >= 0)
+ O << ":g" << SrcNodePort;
+ O << " -> Node" << reinterpret_cast<const void*>(DestNodeID);
+ if (DestNodePort >= 0)
+ O << ":g" << DestNodePort;
+
+ if (!Attrs.empty())
+ O << "[" << Attrs << "]";
+ O << ";\n";
+ }
+};
+
+template<typename GraphType>
+std::ostream &WriteGraph(std::ostream &O, const GraphType &G,
+ const std::string &Name = "") {
+ // Start the graph emission process...
+ GraphWriter<GraphType> W(O, G);
+
+ // Output the header for the graph...
+ W.writeHeader(Name);
+
+ // Emit all of the nodes in the graph...
+ W.writeNodes();
+
+ // Output any customizations on the graph
+ DOTGraphTraits<GraphType>::addCustomGraphFeatures(G, W);
+
+ // Output the end of the graph
+ W.writeFooter();
+ return O;
+}
+
+template<typename GraphType>
+sys::Path WriteGraph(const GraphType &G,
+ const std::string& Name,
+ const std::string& Title = "") {
+ std::string ErrMsg;
+ sys::Path Filename = sys::Path::GetTemporaryDirectory(&ErrMsg);
+ if (Filename.isEmpty()) {
+ cerr << "Error: " << ErrMsg << "\n";
+ return Filename;
+ }
+ Filename.appendComponent(Name + ".dot");
+ if (Filename.makeUnique(true,&ErrMsg)) {
+ cerr << "Error: " << ErrMsg << "\n";
+ return sys::Path();
+ }
+
+ cerr << "Writing '" << Filename << "'... ";
+
+ std::ofstream O(Filename.c_str());
+
+ if (O.good()) {
+ // Start the graph emission process...
+ GraphWriter<GraphType> W(O, G);
+
+ // Output the header for the graph...
+ W.writeHeader(Title);
+
+ // Emit all of the nodes in the graph...
+ W.writeNodes();
+
+ // Output any customizations on the graph
+ DOTGraphTraits<GraphType>::addCustomGraphFeatures(G, W);
+
+ // Output the end of the graph
+ W.writeFooter();
+ cerr << " done. \n";
+
+ O.close();
+
+ } else {
+ cerr << "error opening file for writing!\n";
+ Filename.clear();
+ }
+
+ return Filename;
+}
+
+/// ViewGraph - Emit a dot graph, run 'dot', run gv on the postscript file,
+/// then cleanup. For use from the debugger.
+///
+template<typename GraphType>
+void ViewGraph(const GraphType& G,
+ const std::string& Name,
+ const std::string& Title = "") {
+ sys::Path Filename = WriteGraph(G, Name, Title);
+
+ if (Filename.isEmpty()) {
+ return;
+ }
+
+ DisplayGraph(Filename);
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/support/include/llvm/Support/InstIterator.h b/support/include/llvm/Support/InstIterator.h
new file mode 100644
index 0000000..6f3a45e
--- /dev/null
+++ b/support/include/llvm/Support/InstIterator.h
@@ -0,0 +1,147 @@
+//===- llvm/Support/InstIterator.h - Classes for inst iteration -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains definitions of two iterators for iterating over the
+// instructions in a function. This is effectively a wrapper around a two level
+// iterator that can probably be genericized later.
+//
+// Note that this iterator gets invalidated any time that basic blocks or
+// instructions are moved around.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_INSTITERATOR_H
+#define LLVM_SUPPORT_INSTITERATOR_H
+
+#include "llvm/BasicBlock.h"
+#include "llvm/Function.h"
+
+namespace llvm {
+
+// This class implements inst_begin() & inst_end() for
+// inst_iterator and const_inst_iterator's.
+//
+template <class _BB_t, class _BB_i_t, class _BI_t, class _II_t>
+class InstIterator {
+ typedef _BB_t BBty;
+ typedef _BB_i_t BBIty;
+ typedef _BI_t BIty;
+ typedef _II_t IIty;
+ _BB_t *BBs; // BasicBlocksType
+ _BB_i_t BB; // BasicBlocksType::iterator
+ _BI_t BI; // BasicBlock::iterator
+public:
+ typedef std::bidirectional_iterator_tag iterator_category;
+ typedef IIty value_type;
+ typedef signed difference_type;
+ typedef IIty* pointer;
+ typedef IIty& reference;
+
+ // Default constructor
+ InstIterator() {}
+
+ // Copy constructor...
+ template<typename A, typename B, typename C, typename D>
+ InstIterator(const InstIterator<A,B,C,D> &II)
+ : BBs(II.BBs), BB(II.BB), BI(II.BI) {}
+
+ template<typename A, typename B, typename C, typename D>
+ InstIterator(InstIterator<A,B,C,D> &II)
+ : BBs(II.BBs), BB(II.BB), BI(II.BI) {}
+
+ template<class M> InstIterator(M &m)
+ : BBs(&m.getBasicBlockList()), BB(BBs->begin()) { // begin ctor
+ if (BB != BBs->end()) {
+ BI = BB->begin();
+ advanceToNextBB();
+ }
+ }
+
+ template<class M> InstIterator(M &m, bool)
+ : BBs(&m.getBasicBlockList()), BB(BBs->end()) { // end ctor
+ }
+
+ // Accessors to get at the underlying iterators...
+ inline BBIty &getBasicBlockIterator() { return BB; }
+ inline BIty &getInstructionIterator() { return BI; }
+
+ inline reference operator*() const { return *BI; }
+ inline pointer operator->() const { return &operator*(); }
+
+ inline bool operator==(const InstIterator &y) const {
+ return BB == y.BB && (BB == BBs->end() || BI == y.BI);
+ }
+ inline bool operator!=(const InstIterator& y) const {
+ return !operator==(y);
+ }
+
+ InstIterator& operator++() {
+ ++BI;
+ advanceToNextBB();
+ return *this;
+ }
+ inline InstIterator operator++(int) {
+ InstIterator tmp = *this; ++*this; return tmp;
+ }
+
+ InstIterator& operator--() {
+ while (BB == BBs->end() || BI == BB->begin()) {
+ --BB;
+ BI = BB->end();
+ }
+ --BI;
+ return *this;
+ }
+ inline InstIterator operator--(int) {
+ InstIterator tmp = *this; --*this; return tmp;
+ }
+
+ inline bool atEnd() const { return BB == BBs->end(); }
+
+private:
+ inline void advanceToNextBB() {
+ // The only way that the II could be broken is if it is now pointing to
+ // the end() of the current BasicBlock and there are successor BBs.
+ while (BI == BB->end()) {
+ ++BB;
+ if (BB == BBs->end()) break;
+ BI = BB->begin();
+ }
+ }
+};
+
+
+typedef InstIterator<iplist<BasicBlock>,
+ Function::iterator, BasicBlock::iterator,
+ Instruction> inst_iterator;
+typedef InstIterator<const iplist<BasicBlock>,
+ Function::const_iterator,
+ BasicBlock::const_iterator,
+ const Instruction> const_inst_iterator;
+
+inline inst_iterator inst_begin(Function *F) { return inst_iterator(*F); }
+inline inst_iterator inst_end(Function *F) { return inst_iterator(*F, true); }
+inline const_inst_iterator inst_begin(const Function *F) {
+ return const_inst_iterator(*F);
+}
+inline const_inst_iterator inst_end(const Function *F) {
+ return const_inst_iterator(*F, true);
+}
+inline inst_iterator inst_begin(Function &F) { return inst_iterator(F); }
+inline inst_iterator inst_end(Function &F) { return inst_iterator(F, true); }
+inline const_inst_iterator inst_begin(const Function &F) {
+ return const_inst_iterator(F);
+}
+inline const_inst_iterator inst_end(const Function &F) {
+ return const_inst_iterator(F, true);
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/support/include/llvm/Support/InstVisitor.h b/support/include/llvm/Support/InstVisitor.h
new file mode 100644
index 0000000..e848c9b
--- /dev/null
+++ b/support/include/llvm/Support/InstVisitor.h
@@ -0,0 +1,221 @@
+//===- llvm/Support/InstVisitor.h - Define instruction visitors -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+#ifndef LLVM_SUPPORT_INSTVISITOR_H
+#define LLVM_SUPPORT_INSTVISITOR_H
+
+#include "llvm/Function.h"
+#include "llvm/Instructions.h"
+#include "llvm/Module.h"
+
+namespace llvm {
+
+// We operate on opaque instruction classes, so forward declare all instruction
+// types now...
+//
+#define HANDLE_INST(NUM, OPCODE, CLASS) class CLASS;
+#include "llvm/Instruction.def"
+
+// Forward declare the intermediate types...
+class TerminatorInst; class BinaryOperator;
+class AllocationInst;
+
+#define DELEGATE(CLASS_TO_VISIT) \
+ return static_cast<SubClass*>(this)-> \
+ visit##CLASS_TO_VISIT(static_cast<CLASS_TO_VISIT&>(I))
+
+
+/// @brief Base class for instruction visitors
+///
+/// Instruction visitors are used when you want to perform different action for
+/// different kinds of instruction without without having to use lots of casts
+/// and a big switch statement (in your code that is).
+///
+/// To define your own visitor, inherit from this class, specifying your
+/// new type for the 'SubClass' template parameter, and "override" visitXXX
+/// functions in your class. I say "overriding" because this class is defined
+/// in terms of statically resolved overloading, not virtual functions.
+///
+/// For example, here is a visitor that counts the number of malloc
+/// instructions processed:
+///
+/// /// Declare the class. Note that we derive from InstVisitor instantiated
+/// /// with _our new subclasses_ type.
+/// ///
+/// struct CountMallocVisitor : public InstVisitor<CountMallocVisitor> {
+/// unsigned Count;
+/// CountMallocVisitor() : Count(0) {}
+///
+/// void visitMallocInst(MallocInst &MI) { ++Count; }
+/// };
+///
+/// And this class would be used like this:
+/// CountMallocVistor CMV;
+/// CMV.visit(function);
+/// NumMallocs = CMV.Count;
+///
+/// The defined has 'visit' methods for Instruction, and also for BasicBlock,
+/// Function, and Module, which recursively process all conained instructions.
+///
+/// Note that if you don't implement visitXXX for some instruction type,
+/// the visitXXX method for instruction superclass will be invoked. So
+/// if instructions are added in the future, they will be automatically
+/// supported, if you handle on of their superclasses.
+///
+/// The optional second template argument specifies the type that instruction
+/// visitation functions should return. If you specify this, you *MUST* provide
+/// an implementation of visitInstruction though!.
+///
+/// Note that this class is specifically designed as a template to avoid
+/// virtual function call overhead. Defining and using an InstVisitor is just
+/// as efficient as having your own switch statement over the instruction
+/// opcode.
+template<typename SubClass, typename RetTy=void>
+class InstVisitor {
+ //===--------------------------------------------------------------------===//
+ // Interface code - This is the public interface of the InstVisitor that you
+ // use to visit instructions...
+ //
+
+public:
+ // Generic visit method - Allow visitation to all instructions in a range
+ template<class Iterator>
+ void visit(Iterator Start, Iterator End) {
+ while (Start != End)
+ static_cast<SubClass*>(this)->visit(*Start++);
+ }
+
+ // Define visitors for functions and basic blocks...
+ //
+ void visit(Module &M) {
+ static_cast<SubClass*>(this)->visitModule(M);
+ visit(M.begin(), M.end());
+ }
+ void visit(Function &F) {
+ static_cast<SubClass*>(this)->visitFunction(F);
+ visit(F.begin(), F.end());
+ }
+ void visit(BasicBlock &BB) {
+ static_cast<SubClass*>(this)->visitBasicBlock(BB);
+ visit(BB.begin(), BB.end());
+ }
+
+ // Forwarding functions so that the user can visit with pointers AND refs.
+ void visit(Module *M) { visit(*M); }
+ void visit(Function *F) { visit(*F); }
+ void visit(BasicBlock *BB) { visit(*BB); }
+ RetTy visit(Instruction *I) { return visit(*I); }
+
+ // visit - Finally, code to visit an instruction...
+ //
+ RetTy visit(Instruction &I) {
+ switch (I.getOpcode()) {
+ default: assert(0 && "Unknown instruction type encountered!");
+ abort();
+ // Build the switch statement using the Instruction.def file...
+#define HANDLE_INST(NUM, OPCODE, CLASS) \
+ case Instruction::OPCODE: return \
+ static_cast<SubClass*>(this)-> \
+ visit##OPCODE(static_cast<CLASS&>(I));
+#include "llvm/Instruction.def"
+ }
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Visitation functions... these functions provide default fallbacks in case
+ // the user does not specify what to do for a particular instruction type.
+ // The default behavior is to generalize the instruction type to its subtype
+ // and try visiting the subtype. All of this should be inlined perfectly,
+ // because there are no virtual functions to get in the way.
+ //
+
+ // When visiting a module, function or basic block directly, these methods get
+ // called to indicate when transitioning into a new unit.
+ //
+ void visitModule (Module &M) {}
+ void visitFunction (Function &F) {}
+ void visitBasicBlock(BasicBlock &BB) {}
+
+ // Define instruction specific visitor functions that can be overridden to
+ // handle SPECIFIC instructions. These functions automatically define
+ // visitMul to proxy to visitBinaryOperator for instance in case the user does
+ // not need this generality.
+ //
+ // The one problem case we have to handle here though is that the PHINode
+ // class and opcode name are the exact same. Because of this, we cannot
+ // define visitPHINode (the inst version) to forward to visitPHINode (the
+ // generic version) without multiply defined symbols and recursion. To handle
+ // this, we do not autoexpand "Other" instructions, we do it manually.
+ //
+#define HANDLE_INST(NUM, OPCODE, CLASS) \
+ RetTy visit##OPCODE(CLASS &I) { DELEGATE(CLASS); }
+#include "llvm/Instruction.def"
+
+ // Specific Instruction type classes... note that all of the casts are
+ // necessary because we use the instruction classes as opaque types...
+ //
+ RetTy visitReturnInst(ReturnInst &I) { DELEGATE(TerminatorInst);}
+ RetTy visitBranchInst(BranchInst &I) { DELEGATE(TerminatorInst);}
+ RetTy visitSwitchInst(SwitchInst &I) { DELEGATE(TerminatorInst);}
+ RetTy visitInvokeInst(InvokeInst &I) { DELEGATE(TerminatorInst);}
+ RetTy visitUnwindInst(UnwindInst &I) { DELEGATE(TerminatorInst);}
+ RetTy visitUnreachableInst(UnreachableInst &I) { DELEGATE(TerminatorInst);}
+ RetTy visitICmpInst(ICmpInst &I) { DELEGATE(CmpInst);}
+ RetTy visitFCmpInst(FCmpInst &I) { DELEGATE(CmpInst);}
+ RetTy visitMallocInst(MallocInst &I) { DELEGATE(AllocationInst);}
+ RetTy visitAllocaInst(AllocaInst &I) { DELEGATE(AllocationInst);}
+ RetTy visitFreeInst(FreeInst &I) { DELEGATE(Instruction); }
+ RetTy visitLoadInst(LoadInst &I) { DELEGATE(Instruction); }
+ RetTy visitStoreInst(StoreInst &I) { DELEGATE(Instruction); }
+ RetTy visitGetElementPtrInst(GetElementPtrInst &I){ DELEGATE(Instruction); }
+ RetTy visitPHINode(PHINode &I) { DELEGATE(Instruction); }
+ RetTy visitTruncInst(TruncInst &I) { DELEGATE(CastInst); }
+ RetTy visitZExtInst(ZExtInst &I) { DELEGATE(CastInst); }
+ RetTy visitSExtInst(SExtInst &I) { DELEGATE(CastInst); }
+ RetTy visitFPTruncInst(FPTruncInst &I) { DELEGATE(CastInst); }
+ RetTy visitFPExtInst(FPExtInst &I) { DELEGATE(CastInst); }
+ RetTy visitFPToUIInst(FPToUIInst &I) { DELEGATE(CastInst); }
+ RetTy visitFPToSIInst(FPToSIInst &I) { DELEGATE(CastInst); }
+ RetTy visitUIToFPInst(UIToFPInst &I) { DELEGATE(CastInst); }
+ RetTy visitSIToFPInst(SIToFPInst &I) { DELEGATE(CastInst); }
+ RetTy visitPtrToIntInst(PtrToIntInst &I) { DELEGATE(CastInst); }
+ RetTy visitIntToPtrInst(IntToPtrInst &I) { DELEGATE(CastInst); }
+ RetTy visitBitCastInst(BitCastInst &I) { DELEGATE(CastInst); }
+ RetTy visitSelectInst(SelectInst &I) { DELEGATE(Instruction); }
+ RetTy visitCallInst(CallInst &I) { DELEGATE(Instruction); }
+ RetTy visitVAArgInst(VAArgInst &I) { DELEGATE(Instruction); }
+ RetTy visitExtractElementInst(ExtractElementInst &I) { DELEGATE(Instruction);}
+ RetTy visitInsertElementInst(InsertElementInst &I) { DELEGATE(Instruction); }
+ RetTy visitShuffleVectorInst(ShuffleVectorInst &I) { DELEGATE(Instruction); }
+
+ // Next level propagators... if the user does not overload a specific
+ // instruction type, they can overload one of these to get the whole class
+ // of instructions...
+ //
+ RetTy visitTerminatorInst(TerminatorInst &I) { DELEGATE(Instruction); }
+ RetTy visitBinaryOperator(BinaryOperator &I) { DELEGATE(Instruction); }
+ RetTy visitAllocationInst(AllocationInst &I) { DELEGATE(Instruction); }
+ RetTy visitCmpInst(CmpInst &I) { DELEGATE(Instruction); }
+ RetTy visitCastInst(CastInst &I) { DELEGATE(Instruction); }
+
+ // If the user wants a 'default' case, they can choose to override this
+ // function. If this function is not overloaded in the users subclass, then
+ // this instruction just gets ignored.
+ //
+ // Note that you MUST override this function if your return type is not void.
+ //
+ void visitInstruction(Instruction &I) {} // Ignore unhandled instructions
+};
+
+#undef DELEGATE
+
+} // End llvm namespace
+
+#endif
diff --git a/support/include/llvm/Support/LLVMBuilder.h b/support/include/llvm/Support/LLVMBuilder.h
new file mode 100644
index 0000000..fce601e
--- /dev/null
+++ b/support/include/llvm/Support/LLVMBuilder.h
@@ -0,0 +1,637 @@
+//===-- llvm/Support/LLVMBuilder.h - Builder for LLVM Instrs ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the LLVMBuilder class, which is used as a convenient way
+// to create LLVM instructions with a consistent and simplified interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_LLVMBUILDER_H
+#define LLVM_SUPPORT_LLVMBUILDER_H
+
+#include "llvm/BasicBlock.h"
+#include "llvm/Instructions.h"
+#include "llvm/Constants.h"
+
+namespace llvm {
+
+/// LLVMBuilder - This provides a uniform API for creating instructions and
+/// inserting them into a basic block: either at the end of a BasicBlock, or
+/// at a specific iterator location in a block.
+///
+/// Note that the builder does not expose the full generality of LLVM
+/// instructions. For example, it cannot be used to create instructions with
+/// arbitrary names (specifically, names with nul characters in them) - It only
+/// supports nul-terminated C strings. For fully generic names, use
+/// I->setName(). For access to extra instruction properties, use the mutators
+/// (e.g. setVolatile) on the instructions after they have been created.
+class LLVMBuilder {
+ BasicBlock *BB;
+ BasicBlock::iterator InsertPt;
+public:
+ LLVMBuilder() { ClearInsertionPoint(); }
+ explicit LLVMBuilder(BasicBlock *TheBB) { SetInsertPoint(TheBB); }
+ LLVMBuilder(BasicBlock *TheBB, BasicBlock::iterator IP) {
+ SetInsertPoint(TheBB, IP);
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Builder configuration methods
+ //===--------------------------------------------------------------------===//
+
+ /// ClearInsertionPoint - Clear the insertion point: created instructions will
+ /// not be inserted into a block.
+ void ClearInsertionPoint() {
+ BB = 0;
+ }
+
+ BasicBlock *GetInsertBlock() const { return BB; }
+
+ /// SetInsertPoint - This specifies that created instructions should be
+ /// appended to the end of the specified block.
+ void SetInsertPoint(BasicBlock *TheBB) {
+ BB = TheBB;
+ InsertPt = BB->end();
+ }
+
+ /// SetInsertPoint - This specifies that created instructions should be
+ /// inserted at the specified point.
+ void SetInsertPoint(BasicBlock *TheBB, BasicBlock::iterator IP) {
+ BB = TheBB;
+ InsertPt = IP;
+ }
+
+ /// Insert - Insert and return the specified instruction.
+ template<typename InstTy>
+ InstTy *Insert(InstTy *I) const {
+ InsertHelper(I);
+ return I;
+ }
+
+ /// InsertHelper - Insert the specified instruction at the specified insertion
+ /// point. This is split out of Insert so that it isn't duplicated for every
+ /// template instantiation.
+ void InsertHelper(Instruction *I) const {
+ if (BB) BB->getInstList().insert(InsertPt, I);
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Instruction creation methods: Terminators
+ //===--------------------------------------------------------------------===//
+
+ /// CreateRetVoid - Create a 'ret void' instruction.
+ ReturnInst *CreateRetVoid() {
+ return Insert(new ReturnInst());
+ }
+
+ /// @verbatim
+ /// CreateRet - Create a 'ret <val>' instruction.
+ /// @endverbatim
+ ReturnInst *CreateRet(Value *V) {
+ return Insert(new ReturnInst(V));
+ }
+
+ /// CreateBr - Create an unconditional 'br label X' instruction.
+ BranchInst *CreateBr(BasicBlock *Dest) {
+ return Insert(new BranchInst(Dest));
+ }
+
+ /// CreateCondBr - Create a conditional 'br Cond, TrueDest, FalseDest'
+ /// instruction.
+ BranchInst *CreateCondBr(Value *Cond, BasicBlock *True, BasicBlock *False) {
+ return Insert(new BranchInst(True, False, Cond));
+ }
+
+ /// CreateSwitch - Create a switch instruction with the specified value,
+ /// default dest, and with a hint for the number of cases that will be added
+ /// (for efficient allocation).
+ SwitchInst *CreateSwitch(Value *V, BasicBlock *Dest, unsigned NumCases = 10) {
+ return Insert(new SwitchInst(V, Dest, NumCases));
+ }
+
+ /// CreateInvoke - Create an invoke instruction.
+ template<typename InputIterator>
+ InvokeInst *CreateInvoke(Value *Callee, BasicBlock *NormalDest,
+ BasicBlock *UnwindDest, InputIterator ArgBegin,
+ InputIterator ArgEnd, const char *Name = "") {
+ return(Insert(new InvokeInst(Callee, NormalDest, UnwindDest,
+ ArgBegin, ArgEnd, Name)));
+ }
+
+ UnwindInst *CreateUnwind() {
+ return Insert(new UnwindInst());
+ }
+
+ UnreachableInst *CreateUnreachable() {
+ return Insert(new UnreachableInst());
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Instruction creation methods: Binary Operators
+ //===--------------------------------------------------------------------===//
+
+ BinaryOperator *CreateAdd(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(BinaryOperator::createAdd(LHS, RHS, Name));
+ }
+ BinaryOperator *CreateSub(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(BinaryOperator::createSub(LHS, RHS, Name));
+ }
+ BinaryOperator *CreateMul(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(BinaryOperator::createMul(LHS, RHS, Name));
+ }
+ BinaryOperator *CreateUDiv(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(BinaryOperator::createUDiv(LHS, RHS, Name));
+ }
+ BinaryOperator *CreateSDiv(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(BinaryOperator::createSDiv(LHS, RHS, Name));
+ }
+ BinaryOperator *CreateFDiv(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(BinaryOperator::createFDiv(LHS, RHS, Name));
+ }
+ BinaryOperator *CreateURem(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(BinaryOperator::createURem(LHS, RHS, Name));
+ }
+ BinaryOperator *CreateSRem(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(BinaryOperator::createSRem(LHS, RHS, Name));
+ }
+ BinaryOperator *CreateFRem(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(BinaryOperator::createFRem(LHS, RHS, Name));
+ }
+ BinaryOperator *CreateShl(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(BinaryOperator::createShl(LHS, RHS, Name));
+ }
+ BinaryOperator *CreateLShr(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(BinaryOperator::createLShr(LHS, RHS, Name));
+ }
+ BinaryOperator *CreateAShr(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(BinaryOperator::createAShr(LHS, RHS, Name));
+ }
+ BinaryOperator *CreateAnd(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(BinaryOperator::createAnd(LHS, RHS, Name));
+ }
+ BinaryOperator *CreateOr(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(BinaryOperator::createOr(LHS, RHS, Name));
+ }
+ BinaryOperator *CreateXor(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(BinaryOperator::createXor(LHS, RHS, Name));
+ }
+
+ BinaryOperator *CreateBinOp(Instruction::BinaryOps Opc,
+ Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(BinaryOperator::create(Opc, LHS, RHS, Name));
+ }
+
+ BinaryOperator *CreateNeg(Value *V, const char *Name = "") {
+ return Insert(BinaryOperator::createNeg(V, Name));
+ }
+ BinaryOperator *CreateNot(Value *V, const char *Name = "") {
+ return Insert(BinaryOperator::createNot(V, Name));
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Instruction creation methods: Memory Instructions
+ //===--------------------------------------------------------------------===//
+
+ MallocInst *CreateMalloc(const Type *Ty, Value *ArraySize = 0,
+ const char *Name = "") {
+ return Insert(new MallocInst(Ty, ArraySize, Name));
+ }
+ AllocaInst *CreateAlloca(const Type *Ty, Value *ArraySize = 0,
+ const char *Name = "") {
+ return Insert(new AllocaInst(Ty, ArraySize, Name));
+ }
+ FreeInst *CreateFree(Value *Ptr) {
+ return Insert(new FreeInst(Ptr));
+ }
+ LoadInst *CreateLoad(Value *Ptr, const char *Name = 0) {
+ return Insert(new LoadInst(Ptr, Name));
+ }
+ LoadInst *CreateLoad(Value *Ptr, bool isVolatile, const char *Name = 0) {
+ return Insert(new LoadInst(Ptr, Name, isVolatile));
+ }
+ StoreInst *CreateStore(Value *Val, Value *Ptr, bool isVolatile = false) {
+ return Insert(new StoreInst(Val, Ptr, isVolatile));
+ }
+ template<typename InputIterator>
+ GetElementPtrInst *CreateGEP(Value *Ptr, InputIterator IdxBegin,
+ InputIterator IdxEnd, const char *Name = "") {
+ return(Insert(new GetElementPtrInst(Ptr, IdxBegin, IdxEnd, Name)));
+ }
+ GetElementPtrInst *CreateGEP(Value *Ptr, Value *Idx, const char *Name = "") {
+ return Insert(new GetElementPtrInst(Ptr, Idx, Name));
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Instruction creation methods: Cast/Conversion Operators
+ //===--------------------------------------------------------------------===//
+
+ TruncInst *CreateTrunc(Value *V, const Type *DestTy, const char *Name = "") {
+ return Insert(new TruncInst(V, DestTy, Name));
+ }
+ ZExtInst *CreateZExt(Value *V, const Type *DestTy, const char *Name = "") {
+ return Insert(new ZExtInst(V, DestTy, Name));
+ }
+ SExtInst *CreateSExt(Value *V, const Type *DestTy, const char *Name = "") {
+ return Insert(new SExtInst(V, DestTy, Name));
+ }
+ FPToUIInst *CreateFPToUI(Value *V, const Type *DestTy, const char *Name = ""){
+ return Insert(new FPToUIInst(V, DestTy, Name));
+ }
+ FPToSIInst *CreateFPToSI(Value *V, const Type *DestTy, const char *Name = ""){
+ return Insert(new FPToSIInst(V, DestTy, Name));
+ }
+ UIToFPInst *CreateUIToFP(Value *V, const Type *DestTy, const char *Name = ""){
+ return Insert(new UIToFPInst(V, DestTy, Name));
+ }
+ SIToFPInst *CreateSIToFP(Value *V, const Type *DestTy, const char *Name = ""){
+ return Insert(new SIToFPInst(V, DestTy, Name));
+ }
+ FPTruncInst *CreateFPTrunc(Value *V, const Type *DestTy,
+ const char *Name = "") {
+ return Insert(new FPTruncInst(V, DestTy, Name));
+ }
+ FPExtInst *CreateFPExt(Value *V, const Type *DestTy, const char *Name = "") {
+ return Insert(new FPExtInst(V, DestTy, Name));
+ }
+ PtrToIntInst *CreatePtrToInt(Value *V, const Type *DestTy,
+ const char *Name = "") {
+ return Insert(new PtrToIntInst(V, DestTy, Name));
+ }
+ IntToPtrInst *CreateIntToPtr(Value *V, const Type *DestTy,
+ const char *Name = "") {
+ return Insert(new IntToPtrInst(V, DestTy, Name));
+ }
+ BitCastInst *CreateBitCast(Value *V, const Type *DestTy,
+ const char *Name = "") {
+ return Insert(new BitCastInst(V, DestTy, Name));
+ }
+
+ CastInst *CreateCast(Instruction::CastOps Op, Value *V, const Type *DestTy,
+ const char *Name = "") {
+ return Insert(CastInst::create(Op, V, DestTy, Name));
+ }
+ CastInst *CreateIntCast(Value *V, const Type *DestTy, bool isSigned,
+ const char *Name = "") {
+ return Insert(CastInst::createIntegerCast(V, DestTy, isSigned, Name));
+ }
+
+
+
+ //===--------------------------------------------------------------------===//
+ // Instruction creation methods: Compare Instructions
+ //===--------------------------------------------------------------------===//
+
+ ICmpInst *CreateICmpEQ(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(new ICmpInst(ICmpInst::ICMP_EQ, LHS, RHS, Name));
+ }
+ ICmpInst *CreateICmpNE(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(new ICmpInst(ICmpInst::ICMP_NE, LHS, RHS, Name));
+ }
+ ICmpInst *CreateICmpUGT(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(new ICmpInst(ICmpInst::ICMP_UGT, LHS, RHS, Name));
+ }
+ ICmpInst *CreateICmpUGE(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(new ICmpInst(ICmpInst::ICMP_UGE, LHS, RHS, Name));
+ }
+ ICmpInst *CreateICmpULT(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(new ICmpInst(ICmpInst::ICMP_ULT, LHS, RHS, Name));
+ }
+ ICmpInst *CreateICmpULE(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(new ICmpInst(ICmpInst::ICMP_ULE, LHS, RHS, Name));
+ }
+ ICmpInst *CreateICmpSGT(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(new ICmpInst(ICmpInst::ICMP_SGT, LHS, RHS, Name));
+ }
+ ICmpInst *CreateICmpSGE(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(new ICmpInst(ICmpInst::ICMP_SGE, LHS, RHS, Name));
+ }
+ ICmpInst *CreateICmpSLT(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(new ICmpInst(ICmpInst::ICMP_SLT, LHS, RHS, Name));
+ }
+ ICmpInst *CreateICmpSLE(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(new ICmpInst(ICmpInst::ICMP_SLE, LHS, RHS, Name));
+ }
+
+ FCmpInst *CreateFCmpOEQ(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(new FCmpInst(FCmpInst::FCMP_OEQ, LHS, RHS, Name));
+ }
+ FCmpInst *CreateFCmpOGT(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(new FCmpInst(FCmpInst::FCMP_OGT, LHS, RHS, Name));
+ }
+ FCmpInst *CreateFCmpOGE(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(new FCmpInst(FCmpInst::FCMP_OGE, LHS, RHS, Name));
+ }
+ FCmpInst *CreateFCmpOLT(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(new FCmpInst(FCmpInst::FCMP_OLT, LHS, RHS, Name));
+ }
+ FCmpInst *CreateFCmpOLE(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(new FCmpInst(FCmpInst::FCMP_OLE, LHS, RHS, Name));
+ }
+ FCmpInst *CreateFCmpONE(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(new FCmpInst(FCmpInst::FCMP_ONE, LHS, RHS, Name));
+ }
+ FCmpInst *CreateFCmpORD(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(new FCmpInst(FCmpInst::FCMP_ORD, LHS, RHS, Name));
+ }
+ FCmpInst *CreateFCmpUNO(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(new FCmpInst(FCmpInst::FCMP_UNO, LHS, RHS, Name));
+ }
+ FCmpInst *CreateFCmpUEQ(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(new FCmpInst(FCmpInst::FCMP_UEQ, LHS, RHS, Name));
+ }
+ FCmpInst *CreateFCmpUGT(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(new FCmpInst(FCmpInst::FCMP_UGT, LHS, RHS, Name));
+ }
+ FCmpInst *CreateFCmpUGE(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(new FCmpInst(FCmpInst::FCMP_UGE, LHS, RHS, Name));
+ }
+ FCmpInst *CreateFCmpULT(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(new FCmpInst(FCmpInst::FCMP_ULT, LHS, RHS, Name));
+ }
+ FCmpInst *CreateFCmpULE(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(new FCmpInst(FCmpInst::FCMP_ULE, LHS, RHS, Name));
+ }
+ FCmpInst *CreateFCmpUNE(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(new FCmpInst(FCmpInst::FCMP_UNE, LHS, RHS, Name));
+ }
+
+
+ ICmpInst *CreateICmp(ICmpInst::Predicate P, Value *LHS, Value *RHS,
+ const char *Name = "") {
+ return Insert(new ICmpInst(P, LHS, RHS, Name));
+ }
+ FCmpInst *CreateFCmp(FCmpInst::Predicate P, Value *LHS, Value *RHS,
+ const char *Name = "") {
+ return Insert(new FCmpInst(P, LHS, RHS, Name));
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Instruction creation methods: Other Instructions
+ //===--------------------------------------------------------------------===//
+
+ PHINode *CreatePHI(const Type *Ty, const char *Name = "") {
+ return Insert(new PHINode(Ty, Name));
+ }
+
+ CallInst *CreateCall(Value *Callee, const char *Name = "") {
+ return Insert(new CallInst(Callee, Name));
+ }
+ CallInst *CreateCall(Value *Callee, Value *Arg, const char *Name = "") {
+ return Insert(new CallInst(Callee, Arg, Name));
+ }
+
+ template<typename InputIterator>
+ CallInst *CreateCall(Value *Callee, InputIterator ArgBegin,
+ InputIterator ArgEnd, const char *Name = "") {
+ return(Insert(new CallInst(Callee, ArgBegin, ArgEnd, Name)));
+ }
+
+ SelectInst *CreateSelect(Value *C, Value *True, Value *False,
+ const char *Name = "") {
+ return Insert(new SelectInst(C, True, False, Name));
+ }
+
+ VAArgInst *CreateVAArg(Value *List, const Type *Ty, const char *Name = "") {
+ return Insert(new VAArgInst(List, Ty, Name));
+ }
+
+ ExtractElementInst *CreateExtractElement(Value *Vec, Value *Idx,
+ const char *Name = "") {
+ return Insert(new ExtractElementInst(Vec, Idx, Name));
+ }
+
+ InsertElementInst *CreateInsertElement(Value *Vec, Value *NewElt, Value *Idx,
+ const char *Name = "") {
+ return Insert(new InsertElementInst(Vec, NewElt, Idx, Name));
+ }
+
+ ShuffleVectorInst *CreateShuffleVector(Value *V1, Value *V2, Value *Mask,
+ const char *Name = "") {
+ return Insert(new ShuffleVectorInst(V1, V2, Mask, Name));
+ }
+};
+
+/// LLVMFoldingBuilder - A version of LLVMBuilder that constant folds operands
+/// as they come in.
+class LLVMFoldingBuilder : public LLVMBuilder {
+
+public:
+ LLVMFoldingBuilder() {}
+ explicit LLVMFoldingBuilder(BasicBlock *TheBB)
+ : LLVMBuilder(TheBB) {}
+ LLVMFoldingBuilder(BasicBlock *TheBB, BasicBlock::iterator IP)
+ : LLVMBuilder(TheBB, IP) {}
+
+ //===--------------------------------------------------------------------===//
+ // Instruction creation methods: Binary Operators
+ //===--------------------------------------------------------------------===//
+
+ Value *CreateAdd(Value *LHS, Value *RHS, const char *Name = "") {
+ if (Constant *LC = dyn_cast<Constant>(LHS))
+ if (Constant *RC = dyn_cast<Constant>(RHS))
+ return ConstantExpr::getAdd(LC, RC);
+ return LLVMBuilder::CreateAdd(LHS, RHS, Name);
+ }
+
+ Value *CreateSub(Value *LHS, Value *RHS, const char *Name = "") {
+ if (Constant *LC = dyn_cast<Constant>(LHS))
+ if (Constant *RC = dyn_cast<Constant>(RHS))
+ return ConstantExpr::getSub(LC, RC);
+ return LLVMBuilder::CreateSub(LHS, RHS, Name);
+ }
+
+ Value *CreateMul(Value *LHS, Value *RHS, const char *Name = "") {
+ if (Constant *LC = dyn_cast<Constant>(LHS))
+ if (Constant *RC = dyn_cast<Constant>(RHS))
+ return ConstantExpr::getMul(LC, RC);
+ return LLVMBuilder::CreateMul(LHS, RHS, Name);
+ }
+
+ Value *CreateUDiv(Value *LHS, Value *RHS, const char *Name = "") {
+ if (Constant *LC = dyn_cast<Constant>(LHS))
+ if (Constant *RC = dyn_cast<Constant>(RHS))
+ return ConstantExpr::getUDiv(LC, RC);
+ return LLVMBuilder::CreateUDiv(LHS, RHS, Name);
+ }
+
+ Value *CreateSDiv(Value *LHS, Value *RHS, const char *Name = "") {
+ if (Constant *LC = dyn_cast<Constant>(LHS))
+ if (Constant *RC = dyn_cast<Constant>(RHS))
+ return ConstantExpr::getSDiv(LC, RC);
+ return LLVMBuilder::CreateSDiv(LHS, RHS, Name);
+ }
+
+ Value *CreateFDiv(Value *LHS, Value *RHS, const char *Name = "") {
+ if (Constant *LC = dyn_cast<Constant>(LHS))
+ if (Constant *RC = dyn_cast<Constant>(RHS))
+ return ConstantExpr::getFDiv(LC, RC);
+ return LLVMBuilder::CreateFDiv(LHS, RHS, Name);
+ }
+
+ Value *CreateURem(Value *LHS, Value *RHS, const char *Name = "") {
+ if (Constant *LC = dyn_cast<Constant>(LHS))
+ if (Constant *RC = dyn_cast<Constant>(RHS))
+ return ConstantExpr::getURem(LC, RC);
+ return LLVMBuilder::CreateURem(LHS, RHS, Name);
+ }
+
+ Value *CreateSRem(Value *LHS, Value *RHS, const char *Name = "") {
+ if (Constant *LC = dyn_cast<Constant>(LHS))
+ if (Constant *RC = dyn_cast<Constant>(RHS))
+ return ConstantExpr::getSRem(LC, RC);
+ return LLVMBuilder::CreateSRem(LHS, RHS, Name);
+ }
+
+ Value *CreateFRem(Value *LHS, Value *RHS, const char *Name = "") {
+ if (Constant *LC = dyn_cast<Constant>(LHS))
+ if (Constant *RC = dyn_cast<Constant>(RHS))
+ return ConstantExpr::getFRem(LC, RC);
+ return LLVMBuilder::CreateFRem(LHS, RHS, Name);
+ }
+
+ Value *CreateAnd(Value *LHS, Value *RHS, const char *Name = "") {
+ if (Constant *LC = dyn_cast<Constant>(LHS))
+ if (Constant *RC = dyn_cast<Constant>(RHS))
+ return ConstantExpr::getAnd(LC, RC);
+ return LLVMBuilder::CreateAnd(LHS, RHS, Name);
+ }
+
+ Value *CreateOr(Value *LHS, Value *RHS, const char *Name = "") {
+ if (Constant *LC = dyn_cast<Constant>(LHS))
+ if (Constant *RC = dyn_cast<Constant>(RHS))
+ return ConstantExpr::getOr(LC, RC);
+ return LLVMBuilder::CreateOr(LHS, RHS, Name);
+ }
+
+ Value *CreateXor(Value *LHS, Value *RHS, const char *Name = "") {
+ if (Constant *LC = dyn_cast<Constant>(LHS))
+ if (Constant *RC = dyn_cast<Constant>(RHS))
+ return ConstantExpr::getXor(LC, RC);
+ return LLVMBuilder::CreateXor(LHS, RHS, Name);
+ }
+
+ Value *CreateShl(Value *LHS, Value *RHS, const char *Name = "") {
+ if (Constant *LC = dyn_cast<Constant>(LHS))
+ if (Constant *RC = dyn_cast<Constant>(RHS))
+ return ConstantExpr::getShl(LC, RC);
+ return LLVMBuilder::CreateShl(LHS, RHS, Name);
+ }
+
+ Value *CreateLShr(Value *LHS, Value *RHS, const char *Name = "") {
+ if (Constant *LC = dyn_cast<Constant>(LHS))
+ if (Constant *RC = dyn_cast<Constant>(RHS))
+ return ConstantExpr::getLShr(LC, RC);
+ return LLVMBuilder::CreateLShr(LHS, RHS, Name);
+ }
+
+ Value *CreateAShr(Value *LHS, Value *RHS, const char *Name = "") {
+ if (Constant *LC = dyn_cast<Constant>(LHS))
+ if (Constant *RC = dyn_cast<Constant>(RHS))
+ return ConstantExpr::getAShr(LC, RC);
+ return LLVMBuilder::CreateAShr(LHS, RHS, Name);
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Instruction creation methods: Compare Instructions
+ //===--------------------------------------------------------------------===//
+
+ Value *CreateICmpEQ(Value *LHS, Value *RHS, const char *Name = "") {
+ return CreateICmp(ICmpInst::ICMP_EQ, LHS, RHS, Name);
+ }
+ Value *CreateICmpNE(Value *LHS, Value *RHS, const char *Name = "") {
+ return CreateICmp(ICmpInst::ICMP_NE, LHS, RHS, Name);
+ }
+ Value *CreateICmpUGT(Value *LHS, Value *RHS, const char *Name = "") {
+ return CreateICmp(ICmpInst::ICMP_UGT, LHS, RHS, Name);
+ }
+ Value *CreateICmpUGE(Value *LHS, Value *RHS, const char *Name = "") {
+ return CreateICmp(ICmpInst::ICMP_UGE, LHS, RHS, Name);
+ }
+ Value *CreateICmpULT(Value *LHS, Value *RHS, const char *Name = "") {
+ return CreateICmp(ICmpInst::ICMP_ULT, LHS, RHS, Name);
+ }
+ Value *CreateICmpULE(Value *LHS, Value *RHS, const char *Name = "") {
+ return CreateICmp(ICmpInst::ICMP_ULE, LHS, RHS, Name);
+ }
+ Value *CreateICmpSGT(Value *LHS, Value *RHS, const char *Name = "") {
+ return CreateICmp(ICmpInst::ICMP_SGT, LHS, RHS, Name);
+ }
+ Value *CreateICmpSGE(Value *LHS, Value *RHS, const char *Name = "") {
+ return CreateICmp(ICmpInst::ICMP_SGE, LHS, RHS, Name);
+ }
+ Value *CreateICmpSLT(Value *LHS, Value *RHS, const char *Name = "") {
+ return CreateICmp(ICmpInst::ICMP_SLT, LHS, RHS, Name);
+ }
+ Value *CreateICmpSLE(Value *LHS, Value *RHS, const char *Name = "") {
+ return CreateICmp(ICmpInst::ICMP_SLE, LHS, RHS, Name);
+ }
+
+ Value *CreateFCmpOEQ(Value *LHS, Value *RHS, const char *Name = "") {
+ return CreateFCmp(FCmpInst::FCMP_OEQ, LHS, RHS, Name);
+ }
+ Value *CreateFCmpOGT(Value *LHS, Value *RHS, const char *Name = "") {
+ return CreateFCmp(FCmpInst::FCMP_OGT, LHS, RHS, Name);
+ }
+ Value *CreateFCmpOGE(Value *LHS, Value *RHS, const char *Name = "") {
+ return CreateFCmp(FCmpInst::FCMP_OGE, LHS, RHS, Name);
+ }
+ Value *CreateFCmpOLT(Value *LHS, Value *RHS, const char *Name = "") {
+ return CreateFCmp(FCmpInst::FCMP_OLT, LHS, RHS, Name);
+ }
+ Value *CreateFCmpOLE(Value *LHS, Value *RHS, const char *Name = "") {
+ return CreateFCmp(FCmpInst::FCMP_OLE, LHS, RHS, Name);
+ }
+ Value *CreateFCmpONE(Value *LHS, Value *RHS, const char *Name = "") {
+ return CreateFCmp(FCmpInst::FCMP_ONE, LHS, RHS, Name);
+ }
+ Value *CreateFCmpORD(Value *LHS, Value *RHS, const char *Name = "") {
+ return CreateFCmp(FCmpInst::FCMP_ORD, LHS, RHS, Name);
+ }
+ Value *CreateFCmpUNO(Value *LHS, Value *RHS, const char *Name = "") {
+ return CreateFCmp(FCmpInst::FCMP_UNO, LHS, RHS, Name);
+ }
+ Value *CreateFCmpUEQ(Value *LHS, Value *RHS, const char *Name = "") {
+ return CreateFCmp(FCmpInst::FCMP_UEQ, LHS, RHS, Name);
+ }
+ Value *CreateFCmpUGT(Value *LHS, Value *RHS, const char *Name = "") {
+ return CreateFCmp(FCmpInst::FCMP_UGT, LHS, RHS, Name);
+ }
+ Value *CreateFCmpUGE(Value *LHS, Value *RHS, const char *Name = "") {
+ return CreateFCmp(FCmpInst::FCMP_UGE, LHS, RHS, Name);
+ }
+ Value *CreateFCmpULT(Value *LHS, Value *RHS, const char *Name = "") {
+ return CreateFCmp(FCmpInst::FCMP_ULT, LHS, RHS, Name);
+ }
+ Value *CreateFCmpULE(Value *LHS, Value *RHS, const char *Name = "") {
+ return CreateFCmp(FCmpInst::FCMP_ULE, LHS, RHS, Name);
+ }
+ Value *CreateFCmpUNE(Value *LHS, Value *RHS, const char *Name = "") {
+ return CreateFCmp(FCmpInst::FCMP_UNE, LHS, RHS, Name);
+ }
+
+ Value *CreateICmp(ICmpInst::Predicate P, Value *LHS, Value *RHS,
+ const char *Name = "") {
+ if (Constant *LC = dyn_cast<Constant>(LHS))
+ if (Constant *RC = dyn_cast<Constant>(RHS))
+ return ConstantExpr::getCompare(P, LC, RC);
+ return LLVMBuilder::CreateICmp(P, LHS, RHS, Name);
+ }
+
+ Value *CreateFCmp(FCmpInst::Predicate P, Value *LHS, Value *RHS,
+ const char *Name = "") {
+ if (Constant *LC = dyn_cast<Constant>(LHS))
+ if (Constant *RC = dyn_cast<Constant>(RHS))
+ return ConstantExpr::getCompare(P, LC, RC);
+ return LLVMBuilder::CreateFCmp(P, LHS, RHS, Name);
+ }
+};
+
+}
+
+#endif
diff --git a/support/include/llvm/Support/LeakDetector.h b/support/include/llvm/Support/LeakDetector.h
new file mode 100644
index 0000000..92784ee
--- /dev/null
+++ b/support/include/llvm/Support/LeakDetector.h
@@ -0,0 +1,91 @@
+//===-- llvm/Support/LeakDetector.h - Provide leak detection ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines a class that can be used to provide very simple memory leak
+// checks for an API. Basically LLVM uses this to make sure that Instructions,
+// for example, are deleted when they are supposed to be, and not leaked away.
+//
+// When compiling with NDEBUG (Release build), this class does nothing, thus
+// adding no checking overhead to release builds. Note that this class is
+// implemented in a very simple way, requiring completely manual manipulation
+// and checking for garbage, but this is intentional: users should not be using
+// this API, only other APIs should.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_LEAKDETECTOR_H
+#define LLVM_SUPPORT_LEAKDETECTOR_H
+
+#include <string>
+
+namespace llvm {
+
+class Value;
+
+struct LeakDetector {
+ /// addGarbageObject - Add a pointer to the internal set of "garbage" object
+ /// pointers. This should be called when objects are created, or if they are
+ /// taken out of an owning collection.
+ ///
+ static void addGarbageObject(void *Object) {
+#ifndef NDEBUG
+ addGarbageObjectImpl(Object);
+#endif
+ }
+
+ /// removeGarbageObject - Remove a pointer from our internal representation of
+ /// our "garbage" objects. This should be called when an object is added to
+ /// an "owning" collection.
+ ///
+ static void removeGarbageObject(void *Object) {
+#ifndef NDEBUG
+ removeGarbageObjectImpl(Object);
+#endif
+ }
+
+ /// checkForGarbage - Traverse the internal representation of garbage
+ /// pointers. If there are any pointers that have been add'ed, but not
+ /// remove'd, big obnoxious warnings about memory leaks are issued.
+ ///
+ /// The specified message will be printed indicating when the check was
+ /// performed.
+ ///
+ static void checkForGarbage(const std::string &Message) {
+#ifndef NDEBUG
+ checkForGarbageImpl(Message);
+#endif
+ }
+
+ /// Overload the normal methods to work better with Value*'s because they are
+ /// by far the most common in LLVM. This does not affect the actual
+ /// functioning of this class, it just makes the warning messages nicer.
+ ///
+ static void addGarbageObject(const Value *Object) {
+#ifndef NDEBUG
+ addGarbageObjectImpl(Object);
+#endif
+ }
+ static void removeGarbageObject(const Value *Object) {
+#ifndef NDEBUG
+ removeGarbageObjectImpl(Object);
+#endif
+ }
+
+private:
+ // If we are debugging, the actual implementations will be called...
+ static void addGarbageObjectImpl(const Value *Object);
+ static void removeGarbageObjectImpl(const Value *Object);
+ static void addGarbageObjectImpl(void *Object);
+ static void removeGarbageObjectImpl(void *Object);
+ static void checkForGarbageImpl(const std::string &Message);
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/support/include/llvm/Support/ManagedStatic.h b/support/include/llvm/Support/ManagedStatic.h
new file mode 100644
index 0000000..e65fb1b
--- /dev/null
+++ b/support/include/llvm/Support/ManagedStatic.h
@@ -0,0 +1,96 @@
+//===-- llvm/Support/ManagedStatic.h - Static Global wrapper ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the ManagedStatic class and the llvm_shutdown() function.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_MANAGED_STATIC_H
+#define LLVM_SUPPORT_MANAGED_STATIC_H
+
+namespace llvm {
+
+/// object_deleter - Helper method for ManagedStatic.
+///
+template<class C>
+void object_deleter(void *Ptr) {
+ delete (C*)Ptr;
+}
+
+/// ManagedStaticBase - Common base class for ManagedStatic instances.
+class ManagedStaticBase {
+protected:
+ // This should only be used as a static variable, which guarantees that this
+ // will be zero initialized.
+ mutable void *Ptr;
+ mutable void (*DeleterFn)(void*);
+ mutable const ManagedStaticBase *Next;
+
+ void RegisterManagedStatic(void *ObjPtr, void (*deleter)(void*)) const;
+public:
+ /// isConstructed - Return true if this object has not been created yet.
+ bool isConstructed() const { return Ptr != 0; }
+
+ void destroy() const;
+};
+
+/// ManagedStatic - This transparently changes the behavior of global statics to
+/// be lazily constructed on demand (good for reducing startup times of dynamic
+/// libraries that link in LLVM components) and for making destruction be
+/// explicit through the llvm_shutdown() function call.
+///
+template<class C>
+class ManagedStatic : public ManagedStaticBase {
+public:
+
+ // Accessors.
+ C &operator*() {
+ if (!Ptr) LazyInit();
+ return *static_cast<C*>(Ptr);
+ }
+ C *operator->() {
+ if (!Ptr) LazyInit();
+ return static_cast<C*>(Ptr);
+ }
+ const C &operator*() const {
+ if (!Ptr) LazyInit();
+ return *static_cast<C*>(Ptr);
+ }
+ const C *operator->() const {
+ if (!Ptr) LazyInit();
+ return static_cast<C*>(Ptr);
+ }
+
+public:
+ void LazyInit() const {
+ RegisterManagedStatic(new C(), object_deleter<C>);
+ }
+};
+
+template<void (*CleanupFn)(void*)>
+class ManagedCleanup : public ManagedStaticBase {
+public:
+ void Register() { RegisterManagedStatic(0, CleanupFn); }
+};
+
+
+/// 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 {
+ llvm_shutdown_obj() {}
+ ~llvm_shutdown_obj() { llvm_shutdown(); }
+};
+
+}
+
+#endif
diff --git a/support/include/llvm/Support/Mangler.h b/support/include/llvm/Support/Mangler.h
new file mode 100644
index 0000000..d52ff6a
--- /dev/null
+++ b/support/include/llvm/Support/Mangler.h
@@ -0,0 +1,118 @@
+//===-- llvm/Support/Mangler.h - Self-contained name mangler ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Unified name mangler for various backends.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_MANGLER_H
+#define LLVM_SUPPORT_MANGLER_H
+
+#include "llvm/System/IncludeFile.h"
+#include <map>
+#include <set>
+#include <string>
+
+namespace llvm {
+class Type;
+class Module;
+class Value;
+class GlobalValue;
+
+class Mangler {
+ /// Prefix - This string is added to each symbol that is emitted, unless the
+ /// symbol is marked as not needing this prefix.
+ const char *Prefix;
+
+ /// UseQuotes - If this is set, the target accepts global names in quotes,
+ /// e.g. "foo bar" is a legal name. This syntax is used instead of escaping
+ /// the space character. By default, this is false.
+ bool UseQuotes;
+
+ /// PreserveAsmNames - If this is set, the asm escape character is not removed
+ /// from names with 'asm' specifiers.
+ bool PreserveAsmNames;
+
+ /// Memo - This is used to remember the name that we assign a value.
+ ///
+ std::map<const Value*, std::string> Memo;
+
+ /// Count - This simple counter is used to unique value names.
+ ///
+ unsigned Count;
+
+ /// TypeMap - If the client wants us to unique types, this keeps track of the
+ /// current assignments and TypeCounter keeps track of the next id to assign.
+ std::map<const Type*, unsigned> TypeMap;
+ unsigned TypeCounter;
+
+ /// This keeps track of which global values have had their names
+ /// mangled in the current module.
+ ///
+ std::set<const GlobalValue*> MangledGlobals;
+
+ /// AcceptableChars - This bitfield contains a one for each character that is
+ /// allowed to be part of an unmangled name.
+ unsigned AcceptableChars[256/32];
+public:
+
+ // Mangler ctor - if a prefix is specified, it will be prepended onto all
+ // symbols.
+ Mangler(Module &M, const char *Prefix = "");
+
+ /// setUseQuotes - If UseQuotes is set to true, this target accepts quoted
+ /// strings for assembler labels.
+ void setUseQuotes(bool Val) { UseQuotes = Val; }
+
+ /// setPreserveAsmNames - If the mangler should not strip off the asm name
+ /// @verbatim identifier (\001), this should be set. @endverbatim
+ void setPreserveAsmNames(bool Val) { PreserveAsmNames = Val; }
+
+ /// Acceptable Characters - This allows the target to specify which characters
+ /// are acceptable to the assembler without being mangled. By default we
+ /// allow letters, numbers, '_', '$', and '.', which is what GAS accepts.
+ void markCharAcceptable(unsigned char X) {
+ AcceptableChars[X/32] |= 1 << (X&31);
+ }
+ void markCharUnacceptable(unsigned char X) {
+ AcceptableChars[X/32] &= ~(1 << (X&31));
+ }
+ bool isCharAcceptable(unsigned char X) const {
+ return (AcceptableChars[X/32] & (1 << (X&31))) != 0;
+ }
+
+ /// getTypeID - Return a unique ID for the specified LLVM type.
+ ///
+ unsigned getTypeID(const Type *Ty);
+
+ /// getValueName - Returns the mangled name of V, an LLVM Value,
+ /// in the current module.
+ ///
+ std::string getValueName(const GlobalValue *V, const char *Suffix = "");
+ std::string getValueName(const Value *V);
+
+ /// makeNameProper - We don't want identifier names with ., space, or
+ /// - in them, so we mangle these characters into the strings "d_",
+ /// "s_", and "D_", respectively. This is a very simple mangling that
+ /// doesn't guarantee unique names for values. getValueName already
+ /// does this for you, so there's no point calling it on the result
+ /// from getValueName.
+ ///
+ std::string makeNameProper(const std::string &x, const char *Prefix = "");
+
+private:
+ void InsertName(GlobalValue *GV, std::map<std::string, GlobalValue*> &Names);
+};
+
+} // End llvm namespace
+
+// Force the Mangler.cpp file to be linked when this header is #included
+FORCE_DEFINING_FILE_TO_BE_LINKED(Mangler)
+
+#endif // LLVM_SUPPORT_MANGLER_H
diff --git a/support/include/llvm/Support/MathExtras.h b/support/include/llvm/Support/MathExtras.h
new file mode 100644
index 0000000..3955735
--- /dev/null
+++ b/support/include/llvm/Support/MathExtras.h
@@ -0,0 +1,370 @@
+//===-- llvm/Support/MathExtras.h - Useful math functions -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains some functions that are useful for math stuff.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_MATHEXTRAS_H
+#define LLVM_SUPPORT_MATHEXTRAS_H
+
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+
+// NOTE: The following support functions use the _32/_64 extensions instead of
+// type overloading so that signed and unsigned integers can be used without
+// ambiguity.
+
+/// Hi_32 - This function returns the high 32 bits of a 64 bit value.
+inline uint32_t Hi_32(uint64_t Value) {
+ return static_cast<uint32_t>(Value >> 32);
+}
+
+/// Lo_32 - This function returns the low 32 bits of a 64 bit value.
+inline uint32_t Lo_32(uint64_t Value) {
+ return static_cast<uint32_t>(Value);
+}
+
+/// is?Type - these functions produce optimal testing for integer data types.
+inline bool isInt8 (int64_t Value) {
+ return static_cast<int8_t>(Value) == Value;
+}
+inline bool isUInt8 (int64_t Value) {
+ return static_cast<uint8_t>(Value) == Value;
+}
+inline bool isInt16 (int64_t Value) {
+ return static_cast<int16_t>(Value) == Value;
+}
+inline bool isUInt16(int64_t Value) {
+ return static_cast<uint16_t>(Value) == Value;
+}
+inline bool isInt32 (int64_t Value) {
+ return static_cast<int32_t>(Value) == Value;
+}
+inline bool isUInt32(int64_t Value) {
+ return static_cast<uint32_t>(Value) == Value;
+}
+
+/// isMask_32 - This function returns true if the argument is a sequence of ones
+/// starting at the least significant bit with the remainder zero (32 bit
+/// version). Ex. isMask_32(0x0000FFFFU) == true.
+inline bool isMask_32(uint32_t Value) {
+ return Value && ((Value + 1) & Value) == 0;
+}
+
+/// isMask_64 - This function returns true if the argument is a sequence of ones
+/// starting at the least significant bit with the remainder zero (64 bit
+/// version).
+inline bool isMask_64(uint64_t Value) {
+ return Value && ((Value + 1) & Value) == 0;
+}
+
+/// isShiftedMask_32 - This function returns true if the argument contains a
+/// sequence of ones with the remainder zero (32 bit version.)
+/// Ex. isShiftedMask_32(0x0000FF00U) == true.
+inline bool isShiftedMask_32(uint32_t Value) {
+ return isMask_32((Value - 1) | Value);
+}
+
+/// isShiftedMask_64 - This function returns true if the argument contains a
+/// sequence of ones with the remainder zero (64 bit version.)
+inline bool isShiftedMask_64(uint64_t Value) {
+ return isMask_64((Value - 1) | Value);
+}
+
+/// isPowerOf2_32 - This function returns true if the argument is a power of
+/// two > 0. Ex. isPowerOf2_32(0x00100000U) == true (32 bit edition.)
+inline bool isPowerOf2_32(uint32_t Value) {
+ return Value && !(Value & (Value - 1));
+}
+
+/// isPowerOf2_64 - This function returns true if the argument is a power of two
+/// > 0 (64 bit edition.)
+inline bool isPowerOf2_64(uint64_t Value) {
+ return Value && !(Value & (Value - int64_t(1L)));
+}
+
+/// ByteSwap_16 - This function returns a byte-swapped representation of the
+/// 16-bit argument, Value.
+inline uint16_t ByteSwap_16(uint16_t Value) {
+#if defined(_MSC_VER) && !defined(_DEBUG)
+ // The DLL version of the runtime lacks these functions (bug!?), but in a
+ // release build they're replaced with BSWAP instructions anyway.
+ return _byteswap_ushort(Value);
+#else
+ uint16_t Hi = Value << 8;
+ uint16_t Lo = Value >> 8;
+ return Hi | Lo;
+#endif
+}
+
+/// ByteSwap_32 - This function returns a byte-swapped representation of the
+/// 32-bit argument, Value.
+inline uint32_t ByteSwap_32(uint32_t Value) {
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
+ return __builtin_bswap32(Value);
+#elif defined(_MSC_VER) && !defined(_DEBUG)
+ return _byteswap_ulong(Value);
+#else
+ uint32_t Byte0 = Value & 0x000000FF;
+ uint32_t Byte1 = Value & 0x0000FF00;
+ uint32_t Byte2 = Value & 0x00FF0000;
+ uint32_t Byte3 = Value & 0xFF000000;
+ return (Byte0 << 24) | (Byte1 << 8) | (Byte2 >> 8) | (Byte3 >> 24);
+#endif
+}
+
+/// ByteSwap_64 - This function returns a byte-swapped representation of the
+/// 64-bit argument, Value.
+inline uint64_t ByteSwap_64(uint64_t Value) {
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
+ return __builtin_bswap64(Value);
+#elif defined(_MSC_VER) && !defined(_DEBUG)
+ return _byteswap_uint64(Value);
+#else
+ uint64_t Hi = ByteSwap_32(uint32_t(Value));
+ uint32_t Lo = ByteSwap_32(uint32_t(Value >> 32));
+ return (Hi << 32) | Lo;
+#endif
+}
+
+/// 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;
+ // bisecton 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;
+}
+
+/// 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;
+ // bisecton 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;
+}
+
+/// 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
+ };
+ return Mod37BitPosition[(-Value & Value) % 37];
+#endif
+}
+
+/// 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
+ };
+ return Mod67Position[(-Value & Value) % 67];
+#endif
+}
+
+/// CountPopulation_32 - this function counts the number of set bits in a value.
+/// Ex. CountPopulation(0xF000F000) = 8
+/// Returns 0 if the word is zero.
+inline unsigned CountPopulation_32(uint32_t Value) {
+#if __GNUC__ >= 4
+ return __builtin_popcount(Value);
+#else
+ uint32_t v = Value - ((Value >> 1) & 0x55555555);
+ v = (v & 0x33333333) + ((v >> 2) & 0x33333333);
+ return ((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24;
+#endif
+}
+
+/// CountPopulation_64 - this function counts the number of set bits in a value,
+/// (64 bit edition.)
+inline unsigned CountPopulation_64(uint64_t Value) {
+#if __GNUC__ >= 4
+ return __builtin_popcountll(Value);
+#else
+ uint64_t v = Value - ((Value >> 1) & 0x5555555555555555ULL);
+ v = (v & 0x3333333333333333ULL) + ((v >> 2) & 0x3333333333333333ULL);
+ v = (v + (v >> 4)) & 0x0F0F0F0F0F0F0F0FULL;
+ return unsigned((uint64_t)(v * 0x0101010101010101ULL) >> 56);
+#endif
+}
+
+/// Log2_32 - This function returns the floor log base 2 of the specified 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);
+}
+
+/// 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);
+}
+
+/// 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);
+}
+
+/// Log2_64 - 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);
+}
+
+/// GreatestCommonDivisor64 - Return the greatest common divisor of the two
+/// values using Euclid's algorithm.
+inline uint64_t GreatestCommonDivisor64(uint64_t A, uint64_t B) {
+ while (B) {
+ uint64_t T = B;
+ B = A % B;
+ A = T;
+ }
+ return A;
+}
+
+/// BitsToDouble - This function takes a 64-bit integer and returns the bit
+/// equivalent double.
+inline double BitsToDouble(uint64_t Bits) {
+ union {
+ uint64_t L;
+ double D;
+ } T;
+ T.L = Bits;
+ return T.D;
+}
+
+/// BitsToFloat - This function takes a 32-bit integer and returns the bit
+/// equivalent float.
+inline float BitsToFloat(uint32_t Bits) {
+ union {
+ uint32_t I;
+ float F;
+ } T;
+ T.I = Bits;
+ return T.F;
+}
+
+/// DoubleToBits - This function takes a double and returns the bit
+/// equivalent 64-bit integer.
+inline uint64_t DoubleToBits(double Double) {
+ union {
+ uint64_t L;
+ double D;
+ } T;
+ T.D = Double;
+ return T.L;
+}
+
+/// FloatToBits - This function takes a float and returns the bit
+/// equivalent 32-bit integer.
+inline uint32_t FloatToBits(float Float) {
+ union {
+ uint32_t I;
+ float F;
+ } T;
+ T.F = Float;
+ return T.I;
+}
+
+/// Platform-independent wrappers for the C99 isnan() function.
+int IsNAN(float f);
+int IsNAN(double d);
+
+/// Platform-independent wrappers for the C99 isinf() function.
+int IsInf(float f);
+int IsInf(double d);
+
+/// MinAlign - A and B are either alignments or offsets. Return the minimum
+/// alignment that may be assumed after adding the two together.
+static inline unsigned MinAlign(unsigned A, unsigned B) {
+ // The largest power of 2 that divides both A and B.
+ return (A | B) & -(A | B);
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/support/include/llvm/Support/MemoryBuffer.h b/support/include/llvm/Support/MemoryBuffer.h
new file mode 100644
index 0000000..cfef6b1
--- /dev/null
+++ b/support/include/llvm/Support/MemoryBuffer.h
@@ -0,0 +1,109 @@
+//===--- MemoryBuffer.h - Memory Buffer Interface ---------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the MemoryBuffer interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_MEMORYBUFFER_H
+#define LLVM_SUPPORT_MEMORYBUFFER_H
+
+#include "llvm/Support/DataTypes.h"
+#include <string>
+
+namespace llvm {
+
+/// MemoryBuffer - This interface provides simple read-only access to a block
+/// of memory, and provides simple methods for reading files and standard input
+/// into a memory buffer. In addition to basic access to the characters in the
+/// file, this interface guarantees you can read one character past the end of
+/// @verbatim the file, and that this character will read as '\0'. @endverbatim
+class MemoryBuffer {
+ const char *BufferStart; // Start of the buffer.
+ const char *BufferEnd; // End of the buffer.
+
+ /// MustDeleteBuffer - True if we allocated this buffer. If so, the
+ /// destructor must know the delete[] it.
+ bool MustDeleteBuffer;
+protected:
+ MemoryBuffer() : MustDeleteBuffer(false) {}
+ void init(const char *BufStart, const char *BufEnd);
+ void initCopyOf(const char *BufStart, const char *BufEnd);
+public:
+ virtual ~MemoryBuffer();
+
+ const char *getBufferStart() const { return BufferStart; }
+ const char *getBufferEnd() const { return BufferEnd; }
+ unsigned getBufferSize() const { return BufferEnd-BufferStart; }
+
+ /// getBufferIdentifier - Return an identifier for this buffer, typically the
+ /// filename it was read from.
+ virtual const char *getBufferIdentifier() const {
+ return "Unknown buffer";
+ }
+
+ /// getFile - Open the specified file as a MemoryBuffer, returning a new
+ /// 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 MemoryBuffer *getFile(const char *FilenameStart, unsigned FnSize,
+ std::string *ErrStr = 0,
+ int64_t FileSize = -1);
+
+ /// getMemBuffer - Open the specified memory range as a MemoryBuffer. Note
+ /// that EndPtr[0] must be a null byte and be accessible!
+ static MemoryBuffer *getMemBuffer(const char *StartPtr, const char *EndPtr,
+ const char *BufferName = "");
+
+ /// getMemBufferCopy - Open the specified memory range as a MemoryBuffer,
+ /// copying the contents and taking ownership of it. This has no requirements
+ /// on EndPtr[0].
+ static MemoryBuffer *getMemBufferCopy(const char *StartPtr,const char *EndPtr,
+ const char *BufferName = "");
+
+ /// getNewMemBuffer - Allocate a new MemoryBuffer of the specified size that
+ /// is completely initialized to zeros. Note that the caller should
+ /// initialize the memory allocated by this method. The memory is owned by
+ /// the MemoryBuffer object.
+ static MemoryBuffer *getNewMemBuffer(unsigned Size,
+ const char *BufferName = "");
+
+ /// getNewUninitMemBuffer - Allocate a new MemoryBuffer of the specified size
+ /// that is not initialized. Note that the caller should initialize the
+ /// memory allocated by this method. The memory is owned by the MemoryBuffer
+ /// object.
+ static MemoryBuffer *getNewUninitMemBuffer(unsigned Size,
+ const char *BufferName = "");
+
+ /// getSTDIN - Read all of stdin into a file buffer, and return it. This
+ /// returns null if stdin is empty.
+ static MemoryBuffer *getSTDIN();
+
+
+ /// getFileOrSTDIN - Open the specified file as a MemoryBuffer, or open stdin
+ /// if the Filename is "-". If an error occurs, this returns null and fills
+ /// in *ErrStr with a reason. If stdin is empty, this API (unlike getSTDIN)
+ /// returns an empty buffer.
+ static MemoryBuffer *getFileOrSTDIN(const char *FilenameStart,unsigned FnSize,
+ std::string *ErrStr = 0,
+ int64_t FileSize = -1);
+
+ /// getFileOrSTDIN - Open the specified file as a MemoryBuffer, or open stdin
+ /// if the Filename is "-". If an error occurs, this returns null and fills
+ /// in *ErrStr with a reason.
+ static MemoryBuffer *getFileOrSTDIN(const std::string &FN,
+ std::string *ErrStr = 0,
+ int64_t FileSize = -1) {
+ return getFileOrSTDIN(&FN[0], FN.size(), ErrStr, FileSize);
+ }
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/support/include/llvm/Support/MutexGuard.h b/support/include/llvm/Support/MutexGuard.h
new file mode 100644
index 0000000..21c756d
--- /dev/null
+++ b/support/include/llvm/Support/MutexGuard.h
@@ -0,0 +1,41 @@
+//===-- Support/MutexGuard.h - Acquire/Release Mutex In Scope ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines a guard for a block of code that ensures a Mutex is locked
+// upon construction and released upon destruction.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_MUTEXGUARD_H
+#define LLVM_SUPPORT_MUTEXGUARD_H
+
+#include <llvm/System/Mutex.h>
+
+namespace llvm {
+ /// Instances of this class acquire a given Mutex Lock when constructed and
+ /// hold that lock until destruction. The intention is to instantiate one of
+ /// these on the stack at the top of some scope to be assured that C++
+ /// destruction of the object will always release the Mutex and thus avoid
+ /// a host of nasty multi-threading problems in the face of exceptions, etc.
+ /// @brief Guard a section of code with a Mutex.
+ class MutexGuard {
+ sys::Mutex &M;
+ MutexGuard(const MutexGuard &); // DO NOT IMPLEMENT
+ void operator=(const MutexGuard &); // DO NOT IMPLEMENT
+ public:
+ MutexGuard(sys::Mutex &m) : M(m) { M.acquire(); }
+ ~MutexGuard() { M.release(); }
+ /// holds - Returns true if this locker instance holds the specified lock.
+ /// This is mostly used in assertions to validate that the correct mutex
+ /// is held.
+ bool holds(const sys::Mutex& lock) const { return &M == &lock; }
+ };
+}
+
+#endif // LLVM_SUPPORT_MUTEXGUARD_H
diff --git a/support/include/llvm/Support/OutputBuffer.h b/support/include/llvm/Support/OutputBuffer.h
new file mode 100644
index 0000000..9c6456a
--- /dev/null
+++ b/support/include/llvm/Support/OutputBuffer.h
@@ -0,0 +1,152 @@
+//=== OutputBuffer.h - Output Buffer ----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Bill Wendling and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Methods to output values to a data buffer.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_OUTPUTBUFFER_H
+#define LLVM_SUPPORT_OUTPUTBUFFER_H
+
+#include <string>
+#include <vector>
+
+namespace llvm {
+
+ class OutputBuffer {
+ /// Output buffer.
+ std::vector<unsigned char> &Output;
+
+ /// is64Bit/isLittleEndian - This information is inferred from the target
+ /// machine directly, indicating what header values and flags to set.
+ bool is64Bit, isLittleEndian;
+ public:
+ OutputBuffer(std::vector<unsigned char> &Out,
+ bool is64bit, bool le)
+ : Output(Out), is64Bit(is64bit), isLittleEndian(le) {}
+
+ // align - Emit padding into the file until the current output position is
+ // aligned to the specified power of two boundary.
+ void align(unsigned Boundary) {
+ assert(Boundary && (Boundary & (Boundary - 1)) == 0 &&
+ "Must align to 2^k boundary");
+ size_t Size = Output.size();
+
+ if (Size & (Boundary - 1)) {
+ // Add padding to get alignment to the correct place.
+ size_t Pad = Boundary - (Size & (Boundary - 1));
+ Output.resize(Size + Pad);
+ }
+ }
+
+ //===------------------------------------------------------------------===//
+ // Out Functions - Output the specified value to the data buffer.
+
+ void outbyte(unsigned char X) {
+ Output.push_back(X);
+ }
+ void outhalf(unsigned short X) {
+ if (isLittleEndian) {
+ Output.push_back(X & 255);
+ Output.push_back(X >> 8);
+ } else {
+ Output.push_back(X >> 8);
+ Output.push_back(X & 255);
+ }
+ }
+ void outword(unsigned X) {
+ if (isLittleEndian) {
+ Output.push_back((X >> 0) & 255);
+ Output.push_back((X >> 8) & 255);
+ Output.push_back((X >> 16) & 255);
+ Output.push_back((X >> 24) & 255);
+ } else {
+ Output.push_back((X >> 24) & 255);
+ Output.push_back((X >> 16) & 255);
+ Output.push_back((X >> 8) & 255);
+ Output.push_back((X >> 0) & 255);
+ }
+ }
+ void outxword(uint64_t X) {
+ if (isLittleEndian) {
+ Output.push_back(unsigned(X >> 0) & 255);
+ Output.push_back(unsigned(X >> 8) & 255);
+ Output.push_back(unsigned(X >> 16) & 255);
+ Output.push_back(unsigned(X >> 24) & 255);
+ Output.push_back(unsigned(X >> 32) & 255);
+ Output.push_back(unsigned(X >> 40) & 255);
+ Output.push_back(unsigned(X >> 48) & 255);
+ Output.push_back(unsigned(X >> 56) & 255);
+ } else {
+ Output.push_back(unsigned(X >> 56) & 255);
+ Output.push_back(unsigned(X >> 48) & 255);
+ Output.push_back(unsigned(X >> 40) & 255);
+ Output.push_back(unsigned(X >> 32) & 255);
+ Output.push_back(unsigned(X >> 24) & 255);
+ Output.push_back(unsigned(X >> 16) & 255);
+ Output.push_back(unsigned(X >> 8) & 255);
+ Output.push_back(unsigned(X >> 0) & 255);
+ }
+ }
+ void outaddr32(unsigned X) {
+ outword(X);
+ }
+ void outaddr64(uint64_t X) {
+ outxword(X);
+ }
+ void outaddr(uint64_t X) {
+ if (!is64Bit)
+ outword((unsigned)X);
+ else
+ outxword(X);
+ }
+ void outstring(const std::string &S, unsigned Length) {
+ unsigned len_to_copy = S.length() < Length ? S.length() : Length;
+ unsigned len_to_fill = S.length() < Length ? Length - S.length() : 0;
+
+ for (unsigned i = 0; i < len_to_copy; ++i)
+ outbyte(S[i]);
+
+ for (unsigned i = 0; i < len_to_fill; ++i)
+ outbyte(0);
+ }
+
+ //===------------------------------------------------------------------===//
+ // Fix Functions - Replace an existing entry at an offset.
+
+ void fixhalf(unsigned short X, unsigned Offset) {
+ unsigned char *P = &Output[Offset];
+ P[0] = (X >> (isLittleEndian ? 0 : 8)) & 255;
+ P[1] = (X >> (isLittleEndian ? 8 : 0)) & 255;
+ }
+ void fixword(unsigned X, unsigned Offset) {
+ unsigned char *P = &Output[Offset];
+ P[0] = (X >> (isLittleEndian ? 0 : 24)) & 255;
+ P[1] = (X >> (isLittleEndian ? 8 : 16)) & 255;
+ P[2] = (X >> (isLittleEndian ? 16 : 8)) & 255;
+ P[3] = (X >> (isLittleEndian ? 24 : 0)) & 255;
+ }
+ void fixaddr(uint64_t X, unsigned Offset) {
+ if (!is64Bit)
+ fixword((unsigned)X, Offset);
+ else
+ assert(0 && "Emission of 64-bit data not implemented yet!");
+ }
+
+ unsigned char &operator[](unsigned Index) {
+ return Output[Index];
+ }
+ const unsigned char &operator[](unsigned Index) const {
+ return Output[Index];
+ }
+ };
+
+} // end llvm namespace
+
+#endif // LLVM_SUPPORT_OUTPUTBUFFER_H
diff --git a/support/include/llvm/Support/PassNameParser.h b/support/include/llvm/Support/PassNameParser.h
new file mode 100644
index 0000000..312a8a6
--- /dev/null
+++ b/support/include/llvm/Support/PassNameParser.h
@@ -0,0 +1,132 @@
+//===- llvm/Support/PassNameParser.h ----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+// The PassNameParser class adds ALL passes linked into the system (that are
+// creatable) as command line arguments to the tool (when instantiated with the
+// appropriate command line option template). The FilteredPassNameParser<>
+// template is used for the same purposes as PassNameParser, except that it only
+// includes passes that have a PassType that are compatible with the filter
+// (which is the template argument).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_PASS_NAME_PARSER_H
+#define LLVM_SUPPORT_PASS_NAME_PARSER_H
+
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Pass.h"
+#include <algorithm>
+#include <cstring>
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+// PassNameParser class - Make use of the pass registration mechanism to
+// automatically add a command line argument to opt for each pass.
+//
+class PassNameParser : public PassRegistrationListener,
+ public cl::parser<const PassInfo*> {
+ cl::Option *Opt;
+public:
+ PassNameParser() : Opt(0) {}
+
+ void initialize(cl::Option &O) {
+ Opt = &O;
+ cl::parser<const PassInfo*>::initialize(O);
+
+ // Add all of the passes to the map that got initialized before 'this' did.
+ enumeratePasses();
+ }
+
+ // ignorablePassImpl - Can be overriden in subclasses to refine the list of
+ // which passes we want to include.
+ //
+ virtual bool ignorablePassImpl(const PassInfo *P) const { return false; }
+
+ inline bool ignorablePass(const PassInfo *P) const {
+ // Ignore non-selectable and non-constructible passes! Ignore
+ // non-optimizations.
+ return P->getPassArgument() == 0 || *P->getPassArgument() == 0 ||
+ P->getNormalCtor() == 0 || ignorablePassImpl(P);
+ }
+
+ // Implement the PassRegistrationListener callbacks used to populate our map
+ //
+ virtual void passRegistered(const PassInfo *P) {
+ if (ignorablePass(P) || !Opt) return;
+ if (findOption(P->getPassArgument()) != getNumOptions()) {
+ cerr << "Two passes with the same argument (-"
+ << P->getPassArgument() << ") attempted to be registered!\n";
+ abort();
+ }
+ addLiteralOption(P->getPassArgument(), P, P->getPassName());
+ }
+ virtual void passEnumerate(const PassInfo *P) { passRegistered(P); }
+
+ // ValLessThan - Provide a sorting comparator for Values elements...
+ typedef std::pair<const char*,
+ std::pair<const PassInfo*, const char*> > ValType;
+ static bool ValLessThan(const ValType &VT1, const ValType &VT2) {
+ return std::string(VT1.first) < std::string(VT2.first);
+ }
+
+ // printOptionInfo - Print out information about this option. Override the
+ // default implementation to sort the table before we print...
+ virtual void printOptionInfo(const cl::Option &O, unsigned GlobalWidth) const{
+ PassNameParser *PNP = const_cast<PassNameParser*>(this);
+ std::sort(PNP->Values.begin(), PNP->Values.end(), ValLessThan);
+ cl::parser<const PassInfo*>::printOptionInfo(O, GlobalWidth);
+ }
+};
+
+///===----------------------------------------------------------------------===//
+/// FilteredPassNameParser class - Make use of the pass registration
+/// mechanism to automatically add a command line argument to opt for
+/// each pass that satisfies a filter criteria. Filter should return
+/// true for passes to be registered as command-line options.
+///
+template<typename Filter>
+class FilteredPassNameParser : public PassNameParser {
+private:
+ Filter filter;
+
+public:
+ bool ignorablePassImpl(const PassInfo *P) const { return !filter(*P); }
+};
+
+///===----------------------------------------------------------------------===//
+/// PassArgFilter - A filter for use with PassNameFilterParser that only
+/// accepts a Pass whose Arg matches certain strings.
+///
+/// Use like this:
+///
+/// extern const char AllowedPassArgs[] = "-anders_aa -dse";
+///
+/// static cl::list<
+/// const PassInfo*,
+/// bool,
+/// FilteredPassNameParser<PassArgFilter<AllowedPassArgs> > >
+/// PassList(cl::desc("Passes available:"));
+///
+/// Only the -anders_aa and -dse options will be available to the user.
+///
+template<const char *Args>
+class PassArgFilter {
+public:
+ bool operator()(const PassInfo &P) const {
+ return(std::strstr(Args, P.getPassArgument()));
+ }
+};
+
+} // End llvm namespace
+#endif
diff --git a/support/include/llvm/Support/PatternMatch.h b/support/include/llvm/Support/PatternMatch.h
new file mode 100644
index 0000000..6b295d6
--- /dev/null
+++ b/support/include/llvm/Support/PatternMatch.h
@@ -0,0 +1,382 @@
+//===-- llvm/Support/PatternMatch.h - Match on the LLVM IR ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides a simple and efficient mechanism for performing general
+// tree-based pattern matches on the LLVM IR. The power of these routines is
+// that it allows you to write concise patterns that are expressive and easy to
+// understand. The other major advantage of this is that it allows you to
+// trivially capture/bind elements in the pattern to variables. For example,
+// you can do something like this:
+//
+// Value *Exp = ...
+// Value *X, *Y; ConstantInt *C1, *C2; // (X & C1) | (Y & C2)
+// if (match(Exp, m_Or(m_And(m_Value(X), m_ConstantInt(C1)),
+// m_And(m_Value(Y), m_ConstantInt(C2))))) {
+// ... Pattern is matched and variables are bound ...
+// }
+//
+// This is primarily useful to things like the instruction combiner, but can
+// also be useful for static analysis tools or code generators.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_PATTERNMATCH_H
+#define LLVM_SUPPORT_PATTERNMATCH_H
+
+#include "llvm/Constants.h"
+#include "llvm/Instructions.h"
+
+namespace llvm {
+namespace PatternMatch {
+
+template<typename Val, typename Pattern>
+bool match(Val *V, const Pattern &P) {
+ return const_cast<Pattern&>(P).match(V);
+}
+
+template<typename Class>
+struct leaf_ty {
+ template<typename ITy>
+ bool match(ITy *V) { return isa<Class>(V); }
+};
+
+inline leaf_ty<Value> m_Value() { return leaf_ty<Value>(); }
+inline leaf_ty<ConstantInt> m_ConstantInt() { return leaf_ty<ConstantInt>(); }
+
+template<typename Class>
+struct bind_ty {
+ Class *&VR;
+ bind_ty(Class *&V) : VR(V) {}
+
+ template<typename ITy>
+ bool match(ITy *V) {
+ if (Class *CV = dyn_cast<Class>(V)) {
+ VR = CV;
+ return true;
+ }
+ return false;
+ }
+};
+
+inline bind_ty<Value> m_Value(Value *&V) { return V; }
+inline bind_ty<ConstantInt> m_ConstantInt(ConstantInt *&CI) { return CI; }
+
+//===----------------------------------------------------------------------===//
+// Matchers for specific binary operators.
+//
+
+template<typename LHS_t, typename RHS_t,
+ unsigned Opcode, typename ConcreteTy = BinaryOperator>
+struct BinaryOp_match {
+ LHS_t L;
+ RHS_t R;
+
+ BinaryOp_match(const LHS_t &LHS, const RHS_t &RHS) : L(LHS), R(RHS) {}
+
+ template<typename OpTy>
+ bool match(OpTy *V) {
+ if (V->getValueID() == Value::InstructionVal + Opcode) {
+ ConcreteTy *I = cast<ConcreteTy>(V);
+ return I->getOpcode() == Opcode && L.match(I->getOperand(0)) &&
+ R.match(I->getOperand(1));
+ }
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
+ return CE->getOpcode() == Opcode && L.match(CE->getOperand(0)) &&
+ R.match(CE->getOperand(1));
+ return false;
+ }
+};
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::Add> m_Add(const LHS &L,
+ const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::Add>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::Sub> m_Sub(const LHS &L,
+ const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::Sub>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::Mul> m_Mul(const LHS &L,
+ const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::Mul>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::UDiv> m_UDiv(const LHS &L,
+ const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::UDiv>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::SDiv> m_SDiv(const LHS &L,
+ const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::SDiv>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::FDiv> m_FDiv(const LHS &L,
+ const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::FDiv>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::URem> m_URem(const LHS &L,
+ const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::URem>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::SRem> m_SRem(const LHS &L,
+ const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::SRem>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::FRem> m_FRem(const LHS &L,
+ const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::FRem>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::And> m_And(const LHS &L,
+ const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::And>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::Or> m_Or(const LHS &L,
+ const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::Or>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::Xor> m_Xor(const LHS &L,
+ const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::Xor>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::Shl> m_Shl(const LHS &L,
+ const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::Shl>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::LShr> m_LShr(const LHS &L,
+ const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::LShr>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::AShr> m_AShr(const LHS &L,
+ const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::AShr>(L, R);
+}
+
+//===----------------------------------------------------------------------===//
+// Matchers for either AShr or LShr .. for convenience
+//
+template<typename LHS_t, typename RHS_t, typename ConcreteTy = BinaryOperator>
+struct Shr_match {
+ LHS_t L;
+ RHS_t R;
+
+ Shr_match(const LHS_t &LHS, const RHS_t &RHS) : L(LHS), R(RHS) {}
+
+ template<typename OpTy>
+ bool match(OpTy *V) {
+ if (V->getValueID() == Value::InstructionVal + Instruction::LShr ||
+ V->getValueID() == Value::InstructionVal + Instruction::AShr) {
+ ConcreteTy *I = cast<ConcreteTy>(V);
+ return (I->getOpcode() == Instruction::AShr ||
+ I->getOpcode() == Instruction::LShr) &&
+ L.match(I->getOperand(0)) &&
+ R.match(I->getOperand(1));
+ }
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
+ return (CE->getOpcode() == Instruction::LShr ||
+ CE->getOpcode() == Instruction::AShr) &&
+ L.match(CE->getOperand(0)) &&
+ R.match(CE->getOperand(1));
+ return false;
+ }
+};
+
+template<typename LHS, typename RHS>
+inline Shr_match<LHS, RHS> m_Shr(const LHS &L, const RHS &R) {
+ return Shr_match<LHS, RHS>(L, R);
+}
+
+//===----------------------------------------------------------------------===//
+// Matchers for binary classes
+//
+
+template<typename LHS_t, typename RHS_t, typename Class, typename OpcType>
+struct BinaryOpClass_match {
+ OpcType *Opcode;
+ LHS_t L;
+ RHS_t R;
+
+ BinaryOpClass_match(OpcType &Op, const LHS_t &LHS,
+ const RHS_t &RHS)
+ : Opcode(&Op), L(LHS), R(RHS) {}
+ BinaryOpClass_match(const LHS_t &LHS, const RHS_t &RHS)
+ : Opcode(0), L(LHS), R(RHS) {}
+
+ template<typename OpTy>
+ bool match(OpTy *V) {
+ if (Class *I = dyn_cast<Class>(V))
+ if (L.match(I->getOperand(0)) && R.match(I->getOperand(1))) {
+ if (Opcode)
+ *Opcode = I->getOpcode();
+ return true;
+ }
+#if 0 // Doesn't handle constantexprs yet!
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
+ return CE->getOpcode() == Opcode && L.match(CE->getOperand(0)) &&
+ R.match(CE->getOperand(1));
+#endif
+ return false;
+ }
+};
+
+template<typename LHS, typename RHS>
+inline BinaryOpClass_match<LHS, RHS, BinaryOperator, Instruction::BinaryOps>
+m_Shift(Instruction::BinaryOps &Op, const LHS &L, const RHS &R) {
+ return BinaryOpClass_match<LHS, RHS,
+ BinaryOperator, Instruction::BinaryOps>(Op, L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOpClass_match<LHS, RHS, BinaryOperator, Instruction::BinaryOps>
+m_Shift(const LHS &L, const RHS &R) {
+ return BinaryOpClass_match<LHS, RHS,
+ BinaryOperator, Instruction::BinaryOps>(L, R);
+}
+
+//===----------------------------------------------------------------------===//
+// Matchers for CmpInst classes
+//
+
+template<typename LHS_t, typename RHS_t, typename Class, typename PredicateTy>
+struct CmpClass_match {
+ PredicateTy &Predicate;
+ LHS_t L;
+ RHS_t R;
+
+ CmpClass_match(PredicateTy &Pred, const LHS_t &LHS,
+ const RHS_t &RHS)
+ : Predicate(Pred), L(LHS), R(RHS) {}
+
+ template<typename OpTy>
+ bool match(OpTy *V) {
+ if (Class *I = dyn_cast<Class>(V))
+ if (L.match(I->getOperand(0)) && R.match(I->getOperand(1))) {
+ Predicate = I->getPredicate();
+ return true;
+ }
+ return false;
+ }
+};
+
+template<typename LHS, typename RHS>
+inline CmpClass_match<LHS, RHS, ICmpInst, ICmpInst::Predicate>
+m_ICmp(ICmpInst::Predicate &Pred, const LHS &L, const RHS &R) {
+ return CmpClass_match<LHS, RHS,
+ ICmpInst, ICmpInst::Predicate>(Pred, L, R);
+}
+
+template<typename LHS, typename RHS>
+inline CmpClass_match<LHS, RHS, FCmpInst, FCmpInst::Predicate>
+m_FCmp(FCmpInst::Predicate &Pred, const LHS &L, const RHS &R) {
+ return CmpClass_match<LHS, RHS,
+ FCmpInst, FCmpInst::Predicate>(Pred, L, R);
+}
+
+//===----------------------------------------------------------------------===//
+// Matchers for unary operators
+//
+
+template<typename LHS_t>
+struct not_match {
+ LHS_t L;
+
+ not_match(const LHS_t &LHS) : L(LHS) {}
+
+ template<typename OpTy>
+ bool match(OpTy *V) {
+ if (Instruction *I = dyn_cast<Instruction>(V))
+ if (I->getOpcode() == Instruction::Xor)
+ return matchIfNot(I->getOperand(0), I->getOperand(1));
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
+ if (CE->getOpcode() == Instruction::Xor)
+ return matchIfNot(CE->getOperand(0), CE->getOperand(1));
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(V))
+ return L.match(ConstantExpr::getNot(CI));
+ return false;
+ }
+private:
+ bool matchIfNot(Value *LHS, Value *RHS) {
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(RHS))
+ return CI->isAllOnesValue() && L.match(LHS);
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(LHS))
+ return CI->isAllOnesValue() && L.match(RHS);
+ if (ConstantVector *CV = dyn_cast<ConstantVector>(RHS))
+ return CV->isAllOnesValue() && L.match(LHS);
+ if (ConstantVector *CV = dyn_cast<ConstantVector>(LHS))
+ return CV->isAllOnesValue() && L.match(RHS);
+ return false;
+ }
+};
+
+template<typename LHS>
+inline not_match<LHS> m_Not(const LHS &L) { return L; }
+
+
+//===----------------------------------------------------------------------===//
+// Matchers for control flow
+//
+
+template<typename Cond_t>
+struct brc_match {
+ Cond_t Cond;
+ BasicBlock *&T, *&F;
+ brc_match(const Cond_t &C, BasicBlock *&t, BasicBlock *&f)
+ : Cond(C), T(t), F(f) {
+ }
+
+ template<typename OpTy>
+ bool match(OpTy *V) {
+ if (BranchInst *BI = dyn_cast<BranchInst>(V))
+ if (BI->isConditional()) {
+ if (Cond.match(BI->getCondition())) {
+ T = BI->getSuccessor(0);
+ F = BI->getSuccessor(1);
+ return true;
+ }
+ }
+ return false;
+ }
+};
+
+template<typename Cond_t>
+inline brc_match<Cond_t> m_Br(const Cond_t &C, BasicBlock *&T, BasicBlock *&F){
+ return brc_match<Cond_t>(C, T, F);
+}
+
+
+}} // end llvm::match
+
+
+#endif
+
diff --git a/support/include/llvm/Support/PluginLoader.h b/support/include/llvm/Support/PluginLoader.h
new file mode 100644
index 0000000..7789ae8
--- /dev/null
+++ b/support/include/llvm/Support/PluginLoader.h
@@ -0,0 +1,37 @@
+//===-- llvm/Support/PluginLoader.h - Plugin Loader for Tools ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// A tool can #include this file to get a -load option that allows the user to
+// load arbitrary shared objects into the tool's address space. Note that this
+// header can only be included by a program ONCE, so it should never to used by
+// library authors.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_PLUGINLOADER_H
+#define LLVM_SUPPORT_PLUGINLOADER_H
+
+#include "llvm/Support/CommandLine.h"
+
+namespace llvm {
+ struct PluginLoader {
+ void operator=(const std::string &Filename);
+ static unsigned getNumPlugins();
+ static std::string& getPlugin(unsigned num);
+ };
+
+#ifndef DONT_GET_PLUGIN_LOADER_OPTION
+ // This causes operator= above to be invoked for every -load option.
+ static cl::opt<PluginLoader, false, cl::parser<std::string> >
+ LoadOpt("load", cl::ZeroOrMore, cl::value_desc("pluginfilename"),
+ cl::desc("Load the specified plugin"));
+#endif
+}
+
+#endif
diff --git a/support/include/llvm/Support/Registry.h b/support/include/llvm/Support/Registry.h
new file mode 100644
index 0000000..7488773
--- /dev/null
+++ b/support/include/llvm/Support/Registry.h
@@ -0,0 +1,239 @@
+//=== Registry.h - Linker-supported plugin registries -----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Gordon Henriksen and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Defines a registry template for discovering pluggable modules.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_REGISTRY_H
+#define LLVM_SUPPORT_REGISTRY_H
+
+#include "llvm/Support/CommandLine.h"
+
+namespace llvm {
+ /// A simple registry entry which provides only a name, description, and
+ /// no-argument constructor.
+ template <typename T>
+ class SimpleRegistryEntry {
+ const char *Name, *Desc;
+ T *(*Ctor)();
+
+ public:
+ SimpleRegistryEntry(const char *N, const char *D, T *(*C)())
+ : Name(N), Desc(D), Ctor(C)
+ {}
+
+ const char *getName() const { return Name; }
+ const char *getDesc() const { return Desc; }
+ T *instantiate() const { return Ctor(); }
+ };
+
+
+ /// Traits for registry entries. If using other than SimpleRegistryEntry, it
+ /// is necessary to define an alternate traits class.
+ template <typename T>
+ class RegistryTraits {
+ RegistryTraits(); // Do not implement.
+
+ public:
+ typedef SimpleRegistryEntry<T> entry;
+
+ /// Accessors for .
+ ///
+ static const char *nameof(const entry &Entry) { return Entry.getName(); }
+ static const char *descof(const entry &Entry) { return Entry.getDesc(); }
+ };
+
+
+ /// A global registry used in conjunction with static constructors to make
+ /// pluggable components (like targets or garbage collectors) "just work" when
+ /// linked with an executable.
+ template <typename T, typename U = RegistryTraits<T> >
+ class Registry {
+ public:
+ typedef U traits;
+ typedef typename U::entry entry;
+
+ class node;
+ class listener;
+ class iterator;
+
+ private:
+ Registry(); // Do not implement.
+
+ static void Announce(const entry &E) {
+ for (listener *Cur = ListenerHead; Cur; Cur = Cur->Next)
+ Cur->registered(E);
+ }
+
+ friend class node;
+ static node *Head, *Tail;
+
+ friend class listener;
+ static listener *ListenerHead, *ListenerTail;
+
+ public:
+ class iterator;
+
+
+ /// Node in linked list of entries.
+ ///
+ class node {
+ friend class iterator;
+
+ node *Next;
+ const entry& Val;
+
+ public:
+ node(const entry& V) : Next(0), Val(V) {
+ if (Tail)
+ Tail->Next = this;
+ else
+ Head = this;
+ Tail = this;
+
+ Announce(V);
+ }
+ };
+
+
+ /// Iterators for registry entries.
+ ///
+ class iterator {
+ const node *Cur;
+
+ public:
+ explicit iterator(const node *N) : Cur(N) {}
+
+ bool operator==(const iterator &That) const { return Cur == That.Cur; }
+ bool operator!=(const iterator &That) const { return Cur != That.Cur; }
+ iterator &operator++() { Cur = Cur->Next; return *this; }
+ const entry &operator*() const { return Cur->Val; }
+ const entry *operator->() const { return &Cur->Val; }
+ };
+
+ static iterator begin() { return iterator(Head); }
+ static iterator end() { return iterator(0); }
+
+
+ /// Abstract base class for registry listeners, which are informed when new
+ /// entries are added to the registry. Simply subclass and instantiate:
+ ///
+ /// class CollectorPrinter : public Registry<Collector>::listener {
+ /// protected:
+ /// void registered(const Registry<Collector>::entry &e) {
+ /// cerr << "collector now available: " << e->getName() << "\n";
+ /// }
+ ///
+ /// public:
+ /// CollectorPrinter() { init(); } // Print those already registered.
+ /// };
+ ///
+ /// CollectorPrinter Printer;
+ ///
+ class listener {
+ listener *Prev, *Next;
+
+ friend void Registry::Announce(const entry &E);
+
+ protected:
+ /// Called when an entry is added to the registry.
+ ///
+ virtual void registered(const entry &) = 0;
+
+ /// Calls 'registered' for each pre-existing entry.
+ ///
+ void init() {
+ for (iterator I = begin(), E = end(); I != E; ++I)
+ registered(*I);
+ }
+
+ public:
+ listener() : Prev(ListenerTail), Next(0) {
+ if (Prev)
+ Prev->Next = this;
+ else
+ ListenerHead = this;
+ ListenerTail = this;
+ }
+
+ virtual ~listener() {
+ if (Next)
+ Next->Prev = Prev;
+ else
+ ListenerTail = Prev;
+ if (Prev)
+ Prev->Next = Next;
+ else
+ ListenerHead = Next;
+ }
+ };
+
+
+ /// A static registration template. Use like such:
+ ///
+ /// Registry<Collector>::Add<FancyGC>
+ /// X("fancy-gc", "Newfangled garbage collector.");
+ ///
+ /// Use of this template requires that:
+ ///
+ /// 1. The registered subclass has a default constructor.
+ //
+ /// 2. The registry entry type has a constructor compatible with this
+ /// signature:
+ ///
+ /// entry(const char *Name, const char *ShortDesc, T *(*Ctor)());
+ ///
+ /// If you have more elaborate requirements, then copy and modify.
+ ///
+ template <typename V>
+ class Add {
+ entry Entry;
+ node Node;
+
+ static T *CtorFn() { return new V(); }
+
+ public:
+ Add(const char *Name, const char *Desc)
+ : Entry(Name, Desc, CtorFn), Node(Entry) {}
+ };
+
+
+ /// A command-line parser for a registry. Use like such:
+ ///
+ /// static cl::opt<Registry<Collector>::entry, false,
+ /// Registry<Collector>::Parser>
+ /// GCOpt("gc", cl::desc("Garbage collector to use."),
+ /// cl::value_desc());
+ ///
+ /// To make use of the value:
+ ///
+ /// Collector *TheCollector = GCOpt->instantiate();
+ ///
+ class Parser : public cl::parser<const typename U::entry*>, public listener{
+ typedef U traits;
+ typedef typename U::entry entry;
+
+ protected:
+ void registered(const entry &E) {
+ addLiteralOption(traits::nameof(E), &E, traits::descof(E));
+ }
+
+ public:
+ void initialize(cl::Option &O) {
+ listener::init();
+ cl::parser<const typename U::entry*>::initialize(O);
+ }
+ };
+
+ };
+
+}
+
+#endif
diff --git a/support/include/llvm/Support/SlowOperationInformer.h b/support/include/llvm/Support/SlowOperationInformer.h
new file mode 100644
index 0000000..d057926
--- /dev/null
+++ b/support/include/llvm/Support/SlowOperationInformer.h
@@ -0,0 +1,65 @@
+//===- llvm/Support/SlowOperationInformer.h - Keep user informed *- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines a simple object which can be used to let the user know what
+// is going on when a slow operation is happening, and gives them the ability to
+// cancel it. Potentially slow operations can stack allocate one of these
+// objects, and periodically call the "progress" method to update the progress
+// bar. If the operation takes more than 1 second to complete, the progress bar
+// is automatically shown and updated. As such, the slow operation should not
+// print stuff to the screen, and should not be confused if an extra line
+// appears on the screen (ie, the cursor should be at the start of the line).
+//
+// If the user presses CTRL-C during the operation, the next invocation of the
+// progress method return true indicating that the operation was cancelled.
+//
+// Because SlowOperationInformers fiddle around with signals, they cannot be
+// nested, and interact poorly with threads. The SIGALRM handler is set back to
+// SIGDFL, but the SIGINT signal handler is restored when the
+// SlowOperationInformer is destroyed.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_SLOW_OPERATION_INFORMER_H
+#define LLVM_SUPPORT_SLOW_OPERATION_INFORMER_H
+
+#include <string>
+#include <cassert>
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+ class SlowOperationInformer {
+ std::string OperationName;
+ unsigned LastPrintAmount;
+
+ SlowOperationInformer(const SlowOperationInformer&); // DO NOT IMPLEMENT
+ void operator=(const SlowOperationInformer&); // DO NOT IMPLEMENT
+ public:
+ SlowOperationInformer(const std::string &Name);
+ ~SlowOperationInformer();
+
+ /// progress - Clients should periodically call this method when they can
+ /// handle cancellation. The Amount variable should indicate how far
+ /// along the operation is, given in 1/10ths of a percent (in other words,
+ /// Amount should range from 0 to 1000). If the user cancels the operation,
+ /// this returns true, false otherwise.
+ bool progress(unsigned Amount);
+
+ /// progress - Same as the method above, but this performs the division for
+ /// you, and helps you avoid overflow if you are dealing with largish
+ /// numbers.
+ bool progress(unsigned Current, unsigned Maximum) {
+ assert(Maximum != 0 &&
+ "Shouldn't be doing work if there is nothing to do!");
+ return progress(Current*uint64_t(1000UL)/Maximum);
+ }
+ };
+} // end namespace llvm
+
+#endif /* SLOW_OPERATION_INFORMER_H */
diff --git a/support/include/llvm/Support/StableBasicBlockNumbering.h b/support/include/llvm/Support/StableBasicBlockNumbering.h
new file mode 100644
index 0000000..3ba72ea
--- /dev/null
+++ b/support/include/llvm/Support/StableBasicBlockNumbering.h
@@ -0,0 +1,59 @@
+//===- StableBasicBlockNumbering.h - Provide BB identifiers -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This class provides a *stable* numbering of basic blocks that does not depend
+// on their address in memory (which is nondeterministic). When requested, this
+// class simply provides a unique ID for each basic block in the function
+// specified and the inverse mapping.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_STABLEBASICBLOCKNUMBERING_H
+#define LLVM_SUPPORT_STABLEBASICBLOCKNUMBERING_H
+
+#include "llvm/Function.h"
+#include "llvm/ADT/UniqueVector.h"
+
+namespace llvm {
+ class StableBasicBlockNumbering {
+ // BBNumbering - Holds the numbering.
+ UniqueVector<BasicBlock*> BBNumbering;
+ public:
+ StableBasicBlockNumbering(Function *F = 0) {
+ if (F) compute(*F);
+ }
+
+ /// compute - If we have not computed a numbering for the function yet, do
+ /// so.
+ void compute(Function &F) {
+ if (BBNumbering.empty()) {
+ for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I)
+ BBNumbering.insert(I);
+ }
+ }
+
+ /// getNumber - Return the ID number for the specified BasicBlock.
+ ///
+ unsigned getNumber(BasicBlock *BB) const {
+ unsigned Idx = BBNumbering.idFor(BB);
+ assert(Idx && "Invalid basic block or numbering not computed!");
+ return Idx-1;
+ }
+
+ /// getBlock - Return the BasicBlock corresponding to a particular ID.
+ ///
+ BasicBlock *getBlock(unsigned N) const {
+ assert(N < BBNumbering.size() &&
+ "Block ID out of range or numbering not computed!");
+ return BBNumbering[N+1];
+ }
+ };
+}
+
+#endif
diff --git a/support/include/llvm/Support/Streams.h b/support/include/llvm/Support/Streams.h
new file mode 100644
index 0000000..6758c35
--- /dev/null
+++ b/support/include/llvm/Support/Streams.h
@@ -0,0 +1,72 @@
+//===- llvm/Support/Streams.h - Wrappers for iostreams ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Bill Wendling and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a wrapper for the STL I/O streams. It prevents the need
+// to include <iostream> in a file just to get I/O.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_STREAMS_H
+#define LLVM_SUPPORT_STREAMS_H
+
+#include <iosfwd>
+
+namespace llvm {
+
+ /// BaseStream - Acts like the STL streams. It's a wrapper for the std::cerr,
+ /// std::cout, std::cin, etc. streams. However, it doesn't require #including
+ /// @verbatim <iostream> @endverbatm in every file (doing so increases static
+ /// c'tors & d'tors in the object code).
+ ///
+ template <typename StreamTy>
+ class BaseStream {
+ StreamTy *Stream;
+ public:
+ BaseStream() : Stream(0) {}
+ BaseStream(StreamTy &S) : Stream(&S) {}
+ BaseStream(StreamTy *S) : Stream(S) {}
+
+ StreamTy *stream() const { return Stream; }
+
+ inline BaseStream &operator << (StreamTy &(*Func)(StreamTy&)) {
+ if (Stream) *Stream << Func;
+ return *this;
+ }
+
+ template <typename Ty>
+ BaseStream &operator << (const Ty &Thing) {
+ if (Stream) *Stream << Thing;
+ return *this;
+ }
+
+ template <typename Ty>
+ BaseStream &operator >> (const Ty &Thing) {
+ if (Stream) *Stream >> Thing;
+ return *this;
+ }
+
+ operator StreamTy* () { return Stream; }
+
+ bool operator == (const StreamTy &S) { return &S == Stream; }
+ bool operator != (const StreamTy &S) { return !(*this == S); }
+ bool operator == (const BaseStream &S) { return S.Stream == Stream; }
+ bool operator != (const BaseStream &S) { return !(*this == S); }
+ };
+
+ typedef BaseStream<std::ostream> OStream;
+ typedef BaseStream<std::istream> IStream;
+ typedef BaseStream<std::stringstream> StringStream;
+
+ extern OStream cout;
+ extern OStream cerr;
+ extern IStream cin;
+
+} // End llvm namespace
+
+#endif
diff --git a/support/include/llvm/Support/SystemUtils.h b/support/include/llvm/Support/SystemUtils.h
new file mode 100644
index 0000000..6dc5c27
--- /dev/null
+++ b/support/include/llvm/Support/SystemUtils.h
@@ -0,0 +1,42 @@
+//===- SystemUtils.h - Utilities to do low-level system stuff ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains functions used to do a variety of low-level, often
+// system-specific, tasks.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_SYSTEMUTILS_H
+#define LLVM_SUPPORT_SYSTEMUTILS_H
+
+#include "llvm/System/Program.h"
+
+namespace llvm {
+
+/// Determine if the ostream provided is connected to the std::cout and
+/// displayed or not (to a console window). If so, generate a warning message
+/// advising against display of bitcode and return true. Otherwise just return
+/// false
+/// @brief Check for output written to a console
+bool CheckBitcodeOutputToConsole(
+ std::ostream* stream_to_check, ///< The stream to be checked
+ bool print_warning = true ///< Control whether warnings are printed
+);
+
+/// FindExecutable - Find a named executable, giving the argv[0] of program
+/// being executed. This allows us to find another LLVM tool if it is built into
+/// the same directory, but that directory is neither the current directory, nor
+/// in the PATH. If the executable cannot be found, return an empty string.
+/// @brief Find a named executable.
+sys::Path FindExecutable(const std::string &ExeName,
+ const std::string &ProgramPath);
+
+} // End llvm namespace
+
+#endif
diff --git a/support/include/llvm/Support/Timer.h b/support/include/llvm/Support/Timer.h
new file mode 100644
index 0000000..5a97f49
--- /dev/null
+++ b/support/include/llvm/Support/Timer.h
@@ -0,0 +1,165 @@
+//===-- llvm/Support/Timer.h - Interval Timing Support ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines three classes: Timer, TimeRegion, and TimerGroup,
+// documented below.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_TIMER_H
+#define LLVM_SUPPORT_TIMER_H
+
+#include "llvm/Support/DataTypes.h"
+#include <string>
+#include <vector>
+#include <iosfwd>
+#include <cassert>
+
+namespace llvm {
+
+class TimerGroup;
+
+/// Timer - This class is used to track the amount of time spent between
+/// invocations of it's startTimer()/stopTimer() methods. Given appropriate OS
+/// support it can also keep track of the RSS of the program at various points.
+/// By default, the Timer will print the amount of time it has captured to
+/// standard error when the laster timer is destroyed, otherwise it is printed
+/// when it's TimerGroup is destroyed. Timer's do not print their information
+/// if they are never started.
+///
+class Timer {
+ double Elapsed; // Wall clock time elapsed in seconds
+ double UserTime; // User time elapsed
+ double SystemTime; // System time elapsed
+ ssize_t MemUsed; // Memory allocated (in bytes)
+ size_t PeakMem; // Peak memory used
+ size_t PeakMemBase; // Temporary for peak calculation...
+ std::string Name; // The name of this time variable
+ bool Started; // Has this time variable ever been started?
+ TimerGroup *TG; // The TimerGroup this Timer is in.
+public:
+ Timer(const std::string &N);
+ Timer(const std::string &N, TimerGroup &tg);
+ Timer(const Timer &T);
+ ~Timer();
+
+ double getProcessTime() const { return UserTime+SystemTime; }
+ double getWallTime() const { return Elapsed; }
+ ssize_t getMemUsed() const { return MemUsed; }
+ size_t getPeakMem() const { return PeakMem; }
+ std::string getName() const { return Name; }
+
+ const Timer &operator=(const Timer &T) {
+ Elapsed = T.Elapsed;
+ UserTime = T.UserTime;
+ SystemTime = T.SystemTime;
+ MemUsed = T.MemUsed;
+ PeakMem = T.PeakMem;
+ PeakMemBase = T.PeakMemBase;
+ Name = T.Name;
+ Started = T.Started;
+ assert(TG == T.TG && "Can only assign timers in the same TimerGroup!");
+ return *this;
+ }
+
+ // operator< - Allow sorting...
+ bool operator<(const Timer &T) const {
+ // Sort by Wall Time elapsed, as it is the only thing really accurate
+ return Elapsed < T.Elapsed;
+ }
+ bool operator>(const Timer &T) const { return T.operator<(*this); }
+
+ /// startTimer - Start the timer running. Time between calls to
+ /// startTimer/stopTimer is counted by the Timer class. Note that these calls
+ /// must be correctly paired.
+ ///
+ void startTimer();
+
+ /// stopTimer - Stop the timer.
+ ///
+ void stopTimer();
+
+ /// addPeakMemoryMeasurement - This method should be called whenever memory
+ /// usage needs to be checked. It adds a peak memory measurement to the
+ /// currently active timers, which will be printed when the timer group prints
+ ///
+ static void addPeakMemoryMeasurement();
+
+ /// print - Print the current timer to standard error, and reset the "Started"
+ /// flag.
+ void print(const Timer &Total, std::ostream &OS);
+
+private:
+ friend class TimerGroup;
+
+ // Copy ctor, initialize with no TG member.
+ Timer(bool, const Timer &T);
+
+ /// sum - Add the time accumulated in the specified timer into this timer.
+ ///
+ void sum(const Timer &T);
+};
+
+
+/// The TimeRegion class is used as a helper class to call the startTimer() and
+/// stopTimer() methods of the Timer class. When the object is constructed, it
+/// starts the timer specified as it's argument. When it is destroyed, it stops
+/// the relevant timer. This makes it easy to time a region of code.
+///
+class TimeRegion {
+ Timer &T;
+ TimeRegion(const TimeRegion &); // DO NOT IMPLEMENT
+public:
+ TimeRegion(Timer &t) : T(t) {
+ T.startTimer();
+ }
+ ~TimeRegion() {
+ T.stopTimer();
+ }
+};
+
+
+/// NamedRegionTimer - This class is basically a combination of TimeRegion and
+/// Timer. It allows you to declare a new timer, AND specify the region to
+/// time, all in one statement. All timers with the same name are merged. This
+/// is primarily used for debugging and for hunting performance problems.
+///
+struct NamedRegionTimer : public TimeRegion {
+ NamedRegionTimer(const std::string &Name);
+};
+
+
+/// The TimerGroup class is used to group together related timers into a single
+/// report that is printed when the TimerGroup is destroyed. It is illegal to
+/// destroy a TimerGroup object before all of the Timers in it are gone. A
+/// TimerGroup can be specified for a newly created timer in its constructor.
+///
+class TimerGroup {
+ std::string Name;
+ unsigned NumTimers;
+ std::vector<Timer> TimersToPrint;
+public:
+ TimerGroup(const std::string &name) : Name(name), NumTimers(0) {}
+ ~TimerGroup() {
+ assert(NumTimers == 0 &&
+ "TimerGroup destroyed before all contained timers!");
+ }
+
+private:
+ friend class Timer;
+ void addTimer() { ++NumTimers; }
+ void removeTimer();
+ void addTimerToPrint(const Timer &T) {
+ TimersToPrint.push_back(Timer(true, T));
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/support/include/llvm/Support/type_traits.h b/support/include/llvm/Support/type_traits.h
new file mode 100644
index 0000000..8befb25
--- /dev/null
+++ b/support/include/llvm/Support/type_traits.h
@@ -0,0 +1,54 @@
+//===- llvm/Support/type_traits.h - Simplfied type traits -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides a template class that determines if a type is a class or
+// not. The basic mechanism, based on using the pointer to member function of
+// a zero argument to a function was "boosted" from the boost type_traits
+// library. See http://www.boost.org/ for all the gory details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_TYPE_TRAITS_H
+#define LLVM_SUPPORT_TYPE_TRAITS_H
+
+// This is actually the conforming implementation which works with abstract
+// classes. However, enough compilers have trouble with it that most will use
+// the one in boost/type_traits/object_traits.hpp. This implementation actually
+// works with VC7.0, but other interactions seem to fail when we use it.
+
+namespace llvm {
+
+namespace dont_use
+{
+ // These two functions should never be used. They are helpers to
+ // the is_class template below. They cannot be located inside
+ // is_class because doing so causes at least GCC to think that
+ // the value of the "value" enumerator is not constant. Placing
+ // them out here (for some strange reason) allows the sizeof
+ // operator against them to magically be constant. This is
+ // important to make the is_class<T>::value idiom zero cost. it
+ // evaluates to a constant 1 or 0 depending on whether the
+ // parameter T is a class or not (respectively).
+ template<typename T> char is_class_helper(void(T::*)(void));
+ template<typename T> double is_class_helper(...);
+}
+
+template <typename T>
+struct is_class
+{
+ // is_class<> metafunction due to Paul Mensonides (leavings@attbi.com). For
+ // more details:
+ // http://groups.google.com/groups?hl=en&selm=000001c1cc83%24e154d5e0%247772e50c%40c161550a&rnum=1
+ public:
+ enum { value = sizeof(char) == sizeof(dont_use::is_class_helper<T>(0)) };
+};
+
+}
+
+#endif
diff --git a/support/include/llvm/System/Alarm.h b/support/include/llvm/System/Alarm.h
new file mode 100644
index 0000000..2b78da6
--- /dev/null
+++ b/support/include/llvm/System/Alarm.h
@@ -0,0 +1,49 @@
+//===- llvm/System/Alarm.h - Alarm Generation support ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides an operating system independent interface to alarm(2)
+// type functionality. The Alarm class allows a one-shot alarm to be set up
+// at some number of seconds in the future. When the alarm triggers, a method
+// is called to process the event
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_ALARM_H
+#define LLVM_SYSTEM_ALARM_H
+
+#include "llvm/System/IncludeFile.h"
+
+namespace llvm {
+namespace sys {
+
+ /// This function registers an alarm to trigger some number of \p seconds in
+ /// the future. When that time arrives, the AlarmStatus function will begin
+ /// to return 1 instead of 0. The user must poll the status of the alarm by
+ /// making occasional calls to AlarmStatus. If the user sends an interrupt
+ /// signal, AlarmStatus will begin returning -1, even if the alarm event
+ /// occurred.
+ /// @returns nothing
+ void SetupAlarm(
+ unsigned seconds ///< Number of seconds in future when alarm arrives
+ );
+
+ /// This function terminates the alarm previously set up
+ /// @returns nothing
+ void TerminateAlarm();
+
+ /// This function acquires the status of the alarm.
+ /// @returns -1=cancelled, 0=untriggered, 1=triggered
+ int AlarmStatus();
+
+} // End sys namespace
+} // End llvm namespace
+
+FORCE_DEFINING_FILE_TO_BE_LINKED(SystemAlarm)
+
+#endif
diff --git a/support/include/llvm/System/Disassembler.h b/support/include/llvm/System/Disassembler.h
new file mode 100644
index 0000000..fd08f2d
--- /dev/null
+++ b/support/include/llvm/System/Disassembler.h
@@ -0,0 +1,35 @@
+//===- llvm/Support/Disassembler.h ------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Anton Korobeynikov and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the necessary glue to call external disassembler
+// libraries.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_DISASSEMBLER_H
+#define LLVM_SYSTEM_DISASSEMBLER_H
+
+#include "llvm/Support/DataTypes.h"
+#include <string>
+
+namespace llvm {
+namespace sys {
+
+/// This function returns true, if there is possible to use some external
+/// disassembler library. False otherwise.
+bool hasDisassembler(void);
+
+/// This function provides some "glue" code to call external disassembler
+/// libraries.
+std::string disassembleBuffer(uint8_t* start, size_t length, uint64_t pc = 0);
+
+}
+}
+
+#endif // LLVM_SYSTEM_DISASSEMBLER_H
diff --git a/support/include/llvm/System/DynamicLibrary.h b/support/include/llvm/System/DynamicLibrary.h
new file mode 100644
index 0000000..5499f9d
--- /dev/null
+++ b/support/include/llvm/System/DynamicLibrary.h
@@ -0,0 +1,125 @@
+//===-- llvm/System/DynamicLibrary.h - Portable Dynamic Library -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the sys::DynamicLibrary class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_DYNAMIC_LIBRARY_H
+#define LLVM_SYSTEM_DYNAMIC_LIBRARY_H
+
+#include "llvm/System/Path.h"
+#include "llvm/System/IncludeFile.h"
+#include <string>
+
+namespace llvm {
+namespace sys {
+
+ /// This class provides a portable interface to dynamic libraries which also
+ /// might be known as shared libraries, shared objects, dynamic shared
+ /// objects, or dynamic link libraries. Regardless of the terminology or the
+ /// operating system interface, this class provides a portable interface that
+ /// allows dynamic libraries to be loaded and and searched for externally
+ /// defined symbols. This is typically used to provide "plug-in" support.
+ /// It also allows for symbols to be defined which don't live in any library,
+ /// but rather the main program itself, useful on Windows where the main
+ /// executable cannot be searched.
+ /// @since 1.4
+ /// @brief Portable dynamic library abstraction.
+ class DynamicLibrary {
+ /// @name Constructors
+ /// @{
+ public:
+ /// Construct a DynamicLibrary that represents the currently executing
+ /// program. The program must have been linked with -export-dynamic or
+ /// -dlopen self for this to work. Any symbols retrieved with the
+ /// GetAddressOfSymbol function will refer to the program not to any
+ /// library.
+ /// @throws std::string indicating why the program couldn't be opened.
+ /// @brief Open program as dynamic library.
+ DynamicLibrary();
+
+ /// After destruction, the symbols of the library will no longer be
+ /// available to the program. It is important to make sure the lifespan
+ /// of a DynamicLibrary exceeds the lifetime of the pointers returned
+ /// by the GetAddressOfSymbol otherwise the program may walk off into
+ /// uncharted territory.
+ /// @see GetAddressOfSymbol.
+ /// @brief Closes the DynamicLibrary
+ ~DynamicLibrary();
+
+ /// @}
+ /// @name Functions
+ /// @{
+ public:
+ /// This function allows a library to be loaded without instantiating a
+ /// DynamicLibrary object. Consequently, it is marked as being permanent
+ /// and will only be unloaded when the program terminates. This returns
+ /// false on success or returns true and fills in *ErrMsg on failure.
+ /// @brief Open a dynamic library permanently.
+ static bool LoadLibraryPermanently(const char* filename,
+ std::string *ErrMsg = 0);
+
+ /// This function will search through all previously loaded dynamic
+ /// libraries for the symbol \p symbolName. If it is found, the addressof
+ /// that symbol is returned. If not, null is returned. Note that this will
+ /// search permanently loaded libraries (LoadLibraryPermanently) as well
+ /// as ephemerally loaded libraries (constructors).
+ /// @throws std::string on error.
+ /// @brief Search through libraries for address of a symbol
+ static void* SearchForAddressOfSymbol(const char* symbolName);
+
+ /// @brief Convenience function for C++ophiles.
+ static void* SearchForAddressOfSymbol(const std::string& symbolName) {
+ return SearchForAddressOfSymbol(symbolName.c_str());
+ }
+
+ /// This functions permanently adds the symbol \p symbolName with the
+ /// value \p symbolValue. These symbols are searched before any
+ /// libraries.
+ /// @brief Add searchable symbol/value pair.
+ static void AddSymbol(const char* symbolName, void *symbolValue);
+
+ /// @brief Convenience function for C++ophiles.
+ static void AddSymbol(const std::string& symbolName, void *symbolValue) {
+ AddSymbol(symbolName.c_str(), symbolValue);
+ }
+
+ /// @}
+ /// @name Accessors
+ /// @{
+ public:
+ /// Looks up a \p symbolName in the DynamicLibrary and returns its address
+ /// if it exists. If the symbol does not exist, returns (void*)0.
+ /// @returns the address of the symbol or 0.
+ /// @brief Get the address of a symbol in the DynamicLibrary.
+ void* GetAddressOfSymbol(const char* symbolName);
+
+ /// @brief Convenience function for C++ophiles.
+ void* GetAddressOfSymbol(const std::string& symbolName) {
+ return GetAddressOfSymbol(symbolName.c_str());
+ }
+
+ /// @}
+ /// @name Implementation
+ /// @{
+ protected:
+ void* handle; // Opaque handle for information about the library
+
+ DynamicLibrary(const DynamicLibrary&); ///< Do not implement
+ DynamicLibrary& operator=(const DynamicLibrary&); ///< Do not implement
+ /// @}
+ };
+
+} // End sys namespace
+} // End llvm namespace
+
+FORCE_DEFINING_FILE_TO_BE_LINKED(SystemDynamicLibrary)
+
+#endif // LLVM_SYSTEM_DYNAMIC_LIBRARY_H
diff --git a/support/include/llvm/System/IncludeFile.h b/support/include/llvm/System/IncludeFile.h
new file mode 100644
index 0000000..c9f3882
--- /dev/null
+++ b/support/include/llvm/System/IncludeFile.h
@@ -0,0 +1,65 @@
+//===- llvm/System/IncludeFile.h - Ensure Linking Of Library ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the FORCE_DEFINING_FILE_TO_BE_LINKED and DEFINE_FILE_FOR
+// macros.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_INCLUDEFILE_H
+#define LLVM_SYSTEM_INCLUDEFILE_H
+
+/// This macro is the public interface that IncludeFile.h exports. This gives
+/// us the option to implement the "link the definition" capability in any
+/// manner that we choose. All header files that depend on a specific .cpp
+/// file being linked at run time should use this macro instead of the
+/// IncludeFile class directly.
+///
+/// For example, foo.h would use:<br/>
+/// <tt>FORCE_DEFINING_FILE_TO_BE_LINKED(foo)</tt><br/>
+///
+/// And, foo.cp would use:<br/>
+/// <tt>DEFINING_FILE_FOR(foo)</tt><br/>
+#define FORCE_DEFINING_FILE_TO_BE_LINKED(name) \
+ namespace llvm { \
+ extern char name ## LinkVar; \
+ static IncludeFile name ## LinkObj ( &name ## LinkVar ); \
+ }
+
+/// This macro is the counterpart to FORCE_DEFINING_FILE_TO_BE_LINKED. It should
+/// be used in a .cpp file to define the name referenced in a header file that
+/// will cause linkage of the .cpp file. It should only be used at extern level.
+#define DEFINING_FILE_FOR(name) namespace llvm { char name ## LinkVar; }
+
+namespace llvm {
+
+/// This class is used in the implementation of FORCE_DEFINING_FILE_TO_BE_LINKED
+/// macro to make sure that the implementation of a header file is included
+/// into a tool that uses the header. This is solely
+/// to overcome problems linking .a files and not getting the implementation
+/// of compilation units we need. This is commonly an issue with the various
+/// Passes but also occurs elsewhere in LLVM. We like to use .a files because
+/// they link faster and provide the smallest executables. However, sometimes
+/// those executables are too small, if the program doesn't reference something
+/// that might be needed, especially by a loaded share object. This little class
+/// helps to resolve that problem. The basic strategy is to use this class in
+/// a header file and pass the address of a variable to the constructor. If the
+/// variable is defined in the header file's corresponding .cpp file then all
+/// tools/libraries that #include the header file will require the .cpp as well.
+/// For example:<br/>
+/// <tt>extern int LinkMyCodeStub;</tt><br/>
+/// <tt>static IncludeFile LinkMyModule(&LinkMyCodeStub);</tt><br/>
+/// @brief Class to ensure linking of corresponding object file.
+struct IncludeFile {
+ IncludeFile(void *);
+};
+
+}
+
+#endif
diff --git a/support/include/llvm/System/LICENSE.TXT b/support/include/llvm/System/LICENSE.TXT
new file mode 100644
index 0000000..f569da2
--- /dev/null
+++ b/support/include/llvm/System/LICENSE.TXT
@@ -0,0 +1,6 @@
+LLVM System Interface Library
+-------------------------------------------------------------------------------
+The LLVM System Interface Library is licensed under the Illinois Open Source
+License and has the following additional copyright:
+
+Copyright (C) 2004 eXtensible Systems, Inc.
diff --git a/support/include/llvm/System/MappedFile.h b/support/include/llvm/System/MappedFile.h
new file mode 100644
index 0000000..6276bc3
--- /dev/null
+++ b/support/include/llvm/System/MappedFile.h
@@ -0,0 +1,175 @@
+//===- llvm/System/MappedFile.h - MappedFile OS Concept ---------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the llvm::sys::MappedFile class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_MAPPEDFILE_H
+#define LLVM_SYSTEM_MAPPEDFILE_H
+
+#include "llvm/System/Path.h"
+#include "llvm/System/IncludeFile.h"
+
+namespace llvm {
+namespace sys {
+
+ /// Forward declare a class used for holding platform specific information
+ /// that needs to be
+ struct MappedFileInfo;
+
+ /// This class provides an abstraction for a memory mapped file in the
+ /// operating system's filesystem. It provides platform independent operations
+ /// for mapping a file into memory for both read and write access. This class
+ /// does not provide facilities for finding the file or operating on paths to
+ /// files. The sys::Path class is used for that.
+ /// @since 1.4
+ /// @brief An abstraction for memory mapped files.
+ class MappedFile {
+ /// @name Types
+ /// @{
+ public:
+ enum MappingOptions {
+ READ_ACCESS = 0x0001, ///< Map the file for reading
+ WRITE_ACCESS = 0x0002, ///< Map the file for write access
+ EXEC_ACCESS = 0x0004, ///< Map the file for execution access
+ SHARED_MAPPING = 0x0008 ///< Map the file shared with other processes
+ };
+ /// @}
+ /// @name Constructors
+ /// @{
+ public:
+ /// Construct a MappedFile to the \p path in the operating system's file
+ /// system with the mapping \p options provided.
+ /// @throws std::string if an error occurs
+ MappedFile() : path_(), options_(READ_ACCESS), base_(0), info_(0) {}
+
+ /// Destruct a MappedFile and release all memory associated with it.
+ /// @throws std::string if an error occurs
+ ~MappedFile() { if (info_) terminate(); }
+
+ /// @}
+ /// @name Accessors
+ /// @{
+ public:
+ /// This function determines if the file is currently mapped or not.
+ /// @returns true iff the file is mapped into memory, false otherwise
+ /// @brief Determine if a MappedFile is currently mapped
+ /// @throws nothing
+ bool isMapped() const { return base_ != 0; }
+
+ /// This function returns a void* pointer to the base address of the file
+ /// mapping. This is the memory address of the first byte in the file.
+ /// Note that although a non-const pointer is returned, the memory might
+ /// not actually be writable, depending on the MappingOptions used when
+ /// the MappedFile was opened.
+ /// @returns The base pointer to the memory mapped file.
+ /// @brief Obtain the base pointer to the memory mapped file.
+ /// @throws nothing
+ void* base() const { return base_; }
+
+ /// This function returns a char* pointer to the base address of the file
+ /// mapping. This is the memory address of the first byte in the file.
+ /// Note that although a non-const pointer is returned, the memory might
+ /// not actually be writable, depending on the MappingOptions used when
+ /// the MappedFile was opened.
+ /// @returns The base pointer to the memory mapped file as a char pointer.
+ /// @brief Obtain the base pointer to the memory mapped file.
+ /// @throws nothing
+ char* charBase() const { return reinterpret_cast<char*>(base_); }
+
+ /// This function returns a reference to the sys::Path object kept by the
+ /// MappedFile object. This contains the path to the file that is or
+ /// will be mapped.
+ /// @returns sys::Path containing the path name.
+ /// @brief Returns the mapped file's path as a sys::Path
+ /// @throws nothing
+ const sys::Path& path() const { return path_; }
+
+ /// This function returns the number of bytes in the file.
+ /// @throws std::string if an error occurs
+ size_t size() const;
+
+ /// @}
+ /// @name Mutators
+ /// @{
+ public:
+ /// Open a file to be mapped and get its size but don't map it yet.
+ /// @returns true if an error occurred
+ bool open(
+ const sys::Path& p, ///< Path to file to be mapped
+ int options = READ_ACCESS, ///< Access mode for the mapping
+ std::string* ErrMsg = 0 ///< Optional error string pointer
+ ) {
+ path_ = p;
+ options_ = options;
+ return initialize(ErrMsg);
+ }
+
+ /// The mapped file is removed from memory. If the file was mapped for
+ /// write access, the memory contents will be automatically synchronized
+ /// with the file's disk contents.
+ /// @brief Remove the file mapping from memory.
+ void unmap();
+
+ /// The mapped file is put into memory.
+ /// @returns The base memory address of the mapped file or 0 if an error
+ /// occurred.
+ /// @brief Map the file into memory.
+ void* map(
+ std::string* ErrMsg = 0///< Optional error string pointer
+ );
+
+ /// This method causes the size of the file, and consequently the size
+ /// of the mapping to be set. This is logically the same as unmap(),
+ /// adjust size of the file, map(). Consequently, when calling this
+ /// function, the caller should not rely on previous results of the
+ /// map(), base(), or baseChar() members as they may point to invalid
+ /// areas of memory after this call.
+ /// @throws std::string if an error occurs
+ /// @brief Set the size of the file and memory mapping.
+ bool size(size_t new_size, std::string* ErrMsg = 0);
+
+ void close() { if (info_) terminate(); }
+
+ /// @}
+ /// @name Implementation
+ /// @{
+ private:
+ /// @brief Initialize platform-specific portion
+ bool initialize(std::string* ErrMsg);
+
+ /// @brief Terminate platform-specific portion
+ void terminate();
+
+ /// @}
+ /// @name Data
+ /// @{
+ private:
+ sys::PathWithStatus path_; ///< Path to the file.
+ int options_; ///< Options used to create the mapping
+ void* base_; ///< Pointer to the base memory address
+ mutable MappedFileInfo* info_; ///< Platform specific info for the mapping
+
+ /// @}
+ /// @name Disabled
+ /// @{
+ private:
+ ///< Disallow assignment
+ MappedFile& operator = ( const MappedFile & that );
+ ///< Disallow copying
+ MappedFile(const MappedFile& that);
+ /// @}
+ };
+}
+}
+
+FORCE_DEFINING_FILE_TO_BE_LINKED(SystemMappedFile)
+
+#endif
diff --git a/support/include/llvm/System/Memory.h b/support/include/llvm/System/Memory.h
new file mode 100644
index 0000000..c343177
--- /dev/null
+++ b/support/include/llvm/System/Memory.h
@@ -0,0 +1,76 @@
+//===- llvm/System/Memory.h - Memory Support --------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the llvm::sys::Memory class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_MEMORY_H
+#define LLVM_SYSTEM_MEMORY_H
+
+#include <string>
+#include "llvm/System/IncludeFile.h"
+
+namespace llvm {
+namespace sys {
+
+ /// This class encapsulates the notion of a memory block which has an address
+ /// and a size. It is used by the Memory class (a friend) as the result of
+ /// various memory allocation operations.
+ /// @see Memory
+ /// @brief Memory block abstraction.
+ class MemoryBlock {
+ public:
+ void *base() const { return Address; }
+ unsigned size() const { return Size; }
+ private:
+ void *Address; ///< Address of first byte of memory area
+ unsigned Size; ///< Size, in bytes of the memory area
+ friend class Memory;
+ };
+
+ /// This class provides various memory handling functions that manipulate
+ /// MemoryBlock instances.
+ /// @since 1.4
+ /// @brief An abstraction for memory operations.
+ class Memory {
+ /// @name Functions
+ /// @{
+ public:
+ /// This method allocates a block of Read/Write/Execute memory that is
+ /// suitable for executing dynamically generated code (e.g. JIT). An
+ /// attempt to allocate \p NumBytes bytes of virtual memory is made.
+ /// \p NearBlock may point to an existing allocation in which case
+ /// an attempt is made to allocate more memory near the existing block.
+ ///
+ /// On success, this returns a non-null memory block, otherwise it returns
+ /// a null memory block and fills in *ErrMsg.
+ ///
+ /// @brief Allocate Read/Write/Execute memory.
+ static MemoryBlock AllocateRWX(unsigned NumBytes,
+ const MemoryBlock *NearBlock,
+ std::string *ErrMsg = 0);
+
+ /// This method releases a block of Read/Write/Execute memory that was
+ /// allocated with the AllocateRWX method. It should not be used to
+ /// release any memory block allocated any other way.
+ ///
+ /// On success, this returns false, otherwise it returns true and fills
+ /// in *ErrMsg.
+ /// @throws std::string if an error occurred.
+ /// @brief Release Read/Write/Execute memory.
+ static bool ReleaseRWX(MemoryBlock &block, std::string *ErrMsg = 0);
+ /// @}
+ };
+}
+}
+
+FORCE_DEFINING_FILE_TO_BE_LINKED(SystemMemory)
+
+#endif
diff --git a/support/include/llvm/System/Mutex.h b/support/include/llvm/System/Mutex.h
new file mode 100644
index 0000000..27bcea1
--- /dev/null
+++ b/support/include/llvm/System/Mutex.h
@@ -0,0 +1,88 @@
+//===- llvm/System/Mutex.h - Mutex Operating System Concept -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the llvm::sys::Mutex class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_MUTEX_H
+#define LLVM_SYSTEM_MUTEX_H
+
+#include "llvm/System/IncludeFile.h"
+
+namespace llvm
+{
+ namespace sys
+ {
+ /// @brief Platform agnostic Mutex class.
+ class Mutex
+ {
+ /// @name Constructors
+ /// @{
+ public:
+
+ /// Initializes the lock but doesn't acquire it. if \p recursive is set
+ /// to false, the lock will not be recursive which makes it cheaper but
+ /// also more likely to deadlock (same thread can't acquire more than
+ /// once).
+ /// @brief Default Constructor.
+ Mutex ( bool recursive = true );
+
+ /// Releases and removes the lock
+ /// @brief Destructor
+ ~Mutex ( void );
+
+ /// @}
+ /// @name Methods
+ /// @{
+ public:
+
+ /// Attempts to unconditionally acquire the lock. If the lock is held by
+ /// another thread, this method will wait until it can acquire the lock.
+ /// @returns false if any kind of error occurs, true otherwise.
+ /// @brief Unconditionally acquire the lock.
+ bool acquire();
+
+ /// Attempts to release the lock. If the lock is held by the current
+ /// thread, the lock is released allowing other threads to acquire the
+ /// lock.
+ /// @returns false if any kind of error occurs, true otherwise.
+ /// @brief Unconditionally release the lock.
+ bool release(void);
+
+ /// Attempts to acquire the lock without blocking. If the lock is not
+ /// available, this function returns false quickly (without blocking). If
+ /// the lock is available, it is acquired.
+ /// @returns false if any kind of error occurs or the lock is not
+ /// available, true otherwise.
+ /// @brief Try to acquire the lock.
+ bool tryacquire();
+
+ //@}
+ /// @name Platform Dependent Data
+ /// @{
+ private:
+#ifdef ENABLE_THREADS
+ void* data_; ///< We don't know what the data will be
+#endif
+
+ /// @}
+ /// @name Do Not Implement
+ /// @{
+ private:
+ Mutex(const Mutex & original);
+ void operator=(const Mutex &);
+ /// @}
+ };
+ }
+}
+
+FORCE_DEFINING_FILE_TO_BE_LINKED(SystemMutex)
+
+#endif
diff --git a/support/include/llvm/System/Path.h b/support/include/llvm/System/Path.h
new file mode 100644
index 0000000..aec7399
--- /dev/null
+++ b/support/include/llvm/System/Path.h
@@ -0,0 +1,659 @@
+//===- llvm/System/Path.h - Path Operating System Concept -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and 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_SYSTEM_PATH_H
+#define LLVM_SYSTEM_PATH_H
+
+#include "llvm/System/TimeValue.h"
+#include "llvm/System/IncludeFile.h"
+#include <set>
+#include <string>
+#include <vector>
+#include <iosfwd>
+
+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 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 C:\. 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.
+ static Path GetRootDirectory();
+
+ /// 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 Constrct 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. This function *must*
+ /// return the value of LLVM_LIB_SEARCH_PATH as the first item in \p Paths
+ /// if that environment variable is set and it references a directory.
+ /// @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 default LLVM configuration directory. The
+ /// implementation must ensure that this is a well-known (same on many
+ /// systems) directory in which llvm configuration files exist. For
+ /// example, on Unix, the /etc/llvm directory has been selected.
+ /// @brief Construct a path to the default LLVM configuration directory
+ static Path GetLLVMDefaultConfigDir();
+
+ /// Construct a path to the LLVM installed configuration directory. The
+ /// implementation must ensure that this refers to the "etc" directory of
+ /// the LLVM installation. This is the location where configuration files
+ /// will be located for a particular installation of LLVM on a machine.
+ /// @brief Construct a path to the LLVM installed configuration directory
+ static Path GetLLVMConfigDir();
+
+ /// 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();
+
+ /// 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 std::string GetDLLSuffix();
+
+ /// 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 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(const std::string& p) : path(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.
+ explicit Path(const char *StrStart, unsigned StrLen)
+ : path(StrStart, StrStart+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;
+ }
+
+ /// 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 {
+ return 0 == path.compare(that.path);
+ }
+
+ /// 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 0 != path.compare(that.path);
+ }
+
+ /// 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 {
+ return 0 > path.compare(that.path);
+ }
+
+ /// @}
+ /// @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 current contents of the path as a
+ /// std::string. This allows the underlying path string to be manipulated.
+ /// @returns std::string containing the path name.
+ /// @brief Returns the path as a std::string.
+ const std::string &toString() const { return path; }
+
+ /// This function returns the last component of the path name. The last
+ /// component is the file or directory name occuring after the last
+ /// directory separator. If no directory separator is present, the entire
+ /// path name is returned (i.e. same as toString).
+ /// @returns std::string containing the last component of the path name.
+ /// @brief Returns the last component of the path name.
+ std::string getLast() const;
+
+ /// 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 std::string containing the basename of the path
+ /// @brief Get the base name of the path
+ std::string getBasename() const;
+
+ /// 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(); }
+
+ /// @}
+ /// @name Disk Accessors
+ /// @{
+ public:
+ /// This function determines if the path name in this object references
+ /// the root (top level directory) of the file system. The details of what
+ /// is considered the "root" may vary from system to system so this method
+ /// will do the necessary checking.
+ /// @returns true iff the path name references the root directory.
+ /// @brief Determines if the path references the root directory.
+ bool isRootDirectory() const;
+
+ /// This function determines if the path name is absolute, as opposed to
+ /// relative.
+ /// @brief Determine if the path is absolute.
+ bool isAbsolute() const;
+
+ /// 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
+ bool hasMagicNumber(const std::string& magic) const;
+
+ /// 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.
+ /// @return strue if the file starts with the magid number for a native
+ /// shared library.
+ /// @brief Determine if the path reference a dynamic library.
+ bool isDynamicLibrary() 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.
+ bool exists() const;
+
+ /// 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 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 std::string
+ bool set(const std::string& 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( const std::string& component );
+
+ /// A period and the \p suffix are appended to the end of the pathname.
+ /// The precondition for this function is that the Path reference a file
+ /// name (i.e. isFile() returns true). If the Path is not a file, no
+ /// action is taken and the function returns false. If the path would
+ /// become invalid for the host operating system, false is returned.
+ /// @returns false if the suffix could not be added, true if it was.
+ /// @brief Adds a period and the \p suffix to the end of the pathname.
+ bool appendSuffix(const std::string& 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 );
+
+ /// @}
+ /// @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;
+ /// @}
+ /// @name Data
+ /// @{
+ protected:
+ 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 explicity 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 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(
+ const std::string& 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)
+ /// @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_PreloadExectuable_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
+ 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);
+}
+
+std::ostream& operator<<(std::ostream& strm, const sys::Path& aPath);
+inline std::ostream& operator<<(std::ostream& strm,
+ const sys::PathWithStatus& aPath) {
+ strm << static_cast<const sys::Path&>(aPath);
+ return strm;
+}
+
+}
+
+FORCE_DEFINING_FILE_TO_BE_LINKED(SystemPath)
+#endif
diff --git a/support/include/llvm/System/Process.h b/support/include/llvm/System/Process.h
new file mode 100644
index 0000000..f843af3
--- /dev/null
+++ b/support/include/llvm/System/Process.h
@@ -0,0 +1,105 @@
+//===- llvm/System/Process.h ------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the llvm::sys::Process class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_PROCESS_H
+#define LLVM_SYSTEM_PROCESS_H
+
+#include "llvm/System/TimeValue.h"
+#include "llvm/System/IncludeFile.h"
+
+namespace llvm {
+namespace sys {
+
+ /// This class provides an abstraction for getting information about the
+ /// currently executing process.
+ /// @since 1.4
+ /// @brief An abstraction for operating system processes.
+ class Process {
+ /// @name Accessors
+ /// @{
+ public:
+ /// This static function will return the operating system's virtual memory
+ /// page size.
+ /// @returns The number of bytes in a virtual memory page.
+ /// @throws nothing
+ /// @brief Get the virtual memory page size
+ static unsigned GetPageSize();
+
+ /// This static function will return the total amount of memory allocated
+ /// by the process. This only counts the memory allocated via the malloc,
+ /// calloc and realloc functions and includes any "free" holes in the
+ /// allocated space.
+ /// @throws nothing
+ /// @brief Return process memory usage.
+ static size_t GetMallocUsage();
+
+ /// This static function will return the total memory usage of the
+ /// process. This includes code, data, stack and mapped pages usage. Notei
+ /// that the value returned here is not necessarily the Running Set Size,
+ /// it is the total virtual memory usage, regardless of mapped state of
+ /// that memory.
+ static size_t GetTotalMemoryUsage();
+
+ /// This static function will set \p user_time to the amount of CPU time
+ /// spent in user (non-kernel) mode and \p sys_time to the amount of CPU
+ /// time spent in system (kernel) mode. If the operating system does not
+ /// support collection of these metrics, a zero TimeValue will be for both
+ /// values.
+ static void GetTimeUsage(
+ TimeValue& elapsed,
+ ///< Returns the TimeValue::now() giving current time
+ TimeValue& user_time,
+ ///< Returns the current amount of user time for the process
+ TimeValue& sys_time
+ ///< Returns the current amount of system time for the process
+ );
+
+ /// 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 determines if the standard input is connected directly
+ /// to a user's input (keyboard probably), rather than coming from a file
+ /// or pipe.
+ static bool StandardInIsUserInput();
+
+ /// This function determines if the standard output is connected to a
+ /// "tty" or "console" window. That is, the output would be displayed to
+ /// the user rather than being put on a pipe or stored in a file.
+ static bool StandardOutIsDisplayed();
+
+ /// This function determines if the standard error is connected to a
+ /// "tty" or "console" window. That is, the output would be displayed to
+ /// the user rather than being put on a pipe or stored in a file.
+ static bool StandardErrIsDisplayed();
+
+ /// @}
+ };
+}
+}
+
+FORCE_DEFINING_FILE_TO_BE_LINKED(SystemProcess)
+
+#endif
diff --git a/support/include/llvm/System/Program.h b/support/include/llvm/System/Program.h
new file mode 100644
index 0000000..cef3805
--- /dev/null
+++ b/support/include/llvm/System/Program.h
@@ -0,0 +1,95 @@
+//===- llvm/System/Program.h ------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the llvm::sys::Program class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_PROGRAM_H
+#define LLVM_SYSTEM_PROGRAM_H
+
+#include "llvm/System/Path.h"
+#include "llvm/System/IncludeFile.h"
+#include <vector>
+
+namespace llvm {
+namespace sys {
+
+ /// 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 {
+ /// @name Methods
+ /// @{
+ 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).
+ /// @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.
+ /// @throws nothing
+ /// @brief Construct a Program by finding it by name.
+ static Path FindProgramByName(const std::string& name);
+
+ /// This function executes the program using the \p arguments provided and
+ /// waits for the program to exit. This function will block the current
+ /// program until the invoked program exits. 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 an integer result code indicating the status of the program.
+ /// A zero or positive value indicates the result code of the program. A
+ /// negative value is the signal number on which it terminated.
+ /// @see FindProgrambyName
+ /// @brief Executes the program with the given set of \p args.
+ static int ExecuteAndWait(
+ 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
+ ///< 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
+ ///< 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.
+ 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
+ ///< instance in which error messages will be returned. If the string
+ ///< is non-empty upon return an error occurred while invoking the
+ ///< program.
+ );
+ // These methods change the specified standard stream (stdin or stdout) to
+ // binary mode. They return true if an error occurred
+ static bool ChangeStdinToBinary();
+ static bool ChangeStdoutToBinary();
+ /// @}
+ };
+}
+}
+
+FORCE_DEFINING_FILE_TO_BE_LINKED(SystemProgram)
+
+#endif
diff --git a/support/include/llvm/System/Signals.h b/support/include/llvm/System/Signals.h
new file mode 100644
index 0000000..f4b8b14
--- /dev/null
+++ b/support/include/llvm/System/Signals.h
@@ -0,0 +1,55 @@
+//===- llvm/System/Signals.h - Signal Handling support ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines some helpful functions for dealing with the possibility of
+// unix signals occuring while your program is running.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_SIGNALS_H
+#define LLVM_SYSTEM_SIGNALS_H
+
+#include "llvm/System/Path.h"
+#include "llvm/System/IncludeFile.h"
+
+namespace llvm {
+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);
+
+ /// This function registers a signal handler to ensure that if a fatal signal
+ /// gets delivered to the process that the named directory and all its
+ /// contents are removed.
+ /// @brief Remove a directory if a fatal signal occurs.
+ bool RemoveDirectoryOnSignal(const Path& path, std::string* ErrMsg = 0);
+
+ /// When an error signal (such as SIBABRT or SIGSEGV) is delivered to the
+ /// process, print a stack trace and then exit.
+ /// @brief Print a stack trace if a fatal signal occurs.
+ void PrintStackTraceOnErrorSignal();
+
+ /// This function registers a function to be called when the user "interrupts"
+ /// the program (typically by pressing ctrl-c). When the user interrupts the
+ /// program, the specified interrupt function is called instead of the program
+ /// being killed, and the interrupt function automatically disabled. Note
+ /// that interrupt functions are not allowed to call any non-reentrant
+ /// functions. An null interrupt function pointer disables the current
+ /// installed function. Note also that the handler may be executed on a
+ /// different thread on some platforms.
+ /// @brief Register a function to be called when ctrl-c is pressed.
+ void SetInterruptFunction(void (*IF)());
+} // End sys namespace
+} // End llvm namespace
+
+FORCE_DEFINING_FILE_TO_BE_LINKED(SystemSignals)
+
+#endif
diff --git a/support/include/llvm/System/TimeValue.h b/support/include/llvm/System/TimeValue.h
new file mode 100644
index 0000000..93610b8
--- /dev/null
+++ b/support/include/llvm/System/TimeValue.h
@@ -0,0 +1,385 @@
+//===-- TimeValue.h - Declare OS TimeValue Concept --------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header file declares the operating system TimeValue concept.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/DataTypes.h"
+#include "llvm/System/IncludeFile.h"
+#include <string>
+
+#ifndef LLVM_SYSTEM_TIMEVALUE_H
+#define LLVM_SYSTEM_TIMEVALUE_H
+
+namespace llvm {
+namespace sys {
+ /// This class is used where a precise fixed point in time is required. The
+ /// range of TimeValue spans many hundreds of billions of years both past and
+ /// present. The precision of TimeValue is to the nanosecond. However, the
+ /// actual precision of its values will be determined by the resolution of
+ /// the system clock. The TimeValue class is used in conjunction with several
+ /// other lib/System interfaces to specify the time at which a call should
+ /// timeout, etc.
+ /// @since 1.4
+ /// @brief Provides an abstraction for a fixed point in time.
+ class TimeValue {
+
+ /// @name Constants
+ /// @{
+ public:
+
+ /// A constant TimeValue representing the smallest time
+ /// value permissable by the class. MinTime is some point
+ /// in the distant past, about 300 billion years BCE.
+ /// @brief The smallest possible time value.
+ static const TimeValue MinTime;
+
+ /// A constant TimeValue representing the largest time
+ /// value permissable by the class. MaxTime is some point
+ /// in the distant future, about 300 billion years AD.
+ /// @brief The largest possible time value.
+ static const TimeValue MaxTime;
+
+ /// A constant TimeValue representing the base time,
+ /// or zero time of 00:00:00 (midnight) January 1st, 2000.
+ /// @brief 00:00:00 Jan 1, 2000 UTC.
+ static const TimeValue ZeroTime;
+
+ /// A constant TimeValue for the Posix base time which is
+ /// 00:00:00 (midnight) January 1st, 1970.
+ /// @brief 00:00:00 Jan 1, 1970 UTC.
+ static const TimeValue PosixZeroTime;
+
+ /// A constant TimeValue for the Win32 base time which is
+ /// 00:00:00 (midnight) January 1st, 1601.
+ /// @brief 00:00:00 Jan 1, 1601 UTC.
+ static const TimeValue Win32ZeroTime;
+
+ /// @}
+ /// @name Types
+ /// @{
+ public:
+ typedef int64_t SecondsType; ///< Type used for representing seconds.
+ typedef int32_t NanoSecondsType; ///< Type used for representing nanoseconds.
+
+ enum TimeConversions {
+ NANOSECONDS_PER_SECOND = 1000000000, ///< One Billion
+ MICROSECONDS_PER_SECOND = 1000000, ///< One Million
+ MILLISECONDS_PER_SECOND = 1000, ///< One Thousand
+ NANOSECONDS_PER_MICROSECOND = 1000, ///< One Thousand
+ NANOSECONDS_PER_MILLISECOND = 1000000,///< One Million
+ NANOSECONDS_PER_POSIX_TICK = 100, ///< Posix tick is 100 Hz (10ms)
+ NANOSECONDS_PER_WIN32_TICK = 100 ///< Win32 tick is 100 Hz (10ms)
+ };
+
+ /// @}
+ /// @name Constructors
+ /// @{
+ public:
+ /// Caller provides the exact value in seconds and nanoseconds. The
+ /// \p nanos argument defaults to zero for convenience.
+ /// @brief Explicit constructor
+ explicit TimeValue (SecondsType seconds, NanoSecondsType nanos = 0)
+ : seconds_( seconds ), nanos_( nanos ) { this->normalize(); }
+
+ /// Caller provides the exact value as a double in seconds with the
+ /// fractional part representing nanoseconds.
+ /// @brief Double Constructor.
+ explicit TimeValue( double new_time )
+ : seconds_( 0 ) , nanos_ ( 0 ) {
+ SecondsType integer_part = static_cast<SecondsType>( new_time );
+ seconds_ = integer_part;
+ nanos_ = static_cast<NanoSecondsType>( (new_time -
+ static_cast<double>(integer_part)) * NANOSECONDS_PER_SECOND );
+ this->normalize();
+ }
+
+ /// This is a static constructor that returns a TimeValue that represents
+ /// the current time.
+ /// @brief Creates a TimeValue with the current time (UTC).
+ static TimeValue now();
+
+ /// @}
+ /// @name Operators
+ /// @{
+ public:
+ /// Add \p that to \p this.
+ /// @returns this
+ /// @brief Incrementing assignment operator.
+ TimeValue& operator += (const TimeValue& that ) {
+ this->seconds_ += that.seconds_ ;
+ this->nanos_ += that.nanos_ ;
+ this->normalize();
+ return *this;
+ }
+
+ /// Subtract \p that from \p this.
+ /// @returns this
+ /// @brief Decrementing assignment operator.
+ TimeValue& operator -= (const TimeValue &that ) {
+ this->seconds_ -= that.seconds_ ;
+ this->nanos_ -= that.nanos_ ;
+ this->normalize();
+ return *this;
+ }
+
+ /// Determine if \p this is less than \p that.
+ /// @returns True iff *this < that.
+ /// @brief True if this < that.
+ int operator < (const TimeValue &that) const { return that > *this; }
+
+ /// Determine if \p this is greather than \p that.
+ /// @returns True iff *this > that.
+ /// @brief True if this > that.
+ int operator > (const TimeValue &that) const {
+ if ( this->seconds_ > that.seconds_ ) {
+ return 1;
+ } else if ( this->seconds_ == that.seconds_ ) {
+ if ( this->nanos_ > that.nanos_ ) return 1;
+ }
+ return 0;
+ }
+
+ /// Determine if \p this is less than or equal to \p that.
+ /// @returns True iff *this <= that.
+ /// @brief True if this <= that.
+ int operator <= (const TimeValue &that) const { return that >= *this; }
+
+ /// Determine if \p this is greater than or equal to \p that.
+ /// @returns True iff *this >= that.
+ /// @brief True if this >= that.
+ int operator >= (const TimeValue &that) const {
+ if ( this->seconds_ > that.seconds_ ) {
+ return 1;
+ } else if ( this->seconds_ == that.seconds_ ) {
+ if ( this->nanos_ >= that.nanos_ ) return 1;
+ }
+ return 0;
+ }
+
+ /// Determines if two TimeValue objects represent the same moment in time.
+ /// @brief True iff *this == that.
+ /// @brief True if this == that.
+ int operator == (const TimeValue &that) const {
+ return (this->seconds_ == that.seconds_) &&
+ (this->nanos_ == that.nanos_);
+ }
+
+ /// Determines if two TimeValue objects represent times that are not the
+ /// same.
+ /// @return True iff *this != that.
+ /// @brief True if this != that.
+ int operator != (const TimeValue &that) const { return !(*this == that); }
+
+ /// Adds two TimeValue objects together.
+ /// @returns The sum of the two operands as a new TimeValue
+ /// @brief Addition operator.
+ friend TimeValue operator + (const TimeValue &tv1, const TimeValue &tv2);
+
+ /// Subtracts two TimeValue objects.
+ /// @returns The difference of the two operands as a new TimeValue
+ /// @brief Subtraction operator.
+ friend TimeValue operator - (const TimeValue &tv1, const TimeValue &tv2);
+
+ /// @}
+ /// @name Accessors
+ /// @{
+ public:
+
+ /// Returns only the seconds component of the TimeValue. The nanoseconds
+ /// portion is ignored. No rounding is performed.
+ /// @brief Retrieve the seconds component
+ SecondsType seconds() const { return seconds_; }
+
+ /// Returns only the nanoseconds component of the TimeValue. The seconds
+ /// portion is ignored.
+ /// @brief Retrieve the nanoseconds component.
+ NanoSecondsType nanoseconds() const { return nanos_; }
+
+ /// Returns only the fractional portion of the TimeValue rounded down to the
+ /// nearest microsecond (divide by one thousand).
+ /// @brief Retrieve the fractional part as microseconds;
+ uint32_t microseconds() const {
+ return nanos_ / NANOSECONDS_PER_MICROSECOND;
+ }
+
+ /// Returns only the fractional portion of the TimeValue rounded down to the
+ /// nearest millisecond (divide by one million).
+ /// @brief Retrieve the fractional part as milliseconds;
+ uint32_t milliseconds() const {
+ return nanos_ / NANOSECONDS_PER_MILLISECOND;
+ }
+
+ /// Returns the TimeValue as a number of microseconds. Note that the value
+ /// returned can overflow because the range of a uint64_t is smaller than
+ /// the range of a TimeValue. Nevertheless, this is useful on some operating
+ /// systems and is therefore provided.
+ /// @brief Convert to a number of microseconds (can overflow)
+ uint64_t usec() const {
+ return seconds_ * MICROSECONDS_PER_SECOND +
+ ( nanos_ / NANOSECONDS_PER_MICROSECOND );
+ }
+
+ /// Returns the TimeValue as a number of milliseconds. Note that the value
+ /// returned can overflow because the range of a uint64_t is smaller than
+ /// the range of a TimeValue. Nevertheless, this is useful on some operating
+ /// systems and is therefore provided.
+ /// @brief Convert to a number of milliseconds (can overflow)
+ uint64_t msec() const {
+ return seconds_ * MILLISECONDS_PER_SECOND +
+ ( nanos_ / NANOSECONDS_PER_MILLISECOND );
+ }
+
+ /// Converts the TimeValue into the corresponding number of "ticks" for
+ /// Posix, correcting for the difference in Posix zero time.
+ /// @brief Convert to unix time (100 nanoseconds since 12:00:00a Jan 1,1970)
+ uint64_t toPosixTime() const {
+ uint64_t result = seconds_ - PosixZeroTime.seconds_;
+ result += nanos_ / NANOSECONDS_PER_POSIX_TICK;
+ return result;
+ }
+
+ /// Converts the TimeValue into the corresponding number of seconds
+ /// since the epoch (00:00:00 Jan 1,1970).
+ uint64_t toEpochTime() const {
+ return seconds_ - PosixZeroTime.seconds_;
+ }
+
+ /// Converts the TiemValue into the correspodning 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)
+ uint64_t toWin32Time() const {
+ uint64_t result = seconds_ - Win32ZeroTime.seconds_;
+ result += nanos_ / NANOSECONDS_PER_WIN32_TICK;
+ return result;
+ }
+
+ /// Provides the seconds and nanoseconds as results in its arguments after
+ /// correction for the Posix zero time.
+ /// @brief Convert to timespec time (ala POSIX.1b)
+ void getTimespecTime( uint64_t& seconds, uint32_t& nanos ) const {
+ seconds = seconds_ - PosixZeroTime.seconds_;
+ nanos = nanos_;
+ }
+
+ /// Provides conversion of the TimeValue into a readable time & date.
+ /// @returns std::string containing the readable time value
+ /// @brief Convert time to a string.
+ std::string toString() const;
+
+ /// @}
+ /// @name Mutators
+ /// @{
+ public:
+ /// The seconds component of the TimeValue is set to \p sec without
+ /// modifying the nanoseconds part. This is useful for whole second
+ /// arithmetic.
+ /// @brief Set the seconds component.
+ void seconds (SecondsType sec ) {
+ this->seconds_ = sec;
+ this->normalize();
+ }
+
+ /// The nanoseconds component of the TimeValue is set to \p nanos without
+ /// modifying the seconds part. This is useful for basic computations
+ /// involving just the nanoseconds portion. Note that the TimeValue will be
+ /// normalized after this call so that the fractional (nanoseconds) portion
+ /// will have the smallest equivalent value.
+ /// @brief Set the nanoseconds component using a number of nanoseconds.
+ void nanoseconds ( NanoSecondsType nanos ) {
+ this->nanos_ = nanos;
+ this->normalize();
+ }
+
+ /// The seconds component remains unchanged.
+ /// @brief Set the nanoseconds component using a number of microseconds.
+ void microseconds ( int32_t micros ) {
+ this->nanos_ = micros * NANOSECONDS_PER_MICROSECOND;
+ this->normalize();
+ }
+
+ /// The seconds component remains unchanged.
+ /// @brief Set the nanoseconds component using a number of milliseconds.
+ void milliseconds ( int32_t millis ) {
+ this->nanos_ = millis * NANOSECONDS_PER_MILLISECOND;
+ this->normalize();
+ }
+
+ /// @brief Converts from microsecond format to TimeValue format
+ void usec( int64_t microseconds ) {
+ this->seconds_ = microseconds / MICROSECONDS_PER_SECOND;
+ this->nanos_ = NanoSecondsType(microseconds % MICROSECONDS_PER_SECOND) *
+ NANOSECONDS_PER_MICROSECOND;
+ this->normalize();
+ }
+
+ /// @brief Converts from millisecond format to TimeValue format
+ void msec( int64_t milliseconds ) {
+ this->seconds_ = milliseconds / MILLISECONDS_PER_SECOND;
+ this->nanos_ = NanoSecondsType(milliseconds % MILLISECONDS_PER_SECOND) *
+ NANOSECONDS_PER_MILLISECOND;
+ this->normalize();
+ }
+
+ /// Converts the \p seconds argument from PosixTime to the corresponding
+ /// TimeValue and assigns that value to \p this.
+ /// @brief Convert seconds form PosixTime to TimeValue
+ void fromEpochTime( SecondsType seconds ) {
+ seconds_ = seconds + PosixZeroTime.seconds_;
+ nanos_ = 0;
+ this->normalize();
+ }
+
+ /// Converts the \p win32Time argument from Windows FILETIME to the
+ /// corresponding TimeValue and assigns that value to \p this.
+ /// @brief Convert seconds form Windows FILETIME to TimeValue
+ void fromWin32Time( uint64_t win32Time ) {
+ this->seconds_ = win32Time / 10000000 + Win32ZeroTime.seconds_;
+ this->nanos_ = NanoSecondsType(win32Time % 10000000) * 100;
+ }
+
+ /// @}
+ /// @name Implementation
+ /// @{
+ private:
+ /// This causes the values to be represented so that the fractional
+ /// part is minimized, possibly incrementing the seconds part.
+ /// @brief Normalize to canonical form.
+ void normalize();
+
+ /// @}
+ /// @name Data
+ /// @{
+ private:
+ /// Store the values as a <timeval>.
+ SecondsType seconds_;///< Stores the seconds part of the TimeVal
+ NanoSecondsType nanos_; ///< Stores the nanoseconds part of the TimeVal
+ /// @}
+
+ };
+
+inline TimeValue operator + (const TimeValue &tv1, const TimeValue &tv2) {
+ TimeValue sum (tv1.seconds_ + tv2.seconds_, tv1.nanos_ + tv2.nanos_);
+ sum.normalize ();
+ return sum;
+}
+
+inline TimeValue operator - (const TimeValue &tv1, const TimeValue &tv2) {
+ TimeValue difference (tv1.seconds_ - tv2.seconds_, tv1.nanos_ - tv2.nanos_ );
+ difference.normalize ();
+ return difference;
+}
+
+}
+}
+
+FORCE_DEFINING_FILE_TO_BE_LINKED(SystemTimeValue)
+
+#endif