aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm/lib/Support
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/Support')
-rw-r--r--contrib/llvm/lib/Support/APFloat.cpp3936
-rw-r--r--contrib/llvm/lib/Support/APInt.cpp2907
-rw-r--r--contrib/llvm/lib/Support/APSInt.cpp23
-rw-r--r--contrib/llvm/lib/Support/ARMBuildAttrs.cpp95
-rw-r--r--contrib/llvm/lib/Support/ARMWinEH.cpp38
-rw-r--r--contrib/llvm/lib/Support/Allocator.cpp40
-rw-r--r--contrib/llvm/lib/Support/Atomic.cpp117
-rw-r--r--contrib/llvm/lib/Support/BlockFrequency.cpp72
-rw-r--r--contrib/llvm/lib/Support/BranchProbability.cpp73
-rw-r--r--contrib/llvm/lib/Support/COM.cpp23
-rw-r--r--contrib/llvm/lib/Support/COPYRIGHT.regex54
-rw-r--r--contrib/llvm/lib/Support/CommandLine.cpp1858
-rw-r--r--contrib/llvm/lib/Support/Compression.cpp99
-rw-r--r--contrib/llvm/lib/Support/ConvertUTF.c708
-rw-r--r--contrib/llvm/lib/Support/ConvertUTFWrapper.cpp172
-rw-r--r--contrib/llvm/lib/Support/CrashRecoveryContext.cpp374
-rw-r--r--contrib/llvm/lib/Support/DAGDeltaAlgorithm.cpp354
-rw-r--r--contrib/llvm/lib/Support/DataExtractor.cpp175
-rw-r--r--contrib/llvm/lib/Support/DataStream.cpp86
-rw-r--r--contrib/llvm/lib/Support/Debug.cpp156
-rw-r--r--contrib/llvm/lib/Support/DeltaAlgorithm.cpp114
-rw-r--r--contrib/llvm/lib/Support/Dwarf.cpp590
-rw-r--r--contrib/llvm/lib/Support/DynamicLibrary.cpp189
-rw-r--r--contrib/llvm/lib/Support/Errno.cpp76
-rw-r--r--contrib/llvm/lib/Support/ErrorHandling.cpp206
-rw-r--r--contrib/llvm/lib/Support/FileOutputBuffer.cpp112
-rw-r--r--contrib/llvm/lib/Support/FileUtilities.cpp261
-rw-r--r--contrib/llvm/lib/Support/FoldingSet.cpp427
-rw-r--r--contrib/llvm/lib/Support/FormattedStream.cpp107
-rw-r--r--contrib/llvm/lib/Support/GraphWriter.cpp267
-rw-r--r--contrib/llvm/lib/Support/Hashing.cpp29
-rw-r--r--contrib/llvm/lib/Support/Host.cpp907
-rw-r--r--contrib/llvm/lib/Support/IntEqClasses.cpp70
-rw-r--r--contrib/llvm/lib/Support/IntervalMap.cpp161
-rw-r--r--contrib/llvm/lib/Support/IntrusiveRefCntPtr.cpp14
-rw-r--r--contrib/llvm/lib/Support/LEB128.cpp44
-rw-r--r--contrib/llvm/lib/Support/LineIterator.cpp94
-rw-r--r--contrib/llvm/lib/Support/Locale.cpp31
-rw-r--r--contrib/llvm/lib/Support/LockFileManager.cpp238
-rw-r--r--contrib/llvm/lib/Support/MD5.cpp286
-rw-r--r--contrib/llvm/lib/Support/ManagedStatic.cpp90
-rw-r--r--contrib/llvm/lib/Support/MathExtras.cpp32
-rw-r--r--contrib/llvm/lib/Support/Memory.cpp25
-rw-r--r--contrib/llvm/lib/Support/MemoryBuffer.cpp435
-rw-r--r--contrib/llvm/lib/Support/MemoryObject.cpp14
-rw-r--r--contrib/llvm/lib/Support/Mutex.cpp122
-rw-r--r--contrib/llvm/lib/Support/Options.cpp33
-rw-r--r--contrib/llvm/lib/Support/Path.cpp1076
-rw-r--r--contrib/llvm/lib/Support/PluginLoader.cpp47
-rw-r--r--contrib/llvm/lib/Support/PrettyStackTrace.cpp159
-rw-r--r--contrib/llvm/lib/Support/Process.cpp82
-rw-r--r--contrib/llvm/lib/Support/Program.cpp69
-rw-r--r--contrib/llvm/lib/Support/RWMutex.cpp125
-rw-r--r--contrib/llvm/lib/Support/RandomNumberGenerator.cpp57
-rw-r--r--contrib/llvm/lib/Support/Regex.cpp193
-rw-r--r--contrib/llvm/lib/Support/ScaledNumber.cpp323
-rw-r--r--contrib/llvm/lib/Support/SearchForAddressOfSpecialSymbol.cpp58
-rw-r--r--contrib/llvm/lib/Support/Signals.cpp34
-rw-r--r--contrib/llvm/lib/Support/SmallPtrSet.cpp338
-rw-r--r--contrib/llvm/lib/Support/SmallVector.cpp41
-rw-r--r--contrib/llvm/lib/Support/SourceMgr.cpp483
-rw-r--r--contrib/llvm/lib/Support/SpecialCaseList.cpp168
-rw-r--r--contrib/llvm/lib/Support/Statistic.cpp163
-rw-r--r--contrib/llvm/lib/Support/StreamingMemoryObject.cpp132
-rw-r--r--contrib/llvm/lib/Support/StringExtras.cpp58
-rw-r--r--contrib/llvm/lib/Support/StringMap.cpp245
-rw-r--r--contrib/llvm/lib/Support/StringPool.cpp35
-rw-r--r--contrib/llvm/lib/Support/StringRef.cpp485
-rw-r--r--contrib/llvm/lib/Support/StringSaver.cpp19
-rw-r--r--contrib/llvm/lib/Support/SystemUtils.cpp31
-rw-r--r--contrib/llvm/lib/Support/TargetParser.cpp591
-rw-r--r--contrib/llvm/lib/Support/TargetRegistry.cpp137
-rw-r--r--contrib/llvm/lib/Support/ThreadLocal.cpp48
-rw-r--r--contrib/llvm/lib/Support/Threading.cpp112
-rw-r--r--contrib/llvm/lib/Support/TimeValue.cpp56
-rw-r--r--contrib/llvm/lib/Support/Timer.cpp387
-rw-r--r--contrib/llvm/lib/Support/ToolOutputFile.cpp46
-rw-r--r--contrib/llvm/lib/Support/Triple.cpp1206
-rw-r--r--contrib/llvm/lib/Support/Twine.cpp170
-rw-r--r--contrib/llvm/lib/Support/Unicode.cpp367
-rw-r--r--contrib/llvm/lib/Support/Unix/COM.inc27
-rw-r--r--contrib/llvm/lib/Support/Unix/Host.inc49
-rw-r--r--contrib/llvm/lib/Support/Unix/Memory.inc350
-rw-r--r--contrib/llvm/lib/Support/Unix/Mutex.inc43
-rw-r--r--contrib/llvm/lib/Support/Unix/Path.inc621
-rw-r--r--contrib/llvm/lib/Support/Unix/Process.inc458
-rw-r--r--contrib/llvm/lib/Support/Unix/Program.inc476
-rw-r--r--contrib/llvm/lib/Support/Unix/README.txt16
-rw-r--r--contrib/llvm/lib/Support/Unix/RWMutex.inc51
-rw-r--r--contrib/llvm/lib/Support/Unix/Signals.inc558
-rw-r--r--contrib/llvm/lib/Support/Unix/ThreadLocal.inc69
-rw-r--r--contrib/llvm/lib/Support/Unix/TimeValue.inc54
-rw-r--r--contrib/llvm/lib/Support/Unix/Unix.h79
-rw-r--r--contrib/llvm/lib/Support/Unix/Watchdog.inc32
-rw-r--r--contrib/llvm/lib/Support/Valgrind.cpp74
-rw-r--r--contrib/llvm/lib/Support/Watchdog.cpp23
-rw-r--r--contrib/llvm/lib/Support/Windows/COM.inc37
-rw-r--r--contrib/llvm/lib/Support/Windows/DynamicLibrary.inc172
-rw-r--r--contrib/llvm/lib/Support/Windows/Host.inc22
-rw-r--r--contrib/llvm/lib/Support/Windows/Memory.inc244
-rw-r--r--contrib/llvm/lib/Support/Windows/Mutex.inc58
-rw-r--r--contrib/llvm/lib/Support/Windows/Path.inc859
-rw-r--r--contrib/llvm/lib/Support/Windows/Process.inc432
-rw-r--r--contrib/llvm/lib/Support/Windows/Program.inc538
-rw-r--r--contrib/llvm/lib/Support/Windows/RWMutex.inc130
-rw-r--r--contrib/llvm/lib/Support/Windows/Signals.inc537
-rw-r--r--contrib/llvm/lib/Support/Windows/ThreadLocal.inc53
-rw-r--r--contrib/llvm/lib/Support/Windows/TimeValue.inc61
-rw-r--r--contrib/llvm/lib/Support/Windows/Watchdog.inc24
-rw-r--r--contrib/llvm/lib/Support/Windows/WindowsSupport.h185
-rw-r--r--contrib/llvm/lib/Support/Windows/explicit_symbols.inc102
-rw-r--r--contrib/llvm/lib/Support/YAMLParser.cpp2447
-rw-r--r--contrib/llvm/lib/Support/YAMLTraits.cpp980
-rw-r--r--contrib/llvm/lib/Support/circular_raw_ostream.cpp45
-rw-r--r--contrib/llvm/lib/Support/raw_os_ostream.cpp30
-rw-r--r--contrib/llvm/lib/Support/raw_ostream.cpp847
-rw-r--r--contrib/llvm/lib/Support/regcclass.h75
-rw-r--r--contrib/llvm/lib/Support/regcname.h144
-rw-r--r--contrib/llvm/lib/Support/regcomp.c1574
-rw-r--r--contrib/llvm/lib/Support/regengine.inc1034
-rw-r--r--contrib/llvm/lib/Support/regerror.c135
-rw-r--r--contrib/llvm/lib/Support/regex2.h162
-rw-r--r--contrib/llvm/lib/Support/regex_impl.h108
-rw-r--r--contrib/llvm/lib/Support/regexec.c162
-rw-r--r--contrib/llvm/lib/Support/regfree.c72
-rw-r--r--contrib/llvm/lib/Support/regstrlcpy.c52
-rw-r--r--contrib/llvm/lib/Support/regutils.h58
127 files changed, 38234 insertions, 0 deletions
diff --git a/contrib/llvm/lib/Support/APFloat.cpp b/contrib/llvm/lib/Support/APFloat.cpp
new file mode 100644
index 000000000000..48830e83e9a4
--- /dev/null
+++ b/contrib/llvm/lib/Support/APFloat.cpp
@@ -0,0 +1,3936 @@
+//===-- APFloat.cpp - Implement APFloat class -----------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a class to represent arbitrary precision floating
+// point values and provide a variety of arithmetic operations on them.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/APFloat.h"
+#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/Hashing.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MathExtras.h"
+#include <cstring>
+#include <limits.h>
+
+using namespace llvm;
+
+/// A macro used to combine two fcCategory enums into one key which can be used
+/// in a switch statement to classify how the interaction of two APFloat's
+/// categories affects an operation.
+///
+/// TODO: If clang source code is ever allowed to use constexpr in its own
+/// codebase, change this into a static inline function.
+#define PackCategoriesIntoKey(_lhs, _rhs) ((_lhs) * 4 + (_rhs))
+
+/* Assumed in hexadecimal significand parsing, and conversion to
+ hexadecimal strings. */
+static_assert(integerPartWidth % 4 == 0, "Part width must be divisible by 4!");
+
+namespace llvm {
+
+ /* Represents floating point arithmetic semantics. */
+ struct fltSemantics {
+ /* The largest E such that 2^E is representable; this matches the
+ definition of IEEE 754. */
+ APFloat::ExponentType maxExponent;
+
+ /* The smallest E such that 2^E is a normalized number; this
+ matches the definition of IEEE 754. */
+ APFloat::ExponentType minExponent;
+
+ /* Number of bits in the significand. This includes the integer
+ bit. */
+ unsigned int precision;
+ };
+
+ const fltSemantics APFloat::IEEEhalf = { 15, -14, 11 };
+ const fltSemantics APFloat::IEEEsingle = { 127, -126, 24 };
+ const fltSemantics APFloat::IEEEdouble = { 1023, -1022, 53 };
+ const fltSemantics APFloat::IEEEquad = { 16383, -16382, 113 };
+ const fltSemantics APFloat::x87DoubleExtended = { 16383, -16382, 64 };
+ const fltSemantics APFloat::Bogus = { 0, 0, 0 };
+
+ /* The PowerPC format consists of two doubles. It does not map cleanly
+ onto the usual format above. It is approximated using twice the
+ mantissa bits. Note that for exponents near the double minimum,
+ we no longer can represent the full 106 mantissa bits, so those
+ will be treated as denormal numbers.
+
+ FIXME: While this approximation is equivalent to what GCC uses for
+ compile-time arithmetic on PPC double-double numbers, it is not able
+ to represent all possible values held by a PPC double-double number,
+ for example: (long double) 1.0 + (long double) 0x1p-106
+ Should this be replaced by a full emulation of PPC double-double? */
+ const fltSemantics APFloat::PPCDoubleDouble = { 1023, -1022 + 53, 53 + 53 };
+
+ /* A tight upper bound on number of parts required to hold the value
+ pow(5, power) is
+
+ power * 815 / (351 * integerPartWidth) + 1
+
+ However, whilst the result may require only this many parts,
+ because we are multiplying two values to get it, the
+ multiplication may require an extra part with the excess part
+ being zero (consider the trivial case of 1 * 1, tcFullMultiply
+ requires two parts to hold the single-part result). So we add an
+ extra one to guarantee enough space whilst multiplying. */
+ const unsigned int maxExponent = 16383;
+ const unsigned int maxPrecision = 113;
+ const unsigned int maxPowerOfFiveExponent = maxExponent + maxPrecision - 1;
+ const unsigned int maxPowerOfFiveParts = 2 + ((maxPowerOfFiveExponent * 815)
+ / (351 * integerPartWidth));
+} // namespace llvm
+
+/* A bunch of private, handy routines. */
+
+static inline unsigned int
+partCountForBits(unsigned int bits)
+{
+ return ((bits) + integerPartWidth - 1) / integerPartWidth;
+}
+
+/* Returns 0U-9U. Return values >= 10U are not digits. */
+static inline unsigned int
+decDigitValue(unsigned int c)
+{
+ return c - '0';
+}
+
+/* Return the value of a decimal exponent of the form
+ [+-]ddddddd.
+
+ If the exponent overflows, returns a large exponent with the
+ appropriate sign. */
+static int
+readExponent(StringRef::iterator begin, StringRef::iterator end)
+{
+ bool isNegative;
+ unsigned int absExponent;
+ const unsigned int overlargeExponent = 24000; /* FIXME. */
+ StringRef::iterator p = begin;
+
+ assert(p != end && "Exponent has no digits");
+
+ isNegative = (*p == '-');
+ if (*p == '-' || *p == '+') {
+ p++;
+ assert(p != end && "Exponent has no digits");
+ }
+
+ absExponent = decDigitValue(*p++);
+ assert(absExponent < 10U && "Invalid character in exponent");
+
+ for (; p != end; ++p) {
+ unsigned int value;
+
+ value = decDigitValue(*p);
+ assert(value < 10U && "Invalid character in exponent");
+
+ value += absExponent * 10;
+ if (absExponent >= overlargeExponent) {
+ absExponent = overlargeExponent;
+ p = end; /* outwit assert below */
+ break;
+ }
+ absExponent = value;
+ }
+
+ assert(p == end && "Invalid exponent in exponent");
+
+ if (isNegative)
+ return -(int) absExponent;
+ else
+ return (int) absExponent;
+}
+
+/* This is ugly and needs cleaning up, but I don't immediately see
+ how whilst remaining safe. */
+static int
+totalExponent(StringRef::iterator p, StringRef::iterator end,
+ int exponentAdjustment)
+{
+ int unsignedExponent;
+ bool negative, overflow;
+ int exponent = 0;
+
+ assert(p != end && "Exponent has no digits");
+
+ negative = *p == '-';
+ if (*p == '-' || *p == '+') {
+ p++;
+ assert(p != end && "Exponent has no digits");
+ }
+
+ unsignedExponent = 0;
+ overflow = false;
+ for (; p != end; ++p) {
+ unsigned int value;
+
+ value = decDigitValue(*p);
+ assert(value < 10U && "Invalid character in exponent");
+
+ unsignedExponent = unsignedExponent * 10 + value;
+ if (unsignedExponent > 32767) {
+ overflow = true;
+ break;
+ }
+ }
+
+ if (exponentAdjustment > 32767 || exponentAdjustment < -32768)
+ overflow = true;
+
+ if (!overflow) {
+ exponent = unsignedExponent;
+ if (negative)
+ exponent = -exponent;
+ exponent += exponentAdjustment;
+ if (exponent > 32767 || exponent < -32768)
+ overflow = true;
+ }
+
+ if (overflow)
+ exponent = negative ? -32768: 32767;
+
+ return exponent;
+}
+
+static StringRef::iterator
+skipLeadingZeroesAndAnyDot(StringRef::iterator begin, StringRef::iterator end,
+ StringRef::iterator *dot)
+{
+ StringRef::iterator p = begin;
+ *dot = end;
+ while (p != end && *p == '0')
+ p++;
+
+ if (p != end && *p == '.') {
+ *dot = p++;
+
+ assert(end - begin != 1 && "Significand has no digits");
+
+ while (p != end && *p == '0')
+ p++;
+ }
+
+ return p;
+}
+
+/* Given a normal decimal floating point number of the form
+
+ dddd.dddd[eE][+-]ddd
+
+ where the decimal point and exponent are optional, fill out the
+ structure D. Exponent is appropriate if the significand is
+ treated as an integer, and normalizedExponent if the significand
+ is taken to have the decimal point after a single leading
+ non-zero digit.
+
+ If the value is zero, V->firstSigDigit points to a non-digit, and
+ the return exponent is zero.
+*/
+struct decimalInfo {
+ const char *firstSigDigit;
+ const char *lastSigDigit;
+ int exponent;
+ int normalizedExponent;
+};
+
+static void
+interpretDecimal(StringRef::iterator begin, StringRef::iterator end,
+ decimalInfo *D)
+{
+ StringRef::iterator dot = end;
+ StringRef::iterator p = skipLeadingZeroesAndAnyDot (begin, end, &dot);
+
+ D->firstSigDigit = p;
+ D->exponent = 0;
+ D->normalizedExponent = 0;
+
+ for (; p != end; ++p) {
+ if (*p == '.') {
+ assert(dot == end && "String contains multiple dots");
+ dot = p++;
+ if (p == end)
+ break;
+ }
+ if (decDigitValue(*p) >= 10U)
+ break;
+ }
+
+ if (p != end) {
+ assert((*p == 'e' || *p == 'E') && "Invalid character in significand");
+ assert(p != begin && "Significand has no digits");
+ assert((dot == end || p - begin != 1) && "Significand has no digits");
+
+ /* p points to the first non-digit in the string */
+ D->exponent = readExponent(p + 1, end);
+
+ /* Implied decimal point? */
+ if (dot == end)
+ dot = p;
+ }
+
+ /* If number is all zeroes accept any exponent. */
+ if (p != D->firstSigDigit) {
+ /* Drop insignificant trailing zeroes. */
+ if (p != begin) {
+ do
+ do
+ p--;
+ while (p != begin && *p == '0');
+ while (p != begin && *p == '.');
+ }
+
+ /* Adjust the exponents for any decimal point. */
+ D->exponent += static_cast<APFloat::ExponentType>((dot - p) - (dot > p));
+ D->normalizedExponent = (D->exponent +
+ static_cast<APFloat::ExponentType>((p - D->firstSigDigit)
+ - (dot > D->firstSigDigit && dot < p)));
+ }
+
+ D->lastSigDigit = p;
+}
+
+/* Return the trailing fraction of a hexadecimal number.
+ DIGITVALUE is the first hex digit of the fraction, P points to
+ the next digit. */
+static lostFraction
+trailingHexadecimalFraction(StringRef::iterator p, StringRef::iterator end,
+ unsigned int digitValue)
+{
+ unsigned int hexDigit;
+
+ /* If the first trailing digit isn't 0 or 8 we can work out the
+ fraction immediately. */
+ if (digitValue > 8)
+ return lfMoreThanHalf;
+ else if (digitValue < 8 && digitValue > 0)
+ return lfLessThanHalf;
+
+ // Otherwise we need to find the first non-zero digit.
+ while (p != end && (*p == '0' || *p == '.'))
+ p++;
+
+ assert(p != end && "Invalid trailing hexadecimal fraction!");
+
+ hexDigit = hexDigitValue(*p);
+
+ /* If we ran off the end it is exactly zero or one-half, otherwise
+ a little more. */
+ if (hexDigit == -1U)
+ return digitValue == 0 ? lfExactlyZero: lfExactlyHalf;
+ else
+ return digitValue == 0 ? lfLessThanHalf: lfMoreThanHalf;
+}
+
+/* Return the fraction lost were a bignum truncated losing the least
+ significant BITS bits. */
+static lostFraction
+lostFractionThroughTruncation(const integerPart *parts,
+ unsigned int partCount,
+ unsigned int bits)
+{
+ unsigned int lsb;
+
+ lsb = APInt::tcLSB(parts, partCount);
+
+ /* Note this is guaranteed true if bits == 0, or LSB == -1U. */
+ if (bits <= lsb)
+ return lfExactlyZero;
+ if (bits == lsb + 1)
+ return lfExactlyHalf;
+ if (bits <= partCount * integerPartWidth &&
+ APInt::tcExtractBit(parts, bits - 1))
+ return lfMoreThanHalf;
+
+ return lfLessThanHalf;
+}
+
+/* Shift DST right BITS bits noting lost fraction. */
+static lostFraction
+shiftRight(integerPart *dst, unsigned int parts, unsigned int bits)
+{
+ lostFraction lost_fraction;
+
+ lost_fraction = lostFractionThroughTruncation(dst, parts, bits);
+
+ APInt::tcShiftRight(dst, parts, bits);
+
+ return lost_fraction;
+}
+
+/* Combine the effect of two lost fractions. */
+static lostFraction
+combineLostFractions(lostFraction moreSignificant,
+ lostFraction lessSignificant)
+{
+ if (lessSignificant != lfExactlyZero) {
+ if (moreSignificant == lfExactlyZero)
+ moreSignificant = lfLessThanHalf;
+ else if (moreSignificant == lfExactlyHalf)
+ moreSignificant = lfMoreThanHalf;
+ }
+
+ return moreSignificant;
+}
+
+/* The error from the true value, in half-ulps, on multiplying two
+ floating point numbers, which differ from the value they
+ approximate by at most HUE1 and HUE2 half-ulps, is strictly less
+ than the returned value.
+
+ See "How to Read Floating Point Numbers Accurately" by William D
+ Clinger. */
+static unsigned int
+HUerrBound(bool inexactMultiply, unsigned int HUerr1, unsigned int HUerr2)
+{
+ assert(HUerr1 < 2 || HUerr2 < 2 || (HUerr1 + HUerr2 < 8));
+
+ if (HUerr1 + HUerr2 == 0)
+ return inexactMultiply * 2; /* <= inexactMultiply half-ulps. */
+ else
+ return inexactMultiply + 2 * (HUerr1 + HUerr2);
+}
+
+/* The number of ulps from the boundary (zero, or half if ISNEAREST)
+ when the least significant BITS are truncated. BITS cannot be
+ zero. */
+static integerPart
+ulpsFromBoundary(const integerPart *parts, unsigned int bits, bool isNearest)
+{
+ unsigned int count, partBits;
+ integerPart part, boundary;
+
+ assert(bits != 0);
+
+ bits--;
+ count = bits / integerPartWidth;
+ partBits = bits % integerPartWidth + 1;
+
+ part = parts[count] & (~(integerPart) 0 >> (integerPartWidth - partBits));
+
+ if (isNearest)
+ boundary = (integerPart) 1 << (partBits - 1);
+ else
+ boundary = 0;
+
+ if (count == 0) {
+ if (part - boundary <= boundary - part)
+ return part - boundary;
+ else
+ return boundary - part;
+ }
+
+ if (part == boundary) {
+ while (--count)
+ if (parts[count])
+ return ~(integerPart) 0; /* A lot. */
+
+ return parts[0];
+ } else if (part == boundary - 1) {
+ while (--count)
+ if (~parts[count])
+ return ~(integerPart) 0; /* A lot. */
+
+ return -parts[0];
+ }
+
+ return ~(integerPart) 0; /* A lot. */
+}
+
+/* Place pow(5, power) in DST, and return the number of parts used.
+ DST must be at least one part larger than size of the answer. */
+static unsigned int
+powerOf5(integerPart *dst, unsigned int power)
+{
+ static const integerPart firstEightPowers[] = { 1, 5, 25, 125, 625, 3125,
+ 15625, 78125 };
+ integerPart pow5s[maxPowerOfFiveParts * 2 + 5];
+ pow5s[0] = 78125 * 5;
+
+ unsigned int partsCount[16] = { 1 };
+ integerPart scratch[maxPowerOfFiveParts], *p1, *p2, *pow5;
+ unsigned int result;
+ assert(power <= maxExponent);
+
+ p1 = dst;
+ p2 = scratch;
+
+ *p1 = firstEightPowers[power & 7];
+ power >>= 3;
+
+ result = 1;
+ pow5 = pow5s;
+
+ for (unsigned int n = 0; power; power >>= 1, n++) {
+ unsigned int pc;
+
+ pc = partsCount[n];
+
+ /* Calculate pow(5,pow(2,n+3)) if we haven't yet. */
+ if (pc == 0) {
+ pc = partsCount[n - 1];
+ APInt::tcFullMultiply(pow5, pow5 - pc, pow5 - pc, pc, pc);
+ pc *= 2;
+ if (pow5[pc - 1] == 0)
+ pc--;
+ partsCount[n] = pc;
+ }
+
+ if (power & 1) {
+ integerPart *tmp;
+
+ APInt::tcFullMultiply(p2, p1, pow5, result, pc);
+ result += pc;
+ if (p2[result - 1] == 0)
+ result--;
+
+ /* Now result is in p1 with partsCount parts and p2 is scratch
+ space. */
+ tmp = p1, p1 = p2, p2 = tmp;
+ }
+
+ pow5 += pc;
+ }
+
+ if (p1 != dst)
+ APInt::tcAssign(dst, p1, result);
+
+ return result;
+}
+
+/* Zero at the end to avoid modular arithmetic when adding one; used
+ when rounding up during hexadecimal output. */
+static const char hexDigitsLower[] = "0123456789abcdef0";
+static const char hexDigitsUpper[] = "0123456789ABCDEF0";
+static const char infinityL[] = "infinity";
+static const char infinityU[] = "INFINITY";
+static const char NaNL[] = "nan";
+static const char NaNU[] = "NAN";
+
+/* Write out an integerPart in hexadecimal, starting with the most
+ significant nibble. Write out exactly COUNT hexdigits, return
+ COUNT. */
+static unsigned int
+partAsHex (char *dst, integerPart part, unsigned int count,
+ const char *hexDigitChars)
+{
+ unsigned int result = count;
+
+ assert(count != 0 && count <= integerPartWidth / 4);
+
+ part >>= (integerPartWidth - 4 * count);
+ while (count--) {
+ dst[count] = hexDigitChars[part & 0xf];
+ part >>= 4;
+ }
+
+ return result;
+}
+
+/* Write out an unsigned decimal integer. */
+static char *
+writeUnsignedDecimal (char *dst, unsigned int n)
+{
+ char buff[40], *p;
+
+ p = buff;
+ do
+ *p++ = '0' + n % 10;
+ while (n /= 10);
+
+ do
+ *dst++ = *--p;
+ while (p != buff);
+
+ return dst;
+}
+
+/* Write out a signed decimal integer. */
+static char *
+writeSignedDecimal (char *dst, int value)
+{
+ if (value < 0) {
+ *dst++ = '-';
+ dst = writeUnsignedDecimal(dst, -(unsigned) value);
+ } else
+ dst = writeUnsignedDecimal(dst, value);
+
+ return dst;
+}
+
+/* Constructors. */
+void
+APFloat::initialize(const fltSemantics *ourSemantics)
+{
+ unsigned int count;
+
+ semantics = ourSemantics;
+ count = partCount();
+ if (count > 1)
+ significand.parts = new integerPart[count];
+}
+
+void
+APFloat::freeSignificand()
+{
+ if (needsCleanup())
+ delete [] significand.parts;
+}
+
+void
+APFloat::assign(const APFloat &rhs)
+{
+ assert(semantics == rhs.semantics);
+
+ sign = rhs.sign;
+ category = rhs.category;
+ exponent = rhs.exponent;
+ if (isFiniteNonZero() || category == fcNaN)
+ copySignificand(rhs);
+}
+
+void
+APFloat::copySignificand(const APFloat &rhs)
+{
+ assert(isFiniteNonZero() || category == fcNaN);
+ assert(rhs.partCount() >= partCount());
+
+ APInt::tcAssign(significandParts(), rhs.significandParts(),
+ partCount());
+}
+
+/* Make this number a NaN, with an arbitrary but deterministic value
+ for the significand. If double or longer, this is a signalling NaN,
+ which may not be ideal. If float, this is QNaN(0). */
+void APFloat::makeNaN(bool SNaN, bool Negative, const APInt *fill)
+{
+ category = fcNaN;
+ sign = Negative;
+
+ integerPart *significand = significandParts();
+ unsigned numParts = partCount();
+
+ // Set the significand bits to the fill.
+ if (!fill || fill->getNumWords() < numParts)
+ APInt::tcSet(significand, 0, numParts);
+ if (fill) {
+ APInt::tcAssign(significand, fill->getRawData(),
+ std::min(fill->getNumWords(), numParts));
+
+ // Zero out the excess bits of the significand.
+ unsigned bitsToPreserve = semantics->precision - 1;
+ unsigned part = bitsToPreserve / 64;
+ bitsToPreserve %= 64;
+ significand[part] &= ((1ULL << bitsToPreserve) - 1);
+ for (part++; part != numParts; ++part)
+ significand[part] = 0;
+ }
+
+ unsigned QNaNBit = semantics->precision - 2;
+
+ if (SNaN) {
+ // We always have to clear the QNaN bit to make it an SNaN.
+ APInt::tcClearBit(significand, QNaNBit);
+
+ // If there are no bits set in the payload, we have to set
+ // *something* to make it a NaN instead of an infinity;
+ // conventionally, this is the next bit down from the QNaN bit.
+ if (APInt::tcIsZero(significand, numParts))
+ APInt::tcSetBit(significand, QNaNBit - 1);
+ } else {
+ // We always have to set the QNaN bit to make it a QNaN.
+ APInt::tcSetBit(significand, QNaNBit);
+ }
+
+ // For x87 extended precision, we want to make a NaN, not a
+ // pseudo-NaN. Maybe we should expose the ability to make
+ // pseudo-NaNs?
+ if (semantics == &APFloat::x87DoubleExtended)
+ APInt::tcSetBit(significand, QNaNBit + 1);
+}
+
+APFloat APFloat::makeNaN(const fltSemantics &Sem, bool SNaN, bool Negative,
+ const APInt *fill) {
+ APFloat value(Sem, uninitialized);
+ value.makeNaN(SNaN, Negative, fill);
+ return value;
+}
+
+APFloat &
+APFloat::operator=(const APFloat &rhs)
+{
+ if (this != &rhs) {
+ if (semantics != rhs.semantics) {
+ freeSignificand();
+ initialize(rhs.semantics);
+ }
+ assign(rhs);
+ }
+
+ return *this;
+}
+
+APFloat &
+APFloat::operator=(APFloat &&rhs) {
+ freeSignificand();
+
+ semantics = rhs.semantics;
+ significand = rhs.significand;
+ exponent = rhs.exponent;
+ category = rhs.category;
+ sign = rhs.sign;
+
+ rhs.semantics = &Bogus;
+ return *this;
+}
+
+bool
+APFloat::isDenormal() const {
+ return isFiniteNonZero() && (exponent == semantics->minExponent) &&
+ (APInt::tcExtractBit(significandParts(),
+ semantics->precision - 1) == 0);
+}
+
+bool
+APFloat::isSmallest() const {
+ // The smallest number by magnitude in our format will be the smallest
+ // denormal, i.e. the floating point number with exponent being minimum
+ // exponent and significand bitwise equal to 1 (i.e. with MSB equal to 0).
+ return isFiniteNonZero() && exponent == semantics->minExponent &&
+ significandMSB() == 0;
+}
+
+bool APFloat::isSignificandAllOnes() const {
+ // Test if the significand excluding the integral bit is all ones. This allows
+ // us to test for binade boundaries.
+ const integerPart *Parts = significandParts();
+ const unsigned PartCount = partCount();
+ for (unsigned i = 0; i < PartCount - 1; i++)
+ if (~Parts[i])
+ return false;
+
+ // Set the unused high bits to all ones when we compare.
+ const unsigned NumHighBits =
+ PartCount*integerPartWidth - semantics->precision + 1;
+ assert(NumHighBits <= integerPartWidth && "Can not have more high bits to "
+ "fill than integerPartWidth");
+ const integerPart HighBitFill =
+ ~integerPart(0) << (integerPartWidth - NumHighBits);
+ if (~(Parts[PartCount - 1] | HighBitFill))
+ return false;
+
+ return true;
+}
+
+bool APFloat::isSignificandAllZeros() const {
+ // Test if the significand excluding the integral bit is all zeros. This
+ // allows us to test for binade boundaries.
+ const integerPart *Parts = significandParts();
+ const unsigned PartCount = partCount();
+
+ for (unsigned i = 0; i < PartCount - 1; i++)
+ if (Parts[i])
+ return false;
+
+ const unsigned NumHighBits =
+ PartCount*integerPartWidth - semantics->precision + 1;
+ assert(NumHighBits <= integerPartWidth && "Can not have more high bits to "
+ "clear than integerPartWidth");
+ const integerPart HighBitMask = ~integerPart(0) >> NumHighBits;
+
+ if (Parts[PartCount - 1] & HighBitMask)
+ return false;
+
+ return true;
+}
+
+bool
+APFloat::isLargest() const {
+ // The largest number by magnitude in our format will be the floating point
+ // number with maximum exponent and with significand that is all ones.
+ return isFiniteNonZero() && exponent == semantics->maxExponent
+ && isSignificandAllOnes();
+}
+
+bool
+APFloat::bitwiseIsEqual(const APFloat &rhs) const {
+ if (this == &rhs)
+ return true;
+ if (semantics != rhs.semantics ||
+ category != rhs.category ||
+ sign != rhs.sign)
+ return false;
+ if (category==fcZero || category==fcInfinity)
+ return true;
+ else if (isFiniteNonZero() && exponent!=rhs.exponent)
+ return false;
+ else {
+ int i= partCount();
+ const integerPart* p=significandParts();
+ const integerPart* q=rhs.significandParts();
+ for (; i>0; i--, p++, q++) {
+ if (*p != *q)
+ return false;
+ }
+ return true;
+ }
+}
+
+APFloat::APFloat(const fltSemantics &ourSemantics, integerPart value) {
+ initialize(&ourSemantics);
+ sign = 0;
+ category = fcNormal;
+ zeroSignificand();
+ exponent = ourSemantics.precision - 1;
+ significandParts()[0] = value;
+ normalize(rmNearestTiesToEven, lfExactlyZero);
+}
+
+APFloat::APFloat(const fltSemantics &ourSemantics) {
+ initialize(&ourSemantics);
+ category = fcZero;
+ sign = false;
+}
+
+APFloat::APFloat(const fltSemantics &ourSemantics, uninitializedTag tag) {
+ // Allocates storage if necessary but does not initialize it.
+ initialize(&ourSemantics);
+}
+
+APFloat::APFloat(const fltSemantics &ourSemantics, StringRef text) {
+ initialize(&ourSemantics);
+ convertFromString(text, rmNearestTiesToEven);
+}
+
+APFloat::APFloat(const APFloat &rhs) {
+ initialize(rhs.semantics);
+ assign(rhs);
+}
+
+APFloat::APFloat(APFloat &&rhs) : semantics(&Bogus) {
+ *this = std::move(rhs);
+}
+
+APFloat::~APFloat()
+{
+ freeSignificand();
+}
+
+// Profile - This method 'profiles' an APFloat for use with FoldingSet.
+void APFloat::Profile(FoldingSetNodeID& ID) const {
+ ID.Add(bitcastToAPInt());
+}
+
+unsigned int
+APFloat::partCount() const
+{
+ return partCountForBits(semantics->precision + 1);
+}
+
+unsigned int
+APFloat::semanticsPrecision(const fltSemantics &semantics)
+{
+ return semantics.precision;
+}
+
+const integerPart *
+APFloat::significandParts() const
+{
+ return const_cast<APFloat *>(this)->significandParts();
+}
+
+integerPart *
+APFloat::significandParts()
+{
+ if (partCount() > 1)
+ return significand.parts;
+ else
+ return &significand.part;
+}
+
+void
+APFloat::zeroSignificand()
+{
+ APInt::tcSet(significandParts(), 0, partCount());
+}
+
+/* Increment an fcNormal floating point number's significand. */
+void
+APFloat::incrementSignificand()
+{
+ integerPart carry;
+
+ carry = APInt::tcIncrement(significandParts(), partCount());
+
+ /* Our callers should never cause us to overflow. */
+ assert(carry == 0);
+ (void)carry;
+}
+
+/* Add the significand of the RHS. Returns the carry flag. */
+integerPart
+APFloat::addSignificand(const APFloat &rhs)
+{
+ integerPart *parts;
+
+ parts = significandParts();
+
+ assert(semantics == rhs.semantics);
+ assert(exponent == rhs.exponent);
+
+ return APInt::tcAdd(parts, rhs.significandParts(), 0, partCount());
+}
+
+/* Subtract the significand of the RHS with a borrow flag. Returns
+ the borrow flag. */
+integerPart
+APFloat::subtractSignificand(const APFloat &rhs, integerPart borrow)
+{
+ integerPart *parts;
+
+ parts = significandParts();
+
+ assert(semantics == rhs.semantics);
+ assert(exponent == rhs.exponent);
+
+ return APInt::tcSubtract(parts, rhs.significandParts(), borrow,
+ partCount());
+}
+
+/* Multiply the significand of the RHS. If ADDEND is non-NULL, add it
+ on to the full-precision result of the multiplication. Returns the
+ lost fraction. */
+lostFraction
+APFloat::multiplySignificand(const APFloat &rhs, const APFloat *addend)
+{
+ unsigned int omsb; // One, not zero, based MSB.
+ unsigned int partsCount, newPartsCount, precision;
+ integerPart *lhsSignificand;
+ integerPart scratch[4];
+ integerPart *fullSignificand;
+ lostFraction lost_fraction;
+ bool ignored;
+
+ assert(semantics == rhs.semantics);
+
+ precision = semantics->precision;
+
+ // Allocate space for twice as many bits as the original significand, plus one
+ // extra bit for the addition to overflow into.
+ newPartsCount = partCountForBits(precision * 2 + 1);
+
+ if (newPartsCount > 4)
+ fullSignificand = new integerPart[newPartsCount];
+ else
+ fullSignificand = scratch;
+
+ lhsSignificand = significandParts();
+ partsCount = partCount();
+
+ APInt::tcFullMultiply(fullSignificand, lhsSignificand,
+ rhs.significandParts(), partsCount, partsCount);
+
+ lost_fraction = lfExactlyZero;
+ omsb = APInt::tcMSB(fullSignificand, newPartsCount) + 1;
+ exponent += rhs.exponent;
+
+ // Assume the operands involved in the multiplication are single-precision
+ // FP, and the two multiplicants are:
+ // *this = a23 . a22 ... a0 * 2^e1
+ // rhs = b23 . b22 ... b0 * 2^e2
+ // the result of multiplication is:
+ // *this = c48 c47 c46 . c45 ... c0 * 2^(e1+e2)
+ // Note that there are three significant bits at the left-hand side of the
+ // radix point: two for the multiplication, and an overflow bit for the
+ // addition (that will always be zero at this point). Move the radix point
+ // toward left by two bits, and adjust exponent accordingly.
+ exponent += 2;
+
+ if (addend && addend->isNonZero()) {
+ // The intermediate result of the multiplication has "2 * precision"
+ // signicant bit; adjust the addend to be consistent with mul result.
+ //
+ Significand savedSignificand = significand;
+ const fltSemantics *savedSemantics = semantics;
+ fltSemantics extendedSemantics;
+ opStatus status;
+ unsigned int extendedPrecision;
+
+ // Normalize our MSB to one below the top bit to allow for overflow.
+ extendedPrecision = 2 * precision + 1;
+ if (omsb != extendedPrecision - 1) {
+ assert(extendedPrecision > omsb);
+ APInt::tcShiftLeft(fullSignificand, newPartsCount,
+ (extendedPrecision - 1) - omsb);
+ exponent -= (extendedPrecision - 1) - omsb;
+ }
+
+ /* Create new semantics. */
+ extendedSemantics = *semantics;
+ extendedSemantics.precision = extendedPrecision;
+
+ if (newPartsCount == 1)
+ significand.part = fullSignificand[0];
+ else
+ significand.parts = fullSignificand;
+ semantics = &extendedSemantics;
+
+ APFloat extendedAddend(*addend);
+ status = extendedAddend.convert(extendedSemantics, rmTowardZero, &ignored);
+ assert(status == opOK);
+ (void)status;
+
+ // Shift the significand of the addend right by one bit. This guarantees
+ // that the high bit of the significand is zero (same as fullSignificand),
+ // so the addition will overflow (if it does overflow at all) into the top bit.
+ lost_fraction = extendedAddend.shiftSignificandRight(1);
+ assert(lost_fraction == lfExactlyZero &&
+ "Lost precision while shifting addend for fused-multiply-add.");
+
+ lost_fraction = addOrSubtractSignificand(extendedAddend, false);
+
+ /* Restore our state. */
+ if (newPartsCount == 1)
+ fullSignificand[0] = significand.part;
+ significand = savedSignificand;
+ semantics = savedSemantics;
+
+ omsb = APInt::tcMSB(fullSignificand, newPartsCount) + 1;
+ }
+
+ // Convert the result having "2 * precision" significant-bits back to the one
+ // having "precision" significant-bits. First, move the radix point from
+ // poision "2*precision - 1" to "precision - 1". The exponent need to be
+ // adjusted by "2*precision - 1" - "precision - 1" = "precision".
+ exponent -= precision + 1;
+
+ // In case MSB resides at the left-hand side of radix point, shift the
+ // mantissa right by some amount to make sure the MSB reside right before
+ // the radix point (i.e. "MSB . rest-significant-bits").
+ //
+ // Note that the result is not normalized when "omsb < precision". So, the
+ // caller needs to call APFloat::normalize() if normalized value is expected.
+ if (omsb > precision) {
+ unsigned int bits, significantParts;
+ lostFraction lf;
+
+ bits = omsb - precision;
+ significantParts = partCountForBits(omsb);
+ lf = shiftRight(fullSignificand, significantParts, bits);
+ lost_fraction = combineLostFractions(lf, lost_fraction);
+ exponent += bits;
+ }
+
+ APInt::tcAssign(lhsSignificand, fullSignificand, partsCount);
+
+ if (newPartsCount > 4)
+ delete [] fullSignificand;
+
+ return lost_fraction;
+}
+
+/* Multiply the significands of LHS and RHS to DST. */
+lostFraction
+APFloat::divideSignificand(const APFloat &rhs)
+{
+ unsigned int bit, i, partsCount;
+ const integerPart *rhsSignificand;
+ integerPart *lhsSignificand, *dividend, *divisor;
+ integerPart scratch[4];
+ lostFraction lost_fraction;
+
+ assert(semantics == rhs.semantics);
+
+ lhsSignificand = significandParts();
+ rhsSignificand = rhs.significandParts();
+ partsCount = partCount();
+
+ if (partsCount > 2)
+ dividend = new integerPart[partsCount * 2];
+ else
+ dividend = scratch;
+
+ divisor = dividend + partsCount;
+
+ /* Copy the dividend and divisor as they will be modified in-place. */
+ for (i = 0; i < partsCount; i++) {
+ dividend[i] = lhsSignificand[i];
+ divisor[i] = rhsSignificand[i];
+ lhsSignificand[i] = 0;
+ }
+
+ exponent -= rhs.exponent;
+
+ unsigned int precision = semantics->precision;
+
+ /* Normalize the divisor. */
+ bit = precision - APInt::tcMSB(divisor, partsCount) - 1;
+ if (bit) {
+ exponent += bit;
+ APInt::tcShiftLeft(divisor, partsCount, bit);
+ }
+
+ /* Normalize the dividend. */
+ bit = precision - APInt::tcMSB(dividend, partsCount) - 1;
+ if (bit) {
+ exponent -= bit;
+ APInt::tcShiftLeft(dividend, partsCount, bit);
+ }
+
+ /* Ensure the dividend >= divisor initially for the loop below.
+ Incidentally, this means that the division loop below is
+ guaranteed to set the integer bit to one. */
+ if (APInt::tcCompare(dividend, divisor, partsCount) < 0) {
+ exponent--;
+ APInt::tcShiftLeft(dividend, partsCount, 1);
+ assert(APInt::tcCompare(dividend, divisor, partsCount) >= 0);
+ }
+
+ /* Long division. */
+ for (bit = precision; bit; bit -= 1) {
+ if (APInt::tcCompare(dividend, divisor, partsCount) >= 0) {
+ APInt::tcSubtract(dividend, divisor, 0, partsCount);
+ APInt::tcSetBit(lhsSignificand, bit - 1);
+ }
+
+ APInt::tcShiftLeft(dividend, partsCount, 1);
+ }
+
+ /* Figure out the lost fraction. */
+ int cmp = APInt::tcCompare(dividend, divisor, partsCount);
+
+ if (cmp > 0)
+ lost_fraction = lfMoreThanHalf;
+ else if (cmp == 0)
+ lost_fraction = lfExactlyHalf;
+ else if (APInt::tcIsZero(dividend, partsCount))
+ lost_fraction = lfExactlyZero;
+ else
+ lost_fraction = lfLessThanHalf;
+
+ if (partsCount > 2)
+ delete [] dividend;
+
+ return lost_fraction;
+}
+
+unsigned int
+APFloat::significandMSB() const
+{
+ return APInt::tcMSB(significandParts(), partCount());
+}
+
+unsigned int
+APFloat::significandLSB() const
+{
+ return APInt::tcLSB(significandParts(), partCount());
+}
+
+/* Note that a zero result is NOT normalized to fcZero. */
+lostFraction
+APFloat::shiftSignificandRight(unsigned int bits)
+{
+ /* Our exponent should not overflow. */
+ assert((ExponentType) (exponent + bits) >= exponent);
+
+ exponent += bits;
+
+ return shiftRight(significandParts(), partCount(), bits);
+}
+
+/* Shift the significand left BITS bits, subtract BITS from its exponent. */
+void
+APFloat::shiftSignificandLeft(unsigned int bits)
+{
+ assert(bits < semantics->precision);
+
+ if (bits) {
+ unsigned int partsCount = partCount();
+
+ APInt::tcShiftLeft(significandParts(), partsCount, bits);
+ exponent -= bits;
+
+ assert(!APInt::tcIsZero(significandParts(), partsCount));
+ }
+}
+
+APFloat::cmpResult
+APFloat::compareAbsoluteValue(const APFloat &rhs) const
+{
+ int compare;
+
+ assert(semantics == rhs.semantics);
+ assert(isFiniteNonZero());
+ assert(rhs.isFiniteNonZero());
+
+ compare = exponent - rhs.exponent;
+
+ /* If exponents are equal, do an unsigned bignum comparison of the
+ significands. */
+ if (compare == 0)
+ compare = APInt::tcCompare(significandParts(), rhs.significandParts(),
+ partCount());
+
+ if (compare > 0)
+ return cmpGreaterThan;
+ else if (compare < 0)
+ return cmpLessThan;
+ else
+ return cmpEqual;
+}
+
+/* Handle overflow. Sign is preserved. We either become infinity or
+ the largest finite number. */
+APFloat::opStatus
+APFloat::handleOverflow(roundingMode rounding_mode)
+{
+ /* Infinity? */
+ if (rounding_mode == rmNearestTiesToEven ||
+ rounding_mode == rmNearestTiesToAway ||
+ (rounding_mode == rmTowardPositive && !sign) ||
+ (rounding_mode == rmTowardNegative && sign)) {
+ category = fcInfinity;
+ return (opStatus) (opOverflow | opInexact);
+ }
+
+ /* Otherwise we become the largest finite number. */
+ category = fcNormal;
+ exponent = semantics->maxExponent;
+ APInt::tcSetLeastSignificantBits(significandParts(), partCount(),
+ semantics->precision);
+
+ return opInexact;
+}
+
+/* Returns TRUE if, when truncating the current number, with BIT the
+ new LSB, with the given lost fraction and rounding mode, the result
+ would need to be rounded away from zero (i.e., by increasing the
+ signficand). This routine must work for fcZero of both signs, and
+ fcNormal numbers. */
+bool
+APFloat::roundAwayFromZero(roundingMode rounding_mode,
+ lostFraction lost_fraction,
+ unsigned int bit) const
+{
+ /* NaNs and infinities should not have lost fractions. */
+ assert(isFiniteNonZero() || category == fcZero);
+
+ /* Current callers never pass this so we don't handle it. */
+ assert(lost_fraction != lfExactlyZero);
+
+ switch (rounding_mode) {
+ case rmNearestTiesToAway:
+ return lost_fraction == lfExactlyHalf || lost_fraction == lfMoreThanHalf;
+
+ case rmNearestTiesToEven:
+ if (lost_fraction == lfMoreThanHalf)
+ return true;
+
+ /* Our zeroes don't have a significand to test. */
+ if (lost_fraction == lfExactlyHalf && category != fcZero)
+ return APInt::tcExtractBit(significandParts(), bit);
+
+ return false;
+
+ case rmTowardZero:
+ return false;
+
+ case rmTowardPositive:
+ return !sign;
+
+ case rmTowardNegative:
+ return sign;
+ }
+ llvm_unreachable("Invalid rounding mode found");
+}
+
+APFloat::opStatus
+APFloat::normalize(roundingMode rounding_mode,
+ lostFraction lost_fraction)
+{
+ unsigned int omsb; /* One, not zero, based MSB. */
+ int exponentChange;
+
+ if (!isFiniteNonZero())
+ return opOK;
+
+ /* Before rounding normalize the exponent of fcNormal numbers. */
+ omsb = significandMSB() + 1;
+
+ if (omsb) {
+ /* OMSB is numbered from 1. We want to place it in the integer
+ bit numbered PRECISION if possible, with a compensating change in
+ the exponent. */
+ exponentChange = omsb - semantics->precision;
+
+ /* If the resulting exponent is too high, overflow according to
+ the rounding mode. */
+ if (exponent + exponentChange > semantics->maxExponent)
+ return handleOverflow(rounding_mode);
+
+ /* Subnormal numbers have exponent minExponent, and their MSB
+ is forced based on that. */
+ if (exponent + exponentChange < semantics->minExponent)
+ exponentChange = semantics->minExponent - exponent;
+
+ /* Shifting left is easy as we don't lose precision. */
+ if (exponentChange < 0) {
+ assert(lost_fraction == lfExactlyZero);
+
+ shiftSignificandLeft(-exponentChange);
+
+ return opOK;
+ }
+
+ if (exponentChange > 0) {
+ lostFraction lf;
+
+ /* Shift right and capture any new lost fraction. */
+ lf = shiftSignificandRight(exponentChange);
+
+ lost_fraction = combineLostFractions(lf, lost_fraction);
+
+ /* Keep OMSB up-to-date. */
+ if (omsb > (unsigned) exponentChange)
+ omsb -= exponentChange;
+ else
+ omsb = 0;
+ }
+ }
+
+ /* Now round the number according to rounding_mode given the lost
+ fraction. */
+
+ /* As specified in IEEE 754, since we do not trap we do not report
+ underflow for exact results. */
+ if (lost_fraction == lfExactlyZero) {
+ /* Canonicalize zeroes. */
+ if (omsb == 0)
+ category = fcZero;
+
+ return opOK;
+ }
+
+ /* Increment the significand if we're rounding away from zero. */
+ if (roundAwayFromZero(rounding_mode, lost_fraction, 0)) {
+ if (omsb == 0)
+ exponent = semantics->minExponent;
+
+ incrementSignificand();
+ omsb = significandMSB() + 1;
+
+ /* Did the significand increment overflow? */
+ if (omsb == (unsigned) semantics->precision + 1) {
+ /* Renormalize by incrementing the exponent and shifting our
+ significand right one. However if we already have the
+ maximum exponent we overflow to infinity. */
+ if (exponent == semantics->maxExponent) {
+ category = fcInfinity;
+
+ return (opStatus) (opOverflow | opInexact);
+ }
+
+ shiftSignificandRight(1);
+
+ return opInexact;
+ }
+ }
+
+ /* The normal case - we were and are not denormal, and any
+ significand increment above didn't overflow. */
+ if (omsb == semantics->precision)
+ return opInexact;
+
+ /* We have a non-zero denormal. */
+ assert(omsb < semantics->precision);
+
+ /* Canonicalize zeroes. */
+ if (omsb == 0)
+ category = fcZero;
+
+ /* The fcZero case is a denormal that underflowed to zero. */
+ return (opStatus) (opUnderflow | opInexact);
+}
+
+APFloat::opStatus
+APFloat::addOrSubtractSpecials(const APFloat &rhs, bool subtract)
+{
+ switch (PackCategoriesIntoKey(category, rhs.category)) {
+ default:
+ llvm_unreachable(nullptr);
+
+ case PackCategoriesIntoKey(fcNaN, fcZero):
+ case PackCategoriesIntoKey(fcNaN, fcNormal):
+ case PackCategoriesIntoKey(fcNaN, fcInfinity):
+ case PackCategoriesIntoKey(fcNaN, fcNaN):
+ case PackCategoriesIntoKey(fcNormal, fcZero):
+ case PackCategoriesIntoKey(fcInfinity, fcNormal):
+ case PackCategoriesIntoKey(fcInfinity, fcZero):
+ return opOK;
+
+ case PackCategoriesIntoKey(fcZero, fcNaN):
+ case PackCategoriesIntoKey(fcNormal, fcNaN):
+ case PackCategoriesIntoKey(fcInfinity, fcNaN):
+ // We need to be sure to flip the sign here for subtraction because we
+ // don't have a separate negate operation so -NaN becomes 0 - NaN here.
+ sign = rhs.sign ^ subtract;
+ category = fcNaN;
+ copySignificand(rhs);
+ return opOK;
+
+ case PackCategoriesIntoKey(fcNormal, fcInfinity):
+ case PackCategoriesIntoKey(fcZero, fcInfinity):
+ category = fcInfinity;
+ sign = rhs.sign ^ subtract;
+ return opOK;
+
+ case PackCategoriesIntoKey(fcZero, fcNormal):
+ assign(rhs);
+ sign = rhs.sign ^ subtract;
+ return opOK;
+
+ case PackCategoriesIntoKey(fcZero, fcZero):
+ /* Sign depends on rounding mode; handled by caller. */
+ return opOK;
+
+ case PackCategoriesIntoKey(fcInfinity, fcInfinity):
+ /* Differently signed infinities can only be validly
+ subtracted. */
+ if (((sign ^ rhs.sign)!=0) != subtract) {
+ makeNaN();
+ return opInvalidOp;
+ }
+
+ return opOK;
+
+ case PackCategoriesIntoKey(fcNormal, fcNormal):
+ return opDivByZero;
+ }
+}
+
+/* Add or subtract two normal numbers. */
+lostFraction
+APFloat::addOrSubtractSignificand(const APFloat &rhs, bool subtract)
+{
+ integerPart carry;
+ lostFraction lost_fraction;
+ int bits;
+
+ /* Determine if the operation on the absolute values is effectively
+ an addition or subtraction. */
+ subtract ^= static_cast<bool>(sign ^ rhs.sign);
+
+ /* Are we bigger exponent-wise than the RHS? */
+ bits = exponent - rhs.exponent;
+
+ /* Subtraction is more subtle than one might naively expect. */
+ if (subtract) {
+ APFloat temp_rhs(rhs);
+ bool reverse;
+
+ if (bits == 0) {
+ reverse = compareAbsoluteValue(temp_rhs) == cmpLessThan;
+ lost_fraction = lfExactlyZero;
+ } else if (bits > 0) {
+ lost_fraction = temp_rhs.shiftSignificandRight(bits - 1);
+ shiftSignificandLeft(1);
+ reverse = false;
+ } else {
+ lost_fraction = shiftSignificandRight(-bits - 1);
+ temp_rhs.shiftSignificandLeft(1);
+ reverse = true;
+ }
+
+ if (reverse) {
+ carry = temp_rhs.subtractSignificand
+ (*this, lost_fraction != lfExactlyZero);
+ copySignificand(temp_rhs);
+ sign = !sign;
+ } else {
+ carry = subtractSignificand
+ (temp_rhs, lost_fraction != lfExactlyZero);
+ }
+
+ /* Invert the lost fraction - it was on the RHS and
+ subtracted. */
+ if (lost_fraction == lfLessThanHalf)
+ lost_fraction = lfMoreThanHalf;
+ else if (lost_fraction == lfMoreThanHalf)
+ lost_fraction = lfLessThanHalf;
+
+ /* The code above is intended to ensure that no borrow is
+ necessary. */
+ assert(!carry);
+ (void)carry;
+ } else {
+ if (bits > 0) {
+ APFloat temp_rhs(rhs);
+
+ lost_fraction = temp_rhs.shiftSignificandRight(bits);
+ carry = addSignificand(temp_rhs);
+ } else {
+ lost_fraction = shiftSignificandRight(-bits);
+ carry = addSignificand(rhs);
+ }
+
+ /* We have a guard bit; generating a carry cannot happen. */
+ assert(!carry);
+ (void)carry;
+ }
+
+ return lost_fraction;
+}
+
+APFloat::opStatus
+APFloat::multiplySpecials(const APFloat &rhs)
+{
+ switch (PackCategoriesIntoKey(category, rhs.category)) {
+ default:
+ llvm_unreachable(nullptr);
+
+ case PackCategoriesIntoKey(fcNaN, fcZero):
+ case PackCategoriesIntoKey(fcNaN, fcNormal):
+ case PackCategoriesIntoKey(fcNaN, fcInfinity):
+ case PackCategoriesIntoKey(fcNaN, fcNaN):
+ sign = false;
+ return opOK;
+
+ case PackCategoriesIntoKey(fcZero, fcNaN):
+ case PackCategoriesIntoKey(fcNormal, fcNaN):
+ case PackCategoriesIntoKey(fcInfinity, fcNaN):
+ sign = false;
+ category = fcNaN;
+ copySignificand(rhs);
+ return opOK;
+
+ case PackCategoriesIntoKey(fcNormal, fcInfinity):
+ case PackCategoriesIntoKey(fcInfinity, fcNormal):
+ case PackCategoriesIntoKey(fcInfinity, fcInfinity):
+ category = fcInfinity;
+ return opOK;
+
+ case PackCategoriesIntoKey(fcZero, fcNormal):
+ case PackCategoriesIntoKey(fcNormal, fcZero):
+ case PackCategoriesIntoKey(fcZero, fcZero):
+ category = fcZero;
+ return opOK;
+
+ case PackCategoriesIntoKey(fcZero, fcInfinity):
+ case PackCategoriesIntoKey(fcInfinity, fcZero):
+ makeNaN();
+ return opInvalidOp;
+
+ case PackCategoriesIntoKey(fcNormal, fcNormal):
+ return opOK;
+ }
+}
+
+APFloat::opStatus
+APFloat::divideSpecials(const APFloat &rhs)
+{
+ switch (PackCategoriesIntoKey(category, rhs.category)) {
+ default:
+ llvm_unreachable(nullptr);
+
+ case PackCategoriesIntoKey(fcZero, fcNaN):
+ case PackCategoriesIntoKey(fcNormal, fcNaN):
+ case PackCategoriesIntoKey(fcInfinity, fcNaN):
+ category = fcNaN;
+ copySignificand(rhs);
+ case PackCategoriesIntoKey(fcNaN, fcZero):
+ case PackCategoriesIntoKey(fcNaN, fcNormal):
+ case PackCategoriesIntoKey(fcNaN, fcInfinity):
+ case PackCategoriesIntoKey(fcNaN, fcNaN):
+ sign = false;
+ case PackCategoriesIntoKey(fcInfinity, fcZero):
+ case PackCategoriesIntoKey(fcInfinity, fcNormal):
+ case PackCategoriesIntoKey(fcZero, fcInfinity):
+ case PackCategoriesIntoKey(fcZero, fcNormal):
+ return opOK;
+
+ case PackCategoriesIntoKey(fcNormal, fcInfinity):
+ category = fcZero;
+ return opOK;
+
+ case PackCategoriesIntoKey(fcNormal, fcZero):
+ category = fcInfinity;
+ return opDivByZero;
+
+ case PackCategoriesIntoKey(fcInfinity, fcInfinity):
+ case PackCategoriesIntoKey(fcZero, fcZero):
+ makeNaN();
+ return opInvalidOp;
+
+ case PackCategoriesIntoKey(fcNormal, fcNormal):
+ return opOK;
+ }
+}
+
+APFloat::opStatus
+APFloat::modSpecials(const APFloat &rhs)
+{
+ switch (PackCategoriesIntoKey(category, rhs.category)) {
+ default:
+ llvm_unreachable(nullptr);
+
+ case PackCategoriesIntoKey(fcNaN, fcZero):
+ case PackCategoriesIntoKey(fcNaN, fcNormal):
+ case PackCategoriesIntoKey(fcNaN, fcInfinity):
+ case PackCategoriesIntoKey(fcNaN, fcNaN):
+ case PackCategoriesIntoKey(fcZero, fcInfinity):
+ case PackCategoriesIntoKey(fcZero, fcNormal):
+ case PackCategoriesIntoKey(fcNormal, fcInfinity):
+ return opOK;
+
+ case PackCategoriesIntoKey(fcZero, fcNaN):
+ case PackCategoriesIntoKey(fcNormal, fcNaN):
+ case PackCategoriesIntoKey(fcInfinity, fcNaN):
+ sign = false;
+ category = fcNaN;
+ copySignificand(rhs);
+ return opOK;
+
+ case PackCategoriesIntoKey(fcNormal, fcZero):
+ case PackCategoriesIntoKey(fcInfinity, fcZero):
+ case PackCategoriesIntoKey(fcInfinity, fcNormal):
+ case PackCategoriesIntoKey(fcInfinity, fcInfinity):
+ case PackCategoriesIntoKey(fcZero, fcZero):
+ makeNaN();
+ return opInvalidOp;
+
+ case PackCategoriesIntoKey(fcNormal, fcNormal):
+ return opOK;
+ }
+}
+
+/* Change sign. */
+void
+APFloat::changeSign()
+{
+ /* Look mummy, this one's easy. */
+ sign = !sign;
+}
+
+void
+APFloat::clearSign()
+{
+ /* So is this one. */
+ sign = 0;
+}
+
+void
+APFloat::copySign(const APFloat &rhs)
+{
+ /* And this one. */
+ sign = rhs.sign;
+}
+
+/* Normalized addition or subtraction. */
+APFloat::opStatus
+APFloat::addOrSubtract(const APFloat &rhs, roundingMode rounding_mode,
+ bool subtract)
+{
+ opStatus fs;
+
+ fs = addOrSubtractSpecials(rhs, subtract);
+
+ /* This return code means it was not a simple case. */
+ if (fs == opDivByZero) {
+ lostFraction lost_fraction;
+
+ lost_fraction = addOrSubtractSignificand(rhs, subtract);
+ fs = normalize(rounding_mode, lost_fraction);
+
+ /* Can only be zero if we lost no fraction. */
+ assert(category != fcZero || lost_fraction == lfExactlyZero);
+ }
+
+ /* If two numbers add (exactly) to zero, IEEE 754 decrees it is a
+ positive zero unless rounding to minus infinity, except that
+ adding two like-signed zeroes gives that zero. */
+ if (category == fcZero) {
+ if (rhs.category != fcZero || (sign == rhs.sign) == subtract)
+ sign = (rounding_mode == rmTowardNegative);
+ }
+
+ return fs;
+}
+
+/* Normalized addition. */
+APFloat::opStatus
+APFloat::add(const APFloat &rhs, roundingMode rounding_mode)
+{
+ return addOrSubtract(rhs, rounding_mode, false);
+}
+
+/* Normalized subtraction. */
+APFloat::opStatus
+APFloat::subtract(const APFloat &rhs, roundingMode rounding_mode)
+{
+ return addOrSubtract(rhs, rounding_mode, true);
+}
+
+/* Normalized multiply. */
+APFloat::opStatus
+APFloat::multiply(const APFloat &rhs, roundingMode rounding_mode)
+{
+ opStatus fs;
+
+ sign ^= rhs.sign;
+ fs = multiplySpecials(rhs);
+
+ if (isFiniteNonZero()) {
+ lostFraction lost_fraction = multiplySignificand(rhs, nullptr);
+ fs = normalize(rounding_mode, lost_fraction);
+ if (lost_fraction != lfExactlyZero)
+ fs = (opStatus) (fs | opInexact);
+ }
+
+ return fs;
+}
+
+/* Normalized divide. */
+APFloat::opStatus
+APFloat::divide(const APFloat &rhs, roundingMode rounding_mode)
+{
+ opStatus fs;
+
+ sign ^= rhs.sign;
+ fs = divideSpecials(rhs);
+
+ if (isFiniteNonZero()) {
+ lostFraction lost_fraction = divideSignificand(rhs);
+ fs = normalize(rounding_mode, lost_fraction);
+ if (lost_fraction != lfExactlyZero)
+ fs = (opStatus) (fs | opInexact);
+ }
+
+ return fs;
+}
+
+/* Normalized remainder. This is not currently correct in all cases. */
+APFloat::opStatus
+APFloat::remainder(const APFloat &rhs)
+{
+ opStatus fs;
+ APFloat V = *this;
+ unsigned int origSign = sign;
+
+ fs = V.divide(rhs, rmNearestTiesToEven);
+ if (fs == opDivByZero)
+ return fs;
+
+ int parts = partCount();
+ integerPart *x = new integerPart[parts];
+ bool ignored;
+ fs = V.convertToInteger(x, parts * integerPartWidth, true,
+ rmNearestTiesToEven, &ignored);
+ if (fs==opInvalidOp)
+ return fs;
+
+ fs = V.convertFromZeroExtendedInteger(x, parts * integerPartWidth, true,
+ rmNearestTiesToEven);
+ assert(fs==opOK); // should always work
+
+ fs = V.multiply(rhs, rmNearestTiesToEven);
+ assert(fs==opOK || fs==opInexact); // should not overflow or underflow
+
+ fs = subtract(V, rmNearestTiesToEven);
+ assert(fs==opOK || fs==opInexact); // likewise
+
+ if (isZero())
+ sign = origSign; // IEEE754 requires this
+ delete[] x;
+ return fs;
+}
+
+/* Normalized llvm frem (C fmod).
+ This is not currently correct in all cases. */
+APFloat::opStatus
+APFloat::mod(const APFloat &rhs, roundingMode rounding_mode)
+{
+ opStatus fs;
+ fs = modSpecials(rhs);
+
+ if (isFiniteNonZero() && rhs.isFiniteNonZero()) {
+ APFloat V = *this;
+ unsigned int origSign = sign;
+
+ fs = V.divide(rhs, rmNearestTiesToEven);
+ if (fs == opDivByZero)
+ return fs;
+
+ int parts = partCount();
+ integerPart *x = new integerPart[parts];
+ bool ignored;
+ fs = V.convertToInteger(x, parts * integerPartWidth, true,
+ rmTowardZero, &ignored);
+ if (fs==opInvalidOp)
+ return fs;
+
+ fs = V.convertFromZeroExtendedInteger(x, parts * integerPartWidth, true,
+ rmNearestTiesToEven);
+ assert(fs==opOK); // should always work
+
+ fs = V.multiply(rhs, rounding_mode);
+ assert(fs==opOK || fs==opInexact); // should not overflow or underflow
+
+ fs = subtract(V, rounding_mode);
+ assert(fs==opOK || fs==opInexact); // likewise
+
+ if (isZero())
+ sign = origSign; // IEEE754 requires this
+ delete[] x;
+ }
+ return fs;
+}
+
+/* Normalized fused-multiply-add. */
+APFloat::opStatus
+APFloat::fusedMultiplyAdd(const APFloat &multiplicand,
+ const APFloat &addend,
+ roundingMode rounding_mode)
+{
+ opStatus fs;
+
+ /* Post-multiplication sign, before addition. */
+ sign ^= multiplicand.sign;
+
+ /* If and only if all arguments are normal do we need to do an
+ extended-precision calculation. */
+ if (isFiniteNonZero() &&
+ multiplicand.isFiniteNonZero() &&
+ addend.isFinite()) {
+ lostFraction lost_fraction;
+
+ lost_fraction = multiplySignificand(multiplicand, &addend);
+ fs = normalize(rounding_mode, lost_fraction);
+ if (lost_fraction != lfExactlyZero)
+ fs = (opStatus) (fs | opInexact);
+
+ /* If two numbers add (exactly) to zero, IEEE 754 decrees it is a
+ positive zero unless rounding to minus infinity, except that
+ adding two like-signed zeroes gives that zero. */
+ if (category == fcZero && !(fs & opUnderflow) && sign != addend.sign)
+ sign = (rounding_mode == rmTowardNegative);
+ } else {
+ fs = multiplySpecials(multiplicand);
+
+ /* FS can only be opOK or opInvalidOp. There is no more work
+ to do in the latter case. The IEEE-754R standard says it is
+ implementation-defined in this case whether, if ADDEND is a
+ quiet NaN, we raise invalid op; this implementation does so.
+
+ If we need to do the addition we can do so with normal
+ precision. */
+ if (fs == opOK)
+ fs = addOrSubtract(addend, rounding_mode, false);
+ }
+
+ return fs;
+}
+
+/* Rounding-mode corrrect round to integral value. */
+APFloat::opStatus APFloat::roundToIntegral(roundingMode rounding_mode) {
+ opStatus fs;
+
+ // If the exponent is large enough, we know that this value is already
+ // integral, and the arithmetic below would potentially cause it to saturate
+ // to +/-Inf. Bail out early instead.
+ if (isFiniteNonZero() && exponent+1 >= (int)semanticsPrecision(*semantics))
+ return opOK;
+
+ // The algorithm here is quite simple: we add 2^(p-1), where p is the
+ // precision of our format, and then subtract it back off again. The choice
+ // of rounding modes for the addition/subtraction determines the rounding mode
+ // for our integral rounding as well.
+ // NOTE: When the input value is negative, we do subtraction followed by
+ // addition instead.
+ APInt IntegerConstant(NextPowerOf2(semanticsPrecision(*semantics)), 1);
+ IntegerConstant <<= semanticsPrecision(*semantics)-1;
+ APFloat MagicConstant(*semantics);
+ fs = MagicConstant.convertFromAPInt(IntegerConstant, false,
+ rmNearestTiesToEven);
+ MagicConstant.copySign(*this);
+
+ if (fs != opOK)
+ return fs;
+
+ // Preserve the input sign so that we can handle 0.0/-0.0 cases correctly.
+ bool inputSign = isNegative();
+
+ fs = add(MagicConstant, rounding_mode);
+ if (fs != opOK && fs != opInexact)
+ return fs;
+
+ fs = subtract(MagicConstant, rounding_mode);
+
+ // Restore the input sign.
+ if (inputSign != isNegative())
+ changeSign();
+
+ return fs;
+}
+
+
+/* Comparison requires normalized numbers. */
+APFloat::cmpResult
+APFloat::compare(const APFloat &rhs) const
+{
+ cmpResult result;
+
+ assert(semantics == rhs.semantics);
+
+ switch (PackCategoriesIntoKey(category, rhs.category)) {
+ default:
+ llvm_unreachable(nullptr);
+
+ case PackCategoriesIntoKey(fcNaN, fcZero):
+ case PackCategoriesIntoKey(fcNaN, fcNormal):
+ case PackCategoriesIntoKey(fcNaN, fcInfinity):
+ case PackCategoriesIntoKey(fcNaN, fcNaN):
+ case PackCategoriesIntoKey(fcZero, fcNaN):
+ case PackCategoriesIntoKey(fcNormal, fcNaN):
+ case PackCategoriesIntoKey(fcInfinity, fcNaN):
+ return cmpUnordered;
+
+ case PackCategoriesIntoKey(fcInfinity, fcNormal):
+ case PackCategoriesIntoKey(fcInfinity, fcZero):
+ case PackCategoriesIntoKey(fcNormal, fcZero):
+ if (sign)
+ return cmpLessThan;
+ else
+ return cmpGreaterThan;
+
+ case PackCategoriesIntoKey(fcNormal, fcInfinity):
+ case PackCategoriesIntoKey(fcZero, fcInfinity):
+ case PackCategoriesIntoKey(fcZero, fcNormal):
+ if (rhs.sign)
+ return cmpGreaterThan;
+ else
+ return cmpLessThan;
+
+ case PackCategoriesIntoKey(fcInfinity, fcInfinity):
+ if (sign == rhs.sign)
+ return cmpEqual;
+ else if (sign)
+ return cmpLessThan;
+ else
+ return cmpGreaterThan;
+
+ case PackCategoriesIntoKey(fcZero, fcZero):
+ return cmpEqual;
+
+ case PackCategoriesIntoKey(fcNormal, fcNormal):
+ break;
+ }
+
+ /* Two normal numbers. Do they have the same sign? */
+ if (sign != rhs.sign) {
+ if (sign)
+ result = cmpLessThan;
+ else
+ result = cmpGreaterThan;
+ } else {
+ /* Compare absolute values; invert result if negative. */
+ result = compareAbsoluteValue(rhs);
+
+ if (sign) {
+ if (result == cmpLessThan)
+ result = cmpGreaterThan;
+ else if (result == cmpGreaterThan)
+ result = cmpLessThan;
+ }
+ }
+
+ return result;
+}
+
+/// APFloat::convert - convert a value of one floating point type to another.
+/// The return value corresponds to the IEEE754 exceptions. *losesInfo
+/// records whether the transformation lost information, i.e. whether
+/// converting the result back to the original type will produce the
+/// original value (this is almost the same as return value==fsOK, but there
+/// are edge cases where this is not so).
+
+APFloat::opStatus
+APFloat::convert(const fltSemantics &toSemantics,
+ roundingMode rounding_mode, bool *losesInfo)
+{
+ lostFraction lostFraction;
+ unsigned int newPartCount, oldPartCount;
+ opStatus fs;
+ int shift;
+ const fltSemantics &fromSemantics = *semantics;
+
+ lostFraction = lfExactlyZero;
+ newPartCount = partCountForBits(toSemantics.precision + 1);
+ oldPartCount = partCount();
+ shift = toSemantics.precision - fromSemantics.precision;
+
+ bool X86SpecialNan = false;
+ if (&fromSemantics == &APFloat::x87DoubleExtended &&
+ &toSemantics != &APFloat::x87DoubleExtended && category == fcNaN &&
+ (!(*significandParts() & 0x8000000000000000ULL) ||
+ !(*significandParts() & 0x4000000000000000ULL))) {
+ // x86 has some unusual NaNs which cannot be represented in any other
+ // format; note them here.
+ X86SpecialNan = true;
+ }
+
+ // If this is a truncation of a denormal number, and the target semantics
+ // has larger exponent range than the source semantics (this can happen
+ // when truncating from PowerPC double-double to double format), the
+ // right shift could lose result mantissa bits. Adjust exponent instead
+ // of performing excessive shift.
+ if (shift < 0 && isFiniteNonZero()) {
+ int exponentChange = significandMSB() + 1 - fromSemantics.precision;
+ if (exponent + exponentChange < toSemantics.minExponent)
+ exponentChange = toSemantics.minExponent - exponent;
+ if (exponentChange < shift)
+ exponentChange = shift;
+ if (exponentChange < 0) {
+ shift -= exponentChange;
+ exponent += exponentChange;
+ }
+ }
+
+ // If this is a truncation, perform the shift before we narrow the storage.
+ if (shift < 0 && (isFiniteNonZero() || category==fcNaN))
+ lostFraction = shiftRight(significandParts(), oldPartCount, -shift);
+
+ // Fix the storage so it can hold to new value.
+ if (newPartCount > oldPartCount) {
+ // The new type requires more storage; make it available.
+ integerPart *newParts;
+ newParts = new integerPart[newPartCount];
+ APInt::tcSet(newParts, 0, newPartCount);
+ if (isFiniteNonZero() || category==fcNaN)
+ APInt::tcAssign(newParts, significandParts(), oldPartCount);
+ freeSignificand();
+ significand.parts = newParts;
+ } else if (newPartCount == 1 && oldPartCount != 1) {
+ // Switch to built-in storage for a single part.
+ integerPart newPart = 0;
+ if (isFiniteNonZero() || category==fcNaN)
+ newPart = significandParts()[0];
+ freeSignificand();
+ significand.part = newPart;
+ }
+
+ // Now that we have the right storage, switch the semantics.
+ semantics = &toSemantics;
+
+ // If this is an extension, perform the shift now that the storage is
+ // available.
+ if (shift > 0 && (isFiniteNonZero() || category==fcNaN))
+ APInt::tcShiftLeft(significandParts(), newPartCount, shift);
+
+ if (isFiniteNonZero()) {
+ fs = normalize(rounding_mode, lostFraction);
+ *losesInfo = (fs != opOK);
+ } else if (category == fcNaN) {
+ *losesInfo = lostFraction != lfExactlyZero || X86SpecialNan;
+
+ // For x87 extended precision, we want to make a NaN, not a special NaN if
+ // the input wasn't special either.
+ if (!X86SpecialNan && semantics == &APFloat::x87DoubleExtended)
+ APInt::tcSetBit(significandParts(), semantics->precision - 1);
+
+ // gcc forces the Quiet bit on, which means (float)(double)(float_sNan)
+ // does not give you back the same bits. This is dubious, and we
+ // don't currently do it. You're really supposed to get
+ // an invalid operation signal at runtime, but nobody does that.
+ fs = opOK;
+ } else {
+ *losesInfo = false;
+ fs = opOK;
+ }
+
+ return fs;
+}
+
+/* Convert a floating point number to an integer according to the
+ rounding mode. If the rounded integer value is out of range this
+ returns an invalid operation exception and the contents of the
+ destination parts are unspecified. If the rounded value is in
+ range but the floating point number is not the exact integer, the C
+ standard doesn't require an inexact exception to be raised. IEEE
+ 854 does require it so we do that.
+
+ Note that for conversions to integer type the C standard requires
+ round-to-zero to always be used. */
+APFloat::opStatus
+APFloat::convertToSignExtendedInteger(integerPart *parts, unsigned int width,
+ bool isSigned,
+ roundingMode rounding_mode,
+ bool *isExact) const
+{
+ lostFraction lost_fraction;
+ const integerPart *src;
+ unsigned int dstPartsCount, truncatedBits;
+
+ *isExact = false;
+
+ /* Handle the three special cases first. */
+ if (category == fcInfinity || category == fcNaN)
+ return opInvalidOp;
+
+ dstPartsCount = partCountForBits(width);
+
+ if (category == fcZero) {
+ APInt::tcSet(parts, 0, dstPartsCount);
+ // Negative zero can't be represented as an int.
+ *isExact = !sign;
+ return opOK;
+ }
+
+ src = significandParts();
+
+ /* Step 1: place our absolute value, with any fraction truncated, in
+ the destination. */
+ if (exponent < 0) {
+ /* Our absolute value is less than one; truncate everything. */
+ APInt::tcSet(parts, 0, dstPartsCount);
+ /* For exponent -1 the integer bit represents .5, look at that.
+ For smaller exponents leftmost truncated bit is 0. */
+ truncatedBits = semantics->precision -1U - exponent;
+ } else {
+ /* We want the most significant (exponent + 1) bits; the rest are
+ truncated. */
+ unsigned int bits = exponent + 1U;
+
+ /* Hopelessly large in magnitude? */
+ if (bits > width)
+ return opInvalidOp;
+
+ if (bits < semantics->precision) {
+ /* We truncate (semantics->precision - bits) bits. */
+ truncatedBits = semantics->precision - bits;
+ APInt::tcExtract(parts, dstPartsCount, src, bits, truncatedBits);
+ } else {
+ /* We want at least as many bits as are available. */
+ APInt::tcExtract(parts, dstPartsCount, src, semantics->precision, 0);
+ APInt::tcShiftLeft(parts, dstPartsCount, bits - semantics->precision);
+ truncatedBits = 0;
+ }
+ }
+
+ /* Step 2: work out any lost fraction, and increment the absolute
+ value if we would round away from zero. */
+ if (truncatedBits) {
+ lost_fraction = lostFractionThroughTruncation(src, partCount(),
+ truncatedBits);
+ if (lost_fraction != lfExactlyZero &&
+ roundAwayFromZero(rounding_mode, lost_fraction, truncatedBits)) {
+ if (APInt::tcIncrement(parts, dstPartsCount))
+ return opInvalidOp; /* Overflow. */
+ }
+ } else {
+ lost_fraction = lfExactlyZero;
+ }
+
+ /* Step 3: check if we fit in the destination. */
+ unsigned int omsb = APInt::tcMSB(parts, dstPartsCount) + 1;
+
+ if (sign) {
+ if (!isSigned) {
+ /* Negative numbers cannot be represented as unsigned. */
+ if (omsb != 0)
+ return opInvalidOp;
+ } else {
+ /* It takes omsb bits to represent the unsigned integer value.
+ We lose a bit for the sign, but care is needed as the
+ maximally negative integer is a special case. */
+ if (omsb == width && APInt::tcLSB(parts, dstPartsCount) + 1 != omsb)
+ return opInvalidOp;
+
+ /* This case can happen because of rounding. */
+ if (omsb > width)
+ return opInvalidOp;
+ }
+
+ APInt::tcNegate (parts, dstPartsCount);
+ } else {
+ if (omsb >= width + !isSigned)
+ return opInvalidOp;
+ }
+
+ if (lost_fraction == lfExactlyZero) {
+ *isExact = true;
+ return opOK;
+ } else
+ return opInexact;
+}
+
+/* Same as convertToSignExtendedInteger, except we provide
+ deterministic values in case of an invalid operation exception,
+ namely zero for NaNs and the minimal or maximal value respectively
+ for underflow or overflow.
+ The *isExact output tells whether the result is exact, in the sense
+ that converting it back to the original floating point type produces
+ the original value. This is almost equivalent to result==opOK,
+ except for negative zeroes.
+*/
+APFloat::opStatus
+APFloat::convertToInteger(integerPart *parts, unsigned int width,
+ bool isSigned,
+ roundingMode rounding_mode, bool *isExact) const
+{
+ opStatus fs;
+
+ fs = convertToSignExtendedInteger(parts, width, isSigned, rounding_mode,
+ isExact);
+
+ if (fs == opInvalidOp) {
+ unsigned int bits, dstPartsCount;
+
+ dstPartsCount = partCountForBits(width);
+
+ if (category == fcNaN)
+ bits = 0;
+ else if (sign)
+ bits = isSigned;
+ else
+ bits = width - isSigned;
+
+ APInt::tcSetLeastSignificantBits(parts, dstPartsCount, bits);
+ if (sign && isSigned)
+ APInt::tcShiftLeft(parts, dstPartsCount, width - 1);
+ }
+
+ return fs;
+}
+
+/* Same as convertToInteger(integerPart*, ...), except the result is returned in
+ an APSInt, whose initial bit-width and signed-ness are used to determine the
+ precision of the conversion.
+ */
+APFloat::opStatus
+APFloat::convertToInteger(APSInt &result,
+ roundingMode rounding_mode, bool *isExact) const
+{
+ unsigned bitWidth = result.getBitWidth();
+ SmallVector<uint64_t, 4> parts(result.getNumWords());
+ opStatus status = convertToInteger(
+ parts.data(), bitWidth, result.isSigned(), rounding_mode, isExact);
+ // Keeps the original signed-ness.
+ result = APInt(bitWidth, parts);
+ return status;
+}
+
+/* Convert an unsigned integer SRC to a floating point number,
+ rounding according to ROUNDING_MODE. The sign of the floating
+ point number is not modified. */
+APFloat::opStatus
+APFloat::convertFromUnsignedParts(const integerPart *src,
+ unsigned int srcCount,
+ roundingMode rounding_mode)
+{
+ unsigned int omsb, precision, dstCount;
+ integerPart *dst;
+ lostFraction lost_fraction;
+
+ category = fcNormal;
+ omsb = APInt::tcMSB(src, srcCount) + 1;
+ dst = significandParts();
+ dstCount = partCount();
+ precision = semantics->precision;
+
+ /* We want the most significant PRECISION bits of SRC. There may not
+ be that many; extract what we can. */
+ if (precision <= omsb) {
+ exponent = omsb - 1;
+ lost_fraction = lostFractionThroughTruncation(src, srcCount,
+ omsb - precision);
+ APInt::tcExtract(dst, dstCount, src, precision, omsb - precision);
+ } else {
+ exponent = precision - 1;
+ lost_fraction = lfExactlyZero;
+ APInt::tcExtract(dst, dstCount, src, omsb, 0);
+ }
+
+ return normalize(rounding_mode, lost_fraction);
+}
+
+APFloat::opStatus
+APFloat::convertFromAPInt(const APInt &Val,
+ bool isSigned,
+ roundingMode rounding_mode)
+{
+ unsigned int partCount = Val.getNumWords();
+ APInt api = Val;
+
+ sign = false;
+ if (isSigned && api.isNegative()) {
+ sign = true;
+ api = -api;
+ }
+
+ return convertFromUnsignedParts(api.getRawData(), partCount, rounding_mode);
+}
+
+/* Convert a two's complement integer SRC to a floating point number,
+ rounding according to ROUNDING_MODE. ISSIGNED is true if the
+ integer is signed, in which case it must be sign-extended. */
+APFloat::opStatus
+APFloat::convertFromSignExtendedInteger(const integerPart *src,
+ unsigned int srcCount,
+ bool isSigned,
+ roundingMode rounding_mode)
+{
+ opStatus status;
+
+ if (isSigned &&
+ APInt::tcExtractBit(src, srcCount * integerPartWidth - 1)) {
+ integerPart *copy;
+
+ /* If we're signed and negative negate a copy. */
+ sign = true;
+ copy = new integerPart[srcCount];
+ APInt::tcAssign(copy, src, srcCount);
+ APInt::tcNegate(copy, srcCount);
+ status = convertFromUnsignedParts(copy, srcCount, rounding_mode);
+ delete [] copy;
+ } else {
+ sign = false;
+ status = convertFromUnsignedParts(src, srcCount, rounding_mode);
+ }
+
+ return status;
+}
+
+/* FIXME: should this just take a const APInt reference? */
+APFloat::opStatus
+APFloat::convertFromZeroExtendedInteger(const integerPart *parts,
+ unsigned int width, bool isSigned,
+ roundingMode rounding_mode)
+{
+ unsigned int partCount = partCountForBits(width);
+ APInt api = APInt(width, makeArrayRef(parts, partCount));
+
+ sign = false;
+ if (isSigned && APInt::tcExtractBit(parts, width - 1)) {
+ sign = true;
+ api = -api;
+ }
+
+ return convertFromUnsignedParts(api.getRawData(), partCount, rounding_mode);
+}
+
+APFloat::opStatus
+APFloat::convertFromHexadecimalString(StringRef s, roundingMode rounding_mode)
+{
+ lostFraction lost_fraction = lfExactlyZero;
+
+ category = fcNormal;
+ zeroSignificand();
+ exponent = 0;
+
+ integerPart *significand = significandParts();
+ unsigned partsCount = partCount();
+ unsigned bitPos = partsCount * integerPartWidth;
+ bool computedTrailingFraction = false;
+
+ // Skip leading zeroes and any (hexa)decimal point.
+ StringRef::iterator begin = s.begin();
+ StringRef::iterator end = s.end();
+ StringRef::iterator dot;
+ StringRef::iterator p = skipLeadingZeroesAndAnyDot(begin, end, &dot);
+ StringRef::iterator firstSignificantDigit = p;
+
+ while (p != end) {
+ integerPart hex_value;
+
+ if (*p == '.') {
+ assert(dot == end && "String contains multiple dots");
+ dot = p++;
+ continue;
+ }
+
+ hex_value = hexDigitValue(*p);
+ if (hex_value == -1U)
+ break;
+
+ p++;
+
+ // Store the number while we have space.
+ if (bitPos) {
+ bitPos -= 4;
+ hex_value <<= bitPos % integerPartWidth;
+ significand[bitPos / integerPartWidth] |= hex_value;
+ } else if (!computedTrailingFraction) {
+ lost_fraction = trailingHexadecimalFraction(p, end, hex_value);
+ computedTrailingFraction = true;
+ }
+ }
+
+ /* Hex floats require an exponent but not a hexadecimal point. */
+ assert(p != end && "Hex strings require an exponent");
+ assert((*p == 'p' || *p == 'P') && "Invalid character in significand");
+ assert(p != begin && "Significand has no digits");
+ assert((dot == end || p - begin != 1) && "Significand has no digits");
+
+ /* Ignore the exponent if we are zero. */
+ if (p != firstSignificantDigit) {
+ int expAdjustment;
+
+ /* Implicit hexadecimal point? */
+ if (dot == end)
+ dot = p;
+
+ /* Calculate the exponent adjustment implicit in the number of
+ significant digits. */
+ expAdjustment = static_cast<int>(dot - firstSignificantDigit);
+ if (expAdjustment < 0)
+ expAdjustment++;
+ expAdjustment = expAdjustment * 4 - 1;
+
+ /* Adjust for writing the significand starting at the most
+ significant nibble. */
+ expAdjustment += semantics->precision;
+ expAdjustment -= partsCount * integerPartWidth;
+
+ /* Adjust for the given exponent. */
+ exponent = totalExponent(p + 1, end, expAdjustment);
+ }
+
+ return normalize(rounding_mode, lost_fraction);
+}
+
+APFloat::opStatus
+APFloat::roundSignificandWithExponent(const integerPart *decSigParts,
+ unsigned sigPartCount, int exp,
+ roundingMode rounding_mode)
+{
+ unsigned int parts, pow5PartCount;
+ fltSemantics calcSemantics = { 32767, -32767, 0 };
+ integerPart pow5Parts[maxPowerOfFiveParts];
+ bool isNearest;
+
+ isNearest = (rounding_mode == rmNearestTiesToEven ||
+ rounding_mode == rmNearestTiesToAway);
+
+ parts = partCountForBits(semantics->precision + 11);
+
+ /* Calculate pow(5, abs(exp)). */
+ pow5PartCount = powerOf5(pow5Parts, exp >= 0 ? exp: -exp);
+
+ for (;; parts *= 2) {
+ opStatus sigStatus, powStatus;
+ unsigned int excessPrecision, truncatedBits;
+
+ calcSemantics.precision = parts * integerPartWidth - 1;
+ excessPrecision = calcSemantics.precision - semantics->precision;
+ truncatedBits = excessPrecision;
+
+ APFloat decSig = APFloat::getZero(calcSemantics, sign);
+ APFloat pow5(calcSemantics);
+
+ sigStatus = decSig.convertFromUnsignedParts(decSigParts, sigPartCount,
+ rmNearestTiesToEven);
+ powStatus = pow5.convertFromUnsignedParts(pow5Parts, pow5PartCount,
+ rmNearestTiesToEven);
+ /* Add exp, as 10^n = 5^n * 2^n. */
+ decSig.exponent += exp;
+
+ lostFraction calcLostFraction;
+ integerPart HUerr, HUdistance;
+ unsigned int powHUerr;
+
+ if (exp >= 0) {
+ /* multiplySignificand leaves the precision-th bit set to 1. */
+ calcLostFraction = decSig.multiplySignificand(pow5, nullptr);
+ powHUerr = powStatus != opOK;
+ } else {
+ calcLostFraction = decSig.divideSignificand(pow5);
+ /* Denormal numbers have less precision. */
+ if (decSig.exponent < semantics->minExponent) {
+ excessPrecision += (semantics->minExponent - decSig.exponent);
+ truncatedBits = excessPrecision;
+ if (excessPrecision > calcSemantics.precision)
+ excessPrecision = calcSemantics.precision;
+ }
+ /* Extra half-ulp lost in reciprocal of exponent. */
+ powHUerr = (powStatus == opOK && calcLostFraction == lfExactlyZero) ? 0:2;
+ }
+
+ /* Both multiplySignificand and divideSignificand return the
+ result with the integer bit set. */
+ assert(APInt::tcExtractBit
+ (decSig.significandParts(), calcSemantics.precision - 1) == 1);
+
+ HUerr = HUerrBound(calcLostFraction != lfExactlyZero, sigStatus != opOK,
+ powHUerr);
+ HUdistance = 2 * ulpsFromBoundary(decSig.significandParts(),
+ excessPrecision, isNearest);
+
+ /* Are we guaranteed to round correctly if we truncate? */
+ if (HUdistance >= HUerr) {
+ APInt::tcExtract(significandParts(), partCount(), decSig.significandParts(),
+ calcSemantics.precision - excessPrecision,
+ excessPrecision);
+ /* Take the exponent of decSig. If we tcExtract-ed less bits
+ above we must adjust our exponent to compensate for the
+ implicit right shift. */
+ exponent = (decSig.exponent + semantics->precision
+ - (calcSemantics.precision - excessPrecision));
+ calcLostFraction = lostFractionThroughTruncation(decSig.significandParts(),
+ decSig.partCount(),
+ truncatedBits);
+ return normalize(rounding_mode, calcLostFraction);
+ }
+ }
+}
+
+APFloat::opStatus
+APFloat::convertFromDecimalString(StringRef str, roundingMode rounding_mode)
+{
+ decimalInfo D;
+ opStatus fs;
+
+ /* Scan the text. */
+ StringRef::iterator p = str.begin();
+ interpretDecimal(p, str.end(), &D);
+
+ /* Handle the quick cases. First the case of no significant digits,
+ i.e. zero, and then exponents that are obviously too large or too
+ small. Writing L for log 10 / log 2, a number d.ddddd*10^exp
+ definitely overflows if
+
+ (exp - 1) * L >= maxExponent
+
+ and definitely underflows to zero where
+
+ (exp + 1) * L <= minExponent - precision
+
+ With integer arithmetic the tightest bounds for L are
+
+ 93/28 < L < 196/59 [ numerator <= 256 ]
+ 42039/12655 < L < 28738/8651 [ numerator <= 65536 ]
+ */
+
+ // Test if we have a zero number allowing for strings with no null terminators
+ // and zero decimals with non-zero exponents.
+ //
+ // We computed firstSigDigit by ignoring all zeros and dots. Thus if
+ // D->firstSigDigit equals str.end(), every digit must be a zero and there can
+ // be at most one dot. On the other hand, if we have a zero with a non-zero
+ // exponent, then we know that D.firstSigDigit will be non-numeric.
+ if (D.firstSigDigit == str.end() || decDigitValue(*D.firstSigDigit) >= 10U) {
+ category = fcZero;
+ fs = opOK;
+
+ /* Check whether the normalized exponent is high enough to overflow
+ max during the log-rebasing in the max-exponent check below. */
+ } else if (D.normalizedExponent - 1 > INT_MAX / 42039) {
+ fs = handleOverflow(rounding_mode);
+
+ /* If it wasn't, then it also wasn't high enough to overflow max
+ during the log-rebasing in the min-exponent check. Check that it
+ won't overflow min in either check, then perform the min-exponent
+ check. */
+ } else if (D.normalizedExponent - 1 < INT_MIN / 42039 ||
+ (D.normalizedExponent + 1) * 28738 <=
+ 8651 * (semantics->minExponent - (int) semantics->precision)) {
+ /* Underflow to zero and round. */
+ category = fcNormal;
+ zeroSignificand();
+ fs = normalize(rounding_mode, lfLessThanHalf);
+
+ /* We can finally safely perform the max-exponent check. */
+ } else if ((D.normalizedExponent - 1) * 42039
+ >= 12655 * semantics->maxExponent) {
+ /* Overflow and round. */
+ fs = handleOverflow(rounding_mode);
+ } else {
+ integerPart *decSignificand;
+ unsigned int partCount;
+
+ /* A tight upper bound on number of bits required to hold an
+ N-digit decimal integer is N * 196 / 59. Allocate enough space
+ to hold the full significand, and an extra part required by
+ tcMultiplyPart. */
+ partCount = static_cast<unsigned int>(D.lastSigDigit - D.firstSigDigit) + 1;
+ partCount = partCountForBits(1 + 196 * partCount / 59);
+ decSignificand = new integerPart[partCount + 1];
+ partCount = 0;
+
+ /* Convert to binary efficiently - we do almost all multiplication
+ in an integerPart. When this would overflow do we do a single
+ bignum multiplication, and then revert again to multiplication
+ in an integerPart. */
+ do {
+ integerPart decValue, val, multiplier;
+
+ val = 0;
+ multiplier = 1;
+
+ do {
+ if (*p == '.') {
+ p++;
+ if (p == str.end()) {
+ break;
+ }
+ }
+ decValue = decDigitValue(*p++);
+ assert(decValue < 10U && "Invalid character in significand");
+ multiplier *= 10;
+ val = val * 10 + decValue;
+ /* The maximum number that can be multiplied by ten with any
+ digit added without overflowing an integerPart. */
+ } while (p <= D.lastSigDigit && multiplier <= (~ (integerPart) 0 - 9) / 10);
+
+ /* Multiply out the current part. */
+ APInt::tcMultiplyPart(decSignificand, decSignificand, multiplier, val,
+ partCount, partCount + 1, false);
+
+ /* If we used another part (likely but not guaranteed), increase
+ the count. */
+ if (decSignificand[partCount])
+ partCount++;
+ } while (p <= D.lastSigDigit);
+
+ category = fcNormal;
+ fs = roundSignificandWithExponent(decSignificand, partCount,
+ D.exponent, rounding_mode);
+
+ delete [] decSignificand;
+ }
+
+ return fs;
+}
+
+bool
+APFloat::convertFromStringSpecials(StringRef str) {
+ if (str.equals("inf") || str.equals("INFINITY")) {
+ makeInf(false);
+ return true;
+ }
+
+ if (str.equals("-inf") || str.equals("-INFINITY")) {
+ makeInf(true);
+ return true;
+ }
+
+ if (str.equals("nan") || str.equals("NaN")) {
+ makeNaN(false, false);
+ return true;
+ }
+
+ if (str.equals("-nan") || str.equals("-NaN")) {
+ makeNaN(false, true);
+ return true;
+ }
+
+ return false;
+}
+
+APFloat::opStatus
+APFloat::convertFromString(StringRef str, roundingMode rounding_mode)
+{
+ assert(!str.empty() && "Invalid string length");
+
+ // Handle special cases.
+ if (convertFromStringSpecials(str))
+ return opOK;
+
+ /* Handle a leading minus sign. */
+ StringRef::iterator p = str.begin();
+ size_t slen = str.size();
+ sign = *p == '-' ? 1 : 0;
+ if (*p == '-' || *p == '+') {
+ p++;
+ slen--;
+ assert(slen && "String has no digits");
+ }
+
+ if (slen >= 2 && p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) {
+ assert(slen - 2 && "Invalid string");
+ return convertFromHexadecimalString(StringRef(p + 2, slen - 2),
+ rounding_mode);
+ }
+
+ return convertFromDecimalString(StringRef(p, slen), rounding_mode);
+}
+
+/* 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.
+
+ If UPPERCASE, the output is in upper case, otherwise in lower case.
+
+ HEXDIGITS digits appear altogether, rounding the value if
+ necessary. If HEXDIGITS is 0, the minimal precision to display the
+ number precisely is used instead. If nothing would appear after
+ the decimal point it is suppressed.
+
+ The decimal exponent is always printed and has at least one digit.
+ Zero values display an exponent of zero. Infinities and NaNs
+ appear as "infinity" or "nan" respectively.
+
+ The above rules are as specified by C99. There is ambiguity about
+ what the leading hexadecimal digit should be. This implementation
+ uses whatever is necessary so that the exponent is displayed as
+ stored. This implies the exponent will fall within the IEEE format
+ range, and the leading hexadecimal digit will be 0 (for denormals),
+ 1 (normal numbers) or 2 (normal numbers rounded-away-from-zero with
+ any other digits zero).
+*/
+unsigned int
+APFloat::convertToHexString(char *dst, unsigned int hexDigits,
+ bool upperCase, roundingMode rounding_mode) const
+{
+ char *p;
+
+ p = dst;
+ if (sign)
+ *dst++ = '-';
+
+ switch (category) {
+ case fcInfinity:
+ memcpy (dst, upperCase ? infinityU: infinityL, sizeof infinityU - 1);
+ dst += sizeof infinityL - 1;
+ break;
+
+ case fcNaN:
+ memcpy (dst, upperCase ? NaNU: NaNL, sizeof NaNU - 1);
+ dst += sizeof NaNU - 1;
+ break;
+
+ case fcZero:
+ *dst++ = '0';
+ *dst++ = upperCase ? 'X': 'x';
+ *dst++ = '0';
+ if (hexDigits > 1) {
+ *dst++ = '.';
+ memset (dst, '0', hexDigits - 1);
+ dst += hexDigits - 1;
+ }
+ *dst++ = upperCase ? 'P': 'p';
+ *dst++ = '0';
+ break;
+
+ case fcNormal:
+ dst = convertNormalToHexString (dst, hexDigits, upperCase, rounding_mode);
+ break;
+ }
+
+ *dst = 0;
+
+ return static_cast<unsigned int>(dst - p);
+}
+
+/* Does the hard work of outputting the correctly rounded hexadecimal
+ form of a normal floating point number with the specified number of
+ hexadecimal digits. If HEXDIGITS is zero the minimum number of
+ digits necessary to print the value precisely is output. */
+char *
+APFloat::convertNormalToHexString(char *dst, unsigned int hexDigits,
+ bool upperCase,
+ roundingMode rounding_mode) const
+{
+ unsigned int count, valueBits, shift, partsCount, outputDigits;
+ const char *hexDigitChars;
+ const integerPart *significand;
+ char *p;
+ bool roundUp;
+
+ *dst++ = '0';
+ *dst++ = upperCase ? 'X': 'x';
+
+ roundUp = false;
+ hexDigitChars = upperCase ? hexDigitsUpper: hexDigitsLower;
+
+ significand = significandParts();
+ partsCount = partCount();
+
+ /* +3 because the first digit only uses the single integer bit, so
+ we have 3 virtual zero most-significant-bits. */
+ valueBits = semantics->precision + 3;
+ shift = integerPartWidth - valueBits % integerPartWidth;
+
+ /* The natural number of digits required ignoring trailing
+ insignificant zeroes. */
+ outputDigits = (valueBits - significandLSB () + 3) / 4;
+
+ /* hexDigits of zero means use the required number for the
+ precision. Otherwise, see if we are truncating. If we are,
+ find out if we need to round away from zero. */
+ if (hexDigits) {
+ if (hexDigits < outputDigits) {
+ /* We are dropping non-zero bits, so need to check how to round.
+ "bits" is the number of dropped bits. */
+ unsigned int bits;
+ lostFraction fraction;
+
+ bits = valueBits - hexDigits * 4;
+ fraction = lostFractionThroughTruncation (significand, partsCount, bits);
+ roundUp = roundAwayFromZero(rounding_mode, fraction, bits);
+ }
+ outputDigits = hexDigits;
+ }
+
+ /* Write the digits consecutively, and start writing in the location
+ of the hexadecimal point. We move the most significant digit
+ left and add the hexadecimal point later. */
+ p = ++dst;
+
+ count = (valueBits + integerPartWidth - 1) / integerPartWidth;
+
+ while (outputDigits && count) {
+ integerPart part;
+
+ /* Put the most significant integerPartWidth bits in "part". */
+ if (--count == partsCount)
+ part = 0; /* An imaginary higher zero part. */
+ else
+ part = significand[count] << shift;
+
+ if (count && shift)
+ part |= significand[count - 1] >> (integerPartWidth - shift);
+
+ /* Convert as much of "part" to hexdigits as we can. */
+ unsigned int curDigits = integerPartWidth / 4;
+
+ if (curDigits > outputDigits)
+ curDigits = outputDigits;
+ dst += partAsHex (dst, part, curDigits, hexDigitChars);
+ outputDigits -= curDigits;
+ }
+
+ if (roundUp) {
+ char *q = dst;
+
+ /* Note that hexDigitChars has a trailing '0'. */
+ do {
+ q--;
+ *q = hexDigitChars[hexDigitValue (*q) + 1];
+ } while (*q == '0');
+ assert(q >= p);
+ } else {
+ /* Add trailing zeroes. */
+ memset (dst, '0', outputDigits);
+ dst += outputDigits;
+ }
+
+ /* Move the most significant digit to before the point, and if there
+ is something after the decimal point add it. This must come
+ after rounding above. */
+ p[-1] = p[0];
+ if (dst -1 == p)
+ dst--;
+ else
+ p[0] = '.';
+
+ /* Finally output the exponent. */
+ *dst++ = upperCase ? 'P': 'p';
+
+ return writeSignedDecimal (dst, exponent);
+}
+
+hash_code llvm::hash_value(const APFloat &Arg) {
+ if (!Arg.isFiniteNonZero())
+ return hash_combine((uint8_t)Arg.category,
+ // NaN has no sign, fix it at zero.
+ Arg.isNaN() ? (uint8_t)0 : (uint8_t)Arg.sign,
+ Arg.semantics->precision);
+
+ // Normal floats need their exponent and significand hashed.
+ return hash_combine((uint8_t)Arg.category, (uint8_t)Arg.sign,
+ Arg.semantics->precision, Arg.exponent,
+ hash_combine_range(
+ Arg.significandParts(),
+ Arg.significandParts() + Arg.partCount()));
+}
+
+// Conversion from APFloat to/from host float/double. It may eventually be
+// possible to eliminate these and have everybody deal with APFloats, but that
+// will take a while. This approach will not easily extend to long double.
+// Current implementation requires integerPartWidth==64, which is correct at
+// the moment but could be made more general.
+
+// Denormals have exponent minExponent in APFloat, but minExponent-1 in
+// the actual IEEE respresentations. We compensate for that here.
+
+APInt
+APFloat::convertF80LongDoubleAPFloatToAPInt() const
+{
+ assert(semantics == (const llvm::fltSemantics*)&x87DoubleExtended);
+ assert(partCount()==2);
+
+ uint64_t myexponent, mysignificand;
+
+ if (isFiniteNonZero()) {
+ myexponent = exponent+16383; //bias
+ mysignificand = significandParts()[0];
+ if (myexponent==1 && !(mysignificand & 0x8000000000000000ULL))
+ myexponent = 0; // denormal
+ } else if (category==fcZero) {
+ myexponent = 0;
+ mysignificand = 0;
+ } else if (category==fcInfinity) {
+ myexponent = 0x7fff;
+ mysignificand = 0x8000000000000000ULL;
+ } else {
+ assert(category == fcNaN && "Unknown category");
+ myexponent = 0x7fff;
+ mysignificand = significandParts()[0];
+ }
+
+ uint64_t words[2];
+ words[0] = mysignificand;
+ words[1] = ((uint64_t)(sign & 1) << 15) |
+ (myexponent & 0x7fffLL);
+ return APInt(80, words);
+}
+
+APInt
+APFloat::convertPPCDoubleDoubleAPFloatToAPInt() const
+{
+ assert(semantics == (const llvm::fltSemantics*)&PPCDoubleDouble);
+ assert(partCount()==2);
+
+ uint64_t words[2];
+ opStatus fs;
+ bool losesInfo;
+
+ // Convert number to double. To avoid spurious underflows, we re-
+ // normalize against the "double" minExponent first, and only *then*
+ // truncate the mantissa. The result of that second conversion
+ // may be inexact, but should never underflow.
+ // Declare fltSemantics before APFloat that uses it (and
+ // saves pointer to it) to ensure correct destruction order.
+ fltSemantics extendedSemantics = *semantics;
+ extendedSemantics.minExponent = IEEEdouble.minExponent;
+ APFloat extended(*this);
+ fs = extended.convert(extendedSemantics, rmNearestTiesToEven, &losesInfo);
+ assert(fs == opOK && !losesInfo);
+ (void)fs;
+
+ APFloat u(extended);
+ fs = u.convert(IEEEdouble, rmNearestTiesToEven, &losesInfo);
+ assert(fs == opOK || fs == opInexact);
+ (void)fs;
+ words[0] = *u.convertDoubleAPFloatToAPInt().getRawData();
+
+ // If conversion was exact or resulted in a special case, we're done;
+ // just set the second double to zero. Otherwise, re-convert back to
+ // the extended format and compute the difference. This now should
+ // convert exactly to double.
+ if (u.isFiniteNonZero() && losesInfo) {
+ fs = u.convert(extendedSemantics, rmNearestTiesToEven, &losesInfo);
+ assert(fs == opOK && !losesInfo);
+ (void)fs;
+
+ APFloat v(extended);
+ v.subtract(u, rmNearestTiesToEven);
+ fs = v.convert(IEEEdouble, rmNearestTiesToEven, &losesInfo);
+ assert(fs == opOK && !losesInfo);
+ (void)fs;
+ words[1] = *v.convertDoubleAPFloatToAPInt().getRawData();
+ } else {
+ words[1] = 0;
+ }
+
+ return APInt(128, words);
+}
+
+APInt
+APFloat::convertQuadrupleAPFloatToAPInt() const
+{
+ assert(semantics == (const llvm::fltSemantics*)&IEEEquad);
+ assert(partCount()==2);
+
+ uint64_t myexponent, mysignificand, mysignificand2;
+
+ if (isFiniteNonZero()) {
+ myexponent = exponent+16383; //bias
+ mysignificand = significandParts()[0];
+ mysignificand2 = significandParts()[1];
+ if (myexponent==1 && !(mysignificand2 & 0x1000000000000LL))
+ myexponent = 0; // denormal
+ } else if (category==fcZero) {
+ myexponent = 0;
+ mysignificand = mysignificand2 = 0;
+ } else if (category==fcInfinity) {
+ myexponent = 0x7fff;
+ mysignificand = mysignificand2 = 0;
+ } else {
+ assert(category == fcNaN && "Unknown category!");
+ myexponent = 0x7fff;
+ mysignificand = significandParts()[0];
+ mysignificand2 = significandParts()[1];
+ }
+
+ uint64_t words[2];
+ words[0] = mysignificand;
+ words[1] = ((uint64_t)(sign & 1) << 63) |
+ ((myexponent & 0x7fff) << 48) |
+ (mysignificand2 & 0xffffffffffffLL);
+
+ return APInt(128, words);
+}
+
+APInt
+APFloat::convertDoubleAPFloatToAPInt() const
+{
+ assert(semantics == (const llvm::fltSemantics*)&IEEEdouble);
+ assert(partCount()==1);
+
+ uint64_t myexponent, mysignificand;
+
+ if (isFiniteNonZero()) {
+ myexponent = exponent+1023; //bias
+ mysignificand = *significandParts();
+ if (myexponent==1 && !(mysignificand & 0x10000000000000LL))
+ myexponent = 0; // denormal
+ } else if (category==fcZero) {
+ myexponent = 0;
+ mysignificand = 0;
+ } else if (category==fcInfinity) {
+ myexponent = 0x7ff;
+ mysignificand = 0;
+ } else {
+ assert(category == fcNaN && "Unknown category!");
+ myexponent = 0x7ff;
+ mysignificand = *significandParts();
+ }
+
+ return APInt(64, ((((uint64_t)(sign & 1) << 63) |
+ ((myexponent & 0x7ff) << 52) |
+ (mysignificand & 0xfffffffffffffLL))));
+}
+
+APInt
+APFloat::convertFloatAPFloatToAPInt() const
+{
+ assert(semantics == (const llvm::fltSemantics*)&IEEEsingle);
+ assert(partCount()==1);
+
+ uint32_t myexponent, mysignificand;
+
+ if (isFiniteNonZero()) {
+ myexponent = exponent+127; //bias
+ mysignificand = (uint32_t)*significandParts();
+ if (myexponent == 1 && !(mysignificand & 0x800000))
+ myexponent = 0; // denormal
+ } else if (category==fcZero) {
+ myexponent = 0;
+ mysignificand = 0;
+ } else if (category==fcInfinity) {
+ myexponent = 0xff;
+ mysignificand = 0;
+ } else {
+ assert(category == fcNaN && "Unknown category!");
+ myexponent = 0xff;
+ mysignificand = (uint32_t)*significandParts();
+ }
+
+ return APInt(32, (((sign&1) << 31) | ((myexponent&0xff) << 23) |
+ (mysignificand & 0x7fffff)));
+}
+
+APInt
+APFloat::convertHalfAPFloatToAPInt() const
+{
+ assert(semantics == (const llvm::fltSemantics*)&IEEEhalf);
+ assert(partCount()==1);
+
+ uint32_t myexponent, mysignificand;
+
+ if (isFiniteNonZero()) {
+ myexponent = exponent+15; //bias
+ mysignificand = (uint32_t)*significandParts();
+ if (myexponent == 1 && !(mysignificand & 0x400))
+ myexponent = 0; // denormal
+ } else if (category==fcZero) {
+ myexponent = 0;
+ mysignificand = 0;
+ } else if (category==fcInfinity) {
+ myexponent = 0x1f;
+ mysignificand = 0;
+ } else {
+ assert(category == fcNaN && "Unknown category!");
+ myexponent = 0x1f;
+ mysignificand = (uint32_t)*significandParts();
+ }
+
+ return APInt(16, (((sign&1) << 15) | ((myexponent&0x1f) << 10) |
+ (mysignificand & 0x3ff)));
+}
+
+// This function creates an APInt that is just a bit map of the floating
+// point constant as it would appear in memory. It is not a conversion,
+// and treating the result as a normal integer is unlikely to be useful.
+
+APInt
+APFloat::bitcastToAPInt() const
+{
+ if (semantics == (const llvm::fltSemantics*)&IEEEhalf)
+ return convertHalfAPFloatToAPInt();
+
+ if (semantics == (const llvm::fltSemantics*)&IEEEsingle)
+ return convertFloatAPFloatToAPInt();
+
+ if (semantics == (const llvm::fltSemantics*)&IEEEdouble)
+ return convertDoubleAPFloatToAPInt();
+
+ if (semantics == (const llvm::fltSemantics*)&IEEEquad)
+ return convertQuadrupleAPFloatToAPInt();
+
+ if (semantics == (const llvm::fltSemantics*)&PPCDoubleDouble)
+ return convertPPCDoubleDoubleAPFloatToAPInt();
+
+ assert(semantics == (const llvm::fltSemantics*)&x87DoubleExtended &&
+ "unknown format!");
+ return convertF80LongDoubleAPFloatToAPInt();
+}
+
+float
+APFloat::convertToFloat() const
+{
+ assert(semantics == (const llvm::fltSemantics*)&IEEEsingle &&
+ "Float semantics are not IEEEsingle");
+ APInt api = bitcastToAPInt();
+ return api.bitsToFloat();
+}
+
+double
+APFloat::convertToDouble() const
+{
+ assert(semantics == (const llvm::fltSemantics*)&IEEEdouble &&
+ "Float semantics are not IEEEdouble");
+ APInt api = bitcastToAPInt();
+ return api.bitsToDouble();
+}
+
+/// Integer bit is explicit in this format. Intel hardware (387 and later)
+/// does not support these bit patterns:
+/// exponent = all 1's, integer bit 0, significand 0 ("pseudoinfinity")
+/// exponent = all 1's, integer bit 0, significand nonzero ("pseudoNaN")
+/// exponent = 0, integer bit 1 ("pseudodenormal")
+/// exponent!=0 nor all 1's, integer bit 0 ("unnormal")
+/// At the moment, the first two are treated as NaNs, the second two as Normal.
+void
+APFloat::initFromF80LongDoubleAPInt(const APInt &api)
+{
+ assert(api.getBitWidth()==80);
+ uint64_t i1 = api.getRawData()[0];
+ uint64_t i2 = api.getRawData()[1];
+ uint64_t myexponent = (i2 & 0x7fff);
+ uint64_t mysignificand = i1;
+
+ initialize(&APFloat::x87DoubleExtended);
+ assert(partCount()==2);
+
+ sign = static_cast<unsigned int>(i2>>15);
+ if (myexponent==0 && mysignificand==0) {
+ // exponent, significand meaningless
+ category = fcZero;
+ } else if (myexponent==0x7fff && mysignificand==0x8000000000000000ULL) {
+ // exponent, significand meaningless
+ category = fcInfinity;
+ } else if (myexponent==0x7fff && mysignificand!=0x8000000000000000ULL) {
+ // exponent meaningless
+ category = fcNaN;
+ significandParts()[0] = mysignificand;
+ significandParts()[1] = 0;
+ } else {
+ category = fcNormal;
+ exponent = myexponent - 16383;
+ significandParts()[0] = mysignificand;
+ significandParts()[1] = 0;
+ if (myexponent==0) // denormal
+ exponent = -16382;
+ }
+}
+
+void
+APFloat::initFromPPCDoubleDoubleAPInt(const APInt &api)
+{
+ assert(api.getBitWidth()==128);
+ uint64_t i1 = api.getRawData()[0];
+ uint64_t i2 = api.getRawData()[1];
+ opStatus fs;
+ bool losesInfo;
+
+ // Get the first double and convert to our format.
+ initFromDoubleAPInt(APInt(64, i1));
+ fs = convert(PPCDoubleDouble, rmNearestTiesToEven, &losesInfo);
+ assert(fs == opOK && !losesInfo);
+ (void)fs;
+
+ // Unless we have a special case, add in second double.
+ if (isFiniteNonZero()) {
+ APFloat v(IEEEdouble, APInt(64, i2));
+ fs = v.convert(PPCDoubleDouble, rmNearestTiesToEven, &losesInfo);
+ assert(fs == opOK && !losesInfo);
+ (void)fs;
+
+ add(v, rmNearestTiesToEven);
+ }
+}
+
+void
+APFloat::initFromQuadrupleAPInt(const APInt &api)
+{
+ assert(api.getBitWidth()==128);
+ uint64_t i1 = api.getRawData()[0];
+ uint64_t i2 = api.getRawData()[1];
+ uint64_t myexponent = (i2 >> 48) & 0x7fff;
+ uint64_t mysignificand = i1;
+ uint64_t mysignificand2 = i2 & 0xffffffffffffLL;
+
+ initialize(&APFloat::IEEEquad);
+ assert(partCount()==2);
+
+ sign = static_cast<unsigned int>(i2>>63);
+ if (myexponent==0 &&
+ (mysignificand==0 && mysignificand2==0)) {
+ // exponent, significand meaningless
+ category = fcZero;
+ } else if (myexponent==0x7fff &&
+ (mysignificand==0 && mysignificand2==0)) {
+ // exponent, significand meaningless
+ category = fcInfinity;
+ } else if (myexponent==0x7fff &&
+ (mysignificand!=0 || mysignificand2 !=0)) {
+ // exponent meaningless
+ category = fcNaN;
+ significandParts()[0] = mysignificand;
+ significandParts()[1] = mysignificand2;
+ } else {
+ category = fcNormal;
+ exponent = myexponent - 16383;
+ significandParts()[0] = mysignificand;
+ significandParts()[1] = mysignificand2;
+ if (myexponent==0) // denormal
+ exponent = -16382;
+ else
+ significandParts()[1] |= 0x1000000000000LL; // integer bit
+ }
+}
+
+void
+APFloat::initFromDoubleAPInt(const APInt &api)
+{
+ assert(api.getBitWidth()==64);
+ uint64_t i = *api.getRawData();
+ uint64_t myexponent = (i >> 52) & 0x7ff;
+ uint64_t mysignificand = i & 0xfffffffffffffLL;
+
+ initialize(&APFloat::IEEEdouble);
+ assert(partCount()==1);
+
+ sign = static_cast<unsigned int>(i>>63);
+ if (myexponent==0 && mysignificand==0) {
+ // exponent, significand meaningless
+ category = fcZero;
+ } else if (myexponent==0x7ff && mysignificand==0) {
+ // exponent, significand meaningless
+ category = fcInfinity;
+ } else if (myexponent==0x7ff && mysignificand!=0) {
+ // exponent meaningless
+ category = fcNaN;
+ *significandParts() = mysignificand;
+ } else {
+ category = fcNormal;
+ exponent = myexponent - 1023;
+ *significandParts() = mysignificand;
+ if (myexponent==0) // denormal
+ exponent = -1022;
+ else
+ *significandParts() |= 0x10000000000000LL; // integer bit
+ }
+}
+
+void
+APFloat::initFromFloatAPInt(const APInt & api)
+{
+ assert(api.getBitWidth()==32);
+ uint32_t i = (uint32_t)*api.getRawData();
+ uint32_t myexponent = (i >> 23) & 0xff;
+ uint32_t mysignificand = i & 0x7fffff;
+
+ initialize(&APFloat::IEEEsingle);
+ assert(partCount()==1);
+
+ sign = i >> 31;
+ if (myexponent==0 && mysignificand==0) {
+ // exponent, significand meaningless
+ category = fcZero;
+ } else if (myexponent==0xff && mysignificand==0) {
+ // exponent, significand meaningless
+ category = fcInfinity;
+ } else if (myexponent==0xff && mysignificand!=0) {
+ // sign, exponent, significand meaningless
+ category = fcNaN;
+ *significandParts() = mysignificand;
+ } else {
+ category = fcNormal;
+ exponent = myexponent - 127; //bias
+ *significandParts() = mysignificand;
+ if (myexponent==0) // denormal
+ exponent = -126;
+ else
+ *significandParts() |= 0x800000; // integer bit
+ }
+}
+
+void
+APFloat::initFromHalfAPInt(const APInt & api)
+{
+ assert(api.getBitWidth()==16);
+ uint32_t i = (uint32_t)*api.getRawData();
+ uint32_t myexponent = (i >> 10) & 0x1f;
+ uint32_t mysignificand = i & 0x3ff;
+
+ initialize(&APFloat::IEEEhalf);
+ assert(partCount()==1);
+
+ sign = i >> 15;
+ if (myexponent==0 && mysignificand==0) {
+ // exponent, significand meaningless
+ category = fcZero;
+ } else if (myexponent==0x1f && mysignificand==0) {
+ // exponent, significand meaningless
+ category = fcInfinity;
+ } else if (myexponent==0x1f && mysignificand!=0) {
+ // sign, exponent, significand meaningless
+ category = fcNaN;
+ *significandParts() = mysignificand;
+ } else {
+ category = fcNormal;
+ exponent = myexponent - 15; //bias
+ *significandParts() = mysignificand;
+ if (myexponent==0) // denormal
+ exponent = -14;
+ else
+ *significandParts() |= 0x400; // integer bit
+ }
+}
+
+/// Treat api as containing the bits of a floating point number. Currently
+/// we infer the floating point type from the size of the APInt. The
+/// isIEEE argument distinguishes between PPC128 and IEEE128 (not meaningful
+/// when the size is anything else).
+void
+APFloat::initFromAPInt(const fltSemantics* Sem, const APInt& api)
+{
+ if (Sem == &IEEEhalf)
+ return initFromHalfAPInt(api);
+ if (Sem == &IEEEsingle)
+ return initFromFloatAPInt(api);
+ if (Sem == &IEEEdouble)
+ return initFromDoubleAPInt(api);
+ if (Sem == &x87DoubleExtended)
+ return initFromF80LongDoubleAPInt(api);
+ if (Sem == &IEEEquad)
+ return initFromQuadrupleAPInt(api);
+ if (Sem == &PPCDoubleDouble)
+ return initFromPPCDoubleDoubleAPInt(api);
+
+ llvm_unreachable(nullptr);
+}
+
+APFloat
+APFloat::getAllOnesValue(unsigned BitWidth, bool isIEEE)
+{
+ switch (BitWidth) {
+ case 16:
+ return APFloat(IEEEhalf, APInt::getAllOnesValue(BitWidth));
+ case 32:
+ return APFloat(IEEEsingle, APInt::getAllOnesValue(BitWidth));
+ case 64:
+ return APFloat(IEEEdouble, APInt::getAllOnesValue(BitWidth));
+ case 80:
+ return APFloat(x87DoubleExtended, APInt::getAllOnesValue(BitWidth));
+ case 128:
+ if (isIEEE)
+ return APFloat(IEEEquad, APInt::getAllOnesValue(BitWidth));
+ return APFloat(PPCDoubleDouble, APInt::getAllOnesValue(BitWidth));
+ default:
+ llvm_unreachable("Unknown floating bit width");
+ }
+}
+
+/// Make this number the largest magnitude normal number in the given
+/// semantics.
+void APFloat::makeLargest(bool Negative) {
+ // We want (in interchange format):
+ // sign = {Negative}
+ // exponent = 1..10
+ // significand = 1..1
+ category = fcNormal;
+ sign = Negative;
+ exponent = semantics->maxExponent;
+
+ // Use memset to set all but the highest integerPart to all ones.
+ integerPart *significand = significandParts();
+ unsigned PartCount = partCount();
+ memset(significand, 0xFF, sizeof(integerPart)*(PartCount - 1));
+
+ // Set the high integerPart especially setting all unused top bits for
+ // internal consistency.
+ const unsigned NumUnusedHighBits =
+ PartCount*integerPartWidth - semantics->precision;
+ significand[PartCount - 1] = (NumUnusedHighBits < integerPartWidth)
+ ? (~integerPart(0) >> NumUnusedHighBits)
+ : 0;
+}
+
+/// Make this number the smallest magnitude denormal number in the given
+/// semantics.
+void APFloat::makeSmallest(bool Negative) {
+ // We want (in interchange format):
+ // sign = {Negative}
+ // exponent = 0..0
+ // significand = 0..01
+ category = fcNormal;
+ sign = Negative;
+ exponent = semantics->minExponent;
+ APInt::tcSet(significandParts(), 1, partCount());
+}
+
+
+APFloat APFloat::getLargest(const fltSemantics &Sem, bool Negative) {
+ // We want (in interchange format):
+ // sign = {Negative}
+ // exponent = 1..10
+ // significand = 1..1
+ APFloat Val(Sem, uninitialized);
+ Val.makeLargest(Negative);
+ return Val;
+}
+
+APFloat APFloat::getSmallest(const fltSemantics &Sem, bool Negative) {
+ // We want (in interchange format):
+ // sign = {Negative}
+ // exponent = 0..0
+ // significand = 0..01
+ APFloat Val(Sem, uninitialized);
+ Val.makeSmallest(Negative);
+ return Val;
+}
+
+APFloat APFloat::getSmallestNormalized(const fltSemantics &Sem, bool Negative) {
+ APFloat Val(Sem, uninitialized);
+
+ // We want (in interchange format):
+ // sign = {Negative}
+ // exponent = 0..0
+ // significand = 10..0
+
+ Val.category = fcNormal;
+ Val.zeroSignificand();
+ Val.sign = Negative;
+ Val.exponent = Sem.minExponent;
+ Val.significandParts()[partCountForBits(Sem.precision)-1] |=
+ (((integerPart) 1) << ((Sem.precision - 1) % integerPartWidth));
+
+ return Val;
+}
+
+APFloat::APFloat(const fltSemantics &Sem, const APInt &API) {
+ initFromAPInt(&Sem, API);
+}
+
+APFloat::APFloat(float f) {
+ initFromAPInt(&IEEEsingle, APInt::floatToBits(f));
+}
+
+APFloat::APFloat(double d) {
+ initFromAPInt(&IEEEdouble, APInt::doubleToBits(d));
+}
+
+namespace {
+ void append(SmallVectorImpl<char> &Buffer, StringRef Str) {
+ Buffer.append(Str.begin(), Str.end());
+ }
+
+ /// Removes data from the given significand until it is no more
+ /// precise than is required for the desired precision.
+ void AdjustToPrecision(APInt &significand,
+ int &exp, unsigned FormatPrecision) {
+ unsigned bits = significand.getActiveBits();
+
+ // 196/59 is a very slight overestimate of lg_2(10).
+ unsigned bitsRequired = (FormatPrecision * 196 + 58) / 59;
+
+ if (bits <= bitsRequired) return;
+
+ unsigned tensRemovable = (bits - bitsRequired) * 59 / 196;
+ if (!tensRemovable) return;
+
+ exp += tensRemovable;
+
+ APInt divisor(significand.getBitWidth(), 1);
+ APInt powten(significand.getBitWidth(), 10);
+ while (true) {
+ if (tensRemovable & 1)
+ divisor *= powten;
+ tensRemovable >>= 1;
+ if (!tensRemovable) break;
+ powten *= powten;
+ }
+
+ significand = significand.udiv(divisor);
+
+ // Truncate the significand down to its active bit count.
+ significand = significand.trunc(significand.getActiveBits());
+ }
+
+
+ void AdjustToPrecision(SmallVectorImpl<char> &buffer,
+ int &exp, unsigned FormatPrecision) {
+ unsigned N = buffer.size();
+ if (N <= FormatPrecision) return;
+
+ // The most significant figures are the last ones in the buffer.
+ unsigned FirstSignificant = N - FormatPrecision;
+
+ // Round.
+ // FIXME: this probably shouldn't use 'round half up'.
+
+ // Rounding down is just a truncation, except we also want to drop
+ // trailing zeros from the new result.
+ if (buffer[FirstSignificant - 1] < '5') {
+ while (FirstSignificant < N && buffer[FirstSignificant] == '0')
+ FirstSignificant++;
+
+ exp += FirstSignificant;
+ buffer.erase(&buffer[0], &buffer[FirstSignificant]);
+ return;
+ }
+
+ // Rounding up requires a decimal add-with-carry. If we continue
+ // the carry, the newly-introduced zeros will just be truncated.
+ for (unsigned I = FirstSignificant; I != N; ++I) {
+ if (buffer[I] == '9') {
+ FirstSignificant++;
+ } else {
+ buffer[I]++;
+ break;
+ }
+ }
+
+ // If we carried through, we have exactly one digit of precision.
+ if (FirstSignificant == N) {
+ exp += FirstSignificant;
+ buffer.clear();
+ buffer.push_back('1');
+ return;
+ }
+
+ exp += FirstSignificant;
+ buffer.erase(&buffer[0], &buffer[FirstSignificant]);
+ }
+} // namespace
+
+void APFloat::toString(SmallVectorImpl<char> &Str,
+ unsigned FormatPrecision,
+ unsigned FormatMaxPadding) const {
+ switch (category) {
+ case fcInfinity:
+ if (isNegative())
+ return append(Str, "-Inf");
+ else
+ return append(Str, "+Inf");
+
+ case fcNaN: return append(Str, "NaN");
+
+ case fcZero:
+ if (isNegative())
+ Str.push_back('-');
+
+ if (!FormatMaxPadding)
+ append(Str, "0.0E+0");
+ else
+ Str.push_back('0');
+ return;
+
+ case fcNormal:
+ break;
+ }
+
+ if (isNegative())
+ Str.push_back('-');
+
+ // Decompose the number into an APInt and an exponent.
+ int exp = exponent - ((int) semantics->precision - 1);
+ APInt significand(semantics->precision,
+ makeArrayRef(significandParts(),
+ partCountForBits(semantics->precision)));
+
+ // Set FormatPrecision if zero. We want to do this before we
+ // truncate trailing zeros, as those are part of the precision.
+ if (!FormatPrecision) {
+ // We use enough digits so the number can be round-tripped back to an
+ // APFloat. The formula comes from "How to Print Floating-Point Numbers
+ // Accurately" by Steele and White.
+ // FIXME: Using a formula based purely on the precision is conservative;
+ // we can print fewer digits depending on the actual value being printed.
+
+ // FormatPrecision = 2 + floor(significandBits / lg_2(10))
+ FormatPrecision = 2 + semantics->precision * 59 / 196;
+ }
+
+ // Ignore trailing binary zeros.
+ int trailingZeros = significand.countTrailingZeros();
+ exp += trailingZeros;
+ significand = significand.lshr(trailingZeros);
+
+ // Change the exponent from 2^e to 10^e.
+ if (exp == 0) {
+ // Nothing to do.
+ } else if (exp > 0) {
+ // Just shift left.
+ significand = significand.zext(semantics->precision + exp);
+ significand <<= exp;
+ exp = 0;
+ } else { /* exp < 0 */
+ int texp = -exp;
+
+ // We transform this using the identity:
+ // (N)(2^-e) == (N)(5^e)(10^-e)
+ // This means we have to multiply N (the significand) by 5^e.
+ // To avoid overflow, we have to operate on numbers large
+ // enough to store N * 5^e:
+ // log2(N * 5^e) == log2(N) + e * log2(5)
+ // <= semantics->precision + e * 137 / 59
+ // (log_2(5) ~ 2.321928 < 2.322034 ~ 137/59)
+
+ unsigned precision = semantics->precision + (137 * texp + 136) / 59;
+
+ // Multiply significand by 5^e.
+ // N * 5^0101 == N * 5^(1*1) * 5^(0*2) * 5^(1*4) * 5^(0*8)
+ significand = significand.zext(precision);
+ APInt five_to_the_i(precision, 5);
+ while (true) {
+ if (texp & 1) significand *= five_to_the_i;
+
+ texp >>= 1;
+ if (!texp) break;
+ five_to_the_i *= five_to_the_i;
+ }
+ }
+
+ AdjustToPrecision(significand, exp, FormatPrecision);
+
+ SmallVector<char, 256> buffer;
+
+ // Fill the buffer.
+ unsigned precision = significand.getBitWidth();
+ APInt ten(precision, 10);
+ APInt digit(precision, 0);
+
+ bool inTrail = true;
+ while (significand != 0) {
+ // digit <- significand % 10
+ // significand <- significand / 10
+ APInt::udivrem(significand, ten, significand, digit);
+
+ unsigned d = digit.getZExtValue();
+
+ // Drop trailing zeros.
+ if (inTrail && !d) exp++;
+ else {
+ buffer.push_back((char) ('0' + d));
+ inTrail = false;
+ }
+ }
+
+ assert(!buffer.empty() && "no characters in buffer!");
+
+ // Drop down to FormatPrecision.
+ // TODO: don't do more precise calculations above than are required.
+ AdjustToPrecision(buffer, exp, FormatPrecision);
+
+ unsigned NDigits = buffer.size();
+
+ // Check whether we should use scientific notation.
+ bool FormatScientific;
+ if (!FormatMaxPadding)
+ FormatScientific = true;
+ else {
+ if (exp >= 0) {
+ // 765e3 --> 765000
+ // ^^^
+ // But we shouldn't make the number look more precise than it is.
+ FormatScientific = ((unsigned) exp > FormatMaxPadding ||
+ NDigits + (unsigned) exp > FormatPrecision);
+ } else {
+ // Power of the most significant digit.
+ int MSD = exp + (int) (NDigits - 1);
+ if (MSD >= 0) {
+ // 765e-2 == 7.65
+ FormatScientific = false;
+ } else {
+ // 765e-5 == 0.00765
+ // ^ ^^
+ FormatScientific = ((unsigned) -MSD) > FormatMaxPadding;
+ }
+ }
+ }
+
+ // Scientific formatting is pretty straightforward.
+ if (FormatScientific) {
+ exp += (NDigits - 1);
+
+ Str.push_back(buffer[NDigits-1]);
+ Str.push_back('.');
+ if (NDigits == 1)
+ Str.push_back('0');
+ else
+ for (unsigned I = 1; I != NDigits; ++I)
+ Str.push_back(buffer[NDigits-1-I]);
+ Str.push_back('E');
+
+ Str.push_back(exp >= 0 ? '+' : '-');
+ if (exp < 0) exp = -exp;
+ SmallVector<char, 6> expbuf;
+ do {
+ expbuf.push_back((char) ('0' + (exp % 10)));
+ exp /= 10;
+ } while (exp);
+ for (unsigned I = 0, E = expbuf.size(); I != E; ++I)
+ Str.push_back(expbuf[E-1-I]);
+ return;
+ }
+
+ // Non-scientific, positive exponents.
+ if (exp >= 0) {
+ for (unsigned I = 0; I != NDigits; ++I)
+ Str.push_back(buffer[NDigits-1-I]);
+ for (unsigned I = 0; I != (unsigned) exp; ++I)
+ Str.push_back('0');
+ return;
+ }
+
+ // Non-scientific, negative exponents.
+
+ // The number of digits to the left of the decimal point.
+ int NWholeDigits = exp + (int) NDigits;
+
+ unsigned I = 0;
+ if (NWholeDigits > 0) {
+ for (; I != (unsigned) NWholeDigits; ++I)
+ Str.push_back(buffer[NDigits-I-1]);
+ Str.push_back('.');
+ } else {
+ unsigned NZeros = 1 + (unsigned) -NWholeDigits;
+
+ Str.push_back('0');
+ Str.push_back('.');
+ for (unsigned Z = 1; Z != NZeros; ++Z)
+ Str.push_back('0');
+ }
+
+ for (; I != NDigits; ++I)
+ Str.push_back(buffer[NDigits-I-1]);
+}
+
+bool APFloat::getExactInverse(APFloat *inv) const {
+ // Special floats and denormals have no exact inverse.
+ if (!isFiniteNonZero())
+ return false;
+
+ // Check that the number is a power of two by making sure that only the
+ // integer bit is set in the significand.
+ if (significandLSB() != semantics->precision - 1)
+ return false;
+
+ // Get the inverse.
+ APFloat reciprocal(*semantics, 1ULL);
+ if (reciprocal.divide(*this, rmNearestTiesToEven) != opOK)
+ return false;
+
+ // Avoid multiplication with a denormal, it is not safe on all platforms and
+ // may be slower than a normal division.
+ if (reciprocal.isDenormal())
+ return false;
+
+ assert(reciprocal.isFiniteNonZero() &&
+ reciprocal.significandLSB() == reciprocal.semantics->precision - 1);
+
+ if (inv)
+ *inv = reciprocal;
+
+ return true;
+}
+
+bool APFloat::isSignaling() const {
+ if (!isNaN())
+ return false;
+
+ // IEEE-754R 2008 6.2.1: A signaling NaN bit string should be encoded with the
+ // first bit of the trailing significand being 0.
+ return !APInt::tcExtractBit(significandParts(), semantics->precision - 2);
+}
+
+/// IEEE-754R 2008 5.3.1: nextUp/nextDown.
+///
+/// *NOTE* since nextDown(x) = -nextUp(-x), we only implement nextUp with
+/// appropriate sign switching before/after the computation.
+APFloat::opStatus APFloat::next(bool nextDown) {
+ // If we are performing nextDown, swap sign so we have -x.
+ if (nextDown)
+ changeSign();
+
+ // Compute nextUp(x)
+ opStatus result = opOK;
+
+ // Handle each float category separately.
+ switch (category) {
+ case fcInfinity:
+ // nextUp(+inf) = +inf
+ if (!isNegative())
+ break;
+ // nextUp(-inf) = -getLargest()
+ makeLargest(true);
+ break;
+ case fcNaN:
+ // IEEE-754R 2008 6.2 Par 2: nextUp(sNaN) = qNaN. Set Invalid flag.
+ // IEEE-754R 2008 6.2: nextUp(qNaN) = qNaN. Must be identity so we do not
+ // change the payload.
+ if (isSignaling()) {
+ result = opInvalidOp;
+ // For consistency, propagate the sign of the sNaN to the qNaN.
+ makeNaN(false, isNegative(), nullptr);
+ }
+ break;
+ case fcZero:
+ // nextUp(pm 0) = +getSmallest()
+ makeSmallest(false);
+ break;
+ case fcNormal:
+ // nextUp(-getSmallest()) = -0
+ if (isSmallest() && isNegative()) {
+ APInt::tcSet(significandParts(), 0, partCount());
+ category = fcZero;
+ exponent = 0;
+ break;
+ }
+
+ // nextUp(getLargest()) == INFINITY
+ if (isLargest() && !isNegative()) {
+ APInt::tcSet(significandParts(), 0, partCount());
+ category = fcInfinity;
+ exponent = semantics->maxExponent + 1;
+ break;
+ }
+
+ // nextUp(normal) == normal + inc.
+ if (isNegative()) {
+ // If we are negative, we need to decrement the significand.
+
+ // We only cross a binade boundary that requires adjusting the exponent
+ // if:
+ // 1. exponent != semantics->minExponent. This implies we are not in the
+ // smallest binade or are dealing with denormals.
+ // 2. Our significand excluding the integral bit is all zeros.
+ bool WillCrossBinadeBoundary =
+ exponent != semantics->minExponent && isSignificandAllZeros();
+
+ // Decrement the significand.
+ //
+ // We always do this since:
+ // 1. If we are dealing with a non-binade decrement, by definition we
+ // just decrement the significand.
+ // 2. If we are dealing with a normal -> normal binade decrement, since
+ // we have an explicit integral bit the fact that all bits but the
+ // integral bit are zero implies that subtracting one will yield a
+ // significand with 0 integral bit and 1 in all other spots. Thus we
+ // must just adjust the exponent and set the integral bit to 1.
+ // 3. If we are dealing with a normal -> denormal binade decrement,
+ // since we set the integral bit to 0 when we represent denormals, we
+ // just decrement the significand.
+ integerPart *Parts = significandParts();
+ APInt::tcDecrement(Parts, partCount());
+
+ if (WillCrossBinadeBoundary) {
+ // Our result is a normal number. Do the following:
+ // 1. Set the integral bit to 1.
+ // 2. Decrement the exponent.
+ APInt::tcSetBit(Parts, semantics->precision - 1);
+ exponent--;
+ }
+ } else {
+ // If we are positive, we need to increment the significand.
+
+ // We only cross a binade boundary that requires adjusting the exponent if
+ // the input is not a denormal and all of said input's significand bits
+ // are set. If all of said conditions are true: clear the significand, set
+ // the integral bit to 1, and increment the exponent. If we have a
+ // denormal always increment since moving denormals and the numbers in the
+ // smallest normal binade have the same exponent in our representation.
+ bool WillCrossBinadeBoundary = !isDenormal() && isSignificandAllOnes();
+
+ if (WillCrossBinadeBoundary) {
+ integerPart *Parts = significandParts();
+ APInt::tcSet(Parts, 0, partCount());
+ APInt::tcSetBit(Parts, semantics->precision - 1);
+ assert(exponent != semantics->maxExponent &&
+ "We can not increment an exponent beyond the maxExponent allowed"
+ " by the given floating point semantics.");
+ exponent++;
+ } else {
+ incrementSignificand();
+ }
+ }
+ break;
+ }
+
+ // If we are performing nextDown, swap sign so we have -nextUp(-x)
+ if (nextDown)
+ changeSign();
+
+ return result;
+}
+
+void
+APFloat::makeInf(bool Negative) {
+ category = fcInfinity;
+ sign = Negative;
+ exponent = semantics->maxExponent + 1;
+ APInt::tcSet(significandParts(), 0, partCount());
+}
+
+void
+APFloat::makeZero(bool Negative) {
+ category = fcZero;
+ sign = Negative;
+ exponent = semantics->minExponent-1;
+ APInt::tcSet(significandParts(), 0, partCount());
+}
+
+APFloat llvm::scalbn(APFloat X, int Exp) {
+ if (X.isInfinity() || X.isZero() || X.isNaN())
+ return X;
+
+ auto MaxExp = X.getSemantics().maxExponent;
+ auto MinExp = X.getSemantics().minExponent;
+ if (Exp > (MaxExp - X.exponent))
+ // Overflow saturates to infinity.
+ return APFloat::getInf(X.getSemantics(), X.isNegative());
+ if (Exp < (MinExp - X.exponent))
+ // Underflow saturates to zero.
+ return APFloat::getZero(X.getSemantics(), X.isNegative());
+
+ X.exponent += Exp;
+ return X;
+}
diff --git a/contrib/llvm/lib/Support/APInt.cpp b/contrib/llvm/lib/Support/APInt.cpp
new file mode 100644
index 000000000000..aa026d49c070
--- /dev/null
+++ b/contrib/llvm/lib/Support/APInt.cpp
@@ -0,0 +1,2907 @@
+//===-- APInt.cpp - Implement APInt class ---------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a class to represent arbitrary precision integer
+// constant values and provide a variety of arithmetic operations on them.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/APInt.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/Hashing.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cmath>
+#include <cstdlib>
+#include <cstring>
+#include <limits>
+using namespace llvm;
+
+#define DEBUG_TYPE "apint"
+
+/// A utility function for allocating memory, checking for allocation failures,
+/// and ensuring the contents are zeroed.
+inline static uint64_t* getClearedMemory(unsigned numWords) {
+ uint64_t * result = new uint64_t[numWords];
+ assert(result && "APInt memory allocation fails!");
+ memset(result, 0, numWords * sizeof(uint64_t));
+ return result;
+}
+
+/// A utility function for allocating memory and checking for allocation
+/// failure. The content is not zeroed.
+inline static uint64_t* getMemory(unsigned numWords) {
+ uint64_t * result = new uint64_t[numWords];
+ assert(result && "APInt memory allocation fails!");
+ return result;
+}
+
+/// A utility function that converts a character to a digit.
+inline static unsigned getDigit(char cdigit, uint8_t radix) {
+ unsigned r;
+
+ if (radix == 16 || radix == 36) {
+ r = cdigit - '0';
+ if (r <= 9)
+ return r;
+
+ r = cdigit - 'A';
+ if (r <= radix - 11U)
+ return r + 10;
+
+ r = cdigit - 'a';
+ if (r <= radix - 11U)
+ return r + 10;
+
+ radix = 10;
+ }
+
+ r = cdigit - '0';
+ if (r < radix)
+ return r;
+
+ return -1U;
+}
+
+
+void APInt::initSlowCase(unsigned numBits, uint64_t val, bool isSigned) {
+ pVal = getClearedMemory(getNumWords());
+ pVal[0] = val;
+ if (isSigned && int64_t(val) < 0)
+ for (unsigned i = 1; i < getNumWords(); ++i)
+ pVal[i] = -1ULL;
+}
+
+void APInt::initSlowCase(const APInt& that) {
+ pVal = getMemory(getNumWords());
+ memcpy(pVal, that.pVal, getNumWords() * APINT_WORD_SIZE);
+}
+
+void APInt::initFromArray(ArrayRef<uint64_t> bigVal) {
+ assert(BitWidth && "Bitwidth too small");
+ assert(bigVal.data() && "Null pointer detected!");
+ if (isSingleWord())
+ VAL = bigVal[0];
+ else {
+ // Get memory, cleared to 0
+ pVal = getClearedMemory(getNumWords());
+ // Calculate the number of words to copy
+ unsigned words = std::min<unsigned>(bigVal.size(), getNumWords());
+ // Copy the words from bigVal to pVal
+ memcpy(pVal, bigVal.data(), words * APINT_WORD_SIZE);
+ }
+ // Make sure unused high bits are cleared
+ clearUnusedBits();
+}
+
+APInt::APInt(unsigned numBits, ArrayRef<uint64_t> bigVal)
+ : BitWidth(numBits), VAL(0) {
+ initFromArray(bigVal);
+}
+
+APInt::APInt(unsigned numBits, unsigned numWords, const uint64_t bigVal[])
+ : BitWidth(numBits), VAL(0) {
+ initFromArray(makeArrayRef(bigVal, numWords));
+}
+
+APInt::APInt(unsigned numbits, StringRef Str, uint8_t radix)
+ : BitWidth(numbits), VAL(0) {
+ assert(BitWidth && "Bitwidth too small");
+ fromString(numbits, Str, radix);
+}
+
+APInt& APInt::AssignSlowCase(const APInt& RHS) {
+ // Don't do anything for X = X
+ if (this == &RHS)
+ return *this;
+
+ if (BitWidth == RHS.getBitWidth()) {
+ // assume same bit-width single-word case is already handled
+ assert(!isSingleWord());
+ memcpy(pVal, RHS.pVal, getNumWords() * APINT_WORD_SIZE);
+ return *this;
+ }
+
+ if (isSingleWord()) {
+ // assume case where both are single words is already handled
+ assert(!RHS.isSingleWord());
+ VAL = 0;
+ pVal = getMemory(RHS.getNumWords());
+ memcpy(pVal, RHS.pVal, RHS.getNumWords() * APINT_WORD_SIZE);
+ } else if (getNumWords() == RHS.getNumWords())
+ memcpy(pVal, RHS.pVal, RHS.getNumWords() * APINT_WORD_SIZE);
+ else if (RHS.isSingleWord()) {
+ delete [] pVal;
+ VAL = RHS.VAL;
+ } else {
+ delete [] pVal;
+ pVal = getMemory(RHS.getNumWords());
+ memcpy(pVal, RHS.pVal, RHS.getNumWords() * APINT_WORD_SIZE);
+ }
+ BitWidth = RHS.BitWidth;
+ return clearUnusedBits();
+}
+
+APInt& APInt::operator=(uint64_t RHS) {
+ if (isSingleWord())
+ VAL = RHS;
+ else {
+ pVal[0] = RHS;
+ memset(pVal+1, 0, (getNumWords() - 1) * APINT_WORD_SIZE);
+ }
+ return clearUnusedBits();
+}
+
+/// This method 'profiles' an APInt for use with FoldingSet.
+void APInt::Profile(FoldingSetNodeID& ID) const {
+ ID.AddInteger(BitWidth);
+
+ if (isSingleWord()) {
+ ID.AddInteger(VAL);
+ return;
+ }
+
+ unsigned NumWords = getNumWords();
+ for (unsigned i = 0; i < NumWords; ++i)
+ ID.AddInteger(pVal[i]);
+}
+
+/// This function adds a single "digit" integer, y, to the multiple
+/// "digit" integer array, x[]. x[] is modified to reflect the addition and
+/// 1 is returned if there is a carry out, otherwise 0 is returned.
+/// @returns the carry of the addition.
+static bool add_1(uint64_t dest[], uint64_t x[], unsigned len, uint64_t y) {
+ for (unsigned i = 0; i < len; ++i) {
+ dest[i] = y + x[i];
+ if (dest[i] < y)
+ y = 1; // Carry one to next digit.
+ else {
+ y = 0; // No need to carry so exit early
+ break;
+ }
+ }
+ return y;
+}
+
+/// @brief Prefix increment operator. Increments the APInt by one.
+APInt& APInt::operator++() {
+ if (isSingleWord())
+ ++VAL;
+ else
+ add_1(pVal, pVal, getNumWords(), 1);
+ return clearUnusedBits();
+}
+
+/// This function subtracts a single "digit" (64-bit word), y, from
+/// the multi-digit integer array, x[], propagating the borrowed 1 value until
+/// no further borrowing is neeeded or it runs out of "digits" in x. The result
+/// is 1 if "borrowing" exhausted the digits in x, or 0 if x was not exhausted.
+/// In other words, if y > x then this function returns 1, otherwise 0.
+/// @returns the borrow out of the subtraction
+static bool sub_1(uint64_t x[], unsigned len, uint64_t y) {
+ for (unsigned i = 0; i < len; ++i) {
+ uint64_t X = x[i];
+ x[i] -= y;
+ if (y > X)
+ y = 1; // We have to "borrow 1" from next "digit"
+ else {
+ y = 0; // No need to borrow
+ break; // Remaining digits are unchanged so exit early
+ }
+ }
+ return bool(y);
+}
+
+/// @brief Prefix decrement operator. Decrements the APInt by one.
+APInt& APInt::operator--() {
+ if (isSingleWord())
+ --VAL;
+ else
+ sub_1(pVal, getNumWords(), 1);
+ return clearUnusedBits();
+}
+
+/// This function adds the integer array x to the integer array Y and
+/// places the result in dest.
+/// @returns the carry out from the addition
+/// @brief General addition of 64-bit integer arrays
+static bool add(uint64_t *dest, const uint64_t *x, const uint64_t *y,
+ unsigned len) {
+ bool carry = false;
+ for (unsigned i = 0; i< len; ++i) {
+ uint64_t limit = std::min(x[i],y[i]); // must come first in case dest == x
+ dest[i] = x[i] + y[i] + carry;
+ carry = dest[i] < limit || (carry && dest[i] == limit);
+ }
+ return carry;
+}
+
+/// Adds the RHS APint to this APInt.
+/// @returns this, after addition of RHS.
+/// @brief Addition assignment operator.
+APInt& APInt::operator+=(const APInt& RHS) {
+ assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
+ if (isSingleWord())
+ VAL += RHS.VAL;
+ else {
+ add(pVal, pVal, RHS.pVal, getNumWords());
+ }
+ return clearUnusedBits();
+}
+
+/// Subtracts the integer array y from the integer array x
+/// @returns returns the borrow out.
+/// @brief Generalized subtraction of 64-bit integer arrays.
+static bool sub(uint64_t *dest, const uint64_t *x, const uint64_t *y,
+ unsigned len) {
+ bool borrow = false;
+ for (unsigned i = 0; i < len; ++i) {
+ uint64_t x_tmp = borrow ? x[i] - 1 : x[i];
+ borrow = y[i] > x_tmp || (borrow && x[i] == 0);
+ dest[i] = x_tmp - y[i];
+ }
+ return borrow;
+}
+
+/// Subtracts the RHS APInt from this APInt
+/// @returns this, after subtraction
+/// @brief Subtraction assignment operator.
+APInt& APInt::operator-=(const APInt& RHS) {
+ assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
+ if (isSingleWord())
+ VAL -= RHS.VAL;
+ else
+ sub(pVal, pVal, RHS.pVal, getNumWords());
+ return clearUnusedBits();
+}
+
+/// Multiplies an integer array, x, by a uint64_t integer and places the result
+/// into dest.
+/// @returns the carry out of the multiplication.
+/// @brief Multiply a multi-digit APInt by a single digit (64-bit) integer.
+static uint64_t mul_1(uint64_t dest[], uint64_t x[], unsigned len, uint64_t y) {
+ // Split y into high 32-bit part (hy) and low 32-bit part (ly)
+ uint64_t ly = y & 0xffffffffULL, hy = y >> 32;
+ uint64_t carry = 0;
+
+ // For each digit of x.
+ for (unsigned i = 0; i < len; ++i) {
+ // Split x into high and low words
+ uint64_t lx = x[i] & 0xffffffffULL;
+ uint64_t hx = x[i] >> 32;
+ // hasCarry - A flag to indicate if there is a carry to the next digit.
+ // hasCarry == 0, no carry
+ // hasCarry == 1, has carry
+ // hasCarry == 2, no carry and the calculation result == 0.
+ uint8_t hasCarry = 0;
+ dest[i] = carry + lx * ly;
+ // Determine if the add above introduces carry.
+ hasCarry = (dest[i] < carry) ? 1 : 0;
+ carry = hx * ly + (dest[i] >> 32) + (hasCarry ? (1ULL << 32) : 0);
+ // The upper limit of carry can be (2^32 - 1)(2^32 - 1) +
+ // (2^32 - 1) + 2^32 = 2^64.
+ hasCarry = (!carry && hasCarry) ? 1 : (!carry ? 2 : 0);
+
+ carry += (lx * hy) & 0xffffffffULL;
+ dest[i] = (carry << 32) | (dest[i] & 0xffffffffULL);
+ carry = (((!carry && hasCarry != 2) || hasCarry == 1) ? (1ULL << 32) : 0) +
+ (carry >> 32) + ((lx * hy) >> 32) + hx * hy;
+ }
+ return carry;
+}
+
+/// Multiplies integer array x by integer array y and stores the result into
+/// the integer array dest. Note that dest's size must be >= xlen + ylen.
+/// @brief Generalized multiplicate of integer arrays.
+static void mul(uint64_t dest[], uint64_t x[], unsigned xlen, uint64_t y[],
+ unsigned ylen) {
+ dest[xlen] = mul_1(dest, x, xlen, y[0]);
+ for (unsigned i = 1; i < ylen; ++i) {
+ uint64_t ly = y[i] & 0xffffffffULL, hy = y[i] >> 32;
+ uint64_t carry = 0, lx = 0, hx = 0;
+ for (unsigned j = 0; j < xlen; ++j) {
+ lx = x[j] & 0xffffffffULL;
+ hx = x[j] >> 32;
+ // hasCarry - A flag to indicate if has carry.
+ // hasCarry == 0, no carry
+ // hasCarry == 1, has carry
+ // hasCarry == 2, no carry and the calculation result == 0.
+ uint8_t hasCarry = 0;
+ uint64_t resul = carry + lx * ly;
+ hasCarry = (resul < carry) ? 1 : 0;
+ carry = (hasCarry ? (1ULL << 32) : 0) + hx * ly + (resul >> 32);
+ hasCarry = (!carry && hasCarry) ? 1 : (!carry ? 2 : 0);
+
+ carry += (lx * hy) & 0xffffffffULL;
+ resul = (carry << 32) | (resul & 0xffffffffULL);
+ dest[i+j] += resul;
+ carry = (((!carry && hasCarry != 2) || hasCarry == 1) ? (1ULL << 32) : 0)+
+ (carry >> 32) + (dest[i+j] < resul ? 1 : 0) +
+ ((lx * hy) >> 32) + hx * hy;
+ }
+ dest[i+xlen] = carry;
+ }
+}
+
+APInt& APInt::operator*=(const APInt& RHS) {
+ assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
+ if (isSingleWord()) {
+ VAL *= RHS.VAL;
+ clearUnusedBits();
+ return *this;
+ }
+
+ // Get some bit facts about LHS and check for zero
+ unsigned lhsBits = getActiveBits();
+ unsigned lhsWords = !lhsBits ? 0 : whichWord(lhsBits - 1) + 1;
+ if (!lhsWords)
+ // 0 * X ===> 0
+ return *this;
+
+ // Get some bit facts about RHS and check for zero
+ unsigned rhsBits = RHS.getActiveBits();
+ unsigned rhsWords = !rhsBits ? 0 : whichWord(rhsBits - 1) + 1;
+ if (!rhsWords) {
+ // X * 0 ===> 0
+ clearAllBits();
+ return *this;
+ }
+
+ // Allocate space for the result
+ unsigned destWords = rhsWords + lhsWords;
+ uint64_t *dest = getMemory(destWords);
+
+ // Perform the long multiply
+ mul(dest, pVal, lhsWords, RHS.pVal, rhsWords);
+
+ // Copy result back into *this
+ clearAllBits();
+ unsigned wordsToCopy = destWords >= getNumWords() ? getNumWords() : destWords;
+ memcpy(pVal, dest, wordsToCopy * APINT_WORD_SIZE);
+ clearUnusedBits();
+
+ // delete dest array and return
+ delete[] dest;
+ return *this;
+}
+
+APInt& APInt::operator&=(const APInt& RHS) {
+ assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
+ if (isSingleWord()) {
+ VAL &= RHS.VAL;
+ return *this;
+ }
+ unsigned numWords = getNumWords();
+ for (unsigned i = 0; i < numWords; ++i)
+ pVal[i] &= RHS.pVal[i];
+ return *this;
+}
+
+APInt& APInt::operator|=(const APInt& RHS) {
+ assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
+ if (isSingleWord()) {
+ VAL |= RHS.VAL;
+ return *this;
+ }
+ unsigned numWords = getNumWords();
+ for (unsigned i = 0; i < numWords; ++i)
+ pVal[i] |= RHS.pVal[i];
+ return *this;
+}
+
+APInt& APInt::operator^=(const APInt& RHS) {
+ assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
+ if (isSingleWord()) {
+ VAL ^= RHS.VAL;
+ this->clearUnusedBits();
+ return *this;
+ }
+ unsigned numWords = getNumWords();
+ for (unsigned i = 0; i < numWords; ++i)
+ pVal[i] ^= RHS.pVal[i];
+ return clearUnusedBits();
+}
+
+APInt APInt::AndSlowCase(const APInt& RHS) const {
+ unsigned numWords = getNumWords();
+ uint64_t* val = getMemory(numWords);
+ for (unsigned i = 0; i < numWords; ++i)
+ val[i] = pVal[i] & RHS.pVal[i];
+ return APInt(val, getBitWidth());
+}
+
+APInt APInt::OrSlowCase(const APInt& RHS) const {
+ unsigned numWords = getNumWords();
+ uint64_t *val = getMemory(numWords);
+ for (unsigned i = 0; i < numWords; ++i)
+ val[i] = pVal[i] | RHS.pVal[i];
+ return APInt(val, getBitWidth());
+}
+
+APInt APInt::XorSlowCase(const APInt& RHS) const {
+ unsigned numWords = getNumWords();
+ uint64_t *val = getMemory(numWords);
+ for (unsigned i = 0; i < numWords; ++i)
+ val[i] = pVal[i] ^ RHS.pVal[i];
+
+ APInt Result(val, getBitWidth());
+ // 0^0==1 so clear the high bits in case they got set.
+ Result.clearUnusedBits();
+ return Result;
+}
+
+APInt APInt::operator*(const APInt& RHS) const {
+ assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
+ if (isSingleWord())
+ return APInt(BitWidth, VAL * RHS.VAL);
+ APInt Result(*this);
+ Result *= RHS;
+ return Result;
+}
+
+APInt APInt::operator+(const APInt& RHS) const {
+ assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
+ if (isSingleWord())
+ return APInt(BitWidth, VAL + RHS.VAL);
+ APInt Result(BitWidth, 0);
+ add(Result.pVal, this->pVal, RHS.pVal, getNumWords());
+ Result.clearUnusedBits();
+ return Result;
+}
+
+APInt APInt::operator-(const APInt& RHS) const {
+ assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
+ if (isSingleWord())
+ return APInt(BitWidth, VAL - RHS.VAL);
+ APInt Result(BitWidth, 0);
+ sub(Result.pVal, this->pVal, RHS.pVal, getNumWords());
+ Result.clearUnusedBits();
+ return Result;
+}
+
+bool APInt::EqualSlowCase(const APInt& RHS) const {
+ // Get some facts about the number of bits used in the two operands.
+ unsigned n1 = getActiveBits();
+ unsigned n2 = RHS.getActiveBits();
+
+ // If the number of bits isn't the same, they aren't equal
+ if (n1 != n2)
+ return false;
+
+ // If the number of bits fits in a word, we only need to compare the low word.
+ if (n1 <= APINT_BITS_PER_WORD)
+ return pVal[0] == RHS.pVal[0];
+
+ // Otherwise, compare everything
+ for (int i = whichWord(n1 - 1); i >= 0; --i)
+ if (pVal[i] != RHS.pVal[i])
+ return false;
+ return true;
+}
+
+bool APInt::EqualSlowCase(uint64_t Val) const {
+ unsigned n = getActiveBits();
+ if (n <= APINT_BITS_PER_WORD)
+ return pVal[0] == Val;
+ else
+ return false;
+}
+
+bool APInt::ult(const APInt& RHS) const {
+ assert(BitWidth == RHS.BitWidth && "Bit widths must be same for comparison");
+ if (isSingleWord())
+ return VAL < RHS.VAL;
+
+ // Get active bit length of both operands
+ unsigned n1 = getActiveBits();
+ unsigned n2 = RHS.getActiveBits();
+
+ // If magnitude of LHS is less than RHS, return true.
+ if (n1 < n2)
+ return true;
+
+ // If magnitude of RHS is greather than LHS, return false.
+ if (n2 < n1)
+ return false;
+
+ // If they bot fit in a word, just compare the low order word
+ if (n1 <= APINT_BITS_PER_WORD && n2 <= APINT_BITS_PER_WORD)
+ return pVal[0] < RHS.pVal[0];
+
+ // Otherwise, compare all words
+ unsigned topWord = whichWord(std::max(n1,n2)-1);
+ for (int i = topWord; i >= 0; --i) {
+ if (pVal[i] > RHS.pVal[i])
+ return false;
+ if (pVal[i] < RHS.pVal[i])
+ return true;
+ }
+ return false;
+}
+
+bool APInt::slt(const APInt& RHS) const {
+ assert(BitWidth == RHS.BitWidth && "Bit widths must be same for comparison");
+ if (isSingleWord()) {
+ int64_t lhsSext = (int64_t(VAL) << (64-BitWidth)) >> (64-BitWidth);
+ int64_t rhsSext = (int64_t(RHS.VAL) << (64-BitWidth)) >> (64-BitWidth);
+ return lhsSext < rhsSext;
+ }
+
+ APInt lhs(*this);
+ APInt rhs(RHS);
+ bool lhsNeg = isNegative();
+ bool rhsNeg = rhs.isNegative();
+ if (lhsNeg) {
+ // Sign bit is set so perform two's complement to make it positive
+ lhs.flipAllBits();
+ ++lhs;
+ }
+ if (rhsNeg) {
+ // Sign bit is set so perform two's complement to make it positive
+ rhs.flipAllBits();
+ ++rhs;
+ }
+
+ // Now we have unsigned values to compare so do the comparison if necessary
+ // based on the negativeness of the values.
+ if (lhsNeg)
+ if (rhsNeg)
+ return lhs.ugt(rhs);
+ else
+ return true;
+ else if (rhsNeg)
+ return false;
+ else
+ return lhs.ult(rhs);
+}
+
+void APInt::setBit(unsigned bitPosition) {
+ if (isSingleWord())
+ VAL |= maskBit(bitPosition);
+ else
+ pVal[whichWord(bitPosition)] |= maskBit(bitPosition);
+}
+
+/// Set the given bit to 0 whose position is given as "bitPosition".
+/// @brief Set a given bit to 0.
+void APInt::clearBit(unsigned bitPosition) {
+ if (isSingleWord())
+ VAL &= ~maskBit(bitPosition);
+ else
+ pVal[whichWord(bitPosition)] &= ~maskBit(bitPosition);
+}
+
+/// @brief Toggle every bit to its opposite value.
+
+/// Toggle a given bit to its opposite value whose position is given
+/// as "bitPosition".
+/// @brief Toggles a given bit to its opposite value.
+void APInt::flipBit(unsigned bitPosition) {
+ assert(bitPosition < BitWidth && "Out of the bit-width range!");
+ if ((*this)[bitPosition]) clearBit(bitPosition);
+ else setBit(bitPosition);
+}
+
+unsigned APInt::getBitsNeeded(StringRef str, uint8_t radix) {
+ assert(!str.empty() && "Invalid string length");
+ assert((radix == 10 || radix == 8 || radix == 16 || radix == 2 ||
+ radix == 36) &&
+ "Radix should be 2, 8, 10, 16, or 36!");
+
+ size_t slen = str.size();
+
+ // Each computation below needs to know if it's negative.
+ StringRef::iterator p = str.begin();
+ unsigned isNegative = *p == '-';
+ if (*p == '-' || *p == '+') {
+ p++;
+ slen--;
+ assert(slen && "String is only a sign, needs a value.");
+ }
+
+ // For radixes of power-of-two values, the bits required is accurately and
+ // easily computed
+ if (radix == 2)
+ return slen + isNegative;
+ if (radix == 8)
+ return slen * 3 + isNegative;
+ if (radix == 16)
+ return slen * 4 + isNegative;
+
+ // FIXME: base 36
+
+ // This is grossly inefficient but accurate. We could probably do something
+ // with a computation of roughly slen*64/20 and then adjust by the value of
+ // the first few digits. But, I'm not sure how accurate that could be.
+
+ // Compute a sufficient number of bits that is always large enough but might
+ // be too large. This avoids the assertion in the constructor. This
+ // calculation doesn't work appropriately for the numbers 0-9, so just use 4
+ // bits in that case.
+ unsigned sufficient
+ = radix == 10? (slen == 1 ? 4 : slen * 64/18)
+ : (slen == 1 ? 7 : slen * 16/3);
+
+ // Convert to the actual binary value.
+ APInt tmp(sufficient, StringRef(p, slen), radix);
+
+ // Compute how many bits are required. If the log is infinite, assume we need
+ // just bit.
+ unsigned log = tmp.logBase2();
+ if (log == (unsigned)-1) {
+ return isNegative + 1;
+ } else {
+ return isNegative + log + 1;
+ }
+}
+
+hash_code llvm::hash_value(const APInt &Arg) {
+ if (Arg.isSingleWord())
+ return hash_combine(Arg.VAL);
+
+ return hash_combine_range(Arg.pVal, Arg.pVal + Arg.getNumWords());
+}
+
+bool APInt::isSplat(unsigned SplatSizeInBits) const {
+ assert(getBitWidth() % SplatSizeInBits == 0 &&
+ "SplatSizeInBits must divide width!");
+ // We can check that all parts of an integer are equal by making use of a
+ // little trick: rotate and check if it's still the same value.
+ return *this == rotl(SplatSizeInBits);
+}
+
+/// This function returns the high "numBits" bits of this APInt.
+APInt APInt::getHiBits(unsigned numBits) const {
+ return APIntOps::lshr(*this, BitWidth - numBits);
+}
+
+/// This function returns the low "numBits" bits of this APInt.
+APInt APInt::getLoBits(unsigned numBits) const {
+ return APIntOps::lshr(APIntOps::shl(*this, BitWidth - numBits),
+ BitWidth - numBits);
+}
+
+unsigned APInt::countLeadingZerosSlowCase() const {
+ // Treat the most significand word differently because it might have
+ // meaningless bits set beyond the precision.
+ unsigned BitsInMSW = BitWidth % APINT_BITS_PER_WORD;
+ integerPart MSWMask;
+ if (BitsInMSW) MSWMask = (integerPart(1) << BitsInMSW) - 1;
+ else {
+ MSWMask = ~integerPart(0);
+ BitsInMSW = APINT_BITS_PER_WORD;
+ }
+
+ unsigned i = getNumWords();
+ integerPart MSW = pVal[i-1] & MSWMask;
+ if (MSW)
+ return llvm::countLeadingZeros(MSW) - (APINT_BITS_PER_WORD - BitsInMSW);
+
+ unsigned Count = BitsInMSW;
+ for (--i; i > 0u; --i) {
+ if (pVal[i-1] == 0)
+ Count += APINT_BITS_PER_WORD;
+ else {
+ Count += llvm::countLeadingZeros(pVal[i-1]);
+ break;
+ }
+ }
+ return Count;
+}
+
+unsigned APInt::countLeadingOnes() const {
+ if (isSingleWord())
+ return llvm::countLeadingOnes(VAL << (APINT_BITS_PER_WORD - BitWidth));
+
+ unsigned highWordBits = BitWidth % APINT_BITS_PER_WORD;
+ unsigned shift;
+ if (!highWordBits) {
+ highWordBits = APINT_BITS_PER_WORD;
+ shift = 0;
+ } else {
+ shift = APINT_BITS_PER_WORD - highWordBits;
+ }
+ int i = getNumWords() - 1;
+ unsigned Count = llvm::countLeadingOnes(pVal[i] << shift);
+ if (Count == highWordBits) {
+ for (i--; i >= 0; --i) {
+ if (pVal[i] == -1ULL)
+ Count += APINT_BITS_PER_WORD;
+ else {
+ Count += llvm::countLeadingOnes(pVal[i]);
+ break;
+ }
+ }
+ }
+ return Count;
+}
+
+unsigned APInt::countTrailingZeros() const {
+ if (isSingleWord())
+ return std::min(unsigned(llvm::countTrailingZeros(VAL)), BitWidth);
+ unsigned Count = 0;
+ unsigned i = 0;
+ for (; i < getNumWords() && pVal[i] == 0; ++i)
+ Count += APINT_BITS_PER_WORD;
+ if (i < getNumWords())
+ Count += llvm::countTrailingZeros(pVal[i]);
+ return std::min(Count, BitWidth);
+}
+
+unsigned APInt::countTrailingOnesSlowCase() const {
+ unsigned Count = 0;
+ unsigned i = 0;
+ for (; i < getNumWords() && pVal[i] == -1ULL; ++i)
+ Count += APINT_BITS_PER_WORD;
+ if (i < getNumWords())
+ Count += llvm::countTrailingOnes(pVal[i]);
+ return std::min(Count, BitWidth);
+}
+
+unsigned APInt::countPopulationSlowCase() const {
+ unsigned Count = 0;
+ for (unsigned i = 0; i < getNumWords(); ++i)
+ Count += llvm::countPopulation(pVal[i]);
+ return Count;
+}
+
+/// Perform a logical right-shift from Src to Dst, which must be equal or
+/// non-overlapping, of Words words, by Shift, which must be less than 64.
+static void lshrNear(uint64_t *Dst, uint64_t *Src, unsigned Words,
+ unsigned Shift) {
+ uint64_t Carry = 0;
+ for (int I = Words - 1; I >= 0; --I) {
+ uint64_t Tmp = Src[I];
+ Dst[I] = (Tmp >> Shift) | Carry;
+ Carry = Tmp << (64 - Shift);
+ }
+}
+
+APInt APInt::byteSwap() const {
+ assert(BitWidth >= 16 && BitWidth % 16 == 0 && "Cannot byteswap!");
+ if (BitWidth == 16)
+ return APInt(BitWidth, ByteSwap_16(uint16_t(VAL)));
+ if (BitWidth == 32)
+ return APInt(BitWidth, ByteSwap_32(unsigned(VAL)));
+ if (BitWidth == 48) {
+ unsigned Tmp1 = unsigned(VAL >> 16);
+ Tmp1 = ByteSwap_32(Tmp1);
+ uint16_t Tmp2 = uint16_t(VAL);
+ Tmp2 = ByteSwap_16(Tmp2);
+ return APInt(BitWidth, (uint64_t(Tmp2) << 32) | Tmp1);
+ }
+ if (BitWidth == 64)
+ return APInt(BitWidth, ByteSwap_64(VAL));
+
+ APInt Result(getNumWords() * APINT_BITS_PER_WORD, 0);
+ for (unsigned I = 0, N = getNumWords(); I != N; ++I)
+ Result.pVal[I] = ByteSwap_64(pVal[N - I - 1]);
+ if (Result.BitWidth != BitWidth) {
+ lshrNear(Result.pVal, Result.pVal, getNumWords(),
+ Result.BitWidth - BitWidth);
+ Result.BitWidth = BitWidth;
+ }
+ return Result;
+}
+
+APInt llvm::APIntOps::GreatestCommonDivisor(const APInt& API1,
+ const APInt& API2) {
+ APInt A = API1, B = API2;
+ while (!!B) {
+ APInt T = B;
+ B = APIntOps::urem(A, B);
+ A = T;
+ }
+ return A;
+}
+
+APInt llvm::APIntOps::RoundDoubleToAPInt(double Double, unsigned width) {
+ union {
+ double D;
+ uint64_t I;
+ } T;
+ T.D = Double;
+
+ // Get the sign bit from the highest order bit
+ bool isNeg = T.I >> 63;
+
+ // Get the 11-bit exponent and adjust for the 1023 bit bias
+ int64_t exp = ((T.I >> 52) & 0x7ff) - 1023;
+
+ // If the exponent is negative, the value is < 0 so just return 0.
+ if (exp < 0)
+ return APInt(width, 0u);
+
+ // Extract the mantissa by clearing the top 12 bits (sign + exponent).
+ uint64_t mantissa = (T.I & (~0ULL >> 12)) | 1ULL << 52;
+
+ // If the exponent doesn't shift all bits out of the mantissa
+ if (exp < 52)
+ return isNeg ? -APInt(width, mantissa >> (52 - exp)) :
+ APInt(width, mantissa >> (52 - exp));
+
+ // If the client didn't provide enough bits for us to shift the mantissa into
+ // then the result is undefined, just return 0
+ if (width <= exp - 52)
+ return APInt(width, 0);
+
+ // Otherwise, we have to shift the mantissa bits up to the right location
+ APInt Tmp(width, mantissa);
+ Tmp = Tmp.shl((unsigned)exp - 52);
+ return isNeg ? -Tmp : Tmp;
+}
+
+/// This function converts this APInt to a double.
+/// The layout for double is as following (IEEE Standard 754):
+/// --------------------------------------
+/// | Sign Exponent Fraction Bias |
+/// |-------------------------------------- |
+/// | 1[63] 11[62-52] 52[51-00] 1023 |
+/// --------------------------------------
+double APInt::roundToDouble(bool isSigned) const {
+
+ // Handle the simple case where the value is contained in one uint64_t.
+ // It is wrong to optimize getWord(0) to VAL; there might be more than one word.
+ if (isSingleWord() || getActiveBits() <= APINT_BITS_PER_WORD) {
+ if (isSigned) {
+ int64_t sext = (int64_t(getWord(0)) << (64-BitWidth)) >> (64-BitWidth);
+ return double(sext);
+ } else
+ return double(getWord(0));
+ }
+
+ // Determine if the value is negative.
+ bool isNeg = isSigned ? (*this)[BitWidth-1] : false;
+
+ // Construct the absolute value if we're negative.
+ APInt Tmp(isNeg ? -(*this) : (*this));
+
+ // Figure out how many bits we're using.
+ unsigned n = Tmp.getActiveBits();
+
+ // The exponent (without bias normalization) is just the number of bits
+ // we are using. Note that the sign bit is gone since we constructed the
+ // absolute value.
+ uint64_t exp = n;
+
+ // Return infinity for exponent overflow
+ if (exp > 1023) {
+ if (!isSigned || !isNeg)
+ return std::numeric_limits<double>::infinity();
+ else
+ return -std::numeric_limits<double>::infinity();
+ }
+ exp += 1023; // Increment for 1023 bias
+
+ // Number of bits in mantissa is 52. To obtain the mantissa value, we must
+ // extract the high 52 bits from the correct words in pVal.
+ uint64_t mantissa;
+ unsigned hiWord = whichWord(n-1);
+ if (hiWord == 0) {
+ mantissa = Tmp.pVal[0];
+ if (n > 52)
+ mantissa >>= n - 52; // shift down, we want the top 52 bits.
+ } else {
+ assert(hiWord > 0 && "huh?");
+ uint64_t hibits = Tmp.pVal[hiWord] << (52 - n % APINT_BITS_PER_WORD);
+ uint64_t lobits = Tmp.pVal[hiWord-1] >> (11 + n % APINT_BITS_PER_WORD);
+ mantissa = hibits | lobits;
+ }
+
+ // The leading bit of mantissa is implicit, so get rid of it.
+ uint64_t sign = isNeg ? (1ULL << (APINT_BITS_PER_WORD - 1)) : 0;
+ union {
+ double D;
+ uint64_t I;
+ } T;
+ T.I = sign | (exp << 52) | mantissa;
+ return T.D;
+}
+
+// Truncate to new width.
+APInt APInt::trunc(unsigned width) const {
+ assert(width < BitWidth && "Invalid APInt Truncate request");
+ assert(width && "Can't truncate to 0 bits");
+
+ if (width <= APINT_BITS_PER_WORD)
+ return APInt(width, getRawData()[0]);
+
+ APInt Result(getMemory(getNumWords(width)), width);
+
+ // Copy full words.
+ unsigned i;
+ for (i = 0; i != width / APINT_BITS_PER_WORD; i++)
+ Result.pVal[i] = pVal[i];
+
+ // Truncate and copy any partial word.
+ unsigned bits = (0 - width) % APINT_BITS_PER_WORD;
+ if (bits != 0)
+ Result.pVal[i] = pVal[i] << bits >> bits;
+
+ return Result;
+}
+
+// Sign extend to a new width.
+APInt APInt::sext(unsigned width) const {
+ assert(width > BitWidth && "Invalid APInt SignExtend request");
+
+ if (width <= APINT_BITS_PER_WORD) {
+ uint64_t val = VAL << (APINT_BITS_PER_WORD - BitWidth);
+ val = (int64_t)val >> (width - BitWidth);
+ return APInt(width, val >> (APINT_BITS_PER_WORD - width));
+ }
+
+ APInt Result(getMemory(getNumWords(width)), width);
+
+ // Copy full words.
+ unsigned i;
+ uint64_t word = 0;
+ for (i = 0; i != BitWidth / APINT_BITS_PER_WORD; i++) {
+ word = getRawData()[i];
+ Result.pVal[i] = word;
+ }
+
+ // Read and sign-extend any partial word.
+ unsigned bits = (0 - BitWidth) % APINT_BITS_PER_WORD;
+ if (bits != 0)
+ word = (int64_t)getRawData()[i] << bits >> bits;
+ else
+ word = (int64_t)word >> (APINT_BITS_PER_WORD - 1);
+
+ // Write remaining full words.
+ for (; i != width / APINT_BITS_PER_WORD; i++) {
+ Result.pVal[i] = word;
+ word = (int64_t)word >> (APINT_BITS_PER_WORD - 1);
+ }
+
+ // Write any partial word.
+ bits = (0 - width) % APINT_BITS_PER_WORD;
+ if (bits != 0)
+ Result.pVal[i] = word << bits >> bits;
+
+ return Result;
+}
+
+// Zero extend to a new width.
+APInt APInt::zext(unsigned width) const {
+ assert(width > BitWidth && "Invalid APInt ZeroExtend request");
+
+ if (width <= APINT_BITS_PER_WORD)
+ return APInt(width, VAL);
+
+ APInt Result(getMemory(getNumWords(width)), width);
+
+ // Copy words.
+ unsigned i;
+ for (i = 0; i != getNumWords(); i++)
+ Result.pVal[i] = getRawData()[i];
+
+ // Zero remaining words.
+ memset(&Result.pVal[i], 0, (Result.getNumWords() - i) * APINT_WORD_SIZE);
+
+ return Result;
+}
+
+APInt APInt::zextOrTrunc(unsigned width) const {
+ if (BitWidth < width)
+ return zext(width);
+ if (BitWidth > width)
+ return trunc(width);
+ return *this;
+}
+
+APInt APInt::sextOrTrunc(unsigned width) const {
+ if (BitWidth < width)
+ return sext(width);
+ if (BitWidth > width)
+ return trunc(width);
+ return *this;
+}
+
+APInt APInt::zextOrSelf(unsigned width) const {
+ if (BitWidth < width)
+ return zext(width);
+ return *this;
+}
+
+APInt APInt::sextOrSelf(unsigned width) const {
+ if (BitWidth < width)
+ return sext(width);
+ return *this;
+}
+
+/// Arithmetic right-shift this APInt by shiftAmt.
+/// @brief Arithmetic right-shift function.
+APInt APInt::ashr(const APInt &shiftAmt) const {
+ return ashr((unsigned)shiftAmt.getLimitedValue(BitWidth));
+}
+
+/// Arithmetic right-shift this APInt by shiftAmt.
+/// @brief Arithmetic right-shift function.
+APInt APInt::ashr(unsigned shiftAmt) const {
+ assert(shiftAmt <= BitWidth && "Invalid shift amount");
+ // Handle a degenerate case
+ if (shiftAmt == 0)
+ return *this;
+
+ // Handle single word shifts with built-in ashr
+ if (isSingleWord()) {
+ if (shiftAmt == BitWidth)
+ return APInt(BitWidth, 0); // undefined
+ else {
+ unsigned SignBit = APINT_BITS_PER_WORD - BitWidth;
+ return APInt(BitWidth,
+ (((int64_t(VAL) << SignBit) >> SignBit) >> shiftAmt));
+ }
+ }
+
+ // If all the bits were shifted out, the result is, technically, undefined.
+ // We return -1 if it was negative, 0 otherwise. We check this early to avoid
+ // issues in the algorithm below.
+ if (shiftAmt == BitWidth) {
+ if (isNegative())
+ return APInt(BitWidth, -1ULL, true);
+ else
+ return APInt(BitWidth, 0);
+ }
+
+ // Create some space for the result.
+ uint64_t * val = new uint64_t[getNumWords()];
+
+ // Compute some values needed by the following shift algorithms
+ unsigned wordShift = shiftAmt % APINT_BITS_PER_WORD; // bits to shift per word
+ unsigned offset = shiftAmt / APINT_BITS_PER_WORD; // word offset for shift
+ unsigned breakWord = getNumWords() - 1 - offset; // last word affected
+ unsigned bitsInWord = whichBit(BitWidth); // how many bits in last word?
+ if (bitsInWord == 0)
+ bitsInWord = APINT_BITS_PER_WORD;
+
+ // If we are shifting whole words, just move whole words
+ if (wordShift == 0) {
+ // Move the words containing significant bits
+ for (unsigned i = 0; i <= breakWord; ++i)
+ val[i] = pVal[i+offset]; // move whole word
+
+ // Adjust the top significant word for sign bit fill, if negative
+ if (isNegative())
+ if (bitsInWord < APINT_BITS_PER_WORD)
+ val[breakWord] |= ~0ULL << bitsInWord; // set high bits
+ } else {
+ // Shift the low order words
+ for (unsigned i = 0; i < breakWord; ++i) {
+ // This combines the shifted corresponding word with the low bits from
+ // the next word (shifted into this word's high bits).
+ val[i] = (pVal[i+offset] >> wordShift) |
+ (pVal[i+offset+1] << (APINT_BITS_PER_WORD - wordShift));
+ }
+
+ // Shift the break word. In this case there are no bits from the next word
+ // to include in this word.
+ val[breakWord] = pVal[breakWord+offset] >> wordShift;
+
+ // Deal with sign extension in the break word, and possibly the word before
+ // it.
+ if (isNegative()) {
+ if (wordShift > bitsInWord) {
+ if (breakWord > 0)
+ val[breakWord-1] |=
+ ~0ULL << (APINT_BITS_PER_WORD - (wordShift - bitsInWord));
+ val[breakWord] |= ~0ULL;
+ } else
+ val[breakWord] |= (~0ULL << (bitsInWord - wordShift));
+ }
+ }
+
+ // Remaining words are 0 or -1, just assign them.
+ uint64_t fillValue = (isNegative() ? -1ULL : 0);
+ for (unsigned i = breakWord+1; i < getNumWords(); ++i)
+ val[i] = fillValue;
+ APInt Result(val, BitWidth);
+ Result.clearUnusedBits();
+ return Result;
+}
+
+/// Logical right-shift this APInt by shiftAmt.
+/// @brief Logical right-shift function.
+APInt APInt::lshr(const APInt &shiftAmt) const {
+ return lshr((unsigned)shiftAmt.getLimitedValue(BitWidth));
+}
+
+/// Logical right-shift this APInt by shiftAmt.
+/// @brief Logical right-shift function.
+APInt APInt::lshr(unsigned shiftAmt) const {
+ if (isSingleWord()) {
+ if (shiftAmt >= BitWidth)
+ return APInt(BitWidth, 0);
+ else
+ return APInt(BitWidth, this->VAL >> shiftAmt);
+ }
+
+ // If all the bits were shifted out, the result is 0. This avoids issues
+ // with shifting by the size of the integer type, which produces undefined
+ // results. We define these "undefined results" to always be 0.
+ if (shiftAmt >= BitWidth)
+ return APInt(BitWidth, 0);
+
+ // If none of the bits are shifted out, the result is *this. This avoids
+ // issues with shifting by the size of the integer type, which produces
+ // undefined results in the code below. This is also an optimization.
+ if (shiftAmt == 0)
+ return *this;
+
+ // Create some space for the result.
+ uint64_t * val = new uint64_t[getNumWords()];
+
+ // If we are shifting less than a word, compute the shift with a simple carry
+ if (shiftAmt < APINT_BITS_PER_WORD) {
+ lshrNear(val, pVal, getNumWords(), shiftAmt);
+ APInt Result(val, BitWidth);
+ Result.clearUnusedBits();
+ return Result;
+ }
+
+ // Compute some values needed by the remaining shift algorithms
+ unsigned wordShift = shiftAmt % APINT_BITS_PER_WORD;
+ unsigned offset = shiftAmt / APINT_BITS_PER_WORD;
+
+ // If we are shifting whole words, just move whole words
+ if (wordShift == 0) {
+ for (unsigned i = 0; i < getNumWords() - offset; ++i)
+ val[i] = pVal[i+offset];
+ for (unsigned i = getNumWords()-offset; i < getNumWords(); i++)
+ val[i] = 0;
+ APInt Result(val, BitWidth);
+ Result.clearUnusedBits();
+ return Result;
+ }
+
+ // Shift the low order words
+ unsigned breakWord = getNumWords() - offset -1;
+ for (unsigned i = 0; i < breakWord; ++i)
+ val[i] = (pVal[i+offset] >> wordShift) |
+ (pVal[i+offset+1] << (APINT_BITS_PER_WORD - wordShift));
+ // Shift the break word.
+ val[breakWord] = pVal[breakWord+offset] >> wordShift;
+
+ // Remaining words are 0
+ for (unsigned i = breakWord+1; i < getNumWords(); ++i)
+ val[i] = 0;
+ APInt Result(val, BitWidth);
+ Result.clearUnusedBits();
+ return Result;
+}
+
+/// Left-shift this APInt by shiftAmt.
+/// @brief Left-shift function.
+APInt APInt::shl(const APInt &shiftAmt) const {
+ // It's undefined behavior in C to shift by BitWidth or greater.
+ return shl((unsigned)shiftAmt.getLimitedValue(BitWidth));
+}
+
+APInt APInt::shlSlowCase(unsigned shiftAmt) const {
+ // If all the bits were shifted out, the result is 0. This avoids issues
+ // with shifting by the size of the integer type, which produces undefined
+ // results. We define these "undefined results" to always be 0.
+ if (shiftAmt == BitWidth)
+ return APInt(BitWidth, 0);
+
+ // If none of the bits are shifted out, the result is *this. This avoids a
+ // lshr by the words size in the loop below which can produce incorrect
+ // results. It also avoids the expensive computation below for a common case.
+ if (shiftAmt == 0)
+ return *this;
+
+ // Create some space for the result.
+ uint64_t * val = new uint64_t[getNumWords()];
+
+ // If we are shifting less than a word, do it the easy way
+ if (shiftAmt < APINT_BITS_PER_WORD) {
+ uint64_t carry = 0;
+ for (unsigned i = 0; i < getNumWords(); i++) {
+ val[i] = pVal[i] << shiftAmt | carry;
+ carry = pVal[i] >> (APINT_BITS_PER_WORD - shiftAmt);
+ }
+ APInt Result(val, BitWidth);
+ Result.clearUnusedBits();
+ return Result;
+ }
+
+ // Compute some values needed by the remaining shift algorithms
+ unsigned wordShift = shiftAmt % APINT_BITS_PER_WORD;
+ unsigned offset = shiftAmt / APINT_BITS_PER_WORD;
+
+ // If we are shifting whole words, just move whole words
+ if (wordShift == 0) {
+ for (unsigned i = 0; i < offset; i++)
+ val[i] = 0;
+ for (unsigned i = offset; i < getNumWords(); i++)
+ val[i] = pVal[i-offset];
+ APInt Result(val, BitWidth);
+ Result.clearUnusedBits();
+ return Result;
+ }
+
+ // Copy whole words from this to Result.
+ unsigned i = getNumWords() - 1;
+ for (; i > offset; --i)
+ val[i] = pVal[i-offset] << wordShift |
+ pVal[i-offset-1] >> (APINT_BITS_PER_WORD - wordShift);
+ val[offset] = pVal[0] << wordShift;
+ for (i = 0; i < offset; ++i)
+ val[i] = 0;
+ APInt Result(val, BitWidth);
+ Result.clearUnusedBits();
+ return Result;
+}
+
+APInt APInt::rotl(const APInt &rotateAmt) const {
+ return rotl((unsigned)rotateAmt.getLimitedValue(BitWidth));
+}
+
+APInt APInt::rotl(unsigned rotateAmt) const {
+ rotateAmt %= BitWidth;
+ if (rotateAmt == 0)
+ return *this;
+ return shl(rotateAmt) | lshr(BitWidth - rotateAmt);
+}
+
+APInt APInt::rotr(const APInt &rotateAmt) const {
+ return rotr((unsigned)rotateAmt.getLimitedValue(BitWidth));
+}
+
+APInt APInt::rotr(unsigned rotateAmt) const {
+ rotateAmt %= BitWidth;
+ if (rotateAmt == 0)
+ return *this;
+ return lshr(rotateAmt) | shl(BitWidth - rotateAmt);
+}
+
+// Square Root - this method computes and returns the square root of "this".
+// Three mechanisms are used for computation. For small values (<= 5 bits),
+// a table lookup is done. This gets some performance for common cases. For
+// values using less than 52 bits, the value is converted to double and then
+// the libc sqrt function is called. The result is rounded and then converted
+// back to a uint64_t which is then used to construct the result. Finally,
+// the Babylonian method for computing square roots is used.
+APInt APInt::sqrt() const {
+
+ // Determine the magnitude of the value.
+ unsigned magnitude = getActiveBits();
+
+ // Use a fast table for some small values. This also gets rid of some
+ // rounding errors in libc sqrt for small values.
+ if (magnitude <= 5) {
+ static const uint8_t results[32] = {
+ /* 0 */ 0,
+ /* 1- 2 */ 1, 1,
+ /* 3- 6 */ 2, 2, 2, 2,
+ /* 7-12 */ 3, 3, 3, 3, 3, 3,
+ /* 13-20 */ 4, 4, 4, 4, 4, 4, 4, 4,
+ /* 21-30 */ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ /* 31 */ 6
+ };
+ return APInt(BitWidth, results[ (isSingleWord() ? VAL : pVal[0]) ]);
+ }
+
+ // If the magnitude of the value fits in less than 52 bits (the precision of
+ // an IEEE double precision floating point value), then we can use the
+ // libc sqrt function which will probably use a hardware sqrt computation.
+ // This should be faster than the algorithm below.
+ if (magnitude < 52) {
+ return APInt(BitWidth,
+ uint64_t(::round(::sqrt(double(isSingleWord()?VAL:pVal[0])))));
+ }
+
+ // Okay, all the short cuts are exhausted. We must compute it. The following
+ // is a classical Babylonian method for computing the square root. This code
+ // was adapted to APInt from a wikipedia article on such computations.
+ // See http://www.wikipedia.org/ and go to the page named
+ // Calculate_an_integer_square_root.
+ unsigned nbits = BitWidth, i = 4;
+ APInt testy(BitWidth, 16);
+ APInt x_old(BitWidth, 1);
+ APInt x_new(BitWidth, 0);
+ APInt two(BitWidth, 2);
+
+ // Select a good starting value using binary logarithms.
+ for (;; i += 2, testy = testy.shl(2))
+ if (i >= nbits || this->ule(testy)) {
+ x_old = x_old.shl(i / 2);
+ break;
+ }
+
+ // Use the Babylonian method to arrive at the integer square root:
+ for (;;) {
+ x_new = (this->udiv(x_old) + x_old).udiv(two);
+ if (x_old.ule(x_new))
+ break;
+ x_old = x_new;
+ }
+
+ // Make sure we return the closest approximation
+ // NOTE: The rounding calculation below is correct. It will produce an
+ // off-by-one discrepancy with results from pari/gp. That discrepancy has been
+ // determined to be a rounding issue with pari/gp as it begins to use a
+ // floating point representation after 192 bits. There are no discrepancies
+ // between this algorithm and pari/gp for bit widths < 192 bits.
+ APInt square(x_old * x_old);
+ APInt nextSquare((x_old + 1) * (x_old +1));
+ if (this->ult(square))
+ return x_old;
+ assert(this->ule(nextSquare) && "Error in APInt::sqrt computation");
+ APInt midpoint((nextSquare - square).udiv(two));
+ APInt offset(*this - square);
+ if (offset.ult(midpoint))
+ return x_old;
+ return x_old + 1;
+}
+
+/// Computes the multiplicative inverse of this APInt for a given modulo. The
+/// iterative extended Euclidean algorithm is used to solve for this value,
+/// however we simplify it to speed up calculating only the inverse, and take
+/// advantage of div+rem calculations. We also use some tricks to avoid copying
+/// (potentially large) APInts around.
+APInt APInt::multiplicativeInverse(const APInt& modulo) const {
+ assert(ult(modulo) && "This APInt must be smaller than the modulo");
+
+ // Using the properties listed at the following web page (accessed 06/21/08):
+ // http://www.numbertheory.org/php/euclid.html
+ // (especially the properties numbered 3, 4 and 9) it can be proved that
+ // BitWidth bits suffice for all the computations in the algorithm implemented
+ // below. More precisely, this number of bits suffice if the multiplicative
+ // inverse exists, but may not suffice for the general extended Euclidean
+ // algorithm.
+
+ APInt r[2] = { modulo, *this };
+ APInt t[2] = { APInt(BitWidth, 0), APInt(BitWidth, 1) };
+ APInt q(BitWidth, 0);
+
+ unsigned i;
+ for (i = 0; r[i^1] != 0; i ^= 1) {
+ // An overview of the math without the confusing bit-flipping:
+ // q = r[i-2] / r[i-1]
+ // r[i] = r[i-2] % r[i-1]
+ // t[i] = t[i-2] - t[i-1] * q
+ udivrem(r[i], r[i^1], q, r[i]);
+ t[i] -= t[i^1] * q;
+ }
+
+ // If this APInt and the modulo are not coprime, there is no multiplicative
+ // inverse, so return 0. We check this by looking at the next-to-last
+ // remainder, which is the gcd(*this,modulo) as calculated by the Euclidean
+ // algorithm.
+ if (r[i] != 1)
+ return APInt(BitWidth, 0);
+
+ // The next-to-last t is the multiplicative inverse. However, we are
+ // interested in a positive inverse. Calcuate a positive one from a negative
+ // one if necessary. A simple addition of the modulo suffices because
+ // abs(t[i]) is known to be less than *this/2 (see the link above).
+ return t[i].isNegative() ? t[i] + modulo : t[i];
+}
+
+/// Calculate the magic numbers required to implement a signed integer division
+/// by a constant as a sequence of multiplies, adds and shifts. Requires that
+/// the divisor not be 0, 1, or -1. Taken from "Hacker's Delight", Henry S.
+/// Warren, Jr., chapter 10.
+APInt::ms APInt::magic() const {
+ const APInt& d = *this;
+ unsigned p;
+ APInt ad, anc, delta, q1, r1, q2, r2, t;
+ APInt signedMin = APInt::getSignedMinValue(d.getBitWidth());
+ struct ms mag;
+
+ ad = d.abs();
+ t = signedMin + (d.lshr(d.getBitWidth() - 1));
+ anc = t - 1 - t.urem(ad); // absolute value of nc
+ p = d.getBitWidth() - 1; // initialize p
+ q1 = signedMin.udiv(anc); // initialize q1 = 2p/abs(nc)
+ r1 = signedMin - q1*anc; // initialize r1 = rem(2p,abs(nc))
+ q2 = signedMin.udiv(ad); // initialize q2 = 2p/abs(d)
+ r2 = signedMin - q2*ad; // initialize r2 = rem(2p,abs(d))
+ do {
+ p = p + 1;
+ q1 = q1<<1; // update q1 = 2p/abs(nc)
+ r1 = r1<<1; // update r1 = rem(2p/abs(nc))
+ if (r1.uge(anc)) { // must be unsigned comparison
+ q1 = q1 + 1;
+ r1 = r1 - anc;
+ }
+ q2 = q2<<1; // update q2 = 2p/abs(d)
+ r2 = r2<<1; // update r2 = rem(2p/abs(d))
+ if (r2.uge(ad)) { // must be unsigned comparison
+ q2 = q2 + 1;
+ r2 = r2 - ad;
+ }
+ delta = ad - r2;
+ } while (q1.ult(delta) || (q1 == delta && r1 == 0));
+
+ mag.m = q2 + 1;
+ if (d.isNegative()) mag.m = -mag.m; // resulting magic number
+ mag.s = p - d.getBitWidth(); // resulting shift
+ return mag;
+}
+
+/// Calculate the magic numbers required to implement an unsigned integer
+/// division by a constant as a sequence of multiplies, adds and shifts.
+/// Requires that the divisor not be 0. Taken from "Hacker's Delight", Henry
+/// S. Warren, Jr., chapter 10.
+/// LeadingZeros can be used to simplify the calculation if the upper bits
+/// of the divided value are known zero.
+APInt::mu APInt::magicu(unsigned LeadingZeros) const {
+ const APInt& d = *this;
+ unsigned p;
+ APInt nc, delta, q1, r1, q2, r2;
+ struct mu magu;
+ magu.a = 0; // initialize "add" indicator
+ APInt allOnes = APInt::getAllOnesValue(d.getBitWidth()).lshr(LeadingZeros);
+ APInt signedMin = APInt::getSignedMinValue(d.getBitWidth());
+ APInt signedMax = APInt::getSignedMaxValue(d.getBitWidth());
+
+ nc = allOnes - (allOnes - d).urem(d);
+ p = d.getBitWidth() - 1; // initialize p
+ q1 = signedMin.udiv(nc); // initialize q1 = 2p/nc
+ r1 = signedMin - q1*nc; // initialize r1 = rem(2p,nc)
+ q2 = signedMax.udiv(d); // initialize q2 = (2p-1)/d
+ r2 = signedMax - q2*d; // initialize r2 = rem((2p-1),d)
+ do {
+ p = p + 1;
+ if (r1.uge(nc - r1)) {
+ q1 = q1 + q1 + 1; // update q1
+ r1 = r1 + r1 - nc; // update r1
+ }
+ else {
+ q1 = q1+q1; // update q1
+ r1 = r1+r1; // update r1
+ }
+ if ((r2 + 1).uge(d - r2)) {
+ if (q2.uge(signedMax)) magu.a = 1;
+ q2 = q2+q2 + 1; // update q2
+ r2 = r2+r2 + 1 - d; // update r2
+ }
+ else {
+ if (q2.uge(signedMin)) magu.a = 1;
+ q2 = q2+q2; // update q2
+ r2 = r2+r2 + 1; // update r2
+ }
+ delta = d - 1 - r2;
+ } while (p < d.getBitWidth()*2 &&
+ (q1.ult(delta) || (q1 == delta && r1 == 0)));
+ magu.m = q2 + 1; // resulting magic number
+ magu.s = p - d.getBitWidth(); // resulting shift
+ return magu;
+}
+
+/// Implementation of Knuth's Algorithm D (Division of nonnegative integers)
+/// from "Art of Computer Programming, Volume 2", section 4.3.1, p. 272. The
+/// variables here have the same names as in the algorithm. Comments explain
+/// the algorithm and any deviation from it.
+static void KnuthDiv(unsigned *u, unsigned *v, unsigned *q, unsigned* r,
+ unsigned m, unsigned n) {
+ assert(u && "Must provide dividend");
+ assert(v && "Must provide divisor");
+ assert(q && "Must provide quotient");
+ assert(u != v && u != q && v != q && "Must use different memory");
+ assert(n>1 && "n must be > 1");
+
+ // b denotes the base of the number system. In our case b is 2^32.
+ LLVM_CONSTEXPR uint64_t b = uint64_t(1) << 32;
+
+ DEBUG(dbgs() << "KnuthDiv: m=" << m << " n=" << n << '\n');
+ DEBUG(dbgs() << "KnuthDiv: original:");
+ DEBUG(for (int i = m+n; i >=0; i--) dbgs() << " " << u[i]);
+ DEBUG(dbgs() << " by");
+ DEBUG(for (int i = n; i >0; i--) dbgs() << " " << v[i-1]);
+ DEBUG(dbgs() << '\n');
+ // D1. [Normalize.] Set d = b / (v[n-1] + 1) and multiply all the digits of
+ // u and v by d. Note that we have taken Knuth's advice here to use a power
+ // of 2 value for d such that d * v[n-1] >= b/2 (b is the base). A power of
+ // 2 allows us to shift instead of multiply and it is easy to determine the
+ // shift amount from the leading zeros. We are basically normalizing the u
+ // and v so that its high bits are shifted to the top of v's range without
+ // overflow. Note that this can require an extra word in u so that u must
+ // be of length m+n+1.
+ unsigned shift = countLeadingZeros(v[n-1]);
+ unsigned v_carry = 0;
+ unsigned u_carry = 0;
+ if (shift) {
+ for (unsigned i = 0; i < m+n; ++i) {
+ unsigned u_tmp = u[i] >> (32 - shift);
+ u[i] = (u[i] << shift) | u_carry;
+ u_carry = u_tmp;
+ }
+ for (unsigned i = 0; i < n; ++i) {
+ unsigned v_tmp = v[i] >> (32 - shift);
+ v[i] = (v[i] << shift) | v_carry;
+ v_carry = v_tmp;
+ }
+ }
+ u[m+n] = u_carry;
+
+ DEBUG(dbgs() << "KnuthDiv: normal:");
+ DEBUG(for (int i = m+n; i >=0; i--) dbgs() << " " << u[i]);
+ DEBUG(dbgs() << " by");
+ DEBUG(for (int i = n; i >0; i--) dbgs() << " " << v[i-1]);
+ DEBUG(dbgs() << '\n');
+
+ // D2. [Initialize j.] Set j to m. This is the loop counter over the places.
+ int j = m;
+ do {
+ DEBUG(dbgs() << "KnuthDiv: quotient digit #" << j << '\n');
+ // D3. [Calculate q'.].
+ // Set qp = (u[j+n]*b + u[j+n-1]) / v[n-1]. (qp=qprime=q')
+ // Set rp = (u[j+n]*b + u[j+n-1]) % v[n-1]. (rp=rprime=r')
+ // Now test if qp == b or qp*v[n-2] > b*rp + u[j+n-2]; if so, decrease
+ // qp by 1, inrease rp by v[n-1], and repeat this test if rp < b. The test
+ // on v[n-2] determines at high speed most of the cases in which the trial
+ // value qp is one too large, and it eliminates all cases where qp is two
+ // too large.
+ uint64_t dividend = ((uint64_t(u[j+n]) << 32) + u[j+n-1]);
+ DEBUG(dbgs() << "KnuthDiv: dividend == " << dividend << '\n');
+ uint64_t qp = dividend / v[n-1];
+ uint64_t rp = dividend % v[n-1];
+ if (qp == b || qp*v[n-2] > b*rp + u[j+n-2]) {
+ qp--;
+ rp += v[n-1];
+ if (rp < b && (qp == b || qp*v[n-2] > b*rp + u[j+n-2]))
+ qp--;
+ }
+ DEBUG(dbgs() << "KnuthDiv: qp == " << qp << ", rp == " << rp << '\n');
+
+ // D4. [Multiply and subtract.] Replace (u[j+n]u[j+n-1]...u[j]) with
+ // (u[j+n]u[j+n-1]..u[j]) - qp * (v[n-1]...v[1]v[0]). This computation
+ // consists of a simple multiplication by a one-place number, combined with
+ // a subtraction.
+ // The digits (u[j+n]...u[j]) should be kept positive; if the result of
+ // this step is actually negative, (u[j+n]...u[j]) should be left as the
+ // true value plus b**(n+1), namely as the b's complement of
+ // the true value, and a "borrow" to the left should be remembered.
+ int64_t borrow = 0;
+ for (unsigned i = 0; i < n; ++i) {
+ uint64_t p = uint64_t(qp) * uint64_t(v[i]);
+ int64_t subres = int64_t(u[j+i]) - borrow - (unsigned)p;
+ u[j+i] = (unsigned)subres;
+ borrow = (p >> 32) - (subres >> 32);
+ DEBUG(dbgs() << "KnuthDiv: u[j+i] = " << u[j+i]
+ << ", borrow = " << borrow << '\n');
+ }
+ bool isNeg = u[j+n] < borrow;
+ u[j+n] -= (unsigned)borrow;
+
+ DEBUG(dbgs() << "KnuthDiv: after subtraction:");
+ DEBUG(for (int i = m+n; i >=0; i--) dbgs() << " " << u[i]);
+ DEBUG(dbgs() << '\n');
+
+ // D5. [Test remainder.] Set q[j] = qp. If the result of step D4 was
+ // negative, go to step D6; otherwise go on to step D7.
+ q[j] = (unsigned)qp;
+ if (isNeg) {
+ // D6. [Add back]. The probability that this step is necessary is very
+ // small, on the order of only 2/b. Make sure that test data accounts for
+ // this possibility. Decrease q[j] by 1
+ q[j]--;
+ // and add (0v[n-1]...v[1]v[0]) to (u[j+n]u[j+n-1]...u[j+1]u[j]).
+ // A carry will occur to the left of u[j+n], and it should be ignored
+ // since it cancels with the borrow that occurred in D4.
+ bool carry = false;
+ for (unsigned i = 0; i < n; i++) {
+ unsigned limit = std::min(u[j+i],v[i]);
+ u[j+i] += v[i] + carry;
+ carry = u[j+i] < limit || (carry && u[j+i] == limit);
+ }
+ u[j+n] += carry;
+ }
+ DEBUG(dbgs() << "KnuthDiv: after correction:");
+ DEBUG(for (int i = m+n; i >=0; i--) dbgs() << " " << u[i]);
+ DEBUG(dbgs() << "\nKnuthDiv: digit result = " << q[j] << '\n');
+
+ // D7. [Loop on j.] Decrease j by one. Now if j >= 0, go back to D3.
+ } while (--j >= 0);
+
+ DEBUG(dbgs() << "KnuthDiv: quotient:");
+ DEBUG(for (int i = m; i >=0; i--) dbgs() <<" " << q[i]);
+ DEBUG(dbgs() << '\n');
+
+ // D8. [Unnormalize]. Now q[...] is the desired quotient, and the desired
+ // remainder may be obtained by dividing u[...] by d. If r is non-null we
+ // compute the remainder (urem uses this).
+ if (r) {
+ // The value d is expressed by the "shift" value above since we avoided
+ // multiplication by d by using a shift left. So, all we have to do is
+ // shift right here. In order to mak
+ if (shift) {
+ unsigned carry = 0;
+ DEBUG(dbgs() << "KnuthDiv: remainder:");
+ for (int i = n-1; i >= 0; i--) {
+ r[i] = (u[i] >> shift) | carry;
+ carry = u[i] << (32 - shift);
+ DEBUG(dbgs() << " " << r[i]);
+ }
+ } else {
+ for (int i = n-1; i >= 0; i--) {
+ r[i] = u[i];
+ DEBUG(dbgs() << " " << r[i]);
+ }
+ }
+ DEBUG(dbgs() << '\n');
+ }
+ DEBUG(dbgs() << '\n');
+}
+
+void APInt::divide(const APInt LHS, unsigned lhsWords,
+ const APInt &RHS, unsigned rhsWords,
+ APInt *Quotient, APInt *Remainder)
+{
+ assert(lhsWords >= rhsWords && "Fractional result");
+
+ // First, compose the values into an array of 32-bit words instead of
+ // 64-bit words. This is a necessity of both the "short division" algorithm
+ // and the Knuth "classical algorithm" which requires there to be native
+ // operations for +, -, and * on an m bit value with an m*2 bit result. We
+ // can't use 64-bit operands here because we don't have native results of
+ // 128-bits. Furthermore, casting the 64-bit values to 32-bit values won't
+ // work on large-endian machines.
+ uint64_t mask = ~0ull >> (sizeof(unsigned)*CHAR_BIT);
+ unsigned n = rhsWords * 2;
+ unsigned m = (lhsWords * 2) - n;
+
+ // Allocate space for the temporary values we need either on the stack, if
+ // it will fit, or on the heap if it won't.
+ unsigned SPACE[128];
+ unsigned *U = nullptr;
+ unsigned *V = nullptr;
+ unsigned *Q = nullptr;
+ unsigned *R = nullptr;
+ if ((Remainder?4:3)*n+2*m+1 <= 128) {
+ U = &SPACE[0];
+ V = &SPACE[m+n+1];
+ Q = &SPACE[(m+n+1) + n];
+ if (Remainder)
+ R = &SPACE[(m+n+1) + n + (m+n)];
+ } else {
+ U = new unsigned[m + n + 1];
+ V = new unsigned[n];
+ Q = new unsigned[m+n];
+ if (Remainder)
+ R = new unsigned[n];
+ }
+
+ // Initialize the dividend
+ memset(U, 0, (m+n+1)*sizeof(unsigned));
+ for (unsigned i = 0; i < lhsWords; ++i) {
+ uint64_t tmp = (LHS.getNumWords() == 1 ? LHS.VAL : LHS.pVal[i]);
+ U[i * 2] = (unsigned)(tmp & mask);
+ U[i * 2 + 1] = (unsigned)(tmp >> (sizeof(unsigned)*CHAR_BIT));
+ }
+ U[m+n] = 0; // this extra word is for "spill" in the Knuth algorithm.
+
+ // Initialize the divisor
+ memset(V, 0, (n)*sizeof(unsigned));
+ for (unsigned i = 0; i < rhsWords; ++i) {
+ uint64_t tmp = (RHS.getNumWords() == 1 ? RHS.VAL : RHS.pVal[i]);
+ V[i * 2] = (unsigned)(tmp & mask);
+ V[i * 2 + 1] = (unsigned)(tmp >> (sizeof(unsigned)*CHAR_BIT));
+ }
+
+ // initialize the quotient and remainder
+ memset(Q, 0, (m+n) * sizeof(unsigned));
+ if (Remainder)
+ memset(R, 0, n * sizeof(unsigned));
+
+ // Now, adjust m and n for the Knuth division. n is the number of words in
+ // the divisor. m is the number of words by which the dividend exceeds the
+ // divisor (i.e. m+n is the length of the dividend). These sizes must not
+ // contain any zero words or the Knuth algorithm fails.
+ for (unsigned i = n; i > 0 && V[i-1] == 0; i--) {
+ n--;
+ m++;
+ }
+ for (unsigned i = m+n; i > 0 && U[i-1] == 0; i--)
+ m--;
+
+ // If we're left with only a single word for the divisor, Knuth doesn't work
+ // so we implement the short division algorithm here. This is much simpler
+ // and faster because we are certain that we can divide a 64-bit quantity
+ // by a 32-bit quantity at hardware speed and short division is simply a
+ // series of such operations. This is just like doing short division but we
+ // are using base 2^32 instead of base 10.
+ assert(n != 0 && "Divide by zero?");
+ if (n == 1) {
+ unsigned divisor = V[0];
+ unsigned remainder = 0;
+ for (int i = m+n-1; i >= 0; i--) {
+ uint64_t partial_dividend = uint64_t(remainder) << 32 | U[i];
+ if (partial_dividend == 0) {
+ Q[i] = 0;
+ remainder = 0;
+ } else if (partial_dividend < divisor) {
+ Q[i] = 0;
+ remainder = (unsigned)partial_dividend;
+ } else if (partial_dividend == divisor) {
+ Q[i] = 1;
+ remainder = 0;
+ } else {
+ Q[i] = (unsigned)(partial_dividend / divisor);
+ remainder = (unsigned)(partial_dividend - (Q[i] * divisor));
+ }
+ }
+ if (R)
+ R[0] = remainder;
+ } else {
+ // Now we're ready to invoke the Knuth classical divide algorithm. In this
+ // case n > 1.
+ KnuthDiv(U, V, Q, R, m, n);
+ }
+
+ // If the caller wants the quotient
+ if (Quotient) {
+ // Set up the Quotient value's memory.
+ if (Quotient->BitWidth != LHS.BitWidth) {
+ if (Quotient->isSingleWord())
+ Quotient->VAL = 0;
+ else
+ delete [] Quotient->pVal;
+ Quotient->BitWidth = LHS.BitWidth;
+ if (!Quotient->isSingleWord())
+ Quotient->pVal = getClearedMemory(Quotient->getNumWords());
+ } else
+ Quotient->clearAllBits();
+
+ // The quotient is in Q. Reconstitute the quotient into Quotient's low
+ // order words.
+ // This case is currently dead as all users of divide() handle trivial cases
+ // earlier.
+ if (lhsWords == 1) {
+ uint64_t tmp =
+ uint64_t(Q[0]) | (uint64_t(Q[1]) << (APINT_BITS_PER_WORD / 2));
+ if (Quotient->isSingleWord())
+ Quotient->VAL = tmp;
+ else
+ Quotient->pVal[0] = tmp;
+ } else {
+ assert(!Quotient->isSingleWord() && "Quotient APInt not large enough");
+ for (unsigned i = 0; i < lhsWords; ++i)
+ Quotient->pVal[i] =
+ uint64_t(Q[i*2]) | (uint64_t(Q[i*2+1]) << (APINT_BITS_PER_WORD / 2));
+ }
+ }
+
+ // If the caller wants the remainder
+ if (Remainder) {
+ // Set up the Remainder value's memory.
+ if (Remainder->BitWidth != RHS.BitWidth) {
+ if (Remainder->isSingleWord())
+ Remainder->VAL = 0;
+ else
+ delete [] Remainder->pVal;
+ Remainder->BitWidth = RHS.BitWidth;
+ if (!Remainder->isSingleWord())
+ Remainder->pVal = getClearedMemory(Remainder->getNumWords());
+ } else
+ Remainder->clearAllBits();
+
+ // The remainder is in R. Reconstitute the remainder into Remainder's low
+ // order words.
+ if (rhsWords == 1) {
+ uint64_t tmp =
+ uint64_t(R[0]) | (uint64_t(R[1]) << (APINT_BITS_PER_WORD / 2));
+ if (Remainder->isSingleWord())
+ Remainder->VAL = tmp;
+ else
+ Remainder->pVal[0] = tmp;
+ } else {
+ assert(!Remainder->isSingleWord() && "Remainder APInt not large enough");
+ for (unsigned i = 0; i < rhsWords; ++i)
+ Remainder->pVal[i] =
+ uint64_t(R[i*2]) | (uint64_t(R[i*2+1]) << (APINT_BITS_PER_WORD / 2));
+ }
+ }
+
+ // Clean up the memory we allocated.
+ if (U != &SPACE[0]) {
+ delete [] U;
+ delete [] V;
+ delete [] Q;
+ delete [] R;
+ }
+}
+
+APInt APInt::udiv(const APInt& RHS) const {
+ assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
+
+ // First, deal with the easy case
+ if (isSingleWord()) {
+ assert(RHS.VAL != 0 && "Divide by zero?");
+ return APInt(BitWidth, VAL / RHS.VAL);
+ }
+
+ // Get some facts about the LHS and RHS number of bits and words
+ unsigned rhsBits = RHS.getActiveBits();
+ unsigned rhsWords = !rhsBits ? 0 : (APInt::whichWord(rhsBits - 1) + 1);
+ assert(rhsWords && "Divided by zero???");
+ unsigned lhsBits = this->getActiveBits();
+ unsigned lhsWords = !lhsBits ? 0 : (APInt::whichWord(lhsBits - 1) + 1);
+
+ // Deal with some degenerate cases
+ if (!lhsWords)
+ // 0 / X ===> 0
+ return APInt(BitWidth, 0);
+ else if (lhsWords < rhsWords || this->ult(RHS)) {
+ // X / Y ===> 0, iff X < Y
+ return APInt(BitWidth, 0);
+ } else if (*this == RHS) {
+ // X / X ===> 1
+ return APInt(BitWidth, 1);
+ } else if (lhsWords == 1 && rhsWords == 1) {
+ // All high words are zero, just use native divide
+ return APInt(BitWidth, this->pVal[0] / RHS.pVal[0]);
+ }
+
+ // We have to compute it the hard way. Invoke the Knuth divide algorithm.
+ APInt Quotient(1,0); // to hold result.
+ divide(*this, lhsWords, RHS, rhsWords, &Quotient, nullptr);
+ return Quotient;
+}
+
+APInt APInt::sdiv(const APInt &RHS) const {
+ if (isNegative()) {
+ if (RHS.isNegative())
+ return (-(*this)).udiv(-RHS);
+ return -((-(*this)).udiv(RHS));
+ }
+ if (RHS.isNegative())
+ return -(this->udiv(-RHS));
+ return this->udiv(RHS);
+}
+
+APInt APInt::urem(const APInt& RHS) const {
+ assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
+ if (isSingleWord()) {
+ assert(RHS.VAL != 0 && "Remainder by zero?");
+ return APInt(BitWidth, VAL % RHS.VAL);
+ }
+
+ // Get some facts about the LHS
+ unsigned lhsBits = getActiveBits();
+ unsigned lhsWords = !lhsBits ? 0 : (whichWord(lhsBits - 1) + 1);
+
+ // Get some facts about the RHS
+ unsigned rhsBits = RHS.getActiveBits();
+ unsigned rhsWords = !rhsBits ? 0 : (APInt::whichWord(rhsBits - 1) + 1);
+ assert(rhsWords && "Performing remainder operation by zero ???");
+
+ // Check the degenerate cases
+ if (lhsWords == 0) {
+ // 0 % Y ===> 0
+ return APInt(BitWidth, 0);
+ } else if (lhsWords < rhsWords || this->ult(RHS)) {
+ // X % Y ===> X, iff X < Y
+ return *this;
+ } else if (*this == RHS) {
+ // X % X == 0;
+ return APInt(BitWidth, 0);
+ } else if (lhsWords == 1) {
+ // All high words are zero, just use native remainder
+ return APInt(BitWidth, pVal[0] % RHS.pVal[0]);
+ }
+
+ // We have to compute it the hard way. Invoke the Knuth divide algorithm.
+ APInt Remainder(1,0);
+ divide(*this, lhsWords, RHS, rhsWords, nullptr, &Remainder);
+ return Remainder;
+}
+
+APInt APInt::srem(const APInt &RHS) const {
+ if (isNegative()) {
+ if (RHS.isNegative())
+ return -((-(*this)).urem(-RHS));
+ return -((-(*this)).urem(RHS));
+ }
+ if (RHS.isNegative())
+ return this->urem(-RHS);
+ return this->urem(RHS);
+}
+
+void APInt::udivrem(const APInt &LHS, const APInt &RHS,
+ APInt &Quotient, APInt &Remainder) {
+ assert(LHS.BitWidth == RHS.BitWidth && "Bit widths must be the same");
+
+ // First, deal with the easy case
+ if (LHS.isSingleWord()) {
+ assert(RHS.VAL != 0 && "Divide by zero?");
+ uint64_t QuotVal = LHS.VAL / RHS.VAL;
+ uint64_t RemVal = LHS.VAL % RHS.VAL;
+ Quotient = APInt(LHS.BitWidth, QuotVal);
+ Remainder = APInt(LHS.BitWidth, RemVal);
+ return;
+ }
+
+ // Get some size facts about the dividend and divisor
+ unsigned lhsBits = LHS.getActiveBits();
+ unsigned lhsWords = !lhsBits ? 0 : (APInt::whichWord(lhsBits - 1) + 1);
+ unsigned rhsBits = RHS.getActiveBits();
+ unsigned rhsWords = !rhsBits ? 0 : (APInt::whichWord(rhsBits - 1) + 1);
+
+ // Check the degenerate cases
+ if (lhsWords == 0) {
+ Quotient = 0; // 0 / Y ===> 0
+ Remainder = 0; // 0 % Y ===> 0
+ return;
+ }
+
+ if (lhsWords < rhsWords || LHS.ult(RHS)) {
+ Remainder = LHS; // X % Y ===> X, iff X < Y
+ Quotient = 0; // X / Y ===> 0, iff X < Y
+ return;
+ }
+
+ if (LHS == RHS) {
+ Quotient = 1; // X / X ===> 1
+ Remainder = 0; // X % X ===> 0;
+ return;
+ }
+
+ if (lhsWords == 1 && rhsWords == 1) {
+ // There is only one word to consider so use the native versions.
+ uint64_t lhsValue = LHS.isSingleWord() ? LHS.VAL : LHS.pVal[0];
+ uint64_t rhsValue = RHS.isSingleWord() ? RHS.VAL : RHS.pVal[0];
+ Quotient = APInt(LHS.getBitWidth(), lhsValue / rhsValue);
+ Remainder = APInt(LHS.getBitWidth(), lhsValue % rhsValue);
+ return;
+ }
+
+ // Okay, lets do it the long way
+ divide(LHS, lhsWords, RHS, rhsWords, &Quotient, &Remainder);
+}
+
+void APInt::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);
+ }
+}
+
+APInt APInt::sadd_ov(const APInt &RHS, bool &Overflow) const {
+ APInt Res = *this+RHS;
+ Overflow = isNonNegative() == RHS.isNonNegative() &&
+ Res.isNonNegative() != isNonNegative();
+ return Res;
+}
+
+APInt APInt::uadd_ov(const APInt &RHS, bool &Overflow) const {
+ APInt Res = *this+RHS;
+ Overflow = Res.ult(RHS);
+ return Res;
+}
+
+APInt APInt::ssub_ov(const APInt &RHS, bool &Overflow) const {
+ APInt Res = *this - RHS;
+ Overflow = isNonNegative() != RHS.isNonNegative() &&
+ Res.isNonNegative() != isNonNegative();
+ return Res;
+}
+
+APInt APInt::usub_ov(const APInt &RHS, bool &Overflow) const {
+ APInt Res = *this-RHS;
+ Overflow = Res.ugt(*this);
+ return Res;
+}
+
+APInt APInt::sdiv_ov(const APInt &RHS, bool &Overflow) const {
+ // MININT/-1 --> overflow.
+ Overflow = isMinSignedValue() && RHS.isAllOnesValue();
+ return sdiv(RHS);
+}
+
+APInt APInt::smul_ov(const APInt &RHS, bool &Overflow) const {
+ APInt Res = *this * RHS;
+
+ if (*this != 0 && RHS != 0)
+ Overflow = Res.sdiv(RHS) != *this || Res.sdiv(*this) != RHS;
+ else
+ Overflow = false;
+ return Res;
+}
+
+APInt APInt::umul_ov(const APInt &RHS, bool &Overflow) const {
+ APInt Res = *this * RHS;
+
+ if (*this != 0 && RHS != 0)
+ Overflow = Res.udiv(RHS) != *this || Res.udiv(*this) != RHS;
+ else
+ Overflow = false;
+ return Res;
+}
+
+APInt APInt::sshl_ov(const APInt &ShAmt, bool &Overflow) const {
+ Overflow = ShAmt.uge(getBitWidth());
+ if (Overflow)
+ return APInt(BitWidth, 0);
+
+ if (isNonNegative()) // Don't allow sign change.
+ Overflow = ShAmt.uge(countLeadingZeros());
+ else
+ Overflow = ShAmt.uge(countLeadingOnes());
+
+ return *this << ShAmt;
+}
+
+APInt APInt::ushl_ov(const APInt &ShAmt, bool &Overflow) const {
+ Overflow = ShAmt.uge(getBitWidth());
+ if (Overflow)
+ return APInt(BitWidth, 0);
+
+ Overflow = ShAmt.ugt(countLeadingZeros());
+
+ return *this << ShAmt;
+}
+
+
+
+
+void APInt::fromString(unsigned numbits, StringRef str, uint8_t radix) {
+ // Check our assumptions here
+ assert(!str.empty() && "Invalid string length");
+ assert((radix == 10 || radix == 8 || radix == 16 || radix == 2 ||
+ radix == 36) &&
+ "Radix should be 2, 8, 10, 16, or 36!");
+
+ StringRef::iterator p = str.begin();
+ size_t slen = str.size();
+ bool isNeg = *p == '-';
+ if (*p == '-' || *p == '+') {
+ p++;
+ slen--;
+ assert(slen && "String is only a sign, needs a value.");
+ }
+ assert((slen <= numbits || radix != 2) && "Insufficient bit width");
+ assert(((slen-1)*3 <= numbits || radix != 8) && "Insufficient bit width");
+ assert(((slen-1)*4 <= numbits || radix != 16) && "Insufficient bit width");
+ assert((((slen-1)*64)/22 <= numbits || radix != 10) &&
+ "Insufficient bit width");
+
+ // Allocate memory
+ if (!isSingleWord())
+ pVal = getClearedMemory(getNumWords());
+
+ // Figure out if we can shift instead of multiply
+ unsigned shift = (radix == 16 ? 4 : radix == 8 ? 3 : radix == 2 ? 1 : 0);
+
+ // Set up an APInt for the digit to add outside the loop so we don't
+ // constantly construct/destruct it.
+ APInt apdigit(getBitWidth(), 0);
+ APInt apradix(getBitWidth(), radix);
+
+ // Enter digit traversal loop
+ for (StringRef::iterator e = str.end(); p != e; ++p) {
+ unsigned digit = getDigit(*p, radix);
+ assert(digit < radix && "Invalid character in digit string");
+
+ // Shift or multiply the value by the radix
+ if (slen > 1) {
+ if (shift)
+ *this <<= shift;
+ else
+ *this *= apradix;
+ }
+
+ // Add in the digit we just interpreted
+ if (apdigit.isSingleWord())
+ apdigit.VAL = digit;
+ else
+ apdigit.pVal[0] = digit;
+ *this += apdigit;
+ }
+ // If its negative, put it in two's complement form
+ if (isNeg) {
+ --(*this);
+ this->flipAllBits();
+ }
+}
+
+void APInt::toString(SmallVectorImpl<char> &Str, unsigned Radix,
+ bool Signed, bool formatAsCLiteral) const {
+ assert((Radix == 10 || Radix == 8 || Radix == 16 || Radix == 2 ||
+ Radix == 36) &&
+ "Radix should be 2, 8, 10, 16, or 36!");
+
+ const char *Prefix = "";
+ if (formatAsCLiteral) {
+ switch (Radix) {
+ case 2:
+ // Binary literals are a non-standard extension added in gcc 4.3:
+ // http://gcc.gnu.org/onlinedocs/gcc-4.3.0/gcc/Binary-constants.html
+ Prefix = "0b";
+ break;
+ case 8:
+ Prefix = "0";
+ break;
+ case 10:
+ break; // No prefix
+ case 16:
+ Prefix = "0x";
+ break;
+ default:
+ llvm_unreachable("Invalid radix!");
+ }
+ }
+
+ // First, check for a zero value and just short circuit the logic below.
+ if (*this == 0) {
+ while (*Prefix) {
+ Str.push_back(*Prefix);
+ ++Prefix;
+ };
+ Str.push_back('0');
+ return;
+ }
+
+ static const char Digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+
+ if (isSingleWord()) {
+ char Buffer[65];
+ char *BufPtr = Buffer+65;
+
+ uint64_t N;
+ if (!Signed) {
+ N = getZExtValue();
+ } else {
+ int64_t I = getSExtValue();
+ if (I >= 0) {
+ N = I;
+ } else {
+ Str.push_back('-');
+ N = -(uint64_t)I;
+ }
+ }
+
+ while (*Prefix) {
+ Str.push_back(*Prefix);
+ ++Prefix;
+ };
+
+ while (N) {
+ *--BufPtr = Digits[N % Radix];
+ N /= Radix;
+ }
+ Str.append(BufPtr, Buffer+65);
+ return;
+ }
+
+ APInt Tmp(*this);
+
+ if (Signed && isNegative()) {
+ // They want to print the signed version and it is a negative value
+ // Flip the bits and add one to turn it into the equivalent positive
+ // value and put a '-' in the result.
+ Tmp.flipAllBits();
+ ++Tmp;
+ Str.push_back('-');
+ }
+
+ while (*Prefix) {
+ Str.push_back(*Prefix);
+ ++Prefix;
+ };
+
+ // We insert the digits backward, then reverse them to get the right order.
+ unsigned StartDig = Str.size();
+
+ // For the 2, 8 and 16 bit cases, we can just shift instead of divide
+ // because the number of bits per digit (1, 3 and 4 respectively) divides
+ // equaly. We just shift until the value is zero.
+ if (Radix == 2 || Radix == 8 || Radix == 16) {
+ // Just shift tmp right for each digit width until it becomes zero
+ unsigned ShiftAmt = (Radix == 16 ? 4 : (Radix == 8 ? 3 : 1));
+ unsigned MaskAmt = Radix - 1;
+
+ while (Tmp != 0) {
+ unsigned Digit = unsigned(Tmp.getRawData()[0]) & MaskAmt;
+ Str.push_back(Digits[Digit]);
+ Tmp = Tmp.lshr(ShiftAmt);
+ }
+ } else {
+ APInt divisor(Radix == 10? 4 : 8, Radix);
+ while (Tmp != 0) {
+ APInt APdigit(1, 0);
+ APInt tmp2(Tmp.getBitWidth(), 0);
+ divide(Tmp, Tmp.getNumWords(), divisor, divisor.getNumWords(), &tmp2,
+ &APdigit);
+ unsigned Digit = (unsigned)APdigit.getZExtValue();
+ assert(Digit < Radix && "divide failed");
+ Str.push_back(Digits[Digit]);
+ Tmp = tmp2;
+ }
+ }
+
+ // Reverse the digits before returning.
+ std::reverse(Str.begin()+StartDig, Str.end());
+}
+
+/// Returns the APInt as a std::string. Note that this is an inefficient method.
+/// It is better to pass in a SmallVector/SmallString to the methods above.
+std::string APInt::toString(unsigned Radix = 10, bool Signed = true) const {
+ SmallString<40> S;
+ toString(S, Radix, Signed, /* formatAsCLiteral = */false);
+ return S.str();
+}
+
+
+void APInt::dump() const {
+ SmallString<40> S, U;
+ this->toStringUnsigned(U);
+ this->toStringSigned(S);
+ dbgs() << "APInt(" << BitWidth << "b, "
+ << U << "u " << S << "s)";
+}
+
+void APInt::print(raw_ostream &OS, bool isSigned) const {
+ SmallString<40> S;
+ this->toString(S, 10, isSigned, /* formatAsCLiteral = */false);
+ OS << S;
+}
+
+// This implements a variety of operations on a representation of
+// arbitrary precision, two's-complement, bignum integer values.
+
+// Assumed by lowHalf, highHalf, partMSB and partLSB. A fairly safe
+// and unrestricting assumption.
+static_assert(integerPartWidth % 2 == 0, "Part width must be divisible by 2!");
+
+/* Some handy functions local to this file. */
+namespace {
+
+ /* Returns the integer part with the least significant BITS set.
+ BITS cannot be zero. */
+ static inline integerPart
+ lowBitMask(unsigned int bits)
+ {
+ assert(bits != 0 && bits <= integerPartWidth);
+
+ return ~(integerPart) 0 >> (integerPartWidth - bits);
+ }
+
+ /* Returns the value of the lower half of PART. */
+ static inline integerPart
+ lowHalf(integerPart part)
+ {
+ return part & lowBitMask(integerPartWidth / 2);
+ }
+
+ /* Returns the value of the upper half of PART. */
+ static inline integerPart
+ highHalf(integerPart part)
+ {
+ return part >> (integerPartWidth / 2);
+ }
+
+ /* Returns the bit number of the most significant set bit of a part.
+ If the input number has no bits set -1U is returned. */
+ static unsigned int
+ partMSB(integerPart value)
+ {
+ return findLastSet(value, ZB_Max);
+ }
+
+ /* Returns the bit number of the least significant set bit of a
+ part. If the input number has no bits set -1U is returned. */
+ static unsigned int
+ partLSB(integerPart value)
+ {
+ return findFirstSet(value, ZB_Max);
+ }
+} // namespace
+
+/* Sets the least significant part of a bignum to the input value, and
+ zeroes out higher parts. */
+void
+APInt::tcSet(integerPart *dst, integerPart part, unsigned int parts)
+{
+ unsigned int i;
+
+ assert(parts > 0);
+
+ dst[0] = part;
+ for (i = 1; i < parts; i++)
+ dst[i] = 0;
+}
+
+/* Assign one bignum to another. */
+void
+APInt::tcAssign(integerPart *dst, const integerPart *src, unsigned int parts)
+{
+ unsigned int i;
+
+ for (i = 0; i < parts; i++)
+ dst[i] = src[i];
+}
+
+/* Returns true if a bignum is zero, false otherwise. */
+bool
+APInt::tcIsZero(const integerPart *src, unsigned int parts)
+{
+ unsigned int i;
+
+ for (i = 0; i < parts; i++)
+ if (src[i])
+ return false;
+
+ return true;
+}
+
+/* Extract the given bit of a bignum; returns 0 or 1. */
+int
+APInt::tcExtractBit(const integerPart *parts, unsigned int bit)
+{
+ return (parts[bit / integerPartWidth] &
+ ((integerPart) 1 << bit % integerPartWidth)) != 0;
+}
+
+/* Set the given bit of a bignum. */
+void
+APInt::tcSetBit(integerPart *parts, unsigned int bit)
+{
+ parts[bit / integerPartWidth] |= (integerPart) 1 << (bit % integerPartWidth);
+}
+
+/* Clears the given bit of a bignum. */
+void
+APInt::tcClearBit(integerPart *parts, unsigned int bit)
+{
+ parts[bit / integerPartWidth] &=
+ ~((integerPart) 1 << (bit % integerPartWidth));
+}
+
+/* Returns the bit number of the least significant set bit of a
+ number. If the input number has no bits set -1U is returned. */
+unsigned int
+APInt::tcLSB(const integerPart *parts, unsigned int n)
+{
+ unsigned int i, lsb;
+
+ for (i = 0; i < n; i++) {
+ if (parts[i] != 0) {
+ lsb = partLSB(parts[i]);
+
+ return lsb + i * integerPartWidth;
+ }
+ }
+
+ return -1U;
+}
+
+/* Returns the bit number of the most significant set bit of a number.
+ If the input number has no bits set -1U is returned. */
+unsigned int
+APInt::tcMSB(const integerPart *parts, unsigned int n)
+{
+ unsigned int msb;
+
+ do {
+ --n;
+
+ if (parts[n] != 0) {
+ msb = partMSB(parts[n]);
+
+ return msb + n * integerPartWidth;
+ }
+ } while (n);
+
+ return -1U;
+}
+
+/* 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. */
+void
+APInt::tcExtract(integerPart *dst, unsigned int dstCount,const integerPart *src,
+ unsigned int srcBits, unsigned int srcLSB)
+{
+ unsigned int firstSrcPart, dstParts, shift, n;
+
+ dstParts = (srcBits + integerPartWidth - 1) / integerPartWidth;
+ assert(dstParts <= dstCount);
+
+ firstSrcPart = srcLSB / integerPartWidth;
+ tcAssign (dst, src + firstSrcPart, dstParts);
+
+ shift = srcLSB % integerPartWidth;
+ tcShiftRight (dst, dstParts, shift);
+
+ /* We now have (dstParts * integerPartWidth - shift) bits from SRC
+ in DST. If this is less that srcBits, append the rest, else
+ clear the high bits. */
+ n = dstParts * integerPartWidth - shift;
+ if (n < srcBits) {
+ integerPart mask = lowBitMask (srcBits - n);
+ dst[dstParts - 1] |= ((src[firstSrcPart + dstParts] & mask)
+ << n % integerPartWidth);
+ } else if (n > srcBits) {
+ if (srcBits % integerPartWidth)
+ dst[dstParts - 1] &= lowBitMask (srcBits % integerPartWidth);
+ }
+
+ /* Clear high parts. */
+ while (dstParts < dstCount)
+ dst[dstParts++] = 0;
+}
+
+/* DST += RHS + C where C is zero or one. Returns the carry flag. */
+integerPart
+APInt::tcAdd(integerPart *dst, const integerPart *rhs,
+ integerPart c, unsigned int parts)
+{
+ unsigned int i;
+
+ assert(c <= 1);
+
+ for (i = 0; i < parts; i++) {
+ integerPart l;
+
+ l = dst[i];
+ if (c) {
+ dst[i] += rhs[i] + 1;
+ c = (dst[i] <= l);
+ } else {
+ dst[i] += rhs[i];
+ c = (dst[i] < l);
+ }
+ }
+
+ return c;
+}
+
+/* DST -= RHS + C where C is zero or one. Returns the carry flag. */
+integerPart
+APInt::tcSubtract(integerPart *dst, const integerPart *rhs,
+ integerPart c, unsigned int parts)
+{
+ unsigned int i;
+
+ assert(c <= 1);
+
+ for (i = 0; i < parts; i++) {
+ integerPart l;
+
+ l = dst[i];
+ if (c) {
+ dst[i] -= rhs[i] + 1;
+ c = (dst[i] >= l);
+ } else {
+ dst[i] -= rhs[i];
+ c = (dst[i] > l);
+ }
+ }
+
+ return c;
+}
+
+/* Negate a bignum in-place. */
+void
+APInt::tcNegate(integerPart *dst, unsigned int parts)
+{
+ tcComplement(dst, parts);
+ tcIncrement(dst, parts);
+}
+
+/* DST += SRC * MULTIPLIER + CARRY if add is true
+ DST = SRC * MULTIPLIER + CARRY 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 == SRCPARTS + 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. */
+int
+APInt::tcMultiplyPart(integerPart *dst, const integerPart *src,
+ integerPart multiplier, integerPart carry,
+ unsigned int srcParts, unsigned int dstParts,
+ bool add)
+{
+ unsigned int i, n;
+
+ /* Otherwise our writes of DST kill our later reads of SRC. */
+ assert(dst <= src || dst >= src + srcParts);
+ assert(dstParts <= srcParts + 1);
+
+ /* N loops; minimum of dstParts and srcParts. */
+ n = dstParts < srcParts ? dstParts: srcParts;
+
+ for (i = 0; i < n; i++) {
+ integerPart low, mid, high, srcPart;
+
+ /* [ LOW, HIGH ] = MULTIPLIER * SRC[i] + DST[i] + CARRY.
+
+ This cannot overflow, because
+
+ (n - 1) * (n - 1) + 2 (n - 1) = (n - 1) * (n + 1)
+
+ which is less than n^2. */
+
+ srcPart = src[i];
+
+ if (multiplier == 0 || srcPart == 0) {
+ low = carry;
+ high = 0;
+ } else {
+ low = lowHalf(srcPart) * lowHalf(multiplier);
+ high = highHalf(srcPart) * highHalf(multiplier);
+
+ mid = lowHalf(srcPart) * highHalf(multiplier);
+ high += highHalf(mid);
+ mid <<= integerPartWidth / 2;
+ if (low + mid < low)
+ high++;
+ low += mid;
+
+ mid = highHalf(srcPart) * lowHalf(multiplier);
+ high += highHalf(mid);
+ mid <<= integerPartWidth / 2;
+ if (low + mid < low)
+ high++;
+ low += mid;
+
+ /* Now add carry. */
+ if (low + carry < low)
+ high++;
+ low += carry;
+ }
+
+ if (add) {
+ /* And now DST[i], and store the new low part there. */
+ if (low + dst[i] < low)
+ high++;
+ dst[i] += low;
+ } else
+ dst[i] = low;
+
+ carry = high;
+ }
+
+ if (i < dstParts) {
+ /* Full multiplication, there is no overflow. */
+ assert(i + 1 == dstParts);
+ dst[i] = carry;
+ return 0;
+ } else {
+ /* We overflowed if there is carry. */
+ if (carry)
+ return 1;
+
+ /* We would overflow if any significant unwritten parts would be
+ non-zero. This is true if any remaining src parts are non-zero
+ and the multiplier is non-zero. */
+ if (multiplier)
+ for (; i < srcParts; i++)
+ if (src[i])
+ return 1;
+
+ /* We fitted in the narrow destination. */
+ return 0;
+ }
+}
+
+/* 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. */
+int
+APInt::tcMultiply(integerPart *dst, const integerPart *lhs,
+ const integerPart *rhs, unsigned int parts)
+{
+ unsigned int i;
+ int overflow;
+
+ assert(dst != lhs && dst != rhs);
+
+ overflow = 0;
+ tcSet(dst, 0, parts);
+
+ for (i = 0; i < parts; i++)
+ overflow |= tcMultiplyPart(&dst[i], lhs, rhs[i], 0, parts,
+ parts - i, true);
+
+ return overflow;
+}
+
+/* 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. */
+unsigned int
+APInt::tcFullMultiply(integerPart *dst, const integerPart *lhs,
+ const integerPart *rhs, unsigned int lhsParts,
+ unsigned int rhsParts)
+{
+ /* Put the narrower number on the LHS for less loops below. */
+ if (lhsParts > rhsParts) {
+ return tcFullMultiply (dst, rhs, lhs, rhsParts, lhsParts);
+ } else {
+ unsigned int n;
+
+ assert(dst != lhs && dst != rhs);
+
+ tcSet(dst, 0, rhsParts);
+
+ for (n = 0; n < lhsParts; n++)
+ tcMultiplyPart(&dst[n], rhs, lhs[n], 0, rhsParts, rhsParts + 1, true);
+
+ n = lhsParts + rhsParts;
+
+ return n - (dst[n - 1] == 0);
+ }
+}
+
+/* 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.
+*/
+int
+APInt::tcDivide(integerPart *lhs, const integerPart *rhs,
+ integerPart *remainder, integerPart *srhs,
+ unsigned int parts)
+{
+ unsigned int n, shiftCount;
+ integerPart mask;
+
+ assert(lhs != remainder && lhs != srhs && remainder != srhs);
+
+ shiftCount = tcMSB(rhs, parts) + 1;
+ if (shiftCount == 0)
+ return true;
+
+ shiftCount = parts * integerPartWidth - shiftCount;
+ n = shiftCount / integerPartWidth;
+ mask = (integerPart) 1 << (shiftCount % integerPartWidth);
+
+ tcAssign(srhs, rhs, parts);
+ tcShiftLeft(srhs, parts, shiftCount);
+ tcAssign(remainder, lhs, parts);
+ tcSet(lhs, 0, parts);
+
+ /* Loop, subtracting SRHS if REMAINDER is greater and adding that to
+ the total. */
+ for (;;) {
+ int compare;
+
+ compare = tcCompare(remainder, srhs, parts);
+ if (compare >= 0) {
+ tcSubtract(remainder, srhs, 0, parts);
+ lhs[n] |= mask;
+ }
+
+ if (shiftCount == 0)
+ break;
+ shiftCount--;
+ tcShiftRight(srhs, parts, 1);
+ if ((mask >>= 1) == 0)
+ mask = (integerPart) 1 << (integerPartWidth - 1), n--;
+ }
+
+ return false;
+}
+
+/* Shift a bignum left COUNT bits in-place. Shifted in bits are zero.
+ There are no restrictions on COUNT. */
+void
+APInt::tcShiftLeft(integerPart *dst, unsigned int parts, unsigned int count)
+{
+ if (count) {
+ unsigned int jump, shift;
+
+ /* Jump is the inter-part jump; shift is is intra-part shift. */
+ jump = count / integerPartWidth;
+ shift = count % integerPartWidth;
+
+ while (parts > jump) {
+ integerPart part;
+
+ parts--;
+
+ /* dst[i] comes from the two parts src[i - jump] and, if we have
+ an intra-part shift, src[i - jump - 1]. */
+ part = dst[parts - jump];
+ if (shift) {
+ part <<= shift;
+ if (parts >= jump + 1)
+ part |= dst[parts - jump - 1] >> (integerPartWidth - shift);
+ }
+
+ dst[parts] = part;
+ }
+
+ while (parts > 0)
+ dst[--parts] = 0;
+ }
+}
+
+/* Shift a bignum right COUNT bits in-place. Shifted in bits are
+ zero. There are no restrictions on COUNT. */
+void
+APInt::tcShiftRight(integerPart *dst, unsigned int parts, unsigned int count)
+{
+ if (count) {
+ unsigned int i, jump, shift;
+
+ /* Jump is the inter-part jump; shift is is intra-part shift. */
+ jump = count / integerPartWidth;
+ shift = count % integerPartWidth;
+
+ /* Perform the shift. This leaves the most significant COUNT bits
+ of the result at zero. */
+ for (i = 0; i < parts; i++) {
+ integerPart part;
+
+ if (i + jump >= parts) {
+ part = 0;
+ } else {
+ part = dst[i + jump];
+ if (shift) {
+ part >>= shift;
+ if (i + jump + 1 < parts)
+ part |= dst[i + jump + 1] << (integerPartWidth - shift);
+ }
+ }
+
+ dst[i] = part;
+ }
+ }
+}
+
+/* Bitwise and of two bignums. */
+void
+APInt::tcAnd(integerPart *dst, const integerPart *rhs, unsigned int parts)
+{
+ unsigned int i;
+
+ for (i = 0; i < parts; i++)
+ dst[i] &= rhs[i];
+}
+
+/* Bitwise inclusive or of two bignums. */
+void
+APInt::tcOr(integerPart *dst, const integerPart *rhs, unsigned int parts)
+{
+ unsigned int i;
+
+ for (i = 0; i < parts; i++)
+ dst[i] |= rhs[i];
+}
+
+/* Bitwise exclusive or of two bignums. */
+void
+APInt::tcXor(integerPart *dst, const integerPart *rhs, unsigned int parts)
+{
+ unsigned int i;
+
+ for (i = 0; i < parts; i++)
+ dst[i] ^= rhs[i];
+}
+
+/* Complement a bignum in-place. */
+void
+APInt::tcComplement(integerPart *dst, unsigned int parts)
+{
+ unsigned int i;
+
+ for (i = 0; i < parts; i++)
+ dst[i] = ~dst[i];
+}
+
+/* Comparison (unsigned) of two bignums. */
+int
+APInt::tcCompare(const integerPart *lhs, const integerPart *rhs,
+ unsigned int parts)
+{
+ while (parts) {
+ parts--;
+ if (lhs[parts] == rhs[parts])
+ continue;
+
+ if (lhs[parts] > rhs[parts])
+ return 1;
+ else
+ return -1;
+ }
+
+ return 0;
+}
+
+/* Increment a bignum in-place, return the carry flag. */
+integerPart
+APInt::tcIncrement(integerPart *dst, unsigned int parts)
+{
+ unsigned int i;
+
+ for (i = 0; i < parts; i++)
+ if (++dst[i] != 0)
+ break;
+
+ return i == parts;
+}
+
+/* Decrement a bignum in-place, return the borrow flag. */
+integerPart
+APInt::tcDecrement(integerPart *dst, unsigned int parts) {
+ for (unsigned int i = 0; i < parts; i++) {
+ // If the current word is non-zero, then the decrement has no effect on the
+ // higher-order words of the integer and no borrow can occur. Exit early.
+ if (dst[i]--)
+ return 0;
+ }
+ // If every word was zero, then there is a borrow.
+ return 1;
+}
+
+
+/* Set the least significant BITS bits of a bignum, clear the
+ rest. */
+void
+APInt::tcSetLeastSignificantBits(integerPart *dst, unsigned int parts,
+ unsigned int bits)
+{
+ unsigned int i;
+
+ i = 0;
+ while (bits > integerPartWidth) {
+ dst[i++] = ~(integerPart) 0;
+ bits -= integerPartWidth;
+ }
+
+ if (bits)
+ dst[i++] = ~(integerPart) 0 >> (integerPartWidth - bits);
+
+ while (i < parts)
+ dst[i++] = 0;
+}
diff --git a/contrib/llvm/lib/Support/APSInt.cpp b/contrib/llvm/lib/Support/APSInt.cpp
new file mode 100644
index 000000000000..73acafa690c7
--- /dev/null
+++ b/contrib/llvm/lib/Support/APSInt.cpp
@@ -0,0 +1,23 @@
+//===-- llvm/ADT/APSInt.cpp - Arbitrary Precision Signed Int ---*- C++ -*--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/FoldingSet.h"
+
+using namespace llvm;
+
+void APSInt::Profile(FoldingSetNodeID& ID) const {
+ ID.AddInteger((unsigned) (IsUnsigned ? 1 : 0));
+ APInt::Profile(ID);
+}
diff --git a/contrib/llvm/lib/Support/ARMBuildAttrs.cpp b/contrib/llvm/lib/Support/ARMBuildAttrs.cpp
new file mode 100644
index 000000000000..9c8bb15dc0ae
--- /dev/null
+++ b/contrib/llvm/lib/Support/ARMBuildAttrs.cpp
@@ -0,0 +1,95 @@
+//===-- ARMBuildAttrs.cpp - ARM Build Attributes --------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/ARMBuildAttributes.h"
+#include "llvm/ADT/StringRef.h"
+
+using namespace llvm;
+
+namespace {
+const struct {
+ ARMBuildAttrs::AttrType Attr;
+ const char *TagName;
+} ARMAttributeTags[] = {
+ { ARMBuildAttrs::File, "Tag_File" },
+ { ARMBuildAttrs::Section, "Tag_Section" },
+ { ARMBuildAttrs::Symbol, "Tag_Symbol" },
+ { ARMBuildAttrs::CPU_raw_name, "Tag_CPU_raw_name" },
+ { ARMBuildAttrs::CPU_name, "Tag_CPU_name" },
+ { ARMBuildAttrs::CPU_arch, "Tag_CPU_arch" },
+ { ARMBuildAttrs::CPU_arch_profile, "Tag_CPU_arch_profile" },
+ { ARMBuildAttrs::ARM_ISA_use, "Tag_ARM_ISA_use" },
+ { ARMBuildAttrs::THUMB_ISA_use, "Tag_THUMB_ISA_use" },
+ { ARMBuildAttrs::FP_arch, "Tag_FP_arch" },
+ { ARMBuildAttrs::WMMX_arch, "Tag_WMMX_arch" },
+ { ARMBuildAttrs::Advanced_SIMD_arch, "Tag_Advanced_SIMD_arch" },
+ { ARMBuildAttrs::PCS_config, "Tag_PCS_config" },
+ { ARMBuildAttrs::ABI_PCS_R9_use, "Tag_ABI_PCS_R9_use" },
+ { ARMBuildAttrs::ABI_PCS_RW_data, "Tag_ABI_PCS_RW_data" },
+ { ARMBuildAttrs::ABI_PCS_RO_data, "Tag_ABI_PCS_RO_data" },
+ { ARMBuildAttrs::ABI_PCS_GOT_use, "Tag_ABI_PCS_GOT_use" },
+ { ARMBuildAttrs::ABI_PCS_wchar_t, "Tag_ABI_PCS_wchar_t" },
+ { ARMBuildAttrs::ABI_FP_rounding, "Tag_ABI_FP_rounding" },
+ { ARMBuildAttrs::ABI_FP_denormal, "Tag_ABI_FP_denormal" },
+ { ARMBuildAttrs::ABI_FP_exceptions, "Tag_ABI_FP_exceptions" },
+ { ARMBuildAttrs::ABI_FP_user_exceptions, "Tag_ABI_FP_user_exceptions" },
+ { ARMBuildAttrs::ABI_FP_number_model, "Tag_ABI_FP_number_model" },
+ { ARMBuildAttrs::ABI_align_needed, "Tag_ABI_align_needed" },
+ { ARMBuildAttrs::ABI_align_preserved, "Tag_ABI_align_preserved" },
+ { ARMBuildAttrs::ABI_enum_size, "Tag_ABI_enum_size" },
+ { ARMBuildAttrs::ABI_HardFP_use, "Tag_ABI_HardFP_use" },
+ { ARMBuildAttrs::ABI_VFP_args, "Tag_ABI_VFP_args" },
+ { ARMBuildAttrs::ABI_WMMX_args, "Tag_ABI_WMMX_args" },
+ { ARMBuildAttrs::ABI_optimization_goals, "Tag_ABI_optimization_goals" },
+ { ARMBuildAttrs::ABI_FP_optimization_goals, "Tag_ABI_FP_optimization_goals" },
+ { ARMBuildAttrs::compatibility, "Tag_compatibility" },
+ { ARMBuildAttrs::CPU_unaligned_access, "Tag_CPU_unaligned_access" },
+ { ARMBuildAttrs::FP_HP_extension, "Tag_FP_HP_extension" },
+ { ARMBuildAttrs::ABI_FP_16bit_format, "Tag_ABI_FP_16bit_format" },
+ { ARMBuildAttrs::MPextension_use, "Tag_MPextension_use" },
+ { ARMBuildAttrs::DIV_use, "Tag_DIV_use" },
+ { ARMBuildAttrs::nodefaults, "Tag_nodefaults" },
+ { ARMBuildAttrs::also_compatible_with, "Tag_also_compatible_with" },
+ { ARMBuildAttrs::T2EE_use, "Tag_T2EE_use" },
+ { ARMBuildAttrs::conformance, "Tag_conformance" },
+ { ARMBuildAttrs::Virtualization_use, "Tag_Virtualization_use" },
+
+ // Legacy Names
+ { ARMBuildAttrs::FP_arch, "Tag_VFP_arch" },
+ { ARMBuildAttrs::FP_HP_extension, "Tag_VFP_HP_extension" },
+ { ARMBuildAttrs::ABI_align_needed, "Tag_ABI_align8_needed" },
+ { ARMBuildAttrs::ABI_align_preserved, "Tag_ABI_align8_preserved" },
+};
+} // namespace
+
+namespace llvm {
+namespace ARMBuildAttrs {
+StringRef AttrTypeAsString(unsigned Attr, bool HasTagPrefix) {
+ return AttrTypeAsString(static_cast<AttrType>(Attr), HasTagPrefix);
+}
+
+StringRef AttrTypeAsString(AttrType Attr, bool HasTagPrefix) {
+ for (unsigned TI = 0, TE = sizeof(ARMAttributeTags) / sizeof(*ARMAttributeTags);
+ TI != TE; ++TI)
+ if (ARMAttributeTags[TI].Attr == Attr)
+ return ARMAttributeTags[TI].TagName + (HasTagPrefix ? 0 : 4);
+ return "";
+}
+
+int AttrTypeFromString(StringRef Tag) {
+ bool HasTagPrefix = Tag.startswith("Tag_");
+ for (unsigned TI = 0, TE = sizeof(ARMAttributeTags) / sizeof(*ARMAttributeTags);
+ TI != TE; ++TI)
+ if (StringRef(ARMAttributeTags[TI].TagName + (HasTagPrefix ? 0 : 4)) == Tag)
+ return ARMAttributeTags[TI].Attr;
+ return -1;
+}
+} // namespace ARMBuildAttrs
+} // namespace llvm
+
diff --git a/contrib/llvm/lib/Support/ARMWinEH.cpp b/contrib/llvm/lib/Support/ARMWinEH.cpp
new file mode 100644
index 000000000000..8d21ca5698c1
--- /dev/null
+++ b/contrib/llvm/lib/Support/ARMWinEH.cpp
@@ -0,0 +1,38 @@
+//===-- ARMWinEH.cpp - Windows on ARM EH Support Functions ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/ARMWinEH.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace llvm {
+namespace ARM {
+namespace WinEH {
+std::pair<uint16_t, uint32_t> SavedRegisterMask(const RuntimeFunction &RF) {
+ uint8_t NumRegisters = RF.Reg();
+ uint8_t RegistersVFP = RF.R();
+ uint8_t LinkRegister = RF.L();
+ uint8_t ChainedFrame = RF.C();
+
+ uint16_t GPRMask = (ChainedFrame << 11) | (LinkRegister << 14);
+ uint32_t VFPMask = 0;
+
+ if (RegistersVFP)
+ VFPMask |= (((1 << ((NumRegisters + 1) % 8)) - 1) << 8);
+ else
+ GPRMask |= (((1 << (NumRegisters + 1)) - 1) << 4);
+
+ if (PrologueFolding(RF))
+ GPRMask |= (((1 << (NumRegisters + 1)) - 1) << (~RF.StackAdjust() & 0x3));
+
+ return std::make_pair(GPRMask, VFPMask);
+}
+} // namespace WinEH
+} // namespace ARM
+} // namespace llvm
+
diff --git a/contrib/llvm/lib/Support/Allocator.cpp b/contrib/llvm/lib/Support/Allocator.cpp
new file mode 100644
index 000000000000..021037a2b3dd
--- /dev/null
+++ b/contrib/llvm/lib/Support/Allocator.cpp
@@ -0,0 +1,40 @@
+//===--- Allocator.cpp - Simple memory allocation abstraction -------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the BumpPtrAllocator interface.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace llvm {
+
+namespace detail {
+
+void printBumpPtrAllocatorStats(unsigned NumSlabs, size_t BytesAllocated,
+ size_t TotalMemory) {
+ errs() << "\nNumber of memory regions: " << NumSlabs << '\n'
+ << "Bytes used: " << BytesAllocated << '\n'
+ << "Bytes allocated: " << TotalMemory << '\n'
+ << "Bytes wasted: " << (TotalMemory - BytesAllocated)
+ << " (includes alignment, etc)\n";
+}
+
+} // End namespace detail.
+
+void PrintRecyclerStats(size_t Size,
+ size_t Align,
+ size_t FreeListSize) {
+ errs() << "Recycler element size: " << Size << '\n'
+ << "Recycler element alignment: " << Align << '\n'
+ << "Number of elements free for recycling: " << FreeListSize << '\n';
+}
+
+} // namespace llvm
diff --git a/contrib/llvm/lib/Support/Atomic.cpp b/contrib/llvm/lib/Support/Atomic.cpp
new file mode 100644
index 000000000000..ac4ff3eb5c66
--- /dev/null
+++ b/contrib/llvm/lib/Support/Atomic.cpp
@@ -0,0 +1,117 @@
+//===-- Atomic.cpp - Atomic Operations --------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements atomic operations.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/Atomic.h"
+#include "llvm/Config/llvm-config.h"
+
+using namespace llvm;
+
+#if defined(_MSC_VER)
+#include <Intrin.h>
+#include <windows.h>
+#undef MemoryFence
+#endif
+
+#if defined(__GNUC__) || (defined(__IBMCPP__) && __IBMCPP__ >= 1210)
+#define GNU_ATOMICS
+#endif
+
+void sys::MemoryFence() {
+#if LLVM_HAS_ATOMICS == 0
+ return;
+#else
+# if defined(GNU_ATOMICS)
+ __sync_synchronize();
+# elif defined(_MSC_VER)
+ MemoryBarrier();
+# else
+# error No memory fence implementation for your platform!
+# endif
+#endif
+}
+
+sys::cas_flag sys::CompareAndSwap(volatile sys::cas_flag* ptr,
+ sys::cas_flag new_value,
+ sys::cas_flag old_value) {
+#if LLVM_HAS_ATOMICS == 0
+ sys::cas_flag result = *ptr;
+ if (result == old_value)
+ *ptr = new_value;
+ return result;
+#elif defined(GNU_ATOMICS)
+ return __sync_val_compare_and_swap(ptr, old_value, new_value);
+#elif defined(_MSC_VER)
+ return InterlockedCompareExchange(ptr, new_value, old_value);
+#else
+# error No compare-and-swap implementation for your platform!
+#endif
+}
+
+sys::cas_flag sys::AtomicIncrement(volatile sys::cas_flag* ptr) {
+#if LLVM_HAS_ATOMICS == 0
+ ++(*ptr);
+ return *ptr;
+#elif defined(GNU_ATOMICS)
+ return __sync_add_and_fetch(ptr, 1);
+#elif defined(_MSC_VER)
+ return InterlockedIncrement(ptr);
+#else
+# error No atomic increment implementation for your platform!
+#endif
+}
+
+sys::cas_flag sys::AtomicDecrement(volatile sys::cas_flag* ptr) {
+#if LLVM_HAS_ATOMICS == 0
+ --(*ptr);
+ return *ptr;
+#elif defined(GNU_ATOMICS)
+ return __sync_sub_and_fetch(ptr, 1);
+#elif defined(_MSC_VER)
+ return InterlockedDecrement(ptr);
+#else
+# error No atomic decrement implementation for your platform!
+#endif
+}
+
+sys::cas_flag sys::AtomicAdd(volatile sys::cas_flag* ptr, sys::cas_flag val) {
+#if LLVM_HAS_ATOMICS == 0
+ *ptr += val;
+ return *ptr;
+#elif defined(GNU_ATOMICS)
+ return __sync_add_and_fetch(ptr, val);
+#elif defined(_MSC_VER)
+ return InterlockedExchangeAdd(ptr, val) + val;
+#else
+# error No atomic add implementation for your platform!
+#endif
+}
+
+sys::cas_flag sys::AtomicMul(volatile sys::cas_flag* ptr, sys::cas_flag val) {
+ sys::cas_flag original, result;
+ do {
+ original = *ptr;
+ result = original * val;
+ } while (sys::CompareAndSwap(ptr, result, original) != original);
+
+ return result;
+}
+
+sys::cas_flag sys::AtomicDiv(volatile sys::cas_flag* ptr, sys::cas_flag val) {
+ sys::cas_flag original, result;
+ do {
+ original = *ptr;
+ result = original / val;
+ } while (sys::CompareAndSwap(ptr, result, original) != original);
+
+ return result;
+}
diff --git a/contrib/llvm/lib/Support/BlockFrequency.cpp b/contrib/llvm/lib/Support/BlockFrequency.cpp
new file mode 100644
index 000000000000..6f7e341904b9
--- /dev/null
+++ b/contrib/llvm/lib/Support/BlockFrequency.cpp
@@ -0,0 +1,72 @@
+//====--------------- lib/Support/BlockFrequency.cpp -----------*- C++ -*-====//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements Block Frequency class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/BranchProbability.h"
+#include "llvm/Support/BlockFrequency.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cassert>
+
+using namespace llvm;
+
+BlockFrequency &BlockFrequency::operator*=(const BranchProbability &Prob) {
+ Frequency = Prob.scale(Frequency);
+ return *this;
+}
+
+const BlockFrequency
+BlockFrequency::operator*(const BranchProbability &Prob) const {
+ BlockFrequency Freq(Frequency);
+ Freq *= Prob;
+ return Freq;
+}
+
+BlockFrequency &BlockFrequency::operator/=(const BranchProbability &Prob) {
+ Frequency = Prob.scaleByInverse(Frequency);
+ return *this;
+}
+
+BlockFrequency BlockFrequency::operator/(const BranchProbability &Prob) const {
+ BlockFrequency Freq(Frequency);
+ Freq /= Prob;
+ return Freq;
+}
+
+BlockFrequency &BlockFrequency::operator+=(const BlockFrequency &Freq) {
+ uint64_t Before = Freq.Frequency;
+ Frequency += Freq.Frequency;
+
+ // If overflow, set frequency to the maximum value.
+ if (Frequency < Before)
+ Frequency = UINT64_MAX;
+
+ return *this;
+}
+
+const BlockFrequency
+BlockFrequency::operator+(const BlockFrequency &Prob) const {
+ BlockFrequency Freq(Frequency);
+ Freq += Prob;
+ return Freq;
+}
+
+BlockFrequency &BlockFrequency::operator>>=(const unsigned count) {
+ // Frequency can never be 0 by design.
+ assert(Frequency != 0);
+
+ // Shift right by count.
+ Frequency >>= count;
+
+ // Saturate to 1 if we are 0.
+ Frequency |= Frequency == 0;
+ return *this;
+}
diff --git a/contrib/llvm/lib/Support/BranchProbability.cpp b/contrib/llvm/lib/Support/BranchProbability.cpp
new file mode 100644
index 000000000000..65878d6e3025
--- /dev/null
+++ b/contrib/llvm/lib/Support/BranchProbability.cpp
@@ -0,0 +1,73 @@
+//===-------------- lib/Support/BranchProbability.cpp -----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements Branch Probability class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/BranchProbability.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace llvm;
+
+raw_ostream &BranchProbability::print(raw_ostream &OS) const {
+ return OS << N << " / " << D << " = "
+ << format("%g%%", ((double)N / D) * 100.0);
+}
+
+void BranchProbability::dump() const { print(dbgs()) << '\n'; }
+
+static uint64_t scale(uint64_t Num, uint32_t N, uint32_t D) {
+ assert(D && "divide by 0");
+
+ // Fast path for multiplying by 1.0.
+ if (!Num || D == N)
+ return Num;
+
+ // Split Num into upper and lower parts to multiply, then recombine.
+ uint64_t ProductHigh = (Num >> 32) * N;
+ uint64_t ProductLow = (Num & UINT32_MAX) * N;
+
+ // Split into 32-bit digits.
+ uint32_t Upper32 = ProductHigh >> 32;
+ uint32_t Lower32 = ProductLow & UINT32_MAX;
+ uint32_t Mid32Partial = ProductHigh & UINT32_MAX;
+ uint32_t Mid32 = Mid32Partial + (ProductLow >> 32);
+
+ // Carry.
+ Upper32 += Mid32 < Mid32Partial;
+
+ // Check for overflow.
+ if (Upper32 >= D)
+ return UINT64_MAX;
+
+ uint64_t Rem = (uint64_t(Upper32) << 32) | Mid32;
+ uint64_t UpperQ = Rem / D;
+
+ // Check for overflow.
+ if (UpperQ > UINT32_MAX)
+ return UINT64_MAX;
+
+ Rem = ((Rem % D) << 32) | Lower32;
+ uint64_t LowerQ = Rem / D;
+ uint64_t Q = (UpperQ << 32) + LowerQ;
+
+ // Check for overflow.
+ return Q < LowerQ ? UINT64_MAX : Q;
+}
+
+uint64_t BranchProbability::scale(uint64_t Num) const {
+ return ::scale(Num, N, D);
+}
+
+uint64_t BranchProbability::scaleByInverse(uint64_t Num) const {
+ return ::scale(Num, D, N);
+}
diff --git a/contrib/llvm/lib/Support/COM.cpp b/contrib/llvm/lib/Support/COM.cpp
new file mode 100644
index 000000000000..cf3a133fd9b4
--- /dev/null
+++ b/contrib/llvm/lib/Support/COM.cpp
@@ -0,0 +1,23 @@
+//===-- COM.cpp - Implement COM utility classes -----------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements utility classes related to COM.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/COM.h"
+
+#include "llvm/Config/config.h"
+
+// Include the platform-specific parts of this class.
+#ifdef LLVM_ON_UNIX
+#include "Unix/COM.inc"
+#elif LLVM_ON_WIN32
+#include "Windows/COM.inc"
+#endif
diff --git a/contrib/llvm/lib/Support/COPYRIGHT.regex b/contrib/llvm/lib/Support/COPYRIGHT.regex
new file mode 100644
index 000000000000..a6392fd37c3d
--- /dev/null
+++ b/contrib/llvm/lib/Support/COPYRIGHT.regex
@@ -0,0 +1,54 @@
+$OpenBSD: COPYRIGHT,v 1.3 2003/06/02 20:18:36 millert Exp $
+
+Copyright 1992, 1993, 1994 Henry Spencer. All rights reserved.
+This software is not subject to any license of the American Telephone
+and Telegraph Company or of the Regents of the University of California.
+
+Permission is granted to anyone to use this software for any purpose on
+any computer system, and to alter it and redistribute it, subject
+to the following restrictions:
+
+1. The author is not responsible for the consequences of use of this
+ software, no matter how awful, even if they arise from flaws in it.
+
+2. The origin of this software must not be misrepresented, either by
+ explicit claim or by omission. Since few users ever read sources,
+ credits must appear in the documentation.
+
+3. Altered versions must be plainly marked as such, and must not be
+ misrepresented as being the original software. Since few users
+ ever read sources, credits must appear in the documentation.
+
+4. This notice may not be removed or altered.
+
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+/*-
+ * Copyright (c) 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)COPYRIGHT 8.1 (Berkeley) 3/16/94
+ */
diff --git a/contrib/llvm/lib/Support/CommandLine.cpp b/contrib/llvm/lib/Support/CommandLine.cpp
new file mode 100644
index 000000000000..3638f0df5e2d
--- /dev/null
+++ b/contrib/llvm/lib/Support/CommandLine.cpp
@@ -0,0 +1,1858 @@
+//===-- CommandLine.cpp - Command line parser implementation --------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file 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 could try
+// reading the library documentation located in docs/CommandLine.html
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/CommandLine.h"
+#include "llvm-c/Support.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Config/config.h"
+#include "llvm/Support/ConvertUTF.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/Host.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/StringSaver.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cstdlib>
+#include <map>
+using namespace llvm;
+using namespace cl;
+
+#define DEBUG_TYPE "commandline"
+
+//===----------------------------------------------------------------------===//
+// Template instantiations and anchors.
+//
+namespace llvm {
+namespace cl {
+TEMPLATE_INSTANTIATION(class basic_parser<bool>);
+TEMPLATE_INSTANTIATION(class basic_parser<boolOrDefault>);
+TEMPLATE_INSTANTIATION(class basic_parser<int>);
+TEMPLATE_INSTANTIATION(class basic_parser<unsigned>);
+TEMPLATE_INSTANTIATION(class basic_parser<unsigned long long>);
+TEMPLATE_INSTANTIATION(class basic_parser<double>);
+TEMPLATE_INSTANTIATION(class basic_parser<float>);
+TEMPLATE_INSTANTIATION(class basic_parser<std::string>);
+TEMPLATE_INSTANTIATION(class basic_parser<char>);
+
+TEMPLATE_INSTANTIATION(class opt<unsigned>);
+TEMPLATE_INSTANTIATION(class opt<int>);
+TEMPLATE_INSTANTIATION(class opt<std::string>);
+TEMPLATE_INSTANTIATION(class opt<char>);
+TEMPLATE_INSTANTIATION(class opt<bool>);
+} // namespace cl
+} // namespace llvm
+
+// Pin the vtables to this file.
+void GenericOptionValue::anchor() {}
+void OptionValue<boolOrDefault>::anchor() {}
+void OptionValue<std::string>::anchor() {}
+void Option::anchor() {}
+void basic_parser_impl::anchor() {}
+void parser<bool>::anchor() {}
+void parser<boolOrDefault>::anchor() {}
+void parser<int>::anchor() {}
+void parser<unsigned>::anchor() {}
+void parser<unsigned long long>::anchor() {}
+void parser<double>::anchor() {}
+void parser<float>::anchor() {}
+void parser<std::string>::anchor() {}
+void parser<char>::anchor() {}
+
+//===----------------------------------------------------------------------===//
+
+namespace {
+
+class CommandLineParser {
+public:
+ // Globals for name and overview of program. Program name is not a string to
+ // avoid static ctor/dtor issues.
+ std::string ProgramName;
+ const char *ProgramOverview;
+
+ // This collects additional help to be printed.
+ std::vector<const char *> MoreHelp;
+
+ SmallVector<Option *, 4> PositionalOpts;
+ SmallVector<Option *, 4> SinkOpts;
+ StringMap<Option *> OptionsMap;
+
+ Option *ConsumeAfterOpt; // The ConsumeAfter option if it exists.
+
+ // This collects the different option categories that have been registered.
+ SmallPtrSet<OptionCategory *, 16> RegisteredOptionCategories;
+
+ CommandLineParser() : ProgramOverview(nullptr), ConsumeAfterOpt(nullptr) {}
+
+ void ParseCommandLineOptions(int argc, const char *const *argv,
+ const char *Overview);
+
+ void addLiteralOption(Option &Opt, const char *Name) {
+ if (!Opt.hasArgStr()) {
+ if (!OptionsMap.insert(std::make_pair(Name, &Opt)).second) {
+ errs() << ProgramName << ": CommandLine Error: Option '" << Name
+ << "' registered more than once!\n";
+ report_fatal_error("inconsistency in registered CommandLine options");
+ }
+ }
+ }
+
+ void addOption(Option *O) {
+ bool HadErrors = false;
+ if (O->ArgStr[0]) {
+ // Add argument to the argument map!
+ if (!OptionsMap.insert(std::make_pair(O->ArgStr, O)).second) {
+ errs() << ProgramName << ": CommandLine Error: Option '" << O->ArgStr
+ << "' registered more than once!\n";
+ HadErrors = true;
+ }
+ }
+
+ // Remember information about positional options.
+ if (O->getFormattingFlag() == cl::Positional)
+ PositionalOpts.push_back(O);
+ else if (O->getMiscFlags() & cl::Sink) // Remember sink options
+ SinkOpts.push_back(O);
+ else if (O->getNumOccurrencesFlag() == cl::ConsumeAfter) {
+ if (ConsumeAfterOpt) {
+ O->error("Cannot specify more than one option with cl::ConsumeAfter!");
+ HadErrors = true;
+ }
+ ConsumeAfterOpt = O;
+ }
+
+ // Fail hard if there were errors. These are strictly unrecoverable and
+ // indicate serious issues such as conflicting option names or an
+ // incorrectly
+ // linked LLVM distribution.
+ if (HadErrors)
+ report_fatal_error("inconsistency in registered CommandLine options");
+ }
+
+ void removeOption(Option *O) {
+ SmallVector<const char *, 16> OptionNames;
+ O->getExtraOptionNames(OptionNames);
+ if (O->ArgStr[0])
+ OptionNames.push_back(O->ArgStr);
+ for (auto Name : OptionNames)
+ OptionsMap.erase(StringRef(Name));
+
+ if (O->getFormattingFlag() == cl::Positional)
+ for (auto Opt = PositionalOpts.begin(); Opt != PositionalOpts.end();
+ ++Opt) {
+ if (*Opt == O) {
+ PositionalOpts.erase(Opt);
+ break;
+ }
+ }
+ else if (O->getMiscFlags() & cl::Sink)
+ for (auto Opt = SinkOpts.begin(); Opt != SinkOpts.end(); ++Opt) {
+ if (*Opt == O) {
+ SinkOpts.erase(Opt);
+ break;
+ }
+ }
+ else if (O == ConsumeAfterOpt)
+ ConsumeAfterOpt = nullptr;
+ }
+
+ bool hasOptions() {
+ return (!OptionsMap.empty() || !PositionalOpts.empty() ||
+ nullptr != ConsumeAfterOpt);
+ }
+
+ void updateArgStr(Option *O, const char *NewName) {
+ if (!OptionsMap.insert(std::make_pair(NewName, O)).second) {
+ errs() << ProgramName << ": CommandLine Error: Option '" << O->ArgStr
+ << "' registered more than once!\n";
+ report_fatal_error("inconsistency in registered CommandLine options");
+ }
+ OptionsMap.erase(StringRef(O->ArgStr));
+ }
+
+ void printOptionValues();
+
+ void registerCategory(OptionCategory *cat) {
+ assert(std::count_if(RegisteredOptionCategories.begin(),
+ RegisteredOptionCategories.end(),
+ [cat](const OptionCategory *Category) {
+ return cat->getName() == Category->getName();
+ }) == 0 &&
+ "Duplicate option categories");
+
+ RegisteredOptionCategories.insert(cat);
+ }
+
+private:
+ Option *LookupOption(StringRef &Arg, StringRef &Value);
+};
+
+} // namespace
+
+static ManagedStatic<CommandLineParser> GlobalParser;
+
+void cl::AddLiteralOption(Option &O, const char *Name) {
+ GlobalParser->addLiteralOption(O, Name);
+}
+
+extrahelp::extrahelp(const char *Help) : morehelp(Help) {
+ GlobalParser->MoreHelp.push_back(Help);
+}
+
+void Option::addArgument() {
+ GlobalParser->addOption(this);
+ FullyInitialized = true;
+}
+
+void Option::removeArgument() { GlobalParser->removeOption(this); }
+
+void Option::setArgStr(const char *S) {
+ if (FullyInitialized)
+ GlobalParser->updateArgStr(this, S);
+ ArgStr = S;
+}
+
+// Initialise the general option category.
+OptionCategory llvm::cl::GeneralCategory("General options");
+
+void OptionCategory::registerCategory() {
+ GlobalParser->registerCategory(this);
+}
+
+//===----------------------------------------------------------------------===//
+// Basic, shared command line option processing machinery.
+//
+
+/// LookupOption - Lookup the option specified by the specified option on the
+/// command line. If there is a value specified (after an equal sign) return
+/// that as well. This assumes that leading dashes have already been stripped.
+Option *CommandLineParser::LookupOption(StringRef &Arg, StringRef &Value) {
+ // Reject all dashes.
+ if (Arg.empty())
+ return nullptr;
+
+ size_t EqualPos = Arg.find('=');
+
+ // If we have an equals sign, remember the value.
+ if (EqualPos == StringRef::npos) {
+ // Look up the option.
+ StringMap<Option *>::const_iterator I = OptionsMap.find(Arg);
+ return I != OptionsMap.end() ? I->second : nullptr;
+ }
+
+ // If the argument before the = is a valid option name, we match. If not,
+ // return Arg unmolested.
+ StringMap<Option *>::const_iterator I =
+ OptionsMap.find(Arg.substr(0, EqualPos));
+ if (I == OptionsMap.end())
+ return nullptr;
+
+ Value = Arg.substr(EqualPos + 1);
+ Arg = Arg.substr(0, EqualPos);
+ return I->second;
+}
+
+/// LookupNearestOption - Lookup the closest match to the option specified by
+/// the specified option on the command line. If there is a value specified
+/// (after an equal sign) return that as well. This assumes that leading dashes
+/// have already been stripped.
+static Option *LookupNearestOption(StringRef Arg,
+ const StringMap<Option *> &OptionsMap,
+ std::string &NearestString) {
+ // Reject all dashes.
+ if (Arg.empty())
+ return nullptr;
+
+ // Split on any equal sign.
+ std::pair<StringRef, StringRef> SplitArg = Arg.split('=');
+ StringRef &LHS = SplitArg.first; // LHS == Arg when no '=' is present.
+ StringRef &RHS = SplitArg.second;
+
+ // Find the closest match.
+ Option *Best = nullptr;
+ unsigned BestDistance = 0;
+ for (StringMap<Option *>::const_iterator it = OptionsMap.begin(),
+ ie = OptionsMap.end();
+ it != ie; ++it) {
+ Option *O = it->second;
+ SmallVector<const char *, 16> OptionNames;
+ O->getExtraOptionNames(OptionNames);
+ if (O->ArgStr[0])
+ OptionNames.push_back(O->ArgStr);
+
+ bool PermitValue = O->getValueExpectedFlag() != cl::ValueDisallowed;
+ StringRef Flag = PermitValue ? LHS : Arg;
+ for (size_t i = 0, e = OptionNames.size(); i != e; ++i) {
+ StringRef Name = OptionNames[i];
+ unsigned Distance = StringRef(Name).edit_distance(
+ Flag, /*AllowReplacements=*/true, /*MaxEditDistance=*/BestDistance);
+ if (!Best || Distance < BestDistance) {
+ Best = O;
+ BestDistance = Distance;
+ if (RHS.empty() || !PermitValue)
+ NearestString = OptionNames[i];
+ else
+ NearestString = (Twine(OptionNames[i]) + "=" + RHS).str();
+ }
+ }
+ }
+
+ return Best;
+}
+
+/// CommaSeparateAndAddOccurrence - A wrapper around Handler->addOccurrence()
+/// that does special handling of cl::CommaSeparated options.
+static bool CommaSeparateAndAddOccurrence(Option *Handler, unsigned pos,
+ StringRef ArgName, StringRef Value,
+ bool MultiArg = false) {
+ // Check to see if this option accepts a comma separated list of values. If
+ // it does, we have to split up the value into multiple values.
+ if (Handler->getMiscFlags() & CommaSeparated) {
+ StringRef Val(Value);
+ StringRef::size_type Pos = Val.find(',');
+
+ while (Pos != StringRef::npos) {
+ // Process the portion before the comma.
+ if (Handler->addOccurrence(pos, ArgName, Val.substr(0, Pos), MultiArg))
+ return true;
+ // Erase the portion before the comma, AND the comma.
+ Val = Val.substr(Pos + 1);
+ Value.substr(Pos + 1); // Increment the original value pointer as well.
+ // Check for another comma.
+ Pos = Val.find(',');
+ }
+
+ Value = Val;
+ }
+
+ if (Handler->addOccurrence(pos, ArgName, Value, MultiArg))
+ return true;
+
+ return false;
+}
+
+/// ProvideOption - For Value, this differentiates between an empty value ("")
+/// and a null value (StringRef()). The later is accepted for arguments that
+/// don't allow a value (-foo) the former is rejected (-foo=).
+static inline bool ProvideOption(Option *Handler, StringRef ArgName,
+ StringRef Value, int argc,
+ const char *const *argv, int &i) {
+ // Is this a multi-argument option?
+ unsigned NumAdditionalVals = Handler->getNumAdditionalVals();
+
+ // Enforce value requirements
+ switch (Handler->getValueExpectedFlag()) {
+ case ValueRequired:
+ if (!Value.data()) { // No value specified?
+ if (i + 1 >= argc)
+ return Handler->error("requires a value!");
+ // Steal the next argument, like for '-o filename'
+ assert(argv && "null check");
+ Value = argv[++i];
+ }
+ break;
+ case ValueDisallowed:
+ if (NumAdditionalVals > 0)
+ return Handler->error("multi-valued option specified"
+ " with ValueDisallowed modifier!");
+
+ if (Value.data())
+ return Handler->error("does not allow a value! '" + Twine(Value) +
+ "' specified.");
+ break;
+ case ValueOptional:
+ break;
+ }
+
+ // If this isn't a multi-arg option, just run the handler.
+ if (NumAdditionalVals == 0)
+ return CommaSeparateAndAddOccurrence(Handler, i, ArgName, Value);
+
+ // If it is, run the handle several times.
+ bool MultiArg = false;
+
+ if (Value.data()) {
+ if (CommaSeparateAndAddOccurrence(Handler, i, ArgName, Value, MultiArg))
+ return true;
+ --NumAdditionalVals;
+ MultiArg = true;
+ }
+
+ while (NumAdditionalVals > 0) {
+ if (i + 1 >= argc)
+ return Handler->error("not enough values!");
+ assert(argv && "null check");
+ Value = argv[++i];
+
+ if (CommaSeparateAndAddOccurrence(Handler, i, ArgName, Value, MultiArg))
+ return true;
+ MultiArg = true;
+ --NumAdditionalVals;
+ }
+ return false;
+}
+
+static bool ProvidePositionalOption(Option *Handler, StringRef Arg, int i) {
+ int Dummy = i;
+ return ProvideOption(Handler, Handler->ArgStr, Arg, 0, nullptr, Dummy);
+}
+
+// Option predicates...
+static inline bool isGrouping(const Option *O) {
+ return O->getFormattingFlag() == cl::Grouping;
+}
+static inline bool isPrefixedOrGrouping(const Option *O) {
+ return isGrouping(O) || O->getFormattingFlag() == cl::Prefix;
+}
+
+// getOptionPred - Check to see if there are any options that satisfy the
+// specified predicate with names that are the prefixes in Name. This is
+// checked by progressively stripping characters off of the name, checking to
+// see if there options that satisfy the predicate. If we find one, return it,
+// otherwise return null.
+//
+static Option *getOptionPred(StringRef Name, size_t &Length,
+ bool (*Pred)(const Option *),
+ const StringMap<Option *> &OptionsMap) {
+
+ StringMap<Option *>::const_iterator OMI = OptionsMap.find(Name);
+
+ // Loop while we haven't found an option and Name still has at least two
+ // characters in it (so that the next iteration will not be the empty
+ // string.
+ while (OMI == OptionsMap.end() && Name.size() > 1) {
+ Name = Name.substr(0, Name.size() - 1); // Chop off the last character.
+ OMI = OptionsMap.find(Name);
+ }
+
+ if (OMI != OptionsMap.end() && Pred(OMI->second)) {
+ Length = Name.size();
+ return OMI->second; // Found one!
+ }
+ return nullptr; // No option found!
+}
+
+/// HandlePrefixedOrGroupedOption - The specified argument string (which started
+/// with at least one '-') does not fully match an available option. Check to
+/// see if this is a prefix or grouped option. If so, split arg into output an
+/// Arg/Value pair and return the Option to parse it with.
+static Option *
+HandlePrefixedOrGroupedOption(StringRef &Arg, StringRef &Value,
+ bool &ErrorParsing,
+ const StringMap<Option *> &OptionsMap) {
+ if (Arg.size() == 1)
+ return nullptr;
+
+ // Do the lookup!
+ size_t Length = 0;
+ Option *PGOpt = getOptionPred(Arg, Length, isPrefixedOrGrouping, OptionsMap);
+ if (!PGOpt)
+ return nullptr;
+
+ // If the option is a prefixed option, then the value is simply the
+ // rest of the name... so fall through to later processing, by
+ // setting up the argument name flags and value fields.
+ if (PGOpt->getFormattingFlag() == cl::Prefix) {
+ Value = Arg.substr(Length);
+ Arg = Arg.substr(0, Length);
+ assert(OptionsMap.count(Arg) && OptionsMap.find(Arg)->second == PGOpt);
+ return PGOpt;
+ }
+
+ // This must be a grouped option... handle them now. Grouping options can't
+ // have values.
+ assert(isGrouping(PGOpt) && "Broken getOptionPred!");
+
+ do {
+ // Move current arg name out of Arg into OneArgName.
+ StringRef OneArgName = Arg.substr(0, Length);
+ Arg = Arg.substr(Length);
+
+ // Because ValueRequired is an invalid flag for grouped arguments,
+ // we don't need to pass argc/argv in.
+ assert(PGOpt->getValueExpectedFlag() != cl::ValueRequired &&
+ "Option can not be cl::Grouping AND cl::ValueRequired!");
+ int Dummy = 0;
+ ErrorParsing |=
+ ProvideOption(PGOpt, OneArgName, StringRef(), 0, nullptr, Dummy);
+
+ // Get the next grouping option.
+ PGOpt = getOptionPred(Arg, Length, isGrouping, OptionsMap);
+ } while (PGOpt && Length != Arg.size());
+
+ // Return the last option with Arg cut down to just the last one.
+ return PGOpt;
+}
+
+static bool RequiresValue(const Option *O) {
+ return O->getNumOccurrencesFlag() == cl::Required ||
+ O->getNumOccurrencesFlag() == cl::OneOrMore;
+}
+
+static bool EatsUnboundedNumberOfValues(const Option *O) {
+ return O->getNumOccurrencesFlag() == cl::ZeroOrMore ||
+ O->getNumOccurrencesFlag() == cl::OneOrMore;
+}
+
+static bool isWhitespace(char C) { return strchr(" \t\n\r\f\v", C); }
+
+static bool isQuote(char C) { return C == '\"' || C == '\''; }
+
+static bool isGNUSpecial(char C) { return strchr("\\\"\' ", C); }
+
+void cl::TokenizeGNUCommandLine(StringRef Src, StringSaver &Saver,
+ SmallVectorImpl<const char *> &NewArgv,
+ bool MarkEOLs) {
+ SmallString<128> Token;
+ for (size_t I = 0, E = Src.size(); I != E; ++I) {
+ // Consume runs of whitespace.
+ if (Token.empty()) {
+ while (I != E && isWhitespace(Src[I])) {
+ // Mark the end of lines in response files
+ if (MarkEOLs && Src[I] == '\n')
+ NewArgv.push_back(nullptr);
+ ++I;
+ }
+ if (I == E)
+ break;
+ }
+
+ // Backslashes can escape backslashes, spaces, and other quotes. Otherwise
+ // they are literal. This makes it much easier to read Windows file paths.
+ if (I + 1 < E && Src[I] == '\\' && isGNUSpecial(Src[I + 1])) {
+ ++I; // Skip the escape.
+ Token.push_back(Src[I]);
+ continue;
+ }
+
+ // Consume a quoted string.
+ if (isQuote(Src[I])) {
+ char Quote = Src[I++];
+ while (I != E && Src[I] != Quote) {
+ // Backslashes are literal, unless they escape a special character.
+ if (Src[I] == '\\' && I + 1 != E && isGNUSpecial(Src[I + 1]))
+ ++I;
+ Token.push_back(Src[I]);
+ ++I;
+ }
+ if (I == E)
+ break;
+ continue;
+ }
+
+ // End the token if this is whitespace.
+ if (isWhitespace(Src[I])) {
+ if (!Token.empty())
+ NewArgv.push_back(Saver.save(Token.c_str()));
+ Token.clear();
+ continue;
+ }
+
+ // This is a normal character. Append it.
+ Token.push_back(Src[I]);
+ }
+
+ // Append the last token after hitting EOF with no whitespace.
+ if (!Token.empty())
+ NewArgv.push_back(Saver.save(Token.c_str()));
+ // Mark the end of response files
+ if (MarkEOLs)
+ NewArgv.push_back(nullptr);
+}
+
+/// Backslashes are interpreted in a rather complicated way in the Windows-style
+/// command line, because backslashes are used both to separate path and to
+/// escape double quote. This method consumes runs of backslashes as well as the
+/// following double quote if it's escaped.
+///
+/// * If an even number of backslashes is followed by a double quote, one
+/// backslash is output for every pair of backslashes, and the last double
+/// quote remains unconsumed. The double quote will later be interpreted as
+/// the start or end of a quoted string in the main loop outside of this
+/// function.
+///
+/// * If an odd number of backslashes is followed by a double quote, one
+/// backslash is output for every pair of backslashes, and a double quote is
+/// output for the last pair of backslash-double quote. The double quote is
+/// consumed in this case.
+///
+/// * Otherwise, backslashes are interpreted literally.
+static size_t parseBackslash(StringRef Src, size_t I, SmallString<128> &Token) {
+ size_t E = Src.size();
+ int BackslashCount = 0;
+ // Skip the backslashes.
+ do {
+ ++I;
+ ++BackslashCount;
+ } while (I != E && Src[I] == '\\');
+
+ bool FollowedByDoubleQuote = (I != E && Src[I] == '"');
+ if (FollowedByDoubleQuote) {
+ Token.append(BackslashCount / 2, '\\');
+ if (BackslashCount % 2 == 0)
+ return I - 1;
+ Token.push_back('"');
+ return I;
+ }
+ Token.append(BackslashCount, '\\');
+ return I - 1;
+}
+
+void cl::TokenizeWindowsCommandLine(StringRef Src, StringSaver &Saver,
+ SmallVectorImpl<const char *> &NewArgv,
+ bool MarkEOLs) {
+ SmallString<128> Token;
+
+ // This is a small state machine to consume characters until it reaches the
+ // end of the source string.
+ enum { INIT, UNQUOTED, QUOTED } State = INIT;
+ for (size_t I = 0, E = Src.size(); I != E; ++I) {
+ // INIT state indicates that the current input index is at the start of
+ // the string or between tokens.
+ if (State == INIT) {
+ if (isWhitespace(Src[I])) {
+ // Mark the end of lines in response files
+ if (MarkEOLs && Src[I] == '\n')
+ NewArgv.push_back(nullptr);
+ continue;
+ }
+ if (Src[I] == '"') {
+ State = QUOTED;
+ continue;
+ }
+ if (Src[I] == '\\') {
+ I = parseBackslash(Src, I, Token);
+ State = UNQUOTED;
+ continue;
+ }
+ Token.push_back(Src[I]);
+ State = UNQUOTED;
+ continue;
+ }
+
+ // UNQUOTED state means that it's reading a token not quoted by double
+ // quotes.
+ if (State == UNQUOTED) {
+ // Whitespace means the end of the token.
+ if (isWhitespace(Src[I])) {
+ NewArgv.push_back(Saver.save(Token.c_str()));
+ Token.clear();
+ State = INIT;
+ // Mark the end of lines in response files
+ if (MarkEOLs && Src[I] == '\n')
+ NewArgv.push_back(nullptr);
+ continue;
+ }
+ if (Src[I] == '"') {
+ State = QUOTED;
+ continue;
+ }
+ if (Src[I] == '\\') {
+ I = parseBackslash(Src, I, Token);
+ continue;
+ }
+ Token.push_back(Src[I]);
+ continue;
+ }
+
+ // QUOTED state means that it's reading a token quoted by double quotes.
+ if (State == QUOTED) {
+ if (Src[I] == '"') {
+ State = UNQUOTED;
+ continue;
+ }
+ if (Src[I] == '\\') {
+ I = parseBackslash(Src, I, Token);
+ continue;
+ }
+ Token.push_back(Src[I]);
+ }
+ }
+ // Append the last token after hitting EOF with no whitespace.
+ if (!Token.empty())
+ NewArgv.push_back(Saver.save(Token.c_str()));
+ // Mark the end of response files
+ if (MarkEOLs)
+ NewArgv.push_back(nullptr);
+}
+
+// It is called byte order marker but the UTF-8 BOM is actually not affected
+// by the host system's endianness.
+static bool hasUTF8ByteOrderMark(ArrayRef<char> S) {
+ return (S.size() >= 3 && S[0] == '\xef' && S[1] == '\xbb' && S[2] == '\xbf');
+}
+
+static bool ExpandResponseFile(const char *FName, StringSaver &Saver,
+ TokenizerCallback Tokenizer,
+ SmallVectorImpl<const char *> &NewArgv,
+ bool MarkEOLs = false) {
+ ErrorOr<std::unique_ptr<MemoryBuffer>> MemBufOrErr =
+ MemoryBuffer::getFile(FName);
+ if (!MemBufOrErr)
+ return false;
+ MemoryBuffer &MemBuf = *MemBufOrErr.get();
+ StringRef Str(MemBuf.getBufferStart(), MemBuf.getBufferSize());
+
+ // If we have a UTF-16 byte order mark, convert to UTF-8 for parsing.
+ ArrayRef<char> BufRef(MemBuf.getBufferStart(), MemBuf.getBufferEnd());
+ std::string UTF8Buf;
+ if (hasUTF16ByteOrderMark(BufRef)) {
+ if (!convertUTF16ToUTF8String(BufRef, UTF8Buf))
+ return false;
+ Str = StringRef(UTF8Buf);
+ }
+ // If we see UTF-8 BOM sequence at the beginning of a file, we shall remove
+ // these bytes before parsing.
+ // Reference: http://en.wikipedia.org/wiki/UTF-8#Byte_order_mark
+ else if (hasUTF8ByteOrderMark(BufRef))
+ Str = StringRef(BufRef.data() + 3, BufRef.size() - 3);
+
+ // Tokenize the contents into NewArgv.
+ Tokenizer(Str, Saver, NewArgv, MarkEOLs);
+
+ return true;
+}
+
+/// \brief Expand response files on a command line recursively using the given
+/// StringSaver and tokenization strategy.
+bool cl::ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer,
+ SmallVectorImpl<const char *> &Argv,
+ bool MarkEOLs) {
+ unsigned RspFiles = 0;
+ bool AllExpanded = true;
+
+ // Don't cache Argv.size() because it can change.
+ for (unsigned I = 0; I != Argv.size();) {
+ const char *Arg = Argv[I];
+ // Check if it is an EOL marker
+ if (Arg == nullptr) {
+ ++I;
+ continue;
+ }
+ if (Arg[0] != '@') {
+ ++I;
+ continue;
+ }
+
+ // If we have too many response files, leave some unexpanded. This avoids
+ // crashing on self-referential response files.
+ if (RspFiles++ > 20)
+ return false;
+
+ // Replace this response file argument with the tokenization of its
+ // contents. Nested response files are expanded in subsequent iterations.
+ // FIXME: If a nested response file uses a relative path, is it relative to
+ // the cwd of the process or the response file?
+ SmallVector<const char *, 0> ExpandedArgv;
+ if (!ExpandResponseFile(Arg + 1, Saver, Tokenizer, ExpandedArgv,
+ MarkEOLs)) {
+ // We couldn't read this file, so we leave it in the argument stream and
+ // move on.
+ AllExpanded = false;
+ ++I;
+ continue;
+ }
+ Argv.erase(Argv.begin() + I);
+ Argv.insert(Argv.begin() + I, ExpandedArgv.begin(), ExpandedArgv.end());
+ }
+ return AllExpanded;
+}
+
+/// ParseEnvironmentOptions - An alternative entry point to the
+/// CommandLine library, which allows you to read the program's name
+/// from the caller (as PROGNAME) and its command-line arguments from
+/// an environment variable (whose name is given in ENVVAR).
+///
+void cl::ParseEnvironmentOptions(const char *progName, const char *envVar,
+ const char *Overview) {
+ // Check args.
+ assert(progName && "Program name not specified");
+ assert(envVar && "Environment variable name missing");
+
+ // Get the environment variable they want us to parse options out of.
+ const char *envValue = getenv(envVar);
+ if (!envValue)
+ return;
+
+ // Get program's "name", which we wouldn't know without the caller
+ // telling us.
+ SmallVector<const char *, 20> newArgv;
+ BumpPtrAllocator A;
+ BumpPtrStringSaver Saver(A);
+ newArgv.push_back(Saver.save(progName));
+
+ // Parse the value of the environment variable into a "command line"
+ // and hand it off to ParseCommandLineOptions().
+ TokenizeGNUCommandLine(envValue, Saver, newArgv);
+ int newArgc = static_cast<int>(newArgv.size());
+ ParseCommandLineOptions(newArgc, &newArgv[0], Overview);
+}
+
+void cl::ParseCommandLineOptions(int argc, const char *const *argv,
+ const char *Overview) {
+ GlobalParser->ParseCommandLineOptions(argc, argv, Overview);
+}
+
+void CommandLineParser::ParseCommandLineOptions(int argc,
+ const char *const *argv,
+ const char *Overview) {
+ assert(hasOptions() && "No options specified!");
+
+ // Expand response files.
+ SmallVector<const char *, 20> newArgv(argv, argv + argc);
+ BumpPtrAllocator A;
+ BumpPtrStringSaver Saver(A);
+ ExpandResponseFiles(Saver, TokenizeGNUCommandLine, newArgv);
+ argv = &newArgv[0];
+ argc = static_cast<int>(newArgv.size());
+
+ // Copy the program name into ProgName, making sure not to overflow it.
+ ProgramName = sys::path::filename(argv[0]);
+
+ ProgramOverview = Overview;
+ bool ErrorParsing = false;
+
+ // Check out the positional arguments to collect information about them.
+ unsigned NumPositionalRequired = 0;
+
+ // Determine whether or not there are an unlimited number of positionals
+ bool HasUnlimitedPositionals = false;
+
+ if (ConsumeAfterOpt) {
+ assert(PositionalOpts.size() > 0 &&
+ "Cannot specify cl::ConsumeAfter without a positional argument!");
+ }
+ if (!PositionalOpts.empty()) {
+
+ // Calculate how many positional values are _required_.
+ bool UnboundedFound = false;
+ for (size_t i = 0, e = PositionalOpts.size(); i != e; ++i) {
+ Option *Opt = PositionalOpts[i];
+ if (RequiresValue(Opt))
+ ++NumPositionalRequired;
+ else if (ConsumeAfterOpt) {
+ // ConsumeAfter cannot be combined with "optional" positional options
+ // unless there is only one positional argument...
+ if (PositionalOpts.size() > 1)
+ ErrorParsing |= Opt->error(
+ "error - this positional option will never be matched, "
+ "because it does not Require a value, and a "
+ "cl::ConsumeAfter option is active!");
+ } else if (UnboundedFound && !Opt->ArgStr[0]) {
+ // This option does not "require" a value... Make sure this option is
+ // not specified after an option that eats all extra arguments, or this
+ // one will never get any!
+ //
+ ErrorParsing |= Opt->error("error - option can never match, because "
+ "another positional argument will match an "
+ "unbounded number of values, and this option"
+ " does not require a value!");
+ errs() << ProgramName << ": CommandLine Error: Option '" << Opt->ArgStr
+ << "' is all messed up!\n";
+ errs() << PositionalOpts.size();
+ }
+ UnboundedFound |= EatsUnboundedNumberOfValues(Opt);
+ }
+ HasUnlimitedPositionals = UnboundedFound || ConsumeAfterOpt;
+ }
+
+ // PositionalVals - A vector of "positional" arguments we accumulate into
+ // the process at the end.
+ //
+ SmallVector<std::pair<StringRef, unsigned>, 4> PositionalVals;
+
+ // If the program has named positional arguments, and the name has been run
+ // across, keep track of which positional argument was named. Otherwise put
+ // the positional args into the PositionalVals list...
+ Option *ActivePositionalArg = nullptr;
+
+ // Loop over all of the arguments... processing them.
+ bool DashDashFound = false; // Have we read '--'?
+ for (int i = 1; i < argc; ++i) {
+ Option *Handler = nullptr;
+ Option *NearestHandler = nullptr;
+ std::string NearestHandlerString;
+ StringRef Value;
+ StringRef ArgName = "";
+
+ // Check to see if this is a positional argument. This argument is
+ // considered to be positional if it doesn't start with '-', if it is "-"
+ // itself, or if we have seen "--" already.
+ //
+ if (argv[i][0] != '-' || argv[i][1] == 0 || DashDashFound) {
+ // Positional argument!
+ if (ActivePositionalArg) {
+ ProvidePositionalOption(ActivePositionalArg, argv[i], i);
+ continue; // We are done!
+ }
+
+ if (!PositionalOpts.empty()) {
+ PositionalVals.push_back(std::make_pair(argv[i], i));
+
+ // All of the positional arguments have been fulfulled, give the rest to
+ // the consume after option... if it's specified...
+ //
+ if (PositionalVals.size() >= NumPositionalRequired && ConsumeAfterOpt) {
+ for (++i; i < argc; ++i)
+ PositionalVals.push_back(std::make_pair(argv[i], i));
+ break; // Handle outside of the argument processing loop...
+ }
+
+ // Delay processing positional arguments until the end...
+ continue;
+ }
+ } else if (argv[i][0] == '-' && argv[i][1] == '-' && argv[i][2] == 0 &&
+ !DashDashFound) {
+ DashDashFound = true; // This is the mythical "--"?
+ continue; // Don't try to process it as an argument itself.
+ } else if (ActivePositionalArg &&
+ (ActivePositionalArg->getMiscFlags() & PositionalEatsArgs)) {
+ // If there is a positional argument eating options, check to see if this
+ // option is another positional argument. If so, treat it as an argument,
+ // otherwise feed it to the eating positional.
+ ArgName = argv[i] + 1;
+ // Eat leading dashes.
+ while (!ArgName.empty() && ArgName[0] == '-')
+ ArgName = ArgName.substr(1);
+
+ Handler = LookupOption(ArgName, Value);
+ if (!Handler || Handler->getFormattingFlag() != cl::Positional) {
+ ProvidePositionalOption(ActivePositionalArg, argv[i], i);
+ continue; // We are done!
+ }
+
+ } else { // We start with a '-', must be an argument.
+ ArgName = argv[i] + 1;
+ // Eat leading dashes.
+ while (!ArgName.empty() && ArgName[0] == '-')
+ ArgName = ArgName.substr(1);
+
+ Handler = LookupOption(ArgName, Value);
+
+ // Check to see if this "option" is really a prefixed or grouped argument.
+ if (!Handler)
+ Handler = HandlePrefixedOrGroupedOption(ArgName, Value, ErrorParsing,
+ OptionsMap);
+
+ // Otherwise, look for the closest available option to report to the user
+ // in the upcoming error.
+ if (!Handler && SinkOpts.empty())
+ NearestHandler =
+ LookupNearestOption(ArgName, OptionsMap, NearestHandlerString);
+ }
+
+ if (!Handler) {
+ if (SinkOpts.empty()) {
+ errs() << ProgramName << ": Unknown command line argument '" << argv[i]
+ << "'. Try: '" << argv[0] << " -help'\n";
+
+ if (NearestHandler) {
+ // If we know a near match, report it as well.
+ errs() << ProgramName << ": Did you mean '-" << NearestHandlerString
+ << "'?\n";
+ }
+
+ ErrorParsing = true;
+ } else {
+ for (SmallVectorImpl<Option *>::iterator I = SinkOpts.begin(),
+ E = SinkOpts.end();
+ I != E; ++I)
+ (*I)->addOccurrence(i, "", argv[i]);
+ }
+ continue;
+ }
+
+ // If this is a named positional argument, just remember that it is the
+ // active one...
+ if (Handler->getFormattingFlag() == cl::Positional)
+ ActivePositionalArg = Handler;
+ else
+ ErrorParsing |= ProvideOption(Handler, ArgName, Value, argc, argv, i);
+ }
+
+ // Check and handle positional arguments now...
+ if (NumPositionalRequired > PositionalVals.size()) {
+ errs() << ProgramName
+ << ": Not enough positional command line arguments specified!\n"
+ << "Must specify at least " << NumPositionalRequired
+ << " positional arguments: See: " << argv[0] << " -help\n";
+
+ ErrorParsing = true;
+ } else if (!HasUnlimitedPositionals &&
+ PositionalVals.size() > PositionalOpts.size()) {
+ errs() << ProgramName << ": Too many positional arguments specified!\n"
+ << "Can specify at most " << PositionalOpts.size()
+ << " positional arguments: See: " << argv[0] << " -help\n";
+ ErrorParsing = true;
+
+ } else if (!ConsumeAfterOpt) {
+ // Positional args have already been handled if ConsumeAfter is specified.
+ unsigned ValNo = 0, NumVals = static_cast<unsigned>(PositionalVals.size());
+ for (size_t i = 0, e = PositionalOpts.size(); i != e; ++i) {
+ if (RequiresValue(PositionalOpts[i])) {
+ ProvidePositionalOption(PositionalOpts[i], PositionalVals[ValNo].first,
+ PositionalVals[ValNo].second);
+ ValNo++;
+ --NumPositionalRequired; // We fulfilled our duty...
+ }
+
+ // If we _can_ give this option more arguments, do so now, as long as we
+ // do not give it values that others need. 'Done' controls whether the
+ // option even _WANTS_ any more.
+ //
+ bool Done = PositionalOpts[i]->getNumOccurrencesFlag() == cl::Required;
+ while (NumVals - ValNo > NumPositionalRequired && !Done) {
+ switch (PositionalOpts[i]->getNumOccurrencesFlag()) {
+ case cl::Optional:
+ Done = true; // Optional arguments want _at most_ one value
+ // FALL THROUGH
+ case cl::ZeroOrMore: // Zero or more will take all they can get...
+ case cl::OneOrMore: // One or more will take all they can get...
+ ProvidePositionalOption(PositionalOpts[i],
+ PositionalVals[ValNo].first,
+ PositionalVals[ValNo].second);
+ ValNo++;
+ break;
+ default:
+ llvm_unreachable("Internal error, unexpected NumOccurrences flag in "
+ "positional argument processing!");
+ }
+ }
+ }
+ } else {
+ assert(ConsumeAfterOpt && NumPositionalRequired <= PositionalVals.size());
+ unsigned ValNo = 0;
+ for (size_t j = 1, e = PositionalOpts.size(); j != e; ++j)
+ if (RequiresValue(PositionalOpts[j])) {
+ ErrorParsing |= ProvidePositionalOption(PositionalOpts[j],
+ PositionalVals[ValNo].first,
+ PositionalVals[ValNo].second);
+ ValNo++;
+ }
+
+ // Handle the case where there is just one positional option, and it's
+ // optional. In this case, we want to give JUST THE FIRST option to the
+ // positional option and keep the rest for the consume after. The above
+ // loop would have assigned no values to positional options in this case.
+ //
+ if (PositionalOpts.size() == 1 && ValNo == 0 && !PositionalVals.empty()) {
+ ErrorParsing |= ProvidePositionalOption(PositionalOpts[0],
+ PositionalVals[ValNo].first,
+ PositionalVals[ValNo].second);
+ ValNo++;
+ }
+
+ // Handle over all of the rest of the arguments to the
+ // cl::ConsumeAfter command line option...
+ for (; ValNo != PositionalVals.size(); ++ValNo)
+ ErrorParsing |=
+ ProvidePositionalOption(ConsumeAfterOpt, PositionalVals[ValNo].first,
+ PositionalVals[ValNo].second);
+ }
+
+ // Loop over args and make sure all required args are specified!
+ for (const auto &Opt : OptionsMap) {
+ switch (Opt.second->getNumOccurrencesFlag()) {
+ case Required:
+ case OneOrMore:
+ if (Opt.second->getNumOccurrences() == 0) {
+ Opt.second->error("must be specified at least once!");
+ ErrorParsing = true;
+ }
+ // Fall through
+ default:
+ break;
+ }
+ }
+
+ // Now that we know if -debug is specified, we can use it.
+ // Note that if ReadResponseFiles == true, this must be done before the
+ // memory allocated for the expanded command line is free()d below.
+ DEBUG(dbgs() << "Args: ";
+ for (int i = 0; i < argc; ++i) dbgs() << argv[i] << ' ';
+ dbgs() << '\n';);
+
+ // Free all of the memory allocated to the map. Command line options may only
+ // be processed once!
+ MoreHelp.clear();
+
+ // If we had an error processing our arguments, don't let the program execute
+ if (ErrorParsing)
+ exit(1);
+}
+
+//===----------------------------------------------------------------------===//
+// Option Base class implementation
+//
+
+bool Option::error(const Twine &Message, StringRef ArgName) {
+ if (!ArgName.data())
+ ArgName = ArgStr;
+ if (ArgName.empty())
+ errs() << HelpStr; // Be nice for positional arguments
+ else
+ errs() << GlobalParser->ProgramName << ": for the -" << ArgName;
+
+ errs() << " option: " << Message << "\n";
+ return true;
+}
+
+bool Option::addOccurrence(unsigned pos, StringRef ArgName, StringRef Value,
+ bool MultiArg) {
+ if (!MultiArg)
+ NumOccurrences++; // Increment the number of times we have been seen
+
+ switch (getNumOccurrencesFlag()) {
+ case Optional:
+ if (NumOccurrences > 1)
+ return error("may only occur zero or one times!", ArgName);
+ break;
+ case Required:
+ if (NumOccurrences > 1)
+ return error("must occur exactly one time!", ArgName);
+ // Fall through
+ case OneOrMore:
+ case ZeroOrMore:
+ case ConsumeAfter:
+ break;
+ }
+
+ return handleOccurrence(pos, ArgName, Value);
+}
+
+// getValueStr - Get the value description string, using "DefaultMsg" if nothing
+// has been specified yet.
+//
+static const char *getValueStr(const Option &O, const char *DefaultMsg) {
+ if (O.ValueStr[0] == 0)
+ return DefaultMsg;
+ return O.ValueStr;
+}
+
+//===----------------------------------------------------------------------===//
+// cl::alias class implementation
+//
+
+// Return the width of the option tag for printing...
+size_t alias::getOptionWidth() const { return std::strlen(ArgStr) + 6; }
+
+static void printHelpStr(StringRef HelpStr, size_t Indent,
+ size_t FirstLineIndentedBy) {
+ std::pair<StringRef, StringRef> Split = HelpStr.split('\n');
+ outs().indent(Indent - FirstLineIndentedBy) << " - " << Split.first << "\n";
+ while (!Split.second.empty()) {
+ Split = Split.second.split('\n');
+ outs().indent(Indent) << Split.first << "\n";
+ }
+}
+
+// Print out the option for the alias.
+void alias::printOptionInfo(size_t GlobalWidth) const {
+ outs() << " -" << ArgStr;
+ printHelpStr(HelpStr, GlobalWidth, std::strlen(ArgStr) + 6);
+}
+
+//===----------------------------------------------------------------------===//
+// Parser Implementation code...
+//
+
+// basic_parser implementation
+//
+
+// Return the width of the option tag for printing...
+size_t basic_parser_impl::getOptionWidth(const Option &O) const {
+ size_t Len = std::strlen(O.ArgStr);
+ if (const char *ValName = getValueName())
+ Len += std::strlen(getValueStr(O, ValName)) + 3;
+
+ return Len + 6;
+}
+
+// printOptionInfo - Print out information about this option. The
+// to-be-maintained width is specified.
+//
+void basic_parser_impl::printOptionInfo(const Option &O,
+ size_t GlobalWidth) const {
+ outs() << " -" << O.ArgStr;
+
+ if (const char *ValName = getValueName())
+ outs() << "=<" << getValueStr(O, ValName) << '>';
+
+ printHelpStr(O.HelpStr, GlobalWidth, getOptionWidth(O));
+}
+
+void basic_parser_impl::printOptionName(const Option &O,
+ size_t GlobalWidth) const {
+ outs() << " -" << O.ArgStr;
+ outs().indent(GlobalWidth - std::strlen(O.ArgStr));
+}
+
+// parser<bool> implementation
+//
+bool parser<bool>::parse(Option &O, StringRef ArgName, StringRef Arg,
+ bool &Value) {
+ if (Arg == "" || Arg == "true" || Arg == "TRUE" || Arg == "True" ||
+ Arg == "1") {
+ Value = true;
+ return false;
+ }
+
+ if (Arg == "false" || Arg == "FALSE" || Arg == "False" || Arg == "0") {
+ Value = false;
+ return false;
+ }
+ return O.error("'" + Arg +
+ "' is invalid value for boolean argument! Try 0 or 1");
+}
+
+// parser<boolOrDefault> implementation
+//
+bool parser<boolOrDefault>::parse(Option &O, StringRef ArgName, StringRef Arg,
+ boolOrDefault &Value) {
+ if (Arg == "" || Arg == "true" || Arg == "TRUE" || Arg == "True" ||
+ Arg == "1") {
+ Value = BOU_TRUE;
+ return false;
+ }
+ if (Arg == "false" || Arg == "FALSE" || Arg == "False" || Arg == "0") {
+ Value = BOU_FALSE;
+ return false;
+ }
+
+ return O.error("'" + Arg +
+ "' is invalid value for boolean argument! Try 0 or 1");
+}
+
+// parser<int> implementation
+//
+bool parser<int>::parse(Option &O, StringRef ArgName, StringRef Arg,
+ int &Value) {
+ if (Arg.getAsInteger(0, Value))
+ return O.error("'" + Arg + "' value invalid for integer argument!");
+ return false;
+}
+
+// parser<unsigned> implementation
+//
+bool parser<unsigned>::parse(Option &O, StringRef ArgName, StringRef Arg,
+ unsigned &Value) {
+
+ if (Arg.getAsInteger(0, Value))
+ return O.error("'" + Arg + "' value invalid for uint argument!");
+ return false;
+}
+
+// parser<unsigned long long> implementation
+//
+bool parser<unsigned long long>::parse(Option &O, StringRef ArgName,
+ StringRef Arg,
+ unsigned long long &Value) {
+
+ if (Arg.getAsInteger(0, Value))
+ return O.error("'" + Arg + "' value invalid for uint argument!");
+ return false;
+}
+
+// parser<double>/parser<float> implementation
+//
+static bool parseDouble(Option &O, StringRef Arg, double &Value) {
+ SmallString<32> TmpStr(Arg.begin(), Arg.end());
+ const char *ArgStart = TmpStr.c_str();
+ char *End;
+ Value = strtod(ArgStart, &End);
+ if (*End != 0)
+ return O.error("'" + Arg + "' value invalid for floating point argument!");
+ return false;
+}
+
+bool parser<double>::parse(Option &O, StringRef ArgName, StringRef Arg,
+ double &Val) {
+ return parseDouble(O, Arg, Val);
+}
+
+bool parser<float>::parse(Option &O, StringRef ArgName, StringRef Arg,
+ float &Val) {
+ double dVal;
+ if (parseDouble(O, Arg, dVal))
+ return true;
+ Val = (float)dVal;
+ return false;
+}
+
+// generic_parser_base implementation
+//
+
+// findOption - Return the option number corresponding to the specified
+// argument string. If the option is not found, getNumOptions() is returned.
+//
+unsigned generic_parser_base::findOption(const char *Name) {
+ unsigned e = getNumOptions();
+
+ for (unsigned i = 0; i != e; ++i) {
+ if (strcmp(getOption(i), Name) == 0)
+ return i;
+ }
+ return e;
+}
+
+// Return the width of the option tag for printing...
+size_t generic_parser_base::getOptionWidth(const Option &O) const {
+ if (O.hasArgStr()) {
+ size_t Size = std::strlen(O.ArgStr) + 6;
+ for (unsigned i = 0, e = getNumOptions(); i != e; ++i)
+ Size = std::max(Size, std::strlen(getOption(i)) + 8);
+ return Size;
+ } else {
+ size_t BaseSize = 0;
+ for (unsigned i = 0, e = getNumOptions(); i != e; ++i)
+ BaseSize = std::max(BaseSize, std::strlen(getOption(i)) + 8);
+ return BaseSize;
+ }
+}
+
+// printOptionInfo - Print out information about this option. The
+// to-be-maintained width is specified.
+//
+void generic_parser_base::printOptionInfo(const Option &O,
+ size_t GlobalWidth) const {
+ if (O.hasArgStr()) {
+ outs() << " -" << O.ArgStr;
+ printHelpStr(O.HelpStr, GlobalWidth, std::strlen(O.ArgStr) + 6);
+
+ for (unsigned i = 0, e = getNumOptions(); i != e; ++i) {
+ size_t NumSpaces = GlobalWidth - strlen(getOption(i)) - 8;
+ outs() << " =" << getOption(i);
+ outs().indent(NumSpaces) << " - " << getDescription(i) << '\n';
+ }
+ } else {
+ if (O.HelpStr[0])
+ outs() << " " << O.HelpStr << '\n';
+ for (unsigned i = 0, e = getNumOptions(); i != e; ++i) {
+ const char *Option = getOption(i);
+ outs() << " -" << Option;
+ printHelpStr(getDescription(i), GlobalWidth, std::strlen(Option) + 8);
+ }
+ }
+}
+
+static const size_t MaxOptWidth = 8; // arbitrary spacing for printOptionDiff
+
+// printGenericOptionDiff - Print the value of this option and it's default.
+//
+// "Generic" options have each value mapped to a name.
+void generic_parser_base::printGenericOptionDiff(
+ const Option &O, const GenericOptionValue &Value,
+ const GenericOptionValue &Default, size_t GlobalWidth) const {
+ outs() << " -" << O.ArgStr;
+ outs().indent(GlobalWidth - std::strlen(O.ArgStr));
+
+ unsigned NumOpts = getNumOptions();
+ for (unsigned i = 0; i != NumOpts; ++i) {
+ if (Value.compare(getOptionValue(i)))
+ continue;
+
+ outs() << "= " << getOption(i);
+ size_t L = std::strlen(getOption(i));
+ size_t NumSpaces = MaxOptWidth > L ? MaxOptWidth - L : 0;
+ outs().indent(NumSpaces) << " (default: ";
+ for (unsigned j = 0; j != NumOpts; ++j) {
+ if (Default.compare(getOptionValue(j)))
+ continue;
+ outs() << getOption(j);
+ break;
+ }
+ outs() << ")\n";
+ return;
+ }
+ outs() << "= *unknown option value*\n";
+}
+
+// printOptionDiff - Specializations for printing basic value types.
+//
+#define PRINT_OPT_DIFF(T) \
+ void parser<T>::printOptionDiff(const Option &O, T V, OptionValue<T> D, \
+ size_t GlobalWidth) const { \
+ printOptionName(O, GlobalWidth); \
+ std::string Str; \
+ { \
+ raw_string_ostream SS(Str); \
+ SS << V; \
+ } \
+ outs() << "= " << Str; \
+ size_t NumSpaces = \
+ MaxOptWidth > Str.size() ? MaxOptWidth - Str.size() : 0; \
+ outs().indent(NumSpaces) << " (default: "; \
+ if (D.hasValue()) \
+ outs() << D.getValue(); \
+ else \
+ outs() << "*no default*"; \
+ outs() << ")\n"; \
+ }
+
+PRINT_OPT_DIFF(bool)
+PRINT_OPT_DIFF(boolOrDefault)
+PRINT_OPT_DIFF(int)
+PRINT_OPT_DIFF(unsigned)
+PRINT_OPT_DIFF(unsigned long long)
+PRINT_OPT_DIFF(double)
+PRINT_OPT_DIFF(float)
+PRINT_OPT_DIFF(char)
+
+void parser<std::string>::printOptionDiff(const Option &O, StringRef V,
+ OptionValue<std::string> D,
+ size_t GlobalWidth) const {
+ printOptionName(O, GlobalWidth);
+ outs() << "= " << V;
+ size_t NumSpaces = MaxOptWidth > V.size() ? MaxOptWidth - V.size() : 0;
+ outs().indent(NumSpaces) << " (default: ";
+ if (D.hasValue())
+ outs() << D.getValue();
+ else
+ outs() << "*no default*";
+ outs() << ")\n";
+}
+
+// Print a placeholder for options that don't yet support printOptionDiff().
+void basic_parser_impl::printOptionNoValue(const Option &O,
+ size_t GlobalWidth) const {
+ printOptionName(O, GlobalWidth);
+ outs() << "= *cannot print option value*\n";
+}
+
+//===----------------------------------------------------------------------===//
+// -help and -help-hidden option implementation
+//
+
+static int OptNameCompare(const std::pair<const char *, Option *> *LHS,
+ const std::pair<const char *, Option *> *RHS) {
+ return strcmp(LHS->first, RHS->first);
+}
+
+// Copy Options into a vector so we can sort them as we like.
+static void sortOpts(StringMap<Option *> &OptMap,
+ SmallVectorImpl<std::pair<const char *, Option *>> &Opts,
+ bool ShowHidden) {
+ SmallPtrSet<Option *, 128> OptionSet; // Duplicate option detection.
+
+ for (StringMap<Option *>::iterator I = OptMap.begin(), E = OptMap.end();
+ I != E; ++I) {
+ // Ignore really-hidden options.
+ if (I->second->getOptionHiddenFlag() == ReallyHidden)
+ continue;
+
+ // Unless showhidden is set, ignore hidden flags.
+ if (I->second->getOptionHiddenFlag() == Hidden && !ShowHidden)
+ continue;
+
+ // If we've already seen this option, don't add it to the list again.
+ if (!OptionSet.insert(I->second).second)
+ continue;
+
+ Opts.push_back(
+ std::pair<const char *, Option *>(I->getKey().data(), I->second));
+ }
+
+ // Sort the options list alphabetically.
+ array_pod_sort(Opts.begin(), Opts.end(), OptNameCompare);
+}
+
+namespace {
+
+class HelpPrinter {
+protected:
+ const bool ShowHidden;
+ typedef SmallVector<std::pair<const char *, Option *>, 128>
+ StrOptionPairVector;
+ // Print the options. Opts is assumed to be alphabetically sorted.
+ virtual void printOptions(StrOptionPairVector &Opts, size_t MaxArgLen) {
+ for (size_t i = 0, e = Opts.size(); i != e; ++i)
+ Opts[i].second->printOptionInfo(MaxArgLen);
+ }
+
+public:
+ explicit HelpPrinter(bool showHidden) : ShowHidden(showHidden) {}
+ virtual ~HelpPrinter() {}
+
+ // Invoke the printer.
+ void operator=(bool Value) {
+ if (!Value)
+ return;
+
+ StrOptionPairVector Opts;
+ sortOpts(GlobalParser->OptionsMap, Opts, ShowHidden);
+
+ if (GlobalParser->ProgramOverview)
+ outs() << "OVERVIEW: " << GlobalParser->ProgramOverview << "\n";
+
+ outs() << "USAGE: " << GlobalParser->ProgramName << " [options]";
+
+ for (auto Opt : GlobalParser->PositionalOpts) {
+ if (Opt->ArgStr[0])
+ outs() << " --" << Opt->ArgStr;
+ outs() << " " << Opt->HelpStr;
+ }
+
+ // Print the consume after option info if it exists...
+ if (GlobalParser->ConsumeAfterOpt)
+ outs() << " " << GlobalParser->ConsumeAfterOpt->HelpStr;
+
+ outs() << "\n\n";
+
+ // Compute the maximum argument length...
+ size_t MaxArgLen = 0;
+ for (size_t i = 0, e = Opts.size(); i != e; ++i)
+ MaxArgLen = std::max(MaxArgLen, Opts[i].second->getOptionWidth());
+
+ outs() << "OPTIONS:\n";
+ printOptions(Opts, MaxArgLen);
+
+ // Print any extra help the user has declared.
+ for (auto I : GlobalParser->MoreHelp)
+ outs() << I;
+ GlobalParser->MoreHelp.clear();
+
+ // Halt the program since help information was printed
+ exit(0);
+ }
+};
+
+class CategorizedHelpPrinter : public HelpPrinter {
+public:
+ explicit CategorizedHelpPrinter(bool showHidden) : HelpPrinter(showHidden) {}
+
+ // Helper function for printOptions().
+ // It shall return a negative value if A's name should be lexicographically
+ // ordered before B's name. It returns a value greater equal zero otherwise.
+ static int OptionCategoryCompare(OptionCategory *const *A,
+ OptionCategory *const *B) {
+ return strcmp((*A)->getName(), (*B)->getName());
+ }
+
+ // Make sure we inherit our base class's operator=()
+ using HelpPrinter::operator=;
+
+protected:
+ void printOptions(StrOptionPairVector &Opts, size_t MaxArgLen) override {
+ std::vector<OptionCategory *> SortedCategories;
+ std::map<OptionCategory *, std::vector<Option *>> CategorizedOptions;
+
+ // Collect registered option categories into vector in preparation for
+ // sorting.
+ for (auto I = GlobalParser->RegisteredOptionCategories.begin(),
+ E = GlobalParser->RegisteredOptionCategories.end();
+ I != E; ++I) {
+ SortedCategories.push_back(*I);
+ }
+
+ // Sort the different option categories alphabetically.
+ assert(SortedCategories.size() > 0 && "No option categories registered!");
+ array_pod_sort(SortedCategories.begin(), SortedCategories.end(),
+ OptionCategoryCompare);
+
+ // Create map to empty vectors.
+ for (std::vector<OptionCategory *>::const_iterator
+ I = SortedCategories.begin(),
+ E = SortedCategories.end();
+ I != E; ++I)
+ CategorizedOptions[*I] = std::vector<Option *>();
+
+ // Walk through pre-sorted options and assign into categories.
+ // Because the options are already alphabetically sorted the
+ // options within categories will also be alphabetically sorted.
+ for (size_t I = 0, E = Opts.size(); I != E; ++I) {
+ Option *Opt = Opts[I].second;
+ assert(CategorizedOptions.count(Opt->Category) > 0 &&
+ "Option has an unregistered category");
+ CategorizedOptions[Opt->Category].push_back(Opt);
+ }
+
+ // Now do printing.
+ for (std::vector<OptionCategory *>::const_iterator
+ Category = SortedCategories.begin(),
+ E = SortedCategories.end();
+ Category != E; ++Category) {
+ // Hide empty categories for -help, but show for -help-hidden.
+ bool IsEmptyCategory = CategorizedOptions[*Category].size() == 0;
+ if (!ShowHidden && IsEmptyCategory)
+ continue;
+
+ // Print category information.
+ outs() << "\n";
+ outs() << (*Category)->getName() << ":\n";
+
+ // Check if description is set.
+ if ((*Category)->getDescription() != nullptr)
+ outs() << (*Category)->getDescription() << "\n\n";
+ else
+ outs() << "\n";
+
+ // When using -help-hidden explicitly state if the category has no
+ // options associated with it.
+ if (IsEmptyCategory) {
+ outs() << " This option category has no options.\n";
+ continue;
+ }
+ // Loop over the options in the category and print.
+ for (std::vector<Option *>::const_iterator
+ Opt = CategorizedOptions[*Category].begin(),
+ E = CategorizedOptions[*Category].end();
+ Opt != E; ++Opt)
+ (*Opt)->printOptionInfo(MaxArgLen);
+ }
+ }
+};
+
+// This wraps the Uncategorizing and Categorizing printers and decides
+// at run time which should be invoked.
+class HelpPrinterWrapper {
+private:
+ HelpPrinter &UncategorizedPrinter;
+ CategorizedHelpPrinter &CategorizedPrinter;
+
+public:
+ explicit HelpPrinterWrapper(HelpPrinter &UncategorizedPrinter,
+ CategorizedHelpPrinter &CategorizedPrinter)
+ : UncategorizedPrinter(UncategorizedPrinter),
+ CategorizedPrinter(CategorizedPrinter) {}
+
+ // Invoke the printer.
+ void operator=(bool Value);
+};
+
+} // End anonymous namespace
+
+// Declare the four HelpPrinter instances that are used to print out help, or
+// help-hidden as an uncategorized list or in categories.
+static HelpPrinter UncategorizedNormalPrinter(false);
+static HelpPrinter UncategorizedHiddenPrinter(true);
+static CategorizedHelpPrinter CategorizedNormalPrinter(false);
+static CategorizedHelpPrinter CategorizedHiddenPrinter(true);
+
+// Declare HelpPrinter wrappers that will decide whether or not to invoke
+// a categorizing help printer
+static HelpPrinterWrapper WrappedNormalPrinter(UncategorizedNormalPrinter,
+ CategorizedNormalPrinter);
+static HelpPrinterWrapper WrappedHiddenPrinter(UncategorizedHiddenPrinter,
+ CategorizedHiddenPrinter);
+
+// Define a category for generic options that all tools should have.
+static cl::OptionCategory GenericCategory("Generic Options");
+
+// Define uncategorized help printers.
+// -help-list is hidden by default because if Option categories are being used
+// then -help behaves the same as -help-list.
+static cl::opt<HelpPrinter, true, parser<bool>> HLOp(
+ "help-list",
+ cl::desc("Display list of available options (-help-list-hidden for more)"),
+ cl::location(UncategorizedNormalPrinter), cl::Hidden, cl::ValueDisallowed,
+ cl::cat(GenericCategory));
+
+static cl::opt<HelpPrinter, true, parser<bool>>
+ HLHOp("help-list-hidden", cl::desc("Display list of all available options"),
+ cl::location(UncategorizedHiddenPrinter), cl::Hidden,
+ cl::ValueDisallowed, cl::cat(GenericCategory));
+
+// Define uncategorized/categorized help printers. These printers change their
+// behaviour at runtime depending on whether one or more Option categories have
+// been declared.
+static cl::opt<HelpPrinterWrapper, true, parser<bool>>
+ HOp("help", cl::desc("Display available options (-help-hidden for more)"),
+ cl::location(WrappedNormalPrinter), cl::ValueDisallowed,
+ cl::cat(GenericCategory));
+
+static cl::opt<HelpPrinterWrapper, true, parser<bool>>
+ HHOp("help-hidden", cl::desc("Display all available options"),
+ cl::location(WrappedHiddenPrinter), cl::Hidden, cl::ValueDisallowed,
+ cl::cat(GenericCategory));
+
+static cl::opt<bool> PrintOptions(
+ "print-options",
+ cl::desc("Print non-default options after command line parsing"),
+ cl::Hidden, cl::init(false), cl::cat(GenericCategory));
+
+static cl::opt<bool> PrintAllOptions(
+ "print-all-options",
+ cl::desc("Print all option values after command line parsing"), cl::Hidden,
+ cl::init(false), cl::cat(GenericCategory));
+
+void HelpPrinterWrapper::operator=(bool Value) {
+ if (!Value)
+ return;
+
+ // Decide which printer to invoke. If more than one option category is
+ // registered then it is useful to show the categorized help instead of
+ // uncategorized help.
+ if (GlobalParser->RegisteredOptionCategories.size() > 1) {
+ // unhide -help-list option so user can have uncategorized output if they
+ // want it.
+ HLOp.setHiddenFlag(NotHidden);
+
+ CategorizedPrinter = true; // Invoke categorized printer
+ } else
+ UncategorizedPrinter = true; // Invoke uncategorized printer
+}
+
+// Print the value of each option.
+void cl::PrintOptionValues() { GlobalParser->printOptionValues(); }
+
+void CommandLineParser::printOptionValues() {
+ if (!PrintOptions && !PrintAllOptions)
+ return;
+
+ SmallVector<std::pair<const char *, Option *>, 128> Opts;
+ sortOpts(OptionsMap, Opts, /*ShowHidden*/ true);
+
+ // Compute the maximum argument length...
+ size_t MaxArgLen = 0;
+ for (size_t i = 0, e = Opts.size(); i != e; ++i)
+ MaxArgLen = std::max(MaxArgLen, Opts[i].second->getOptionWidth());
+
+ for (size_t i = 0, e = Opts.size(); i != e; ++i)
+ Opts[i].second->printOptionValue(MaxArgLen, PrintAllOptions);
+}
+
+static void (*OverrideVersionPrinter)() = nullptr;
+
+static std::vector<void (*)()> *ExtraVersionPrinters = nullptr;
+
+namespace {
+class VersionPrinter {
+public:
+ void print() {
+ raw_ostream &OS = outs();
+ OS << "LLVM (http://llvm.org/):\n"
+ << " " << PACKAGE_NAME << " version " << PACKAGE_VERSION;
+#ifdef LLVM_VERSION_INFO
+ OS << " " << LLVM_VERSION_INFO;
+#endif
+ OS << "\n ";
+#ifndef __OPTIMIZE__
+ OS << "DEBUG build";
+#else
+ OS << "Optimized build";
+#endif
+#ifndef NDEBUG
+ OS << " with assertions";
+#endif
+ std::string CPU = sys::getHostCPUName();
+ if (CPU == "generic")
+ CPU = "(unknown)";
+ OS << ".\n"
+#if (ENABLE_TIMESTAMPS == 1)
+ << " Built " << __DATE__ << " (" << __TIME__ << ").\n"
+#endif
+ << " Default target: " << sys::getDefaultTargetTriple() << '\n'
+ << " Host CPU: " << CPU << '\n';
+ }
+ void operator=(bool OptionWasSpecified) {
+ if (!OptionWasSpecified)
+ return;
+
+ if (OverrideVersionPrinter != nullptr) {
+ (*OverrideVersionPrinter)();
+ exit(0);
+ }
+ print();
+
+ // Iterate over any registered extra printers and call them to add further
+ // information.
+ if (ExtraVersionPrinters != nullptr) {
+ outs() << '\n';
+ for (std::vector<void (*)()>::iterator I = ExtraVersionPrinters->begin(),
+ E = ExtraVersionPrinters->end();
+ I != E; ++I)
+ (*I)();
+ }
+
+ exit(0);
+ }
+};
+} // End anonymous namespace
+
+// Define the --version option that prints out the LLVM version for the tool
+static VersionPrinter VersionPrinterInstance;
+
+static cl::opt<VersionPrinter, true, parser<bool>>
+ VersOp("version", cl::desc("Display the version of this program"),
+ cl::location(VersionPrinterInstance), cl::ValueDisallowed,
+ cl::cat(GenericCategory));
+
+// Utility function for printing the help message.
+void cl::PrintHelpMessage(bool Hidden, bool Categorized) {
+ // This looks weird, but it actually prints the help message. The Printers are
+ // types of HelpPrinter and the help gets printed when its operator= is
+ // invoked. That's because the "normal" usages of the help printer is to be
+ // assigned true/false depending on whether -help or -help-hidden was given or
+ // not. Since we're circumventing that we have to make it look like -help or
+ // -help-hidden were given, so we assign true.
+
+ if (!Hidden && !Categorized)
+ UncategorizedNormalPrinter = true;
+ else if (!Hidden && Categorized)
+ CategorizedNormalPrinter = true;
+ else if (Hidden && !Categorized)
+ UncategorizedHiddenPrinter = true;
+ else
+ CategorizedHiddenPrinter = true;
+}
+
+/// Utility function for printing version number.
+void cl::PrintVersionMessage() { VersionPrinterInstance.print(); }
+
+void cl::SetVersionPrinter(void (*func)()) { OverrideVersionPrinter = func; }
+
+void cl::AddExtraVersionPrinter(void (*func)()) {
+ if (!ExtraVersionPrinters)
+ ExtraVersionPrinters = new std::vector<void (*)()>;
+
+ ExtraVersionPrinters->push_back(func);
+}
+
+StringMap<Option *> &cl::getRegisteredOptions() {
+ return GlobalParser->OptionsMap;
+}
+
+void cl::HideUnrelatedOptions(cl::OptionCategory &Category) {
+ for (auto &I : GlobalParser->OptionsMap) {
+ if (I.second->Category != &Category &&
+ I.second->Category != &GenericCategory)
+ I.second->setHiddenFlag(cl::ReallyHidden);
+ }
+}
+
+void cl::HideUnrelatedOptions(ArrayRef<const cl::OptionCategory *> Categories) {
+ auto CategoriesBegin = Categories.begin();
+ auto CategoriesEnd = Categories.end();
+ for (auto &I : GlobalParser->OptionsMap) {
+ if (std::find(CategoriesBegin, CategoriesEnd, I.second->Category) ==
+ CategoriesEnd &&
+ I.second->Category != &GenericCategory)
+ I.second->setHiddenFlag(cl::ReallyHidden);
+ }
+}
+
+void LLVMParseCommandLineOptions(int argc, const char *const *argv,
+ const char *Overview) {
+ llvm::cl::ParseCommandLineOptions(argc, argv, Overview);
+}
diff --git a/contrib/llvm/lib/Support/Compression.cpp b/contrib/llvm/lib/Support/Compression.cpp
new file mode 100644
index 000000000000..b54613e92b8b
--- /dev/null
+++ b/contrib/llvm/lib/Support/Compression.cpp
@@ -0,0 +1,99 @@
+//===--- Compression.cpp - Compression implementation ---------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements compression functions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/Compression.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Config/config.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/ErrorHandling.h"
+#if LLVM_ENABLE_ZLIB == 1 && HAVE_ZLIB_H
+#include <zlib.h>
+#endif
+
+using namespace llvm;
+
+#if LLVM_ENABLE_ZLIB == 1 && HAVE_LIBZ
+static int encodeZlibCompressionLevel(zlib::CompressionLevel Level) {
+ switch (Level) {
+ case zlib::NoCompression: return 0;
+ case zlib::BestSpeedCompression: return 1;
+ case zlib::DefaultCompression: return Z_DEFAULT_COMPRESSION;
+ case zlib::BestSizeCompression: return 9;
+ }
+ llvm_unreachable("Invalid zlib::CompressionLevel!");
+}
+
+static zlib::Status encodeZlibReturnValue(int ReturnValue) {
+ switch (ReturnValue) {
+ case Z_OK: return zlib::StatusOK;
+ case Z_MEM_ERROR: return zlib::StatusOutOfMemory;
+ case Z_BUF_ERROR: return zlib::StatusBufferTooShort;
+ case Z_STREAM_ERROR: return zlib::StatusInvalidArg;
+ case Z_DATA_ERROR: return zlib::StatusInvalidData;
+ default: llvm_unreachable("unknown zlib return status!");
+ }
+}
+
+bool zlib::isAvailable() { return true; }
+zlib::Status zlib::compress(StringRef InputBuffer,
+ SmallVectorImpl<char> &CompressedBuffer,
+ CompressionLevel Level) {
+ unsigned long CompressedSize = ::compressBound(InputBuffer.size());
+ CompressedBuffer.resize(CompressedSize);
+ int CLevel = encodeZlibCompressionLevel(Level);
+ Status Res = encodeZlibReturnValue(::compress2(
+ (Bytef *)CompressedBuffer.data(), &CompressedSize,
+ (const Bytef *)InputBuffer.data(), InputBuffer.size(), CLevel));
+ // Tell MemorySanitizer that zlib output buffer is fully initialized.
+ // This avoids a false report when running LLVM with uninstrumented ZLib.
+ __msan_unpoison(CompressedBuffer.data(), CompressedSize);
+ CompressedBuffer.resize(CompressedSize);
+ return Res;
+}
+
+zlib::Status zlib::uncompress(StringRef InputBuffer,
+ SmallVectorImpl<char> &UncompressedBuffer,
+ size_t UncompressedSize) {
+ UncompressedBuffer.resize(UncompressedSize);
+ Status Res = encodeZlibReturnValue(::uncompress(
+ (Bytef *)UncompressedBuffer.data(), (uLongf *)&UncompressedSize,
+ (const Bytef *)InputBuffer.data(), InputBuffer.size()));
+ // Tell MemorySanitizer that zlib output buffer is fully initialized.
+ // This avoids a false report when running LLVM with uninstrumented ZLib.
+ __msan_unpoison(UncompressedBuffer.data(), UncompressedSize);
+ UncompressedBuffer.resize(UncompressedSize);
+ return Res;
+}
+
+uint32_t zlib::crc32(StringRef Buffer) {
+ return ::crc32(0, (const Bytef *)Buffer.data(), Buffer.size());
+}
+
+#else
+bool zlib::isAvailable() { return false; }
+zlib::Status zlib::compress(StringRef InputBuffer,
+ SmallVectorImpl<char> &CompressedBuffer,
+ CompressionLevel Level) {
+ return zlib::StatusUnsupported;
+}
+zlib::Status zlib::uncompress(StringRef InputBuffer,
+ SmallVectorImpl<char> &UncompressedBuffer,
+ size_t UncompressedSize) {
+ return zlib::StatusUnsupported;
+}
+uint32_t zlib::crc32(StringRef Buffer) {
+ llvm_unreachable("zlib::crc32 is unavailable");
+}
+#endif
+
diff --git a/contrib/llvm/lib/Support/ConvertUTF.c b/contrib/llvm/lib/Support/ConvertUTF.c
new file mode 100644
index 000000000000..128459a1d548
--- /dev/null
+++ b/contrib/llvm/lib/Support/ConvertUTF.c
@@ -0,0 +1,708 @@
+/*===--- ConvertUTF.c - Universal Character Names conversions ---------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ *===------------------------------------------------------------------------=*/
+/*
+ * Copyright 2001-2004 Unicode, Inc.
+ *
+ * Disclaimer
+ *
+ * This source code is provided as is by Unicode, Inc. No claims are
+ * made as to fitness for any particular purpose. No warranties of any
+ * kind are expressed or implied. The recipient agrees to determine
+ * applicability of information provided. If this file has been
+ * purchased on magnetic or optical media from Unicode, Inc., the
+ * sole remedy for any claim will be exchange of defective media
+ * within 90 days of receipt.
+ *
+ * Limitations on Rights to Redistribute This Code
+ *
+ * Unicode, Inc. hereby grants the right to freely use the information
+ * supplied in this file in the creation of products supporting the
+ * Unicode Standard, and to make copies of this file in any form
+ * for internal or external distribution as long as this notice
+ * remains attached.
+ */
+
+/* ---------------------------------------------------------------------
+
+ Conversions between UTF32, UTF-16, and UTF-8. Source code file.
+ Author: Mark E. Davis, 1994.
+ Rev History: Rick McGowan, fixes & updates May 2001.
+ Sept 2001: fixed const & error conditions per
+ mods suggested by S. Parent & A. Lillich.
+ June 2002: Tim Dodd added detection and handling of incomplete
+ source sequences, enhanced error detection, added casts
+ to eliminate compiler warnings.
+ July 2003: slight mods to back out aggressive FFFE detection.
+ Jan 2004: updated switches in from-UTF8 conversions.
+ Oct 2004: updated to use UNI_MAX_LEGAL_UTF32 in UTF-32 conversions.
+
+ See the header file "ConvertUTF.h" for complete documentation.
+
+------------------------------------------------------------------------ */
+
+
+#include "llvm/Support/ConvertUTF.h"
+#ifdef CVTUTF_DEBUG
+#include <stdio.h>
+#endif
+#include <assert.h>
+
+static const int halfShift = 10; /* used for shifting by 10 bits */
+
+static const UTF32 halfBase = 0x0010000UL;
+static const UTF32 halfMask = 0x3FFUL;
+
+#define UNI_SUR_HIGH_START (UTF32)0xD800
+#define UNI_SUR_HIGH_END (UTF32)0xDBFF
+#define UNI_SUR_LOW_START (UTF32)0xDC00
+#define UNI_SUR_LOW_END (UTF32)0xDFFF
+#define false 0
+#define true 1
+
+/* --------------------------------------------------------------------- */
+
+/*
+ * Index into the table below with the first byte of a UTF-8 sequence to
+ * get the number of trailing bytes that are supposed to follow it.
+ * Note that *legal* UTF-8 values can't have 4 or 5-bytes. The table is
+ * left as-is for anyone who may want to do such conversion, which was
+ * allowed in earlier algorithms.
+ */
+static const char trailingBytesForUTF8[256] = {
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5
+};
+
+/*
+ * Magic values subtracted from a buffer value during UTF8 conversion.
+ * This table contains as many values as there might be trailing bytes
+ * in a UTF-8 sequence.
+ */
+static const UTF32 offsetsFromUTF8[6] = { 0x00000000UL, 0x00003080UL, 0x000E2080UL,
+ 0x03C82080UL, 0xFA082080UL, 0x82082080UL };
+
+/*
+ * Once the bits are split out into bytes of UTF-8, this is a mask OR-ed
+ * into the first byte, depending on how many bytes follow. There are
+ * as many entries in this table as there are UTF-8 sequence types.
+ * (I.e., one byte sequence, two byte... etc.). Remember that sequencs
+ * for *legal* UTF-8 will be 4 or fewer bytes total.
+ */
+static const UTF8 firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
+
+/* --------------------------------------------------------------------- */
+
+/* The interface converts a whole buffer to avoid function-call overhead.
+ * Constants have been gathered. Loops & conditionals have been removed as
+ * much as possible for efficiency, in favor of drop-through switches.
+ * (See "Note A" at the bottom of the file for equivalent code.)
+ * If your compiler supports it, the "isLegalUTF8" call can be turned
+ * into an inline function.
+ */
+
+
+/* --------------------------------------------------------------------- */
+
+ConversionResult ConvertUTF32toUTF16 (
+ const UTF32** sourceStart, const UTF32* sourceEnd,
+ UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags) {
+ ConversionResult result = conversionOK;
+ const UTF32* source = *sourceStart;
+ UTF16* target = *targetStart;
+ while (source < sourceEnd) {
+ UTF32 ch;
+ if (target >= targetEnd) {
+ result = targetExhausted; break;
+ }
+ ch = *source++;
+ if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */
+ /* UTF-16 surrogate values are illegal in UTF-32; 0xffff or 0xfffe are both reserved values */
+ if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
+ if (flags == strictConversion) {
+ --source; /* return to the illegal value itself */
+ result = sourceIllegal;
+ break;
+ } else {
+ *target++ = UNI_REPLACEMENT_CHAR;
+ }
+ } else {
+ *target++ = (UTF16)ch; /* normal case */
+ }
+ } else if (ch > UNI_MAX_LEGAL_UTF32) {
+ if (flags == strictConversion) {
+ result = sourceIllegal;
+ } else {
+ *target++ = UNI_REPLACEMENT_CHAR;
+ }
+ } else {
+ /* target is a character in range 0xFFFF - 0x10FFFF. */
+ if (target + 1 >= targetEnd) {
+ --source; /* Back up source pointer! */
+ result = targetExhausted; break;
+ }
+ ch -= halfBase;
+ *target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START);
+ *target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START);
+ }
+ }
+ *sourceStart = source;
+ *targetStart = target;
+ return result;
+}
+
+/* --------------------------------------------------------------------- */
+
+ConversionResult ConvertUTF16toUTF32 (
+ const UTF16** sourceStart, const UTF16* sourceEnd,
+ UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags) {
+ ConversionResult result = conversionOK;
+ const UTF16* source = *sourceStart;
+ UTF32* target = *targetStart;
+ UTF32 ch, ch2;
+ while (source < sourceEnd) {
+ const UTF16* oldSource = source; /* In case we have to back up because of target overflow. */
+ ch = *source++;
+ /* If we have a surrogate pair, convert to UTF32 first. */
+ if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) {
+ /* If the 16 bits following the high surrogate are in the source buffer... */
+ if (source < sourceEnd) {
+ ch2 = *source;
+ /* If it's a low surrogate, convert to UTF32. */
+ if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) {
+ ch = ((ch - UNI_SUR_HIGH_START) << halfShift)
+ + (ch2 - UNI_SUR_LOW_START) + halfBase;
+ ++source;
+ } else if (flags == strictConversion) { /* it's an unpaired high surrogate */
+ --source; /* return to the illegal value itself */
+ result = sourceIllegal;
+ break;
+ }
+ } else { /* We don't have the 16 bits following the high surrogate. */
+ --source; /* return to the high surrogate */
+ result = sourceExhausted;
+ break;
+ }
+ } else if (flags == strictConversion) {
+ /* UTF-16 surrogate values are illegal in UTF-32 */
+ if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) {
+ --source; /* return to the illegal value itself */
+ result = sourceIllegal;
+ break;
+ }
+ }
+ if (target >= targetEnd) {
+ source = oldSource; /* Back up source pointer! */
+ result = targetExhausted; break;
+ }
+ *target++ = ch;
+ }
+ *sourceStart = source;
+ *targetStart = target;
+#ifdef CVTUTF_DEBUG
+if (result == sourceIllegal) {
+ fprintf(stderr, "ConvertUTF16toUTF32 illegal seq 0x%04x,%04x\n", ch, ch2);
+ fflush(stderr);
+}
+#endif
+ return result;
+}
+ConversionResult ConvertUTF16toUTF8 (
+ const UTF16** sourceStart, const UTF16* sourceEnd,
+ UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags) {
+ ConversionResult result = conversionOK;
+ const UTF16* source = *sourceStart;
+ UTF8* target = *targetStart;
+ while (source < sourceEnd) {
+ UTF32 ch;
+ unsigned short bytesToWrite = 0;
+ const UTF32 byteMask = 0xBF;
+ const UTF32 byteMark = 0x80;
+ const UTF16* oldSource = source; /* In case we have to back up because of target overflow. */
+ ch = *source++;
+ /* If we have a surrogate pair, convert to UTF32 first. */
+ if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) {
+ /* If the 16 bits following the high surrogate are in the source buffer... */
+ if (source < sourceEnd) {
+ UTF32 ch2 = *source;
+ /* If it's a low surrogate, convert to UTF32. */
+ if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) {
+ ch = ((ch - UNI_SUR_HIGH_START) << halfShift)
+ + (ch2 - UNI_SUR_LOW_START) + halfBase;
+ ++source;
+ } else if (flags == strictConversion) { /* it's an unpaired high surrogate */
+ --source; /* return to the illegal value itself */
+ result = sourceIllegal;
+ break;
+ }
+ } else { /* We don't have the 16 bits following the high surrogate. */
+ --source; /* return to the high surrogate */
+ result = sourceExhausted;
+ break;
+ }
+ } else if (flags == strictConversion) {
+ /* UTF-16 surrogate values are illegal in UTF-32 */
+ if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) {
+ --source; /* return to the illegal value itself */
+ result = sourceIllegal;
+ break;
+ }
+ }
+ /* Figure out how many bytes the result will require */
+ if (ch < (UTF32)0x80) { bytesToWrite = 1;
+ } else if (ch < (UTF32)0x800) { bytesToWrite = 2;
+ } else if (ch < (UTF32)0x10000) { bytesToWrite = 3;
+ } else if (ch < (UTF32)0x110000) { bytesToWrite = 4;
+ } else { bytesToWrite = 3;
+ ch = UNI_REPLACEMENT_CHAR;
+ }
+
+ target += bytesToWrite;
+ if (target > targetEnd) {
+ source = oldSource; /* Back up source pointer! */
+ target -= bytesToWrite; result = targetExhausted; break;
+ }
+ switch (bytesToWrite) { /* note: everything falls through. */
+ case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
+ case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
+ case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
+ case 1: *--target = (UTF8)(ch | firstByteMark[bytesToWrite]);
+ }
+ target += bytesToWrite;
+ }
+ *sourceStart = source;
+ *targetStart = target;
+ return result;
+}
+
+/* --------------------------------------------------------------------- */
+
+ConversionResult ConvertUTF32toUTF8 (
+ const UTF32** sourceStart, const UTF32* sourceEnd,
+ UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags) {
+ ConversionResult result = conversionOK;
+ const UTF32* source = *sourceStart;
+ UTF8* target = *targetStart;
+ while (source < sourceEnd) {
+ UTF32 ch;
+ unsigned short bytesToWrite = 0;
+ const UTF32 byteMask = 0xBF;
+ const UTF32 byteMark = 0x80;
+ ch = *source++;
+ if (flags == strictConversion ) {
+ /* UTF-16 surrogate values are illegal in UTF-32 */
+ if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
+ --source; /* return to the illegal value itself */
+ result = sourceIllegal;
+ break;
+ }
+ }
+ /*
+ * Figure out how many bytes the result will require. Turn any
+ * illegally large UTF32 things (> Plane 17) into replacement chars.
+ */
+ if (ch < (UTF32)0x80) { bytesToWrite = 1;
+ } else if (ch < (UTF32)0x800) { bytesToWrite = 2;
+ } else if (ch < (UTF32)0x10000) { bytesToWrite = 3;
+ } else if (ch <= UNI_MAX_LEGAL_UTF32) { bytesToWrite = 4;
+ } else { bytesToWrite = 3;
+ ch = UNI_REPLACEMENT_CHAR;
+ result = sourceIllegal;
+ }
+
+ target += bytesToWrite;
+ if (target > targetEnd) {
+ --source; /* Back up source pointer! */
+ target -= bytesToWrite; result = targetExhausted; break;
+ }
+ switch (bytesToWrite) { /* note: everything falls through. */
+ case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
+ case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
+ case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
+ case 1: *--target = (UTF8) (ch | firstByteMark[bytesToWrite]);
+ }
+ target += bytesToWrite;
+ }
+ *sourceStart = source;
+ *targetStart = target;
+ return result;
+}
+
+/* --------------------------------------------------------------------- */
+
+/*
+ * Utility routine to tell whether a sequence of bytes is legal UTF-8.
+ * This must be called with the length pre-determined by the first byte.
+ * If not calling this from ConvertUTF8to*, then the length can be set by:
+ * length = trailingBytesForUTF8[*source]+1;
+ * and the sequence is illegal right away if there aren't that many bytes
+ * available.
+ * If presented with a length > 4, this returns false. The Unicode
+ * definition of UTF-8 goes up to 4-byte sequences.
+ */
+
+static Boolean isLegalUTF8(const UTF8 *source, int length) {
+ UTF8 a;
+ const UTF8 *srcptr = source+length;
+ switch (length) {
+ default: return false;
+ /* Everything else falls through when "true"... */
+ case 4: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false;
+ case 3: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false;
+ case 2: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false;
+
+ switch (*source) {
+ /* no fall-through in this inner switch */
+ case 0xE0: if (a < 0xA0) return false; break;
+ case 0xED: if (a > 0x9F) return false; break;
+ case 0xF0: if (a < 0x90) return false; break;
+ case 0xF4: if (a > 0x8F) return false; break;
+ default: if (a < 0x80) return false;
+ }
+
+ case 1: if (*source >= 0x80 && *source < 0xC2) return false;
+ }
+ if (*source > 0xF4) return false;
+ return true;
+}
+
+/* --------------------------------------------------------------------- */
+
+/*
+ * Exported function to return whether a UTF-8 sequence is legal or not.
+ * This is not used here; it's just exported.
+ */
+Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd) {
+ int length = trailingBytesForUTF8[*source]+1;
+ if (length > sourceEnd - source) {
+ return false;
+ }
+ return isLegalUTF8(source, length);
+}
+
+/* --------------------------------------------------------------------- */
+
+static unsigned
+findMaximalSubpartOfIllFormedUTF8Sequence(const UTF8 *source,
+ const UTF8 *sourceEnd) {
+ UTF8 b1, b2, b3;
+
+ assert(!isLegalUTF8Sequence(source, sourceEnd));
+
+ /*
+ * Unicode 6.3.0, D93b:
+ *
+ * Maximal subpart of an ill-formed subsequence: The longest code unit
+ * subsequence starting at an unconvertible offset that is either:
+ * a. the initial subsequence of a well-formed code unit sequence, or
+ * b. a subsequence of length one.
+ */
+
+ if (source == sourceEnd)
+ return 0;
+
+ /*
+ * Perform case analysis. See Unicode 6.3.0, Table 3-7. Well-Formed UTF-8
+ * Byte Sequences.
+ */
+
+ b1 = *source;
+ ++source;
+ if (b1 >= 0xC2 && b1 <= 0xDF) {
+ /*
+ * First byte is valid, but we know that this code unit sequence is
+ * invalid, so the maximal subpart has to end after the first byte.
+ */
+ return 1;
+ }
+
+ if (source == sourceEnd)
+ return 1;
+
+ b2 = *source;
+ ++source;
+
+ if (b1 == 0xE0) {
+ return (b2 >= 0xA0 && b2 <= 0xBF) ? 2 : 1;
+ }
+ if (b1 >= 0xE1 && b1 <= 0xEC) {
+ return (b2 >= 0x80 && b2 <= 0xBF) ? 2 : 1;
+ }
+ if (b1 == 0xED) {
+ return (b2 >= 0x80 && b2 <= 0x9F) ? 2 : 1;
+ }
+ if (b1 >= 0xEE && b1 <= 0xEF) {
+ return (b2 >= 0x80 && b2 <= 0xBF) ? 2 : 1;
+ }
+ if (b1 == 0xF0) {
+ if (b2 >= 0x90 && b2 <= 0xBF) {
+ if (source == sourceEnd)
+ return 2;
+
+ b3 = *source;
+ return (b3 >= 0x80 && b3 <= 0xBF) ? 3 : 2;
+ }
+ return 1;
+ }
+ if (b1 >= 0xF1 && b1 <= 0xF3) {
+ if (b2 >= 0x80 && b2 <= 0xBF) {
+ if (source == sourceEnd)
+ return 2;
+
+ b3 = *source;
+ return (b3 >= 0x80 && b3 <= 0xBF) ? 3 : 2;
+ }
+ return 1;
+ }
+ if (b1 == 0xF4) {
+ if (b2 >= 0x80 && b2 <= 0x8F) {
+ if (source == sourceEnd)
+ return 2;
+
+ b3 = *source;
+ return (b3 >= 0x80 && b3 <= 0xBF) ? 3 : 2;
+ }
+ return 1;
+ }
+
+ assert((b1 >= 0x80 && b1 <= 0xC1) || b1 >= 0xF5);
+ /*
+ * There are no valid sequences that start with these bytes. Maximal subpart
+ * is defined to have length 1 in these cases.
+ */
+ return 1;
+}
+
+/* --------------------------------------------------------------------- */
+
+/*
+ * Exported function to return the total number of bytes in a codepoint
+ * represented in UTF-8, given the value of the first byte.
+ */
+unsigned getNumBytesForUTF8(UTF8 first) {
+ return trailingBytesForUTF8[first] + 1;
+}
+
+/* --------------------------------------------------------------------- */
+
+/*
+ * Exported function to return whether a UTF-8 string is legal or not.
+ * This is not used here; it's just exported.
+ */
+Boolean isLegalUTF8String(const UTF8 **source, const UTF8 *sourceEnd) {
+ while (*source != sourceEnd) {
+ int length = trailingBytesForUTF8[**source] + 1;
+ if (length > sourceEnd - *source || !isLegalUTF8(*source, length))
+ return false;
+ *source += length;
+ }
+ return true;
+}
+
+/* --------------------------------------------------------------------- */
+
+ConversionResult ConvertUTF8toUTF16 (
+ const UTF8** sourceStart, const UTF8* sourceEnd,
+ UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags) {
+ ConversionResult result = conversionOK;
+ const UTF8* source = *sourceStart;
+ UTF16* target = *targetStart;
+ while (source < sourceEnd) {
+ UTF32 ch = 0;
+ unsigned short extraBytesToRead = trailingBytesForUTF8[*source];
+ if (extraBytesToRead >= sourceEnd - source) {
+ result = sourceExhausted; break;
+ }
+ /* Do this check whether lenient or strict */
+ if (!isLegalUTF8(source, extraBytesToRead+1)) {
+ result = sourceIllegal;
+ break;
+ }
+ /*
+ * The cases all fall through. See "Note A" below.
+ */
+ switch (extraBytesToRead) {
+ case 5: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */
+ case 4: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */
+ case 3: ch += *source++; ch <<= 6;
+ case 2: ch += *source++; ch <<= 6;
+ case 1: ch += *source++; ch <<= 6;
+ case 0: ch += *source++;
+ }
+ ch -= offsetsFromUTF8[extraBytesToRead];
+
+ if (target >= targetEnd) {
+ source -= (extraBytesToRead+1); /* Back up source pointer! */
+ result = targetExhausted; break;
+ }
+ if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */
+ /* UTF-16 surrogate values are illegal in UTF-32 */
+ if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
+ if (flags == strictConversion) {
+ source -= (extraBytesToRead+1); /* return to the illegal value itself */
+ result = sourceIllegal;
+ break;
+ } else {
+ *target++ = UNI_REPLACEMENT_CHAR;
+ }
+ } else {
+ *target++ = (UTF16)ch; /* normal case */
+ }
+ } else if (ch > UNI_MAX_UTF16) {
+ if (flags == strictConversion) {
+ result = sourceIllegal;
+ source -= (extraBytesToRead+1); /* return to the start */
+ break; /* Bail out; shouldn't continue */
+ } else {
+ *target++ = UNI_REPLACEMENT_CHAR;
+ }
+ } else {
+ /* target is a character in range 0xFFFF - 0x10FFFF. */
+ if (target + 1 >= targetEnd) {
+ source -= (extraBytesToRead+1); /* Back up source pointer! */
+ result = targetExhausted; break;
+ }
+ ch -= halfBase;
+ *target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START);
+ *target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START);
+ }
+ }
+ *sourceStart = source;
+ *targetStart = target;
+ return result;
+}
+
+/* --------------------------------------------------------------------- */
+
+static ConversionResult ConvertUTF8toUTF32Impl(
+ const UTF8** sourceStart, const UTF8* sourceEnd,
+ UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags,
+ Boolean InputIsPartial) {
+ ConversionResult result = conversionOK;
+ const UTF8* source = *sourceStart;
+ UTF32* target = *targetStart;
+ while (source < sourceEnd) {
+ UTF32 ch = 0;
+ unsigned short extraBytesToRead = trailingBytesForUTF8[*source];
+ if (extraBytesToRead >= sourceEnd - source) {
+ if (flags == strictConversion || InputIsPartial) {
+ result = sourceExhausted;
+ break;
+ } else {
+ result = sourceIllegal;
+
+ /*
+ * Replace the maximal subpart of ill-formed sequence with
+ * replacement character.
+ */
+ source += findMaximalSubpartOfIllFormedUTF8Sequence(source,
+ sourceEnd);
+ *target++ = UNI_REPLACEMENT_CHAR;
+ continue;
+ }
+ }
+ if (target >= targetEnd) {
+ result = targetExhausted; break;
+ }
+
+ /* Do this check whether lenient or strict */
+ if (!isLegalUTF8(source, extraBytesToRead+1)) {
+ result = sourceIllegal;
+ if (flags == strictConversion) {
+ /* Abort conversion. */
+ break;
+ } else {
+ /*
+ * Replace the maximal subpart of ill-formed sequence with
+ * replacement character.
+ */
+ source += findMaximalSubpartOfIllFormedUTF8Sequence(source,
+ sourceEnd);
+ *target++ = UNI_REPLACEMENT_CHAR;
+ continue;
+ }
+ }
+ /*
+ * The cases all fall through. See "Note A" below.
+ */
+ switch (extraBytesToRead) {
+ case 5: ch += *source++; ch <<= 6;
+ case 4: ch += *source++; ch <<= 6;
+ case 3: ch += *source++; ch <<= 6;
+ case 2: ch += *source++; ch <<= 6;
+ case 1: ch += *source++; ch <<= 6;
+ case 0: ch += *source++;
+ }
+ ch -= offsetsFromUTF8[extraBytesToRead];
+
+ if (ch <= UNI_MAX_LEGAL_UTF32) {
+ /*
+ * UTF-16 surrogate values are illegal in UTF-32, and anything
+ * over Plane 17 (> 0x10FFFF) is illegal.
+ */
+ if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
+ if (flags == strictConversion) {
+ source -= (extraBytesToRead+1); /* return to the illegal value itself */
+ result = sourceIllegal;
+ break;
+ } else {
+ *target++ = UNI_REPLACEMENT_CHAR;
+ }
+ } else {
+ *target++ = ch;
+ }
+ } else { /* i.e., ch > UNI_MAX_LEGAL_UTF32 */
+ result = sourceIllegal;
+ *target++ = UNI_REPLACEMENT_CHAR;
+ }
+ }
+ *sourceStart = source;
+ *targetStart = target;
+ return result;
+}
+
+ConversionResult ConvertUTF8toUTF32Partial(const UTF8 **sourceStart,
+ const UTF8 *sourceEnd,
+ UTF32 **targetStart,
+ UTF32 *targetEnd,
+ ConversionFlags flags) {
+ return ConvertUTF8toUTF32Impl(sourceStart, sourceEnd, targetStart, targetEnd,
+ flags, /*InputIsPartial=*/true);
+}
+
+ConversionResult ConvertUTF8toUTF32(const UTF8 **sourceStart,
+ const UTF8 *sourceEnd, UTF32 **targetStart,
+ UTF32 *targetEnd, ConversionFlags flags) {
+ return ConvertUTF8toUTF32Impl(sourceStart, sourceEnd, targetStart, targetEnd,
+ flags, /*InputIsPartial=*/false);
+}
+
+/* ---------------------------------------------------------------------
+
+ Note A.
+ The fall-through switches in UTF-8 reading code save a
+ temp variable, some decrements & conditionals. The switches
+ are equivalent to the following loop:
+ {
+ int tmpBytesToRead = extraBytesToRead+1;
+ do {
+ ch += *source++;
+ --tmpBytesToRead;
+ if (tmpBytesToRead) ch <<= 6;
+ } while (tmpBytesToRead > 0);
+ }
+ In UTF-8 writing code, the switches on "bytesToWrite" are
+ similarly unrolled loops.
+
+ --------------------------------------------------------------------- */
diff --git a/contrib/llvm/lib/Support/ConvertUTFWrapper.cpp b/contrib/llvm/lib/Support/ConvertUTFWrapper.cpp
new file mode 100644
index 000000000000..1bbef233b82f
--- /dev/null
+++ b/contrib/llvm/lib/Support/ConvertUTFWrapper.cpp
@@ -0,0 +1,172 @@
+//===-- ConvertUTFWrapper.cpp - Wrap ConvertUTF.h with clang data types -----===
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/ConvertUTF.h"
+#include "llvm/Support/SwapByteOrder.h"
+#include <string>
+#include <vector>
+
+namespace llvm {
+
+bool ConvertUTF8toWide(unsigned WideCharWidth, llvm::StringRef Source,
+ char *&ResultPtr, const UTF8 *&ErrorPtr) {
+ assert(WideCharWidth == 1 || WideCharWidth == 2 || WideCharWidth == 4);
+ ConversionResult result = conversionOK;
+ // Copy the character span over.
+ if (WideCharWidth == 1) {
+ const UTF8 *Pos = reinterpret_cast<const UTF8*>(Source.begin());
+ if (!isLegalUTF8String(&Pos, reinterpret_cast<const UTF8*>(Source.end()))) {
+ result = sourceIllegal;
+ ErrorPtr = Pos;
+ } else {
+ memcpy(ResultPtr, Source.data(), Source.size());
+ ResultPtr += Source.size();
+ }
+ } else if (WideCharWidth == 2) {
+ const UTF8 *sourceStart = (const UTF8*)Source.data();
+ // FIXME: Make the type of the result buffer correct instead of
+ // using reinterpret_cast.
+ UTF16 *targetStart = reinterpret_cast<UTF16*>(ResultPtr);
+ ConversionFlags flags = strictConversion;
+ result = ConvertUTF8toUTF16(
+ &sourceStart, sourceStart + Source.size(),
+ &targetStart, targetStart + 2*Source.size(), flags);
+ if (result == conversionOK)
+ ResultPtr = reinterpret_cast<char*>(targetStart);
+ else
+ ErrorPtr = sourceStart;
+ } else if (WideCharWidth == 4) {
+ const UTF8 *sourceStart = (const UTF8*)Source.data();
+ // FIXME: Make the type of the result buffer correct instead of
+ // using reinterpret_cast.
+ UTF32 *targetStart = reinterpret_cast<UTF32*>(ResultPtr);
+ ConversionFlags flags = strictConversion;
+ result = ConvertUTF8toUTF32(
+ &sourceStart, sourceStart + Source.size(),
+ &targetStart, targetStart + 4*Source.size(), flags);
+ if (result == conversionOK)
+ ResultPtr = reinterpret_cast<char*>(targetStart);
+ else
+ ErrorPtr = sourceStart;
+ }
+ assert((result != targetExhausted)
+ && "ConvertUTF8toUTFXX exhausted target buffer");
+ return result == conversionOK;
+}
+
+bool ConvertCodePointToUTF8(unsigned Source, char *&ResultPtr) {
+ const UTF32 *SourceStart = &Source;
+ const UTF32 *SourceEnd = SourceStart + 1;
+ UTF8 *TargetStart = reinterpret_cast<UTF8 *>(ResultPtr);
+ UTF8 *TargetEnd = TargetStart + 4;
+ ConversionResult CR = ConvertUTF32toUTF8(&SourceStart, SourceEnd,
+ &TargetStart, TargetEnd,
+ strictConversion);
+ if (CR != conversionOK)
+ return false;
+
+ ResultPtr = reinterpret_cast<char*>(TargetStart);
+ return true;
+}
+
+bool hasUTF16ByteOrderMark(ArrayRef<char> S) {
+ return (S.size() >= 2 &&
+ ((S[0] == '\xff' && S[1] == '\xfe') ||
+ (S[0] == '\xfe' && S[1] == '\xff')));
+}
+
+bool convertUTF16ToUTF8String(ArrayRef<char> SrcBytes, std::string &Out) {
+ assert(Out.empty());
+
+ // Error out on an uneven byte count.
+ if (SrcBytes.size() % 2)
+ return false;
+
+ // Avoid OOB by returning early on empty input.
+ if (SrcBytes.empty())
+ return true;
+
+ const UTF16 *Src = reinterpret_cast<const UTF16 *>(SrcBytes.begin());
+ const UTF16 *SrcEnd = reinterpret_cast<const UTF16 *>(SrcBytes.end());
+
+ // Byteswap if necessary.
+ std::vector<UTF16> ByteSwapped;
+ if (Src[0] == UNI_UTF16_BYTE_ORDER_MARK_SWAPPED) {
+ ByteSwapped.insert(ByteSwapped.end(), Src, SrcEnd);
+ for (unsigned I = 0, E = ByteSwapped.size(); I != E; ++I)
+ ByteSwapped[I] = llvm::sys::SwapByteOrder_16(ByteSwapped[I]);
+ Src = &ByteSwapped[0];
+ SrcEnd = &ByteSwapped[ByteSwapped.size() - 1] + 1;
+ }
+
+ // Skip the BOM for conversion.
+ if (Src[0] == UNI_UTF16_BYTE_ORDER_MARK_NATIVE)
+ Src++;
+
+ // Just allocate enough space up front. We'll shrink it later. Allocate
+ // enough that we can fit a null terminator without reallocating.
+ Out.resize(SrcBytes.size() * UNI_MAX_UTF8_BYTES_PER_CODE_POINT + 1);
+ UTF8 *Dst = reinterpret_cast<UTF8 *>(&Out[0]);
+ UTF8 *DstEnd = Dst + Out.size();
+
+ ConversionResult CR =
+ ConvertUTF16toUTF8(&Src, SrcEnd, &Dst, DstEnd, strictConversion);
+ assert(CR != targetExhausted);
+
+ if (CR != conversionOK) {
+ Out.clear();
+ return false;
+ }
+
+ Out.resize(reinterpret_cast<char *>(Dst) - &Out[0]);
+ Out.push_back(0);
+ Out.pop_back();
+ return true;
+}
+
+bool convertUTF8ToUTF16String(StringRef SrcUTF8,
+ SmallVectorImpl<UTF16> &DstUTF16) {
+ assert(DstUTF16.empty());
+
+ // Avoid OOB by returning early on empty input.
+ if (SrcUTF8.empty()) {
+ DstUTF16.push_back(0);
+ DstUTF16.pop_back();
+ return true;
+ }
+
+ const UTF8 *Src = reinterpret_cast<const UTF8 *>(SrcUTF8.begin());
+ const UTF8 *SrcEnd = reinterpret_cast<const UTF8 *>(SrcUTF8.end());
+
+ // Allocate the same number of UTF-16 code units as UTF-8 code units. Encoding
+ // as UTF-16 should always require the same amount or less code units than the
+ // UTF-8 encoding. Allocate one extra byte for the null terminator though,
+ // so that someone calling DstUTF16.data() gets a null terminated string.
+ // We resize down later so we don't have to worry that this over allocates.
+ DstUTF16.resize(SrcUTF8.size()+1);
+ UTF16 *Dst = &DstUTF16[0];
+ UTF16 *DstEnd = Dst + DstUTF16.size();
+
+ ConversionResult CR =
+ ConvertUTF8toUTF16(&Src, SrcEnd, &Dst, DstEnd, strictConversion);
+ assert(CR != targetExhausted);
+
+ if (CR != conversionOK) {
+ DstUTF16.clear();
+ return false;
+ }
+
+ DstUTF16.resize(Dst - &DstUTF16[0]);
+ DstUTF16.push_back(0);
+ DstUTF16.pop_back();
+ return true;
+}
+
+} // end namespace llvm
+
diff --git a/contrib/llvm/lib/Support/CrashRecoveryContext.cpp b/contrib/llvm/lib/Support/CrashRecoveryContext.cpp
new file mode 100644
index 000000000000..929f5dacd729
--- /dev/null
+++ b/contrib/llvm/lib/Support/CrashRecoveryContext.cpp
@@ -0,0 +1,374 @@
+//===--- CrashRecoveryContext.cpp - Crash Recovery ------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/CrashRecoveryContext.h"
+#include "llvm/Config/config.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/Mutex.h"
+#include "llvm/Support/ThreadLocal.h"
+#include <setjmp.h>
+using namespace llvm;
+
+namespace {
+
+struct CrashRecoveryContextImpl;
+
+static ManagedStatic<
+ sys::ThreadLocal<const CrashRecoveryContextImpl> > CurrentContext;
+
+struct CrashRecoveryContextImpl {
+ CrashRecoveryContext *CRC;
+ std::string Backtrace;
+ ::jmp_buf JumpBuffer;
+ volatile unsigned Failed : 1;
+ unsigned SwitchedThread : 1;
+
+public:
+ CrashRecoveryContextImpl(CrashRecoveryContext *CRC) : CRC(CRC),
+ Failed(false),
+ SwitchedThread(false) {
+ CurrentContext->set(this);
+ }
+ ~CrashRecoveryContextImpl() {
+ if (!SwitchedThread)
+ CurrentContext->erase();
+ }
+
+ /// \brief Called when the separate crash-recovery thread was finished, to
+ /// indicate that we don't need to clear the thread-local CurrentContext.
+ void setSwitchedThread() { SwitchedThread = true; }
+
+ void HandleCrash() {
+ // Eliminate the current context entry, to avoid re-entering in case the
+ // cleanup code crashes.
+ CurrentContext->erase();
+
+ assert(!Failed && "Crash recovery context already failed!");
+ Failed = true;
+
+ // FIXME: Stash the backtrace.
+
+ // Jump back to the RunSafely we were called under.
+ longjmp(JumpBuffer, 1);
+ }
+};
+
+} // namespace
+
+static ManagedStatic<sys::Mutex> gCrashRecoveryContextMutex;
+static bool gCrashRecoveryEnabled = false;
+
+static ManagedStatic<sys::ThreadLocal<const CrashRecoveryContextCleanup> >
+ tlIsRecoveringFromCrash;
+
+CrashRecoveryContextCleanup::~CrashRecoveryContextCleanup() {}
+
+CrashRecoveryContext::~CrashRecoveryContext() {
+ // Reclaim registered resources.
+ CrashRecoveryContextCleanup *i = head;
+ tlIsRecoveringFromCrash->set(head);
+ while (i) {
+ CrashRecoveryContextCleanup *tmp = i;
+ i = tmp->next;
+ tmp->cleanupFired = true;
+ tmp->recoverResources();
+ delete tmp;
+ }
+ tlIsRecoveringFromCrash->erase();
+
+ CrashRecoveryContextImpl *CRCI = (CrashRecoveryContextImpl *) Impl;
+ delete CRCI;
+}
+
+bool CrashRecoveryContext::isRecoveringFromCrash() {
+ return tlIsRecoveringFromCrash->get() != nullptr;
+}
+
+CrashRecoveryContext *CrashRecoveryContext::GetCurrent() {
+ if (!gCrashRecoveryEnabled)
+ return nullptr;
+
+ const CrashRecoveryContextImpl *CRCI = CurrentContext->get();
+ if (!CRCI)
+ return nullptr;
+
+ return CRCI->CRC;
+}
+
+void CrashRecoveryContext::registerCleanup(CrashRecoveryContextCleanup *cleanup)
+{
+ if (!cleanup)
+ return;
+ if (head)
+ head->prev = cleanup;
+ cleanup->next = head;
+ head = cleanup;
+}
+
+void
+CrashRecoveryContext::unregisterCleanup(CrashRecoveryContextCleanup *cleanup) {
+ if (!cleanup)
+ return;
+ if (cleanup == head) {
+ head = cleanup->next;
+ if (head)
+ head->prev = nullptr;
+ }
+ else {
+ cleanup->prev->next = cleanup->next;
+ if (cleanup->next)
+ cleanup->next->prev = cleanup->prev;
+ }
+ delete cleanup;
+}
+
+#ifdef LLVM_ON_WIN32
+
+#include "Windows/WindowsSupport.h"
+
+// On Windows, we can make use of vectored exception handling to
+// catch most crashing situations. Note that this does mean
+// we will be alerted of exceptions *before* structured exception
+// handling has the opportunity to catch it. But that isn't likely
+// to cause problems because nowhere in the project is SEH being
+// used.
+//
+// Vectored exception handling is built on top of SEH, and so it
+// works on a per-thread basis.
+//
+// The vectored exception handler functionality was added in Windows
+// XP, so if support for older versions of Windows is required,
+// it will have to be added.
+//
+// If we want to support as far back as Win2k, we could use the
+// SetUnhandledExceptionFilter API, but there's a risk of that
+// being entirely overwritten (it's not a chain).
+
+static LONG CALLBACK ExceptionHandler(PEXCEPTION_POINTERS ExceptionInfo)
+{
+ // Lookup the current thread local recovery object.
+ const CrashRecoveryContextImpl *CRCI = CurrentContext->get();
+
+ if (!CRCI) {
+ // Something has gone horribly wrong, so let's just tell everyone
+ // to keep searching
+ CrashRecoveryContext::Disable();
+ return EXCEPTION_CONTINUE_SEARCH;
+ }
+
+ // TODO: We can capture the stack backtrace here and store it on the
+ // implementation if we so choose.
+
+ // Handle the crash
+ const_cast<CrashRecoveryContextImpl*>(CRCI)->HandleCrash();
+
+ // Note that we don't actually get here because HandleCrash calls
+ // longjmp, which means the HandleCrash function never returns.
+ llvm_unreachable("Handled the crash, should have longjmp'ed out of here");
+}
+
+// Because the Enable and Disable calls are static, it means that
+// there may not actually be an Impl available, or even a current
+// CrashRecoveryContext at all. So we make use of a thread-local
+// exception table. The handles contained in here will either be
+// non-NULL, valid VEH handles, or NULL.
+static sys::ThreadLocal<const void> sCurrentExceptionHandle;
+
+void CrashRecoveryContext::Enable() {
+ sys::ScopedLock L(*gCrashRecoveryContextMutex);
+
+ if (gCrashRecoveryEnabled)
+ return;
+
+ gCrashRecoveryEnabled = true;
+
+ // We can set up vectored exception handling now. We will install our
+ // handler as the front of the list, though there's no assurances that
+ // it will remain at the front (another call could install itself before
+ // our handler). This 1) isn't likely, and 2) shouldn't cause problems.
+ PVOID handle = ::AddVectoredExceptionHandler(1, ExceptionHandler);
+ sCurrentExceptionHandle.set(handle);
+}
+
+void CrashRecoveryContext::Disable() {
+ sys::ScopedLock L(*gCrashRecoveryContextMutex);
+
+ if (!gCrashRecoveryEnabled)
+ return;
+
+ gCrashRecoveryEnabled = false;
+
+ PVOID currentHandle = const_cast<PVOID>(sCurrentExceptionHandle.get());
+ if (currentHandle) {
+ // Now we can remove the vectored exception handler from the chain
+ ::RemoveVectoredExceptionHandler(currentHandle);
+
+ // Reset the handle in our thread-local set.
+ sCurrentExceptionHandle.set(NULL);
+ }
+}
+
+#else
+
+// Generic POSIX implementation.
+//
+// This implementation relies on synchronous signals being delivered to the
+// current thread. We use a thread local object to keep track of the active
+// crash recovery context, and install signal handlers to invoke HandleCrash on
+// the active object.
+//
+// This implementation does not to attempt to chain signal handlers in any
+// reliable fashion -- if we get a signal outside of a crash recovery context we
+// simply disable crash recovery and raise the signal again.
+
+#include <signal.h>
+
+static const int Signals[] =
+ { SIGABRT, SIGBUS, SIGFPE, SIGILL, SIGSEGV, SIGTRAP };
+static const unsigned NumSignals = sizeof(Signals) / sizeof(Signals[0]);
+static struct sigaction PrevActions[NumSignals];
+
+static void CrashRecoverySignalHandler(int Signal) {
+ // Lookup the current thread local recovery object.
+ const CrashRecoveryContextImpl *CRCI = CurrentContext->get();
+
+ if (!CRCI) {
+ // We didn't find a crash recovery context -- this means either we got a
+ // signal on a thread we didn't expect it on, the application got a signal
+ // outside of a crash recovery context, or something else went horribly
+ // wrong.
+ //
+ // Disable crash recovery and raise the signal again. The assumption here is
+ // that the enclosing application will terminate soon, and we won't want to
+ // attempt crash recovery again.
+ //
+ // This call of Disable isn't thread safe, but it doesn't actually matter.
+ CrashRecoveryContext::Disable();
+ raise(Signal);
+
+ // The signal will be thrown once the signal mask is restored.
+ return;
+ }
+
+ // Unblock the signal we received.
+ sigset_t SigMask;
+ sigemptyset(&SigMask);
+ sigaddset(&SigMask, Signal);
+ sigprocmask(SIG_UNBLOCK, &SigMask, nullptr);
+
+ if (CRCI)
+ const_cast<CrashRecoveryContextImpl*>(CRCI)->HandleCrash();
+}
+
+void CrashRecoveryContext::Enable() {
+ sys::ScopedLock L(*gCrashRecoveryContextMutex);
+
+ if (gCrashRecoveryEnabled)
+ return;
+
+ gCrashRecoveryEnabled = true;
+
+ // Setup the signal handler.
+ struct sigaction Handler;
+ Handler.sa_handler = CrashRecoverySignalHandler;
+ Handler.sa_flags = 0;
+ sigemptyset(&Handler.sa_mask);
+
+ for (unsigned i = 0; i != NumSignals; ++i) {
+ sigaction(Signals[i], &Handler, &PrevActions[i]);
+ }
+}
+
+void CrashRecoveryContext::Disable() {
+ sys::ScopedLock L(*gCrashRecoveryContextMutex);
+
+ if (!gCrashRecoveryEnabled)
+ return;
+
+ gCrashRecoveryEnabled = false;
+
+ // Restore the previous signal handlers.
+ for (unsigned i = 0; i != NumSignals; ++i)
+ sigaction(Signals[i], &PrevActions[i], nullptr);
+}
+
+#endif
+
+bool CrashRecoveryContext::RunSafely(function_ref<void()> Fn) {
+ // If crash recovery is disabled, do nothing.
+ if (gCrashRecoveryEnabled) {
+ assert(!Impl && "Crash recovery context already initialized!");
+ CrashRecoveryContextImpl *CRCI = new CrashRecoveryContextImpl(this);
+ Impl = CRCI;
+
+ if (setjmp(CRCI->JumpBuffer) != 0) {
+ return false;
+ }
+ }
+
+ Fn();
+ return true;
+}
+
+void CrashRecoveryContext::HandleCrash() {
+ CrashRecoveryContextImpl *CRCI = (CrashRecoveryContextImpl *) Impl;
+ assert(CRCI && "Crash recovery context never initialized!");
+ CRCI->HandleCrash();
+}
+
+const std::string &CrashRecoveryContext::getBacktrace() const {
+ CrashRecoveryContextImpl *CRC = (CrashRecoveryContextImpl *) Impl;
+ assert(CRC && "Crash recovery context never initialized!");
+ assert(CRC->Failed && "No crash was detected!");
+ return CRC->Backtrace;
+}
+
+// FIXME: Portability.
+static void setThreadBackgroundPriority() {
+#ifdef __APPLE__
+ setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
+#endif
+}
+
+static bool hasThreadBackgroundPriority() {
+#ifdef __APPLE__
+ return getpriority(PRIO_DARWIN_THREAD, 0) == 1;
+#else
+ return false;
+#endif
+}
+
+namespace {
+struct RunSafelyOnThreadInfo {
+ function_ref<void()> Fn;
+ CrashRecoveryContext *CRC;
+ bool UseBackgroundPriority;
+ bool Result;
+};
+}
+
+static void RunSafelyOnThread_Dispatch(void *UserData) {
+ RunSafelyOnThreadInfo *Info =
+ reinterpret_cast<RunSafelyOnThreadInfo*>(UserData);
+
+ if (Info->UseBackgroundPriority)
+ setThreadBackgroundPriority();
+
+ Info->Result = Info->CRC->RunSafely(Info->Fn);
+}
+bool CrashRecoveryContext::RunSafelyOnThread(function_ref<void()> Fn,
+ unsigned RequestedStackSize) {
+ bool UseBackgroundPriority = hasThreadBackgroundPriority();
+ RunSafelyOnThreadInfo Info = { Fn, this, UseBackgroundPriority, false };
+ llvm_execute_on_thread(RunSafelyOnThread_Dispatch, &Info, RequestedStackSize);
+ if (CrashRecoveryContextImpl *CRC = (CrashRecoveryContextImpl *)Impl)
+ CRC->setSwitchedThread();
+ return Info.Result;
+}
diff --git a/contrib/llvm/lib/Support/DAGDeltaAlgorithm.cpp b/contrib/llvm/lib/Support/DAGDeltaAlgorithm.cpp
new file mode 100644
index 000000000000..0f447808cc4d
--- /dev/null
+++ b/contrib/llvm/lib/Support/DAGDeltaAlgorithm.cpp
@@ -0,0 +1,354 @@
+//===--- DAGDeltaAlgorithm.cpp - A DAG Minimization Algorithm --*- C++ -*--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//===----------------------------------------------------------------------===//
+//
+// The algorithm we use attempts to exploit the dependency information by
+// minimizing top-down. We start by constructing an initial root set R, and
+// then iteratively:
+//
+// 1. Minimize the set R using the test predicate:
+// P'(S) = P(S union pred*(S))
+//
+// 2. Extend R to R' = R union pred(R).
+//
+// until a fixed point is reached.
+//
+// The idea is that we want to quickly prune entire portions of the graph, so we
+// try to find high-level nodes that can be eliminated with all of their
+// dependents.
+//
+// FIXME: The current algorithm doesn't actually provide a strong guarantee
+// about the minimality of the result. The problem is that after adding nodes to
+// the required set, we no longer consider them for elimination. For strictly
+// well formed predicates, this doesn't happen, but it commonly occurs in
+// practice when there are unmodelled dependencies. I believe we can resolve
+// this by allowing the required set to be minimized as well, but need more test
+// cases first.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/DAGDeltaAlgorithm.h"
+#include "llvm/ADT/DeltaAlgorithm.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <cassert>
+#include <iterator>
+#include <map>
+using namespace llvm;
+
+#define DEBUG_TYPE "dag-delta"
+
+namespace {
+
+class DAGDeltaAlgorithmImpl {
+ friend class DeltaActiveSetHelper;
+
+public:
+ typedef DAGDeltaAlgorithm::change_ty change_ty;
+ typedef DAGDeltaAlgorithm::changeset_ty changeset_ty;
+ typedef DAGDeltaAlgorithm::changesetlist_ty changesetlist_ty;
+ typedef DAGDeltaAlgorithm::edge_ty edge_ty;
+
+private:
+ typedef std::vector<change_ty>::iterator pred_iterator_ty;
+ typedef std::vector<change_ty>::iterator succ_iterator_ty;
+ typedef std::set<change_ty>::iterator pred_closure_iterator_ty;
+ typedef std::set<change_ty>::iterator succ_closure_iterator_ty;
+
+ DAGDeltaAlgorithm &DDA;
+
+ std::vector<change_ty> Roots;
+
+ /// Cache of failed test results. Successful test results are never cached
+ /// since we always reduce following a success. We maintain an independent
+ /// cache from that used by the individual delta passes because we may get
+ /// hits across multiple individual delta invocations.
+ mutable std::set<changeset_ty> FailedTestsCache;
+
+ // FIXME: Gross.
+ std::map<change_ty, std::vector<change_ty> > Predecessors;
+ std::map<change_ty, std::vector<change_ty> > Successors;
+
+ std::map<change_ty, std::set<change_ty> > PredClosure;
+ std::map<change_ty, std::set<change_ty> > SuccClosure;
+
+private:
+ pred_iterator_ty pred_begin(change_ty Node) {
+ assert(Predecessors.count(Node) && "Invalid node!");
+ return Predecessors[Node].begin();
+ }
+ pred_iterator_ty pred_end(change_ty Node) {
+ assert(Predecessors.count(Node) && "Invalid node!");
+ return Predecessors[Node].end();
+ }
+
+ pred_closure_iterator_ty pred_closure_begin(change_ty Node) {
+ assert(PredClosure.count(Node) && "Invalid node!");
+ return PredClosure[Node].begin();
+ }
+ pred_closure_iterator_ty pred_closure_end(change_ty Node) {
+ assert(PredClosure.count(Node) && "Invalid node!");
+ return PredClosure[Node].end();
+ }
+
+ succ_iterator_ty succ_begin(change_ty Node) {
+ assert(Successors.count(Node) && "Invalid node!");
+ return Successors[Node].begin();
+ }
+ succ_iterator_ty succ_end(change_ty Node) {
+ assert(Successors.count(Node) && "Invalid node!");
+ return Successors[Node].end();
+ }
+
+ succ_closure_iterator_ty succ_closure_begin(change_ty Node) {
+ assert(SuccClosure.count(Node) && "Invalid node!");
+ return SuccClosure[Node].begin();
+ }
+ succ_closure_iterator_ty succ_closure_end(change_ty Node) {
+ assert(SuccClosure.count(Node) && "Invalid node!");
+ return SuccClosure[Node].end();
+ }
+
+ void UpdatedSearchState(const changeset_ty &Changes,
+ const changesetlist_ty &Sets,
+ const changeset_ty &Required) {
+ DDA.UpdatedSearchState(Changes, Sets, Required);
+ }
+
+ /// ExecuteOneTest - Execute a single test predicate on the change set \p S.
+ bool ExecuteOneTest(const changeset_ty &S) {
+ // Check dependencies invariant.
+ DEBUG({
+ for (changeset_ty::const_iterator it = S.begin(),
+ ie = S.end(); it != ie; ++it)
+ for (succ_iterator_ty it2 = succ_begin(*it),
+ ie2 = succ_end(*it); it2 != ie2; ++it2)
+ assert(S.count(*it2) && "Attempt to run invalid changeset!");
+ });
+
+ return DDA.ExecuteOneTest(S);
+ }
+
+public:
+ DAGDeltaAlgorithmImpl(DAGDeltaAlgorithm &DDA, const changeset_ty &Changes,
+ const std::vector<edge_ty> &Dependencies);
+
+ changeset_ty Run();
+
+ /// GetTestResult - Get the test result for the active set \p Changes with
+ /// \p Required changes from the cache, executing the test if necessary.
+ ///
+ /// \param Changes - The set of active changes being minimized, which should
+ /// have their pred closure included in the test.
+ /// \param Required - The set of changes which have previously been
+ /// established to be required.
+ /// \return - The test result.
+ bool GetTestResult(const changeset_ty &Changes, const changeset_ty &Required);
+};
+
+/// Helper object for minimizing an active set of changes.
+class DeltaActiveSetHelper : public DeltaAlgorithm {
+ DAGDeltaAlgorithmImpl &DDAI;
+
+ const changeset_ty &Required;
+
+protected:
+ /// UpdatedSearchState - Callback used when the search state changes.
+ void UpdatedSearchState(const changeset_ty &Changes,
+ const changesetlist_ty &Sets) override {
+ DDAI.UpdatedSearchState(Changes, Sets, Required);
+ }
+
+ bool ExecuteOneTest(const changeset_ty &S) override {
+ return DDAI.GetTestResult(S, Required);
+ }
+
+public:
+ DeltaActiveSetHelper(DAGDeltaAlgorithmImpl &DDAI,
+ const changeset_ty &Required)
+ : DDAI(DDAI), Required(Required) {}
+};
+
+} // namespace
+
+DAGDeltaAlgorithmImpl::DAGDeltaAlgorithmImpl(
+ DAGDeltaAlgorithm &DDA, const changeset_ty &Changes,
+ const std::vector<edge_ty> &Dependencies)
+ : DDA(DDA) {
+ for (changeset_ty::const_iterator it = Changes.begin(),
+ ie = Changes.end(); it != ie; ++it) {
+ Predecessors.insert(std::make_pair(*it, std::vector<change_ty>()));
+ Successors.insert(std::make_pair(*it, std::vector<change_ty>()));
+ }
+ for (std::vector<edge_ty>::const_iterator it = Dependencies.begin(),
+ ie = Dependencies.end(); it != ie; ++it) {
+ Predecessors[it->second].push_back(it->first);
+ Successors[it->first].push_back(it->second);
+ }
+
+ // Compute the roots.
+ for (changeset_ty::const_iterator it = Changes.begin(),
+ ie = Changes.end(); it != ie; ++it)
+ if (succ_begin(*it) == succ_end(*it))
+ Roots.push_back(*it);
+
+ // Pre-compute the closure of the successor relation.
+ std::vector<change_ty> Worklist(Roots.begin(), Roots.end());
+ while (!Worklist.empty()) {
+ change_ty Change = Worklist.back();
+ Worklist.pop_back();
+
+ std::set<change_ty> &ChangeSuccs = SuccClosure[Change];
+ for (pred_iterator_ty it = pred_begin(Change),
+ ie = pred_end(Change); it != ie; ++it) {
+ SuccClosure[*it].insert(Change);
+ SuccClosure[*it].insert(ChangeSuccs.begin(), ChangeSuccs.end());
+ Worklist.push_back(*it);
+ }
+ }
+
+ // Invert to form the predecessor closure map.
+ for (changeset_ty::const_iterator it = Changes.begin(),
+ ie = Changes.end(); it != ie; ++it)
+ PredClosure.insert(std::make_pair(*it, std::set<change_ty>()));
+ for (changeset_ty::const_iterator it = Changes.begin(),
+ ie = Changes.end(); it != ie; ++it)
+ for (succ_closure_iterator_ty it2 = succ_closure_begin(*it),
+ ie2 = succ_closure_end(*it); it2 != ie2; ++it2)
+ PredClosure[*it2].insert(*it);
+
+ // Dump useful debug info.
+ DEBUG({
+ llvm::errs() << "-- DAGDeltaAlgorithmImpl --\n";
+ llvm::errs() << "Changes: [";
+ for (changeset_ty::const_iterator it = Changes.begin(),
+ ie = Changes.end(); it != ie; ++it) {
+ if (it != Changes.begin()) llvm::errs() << ", ";
+ llvm::errs() << *it;
+
+ if (succ_begin(*it) != succ_end(*it)) {
+ llvm::errs() << "(";
+ for (succ_iterator_ty it2 = succ_begin(*it),
+ ie2 = succ_end(*it); it2 != ie2; ++it2) {
+ if (it2 != succ_begin(*it)) llvm::errs() << ", ";
+ llvm::errs() << "->" << *it2;
+ }
+ llvm::errs() << ")";
+ }
+ }
+ llvm::errs() << "]\n";
+
+ llvm::errs() << "Roots: [";
+ for (std::vector<change_ty>::const_iterator it = Roots.begin(),
+ ie = Roots.end(); it != ie; ++it) {
+ if (it != Roots.begin()) llvm::errs() << ", ";
+ llvm::errs() << *it;
+ }
+ llvm::errs() << "]\n";
+
+ llvm::errs() << "Predecessor Closure:\n";
+ for (changeset_ty::const_iterator it = Changes.begin(),
+ ie = Changes.end(); it != ie; ++it) {
+ llvm::errs() << format(" %-4d: [", *it);
+ for (pred_closure_iterator_ty it2 = pred_closure_begin(*it),
+ ie2 = pred_closure_end(*it); it2 != ie2; ++it2) {
+ if (it2 != pred_closure_begin(*it)) llvm::errs() << ", ";
+ llvm::errs() << *it2;
+ }
+ llvm::errs() << "]\n";
+ }
+
+ llvm::errs() << "Successor Closure:\n";
+ for (changeset_ty::const_iterator it = Changes.begin(),
+ ie = Changes.end(); it != ie; ++it) {
+ llvm::errs() << format(" %-4d: [", *it);
+ for (succ_closure_iterator_ty it2 = succ_closure_begin(*it),
+ ie2 = succ_closure_end(*it); it2 != ie2; ++it2) {
+ if (it2 != succ_closure_begin(*it)) llvm::errs() << ", ";
+ llvm::errs() << *it2;
+ }
+ llvm::errs() << "]\n";
+ }
+
+ llvm::errs() << "\n\n";
+ });
+}
+
+bool DAGDeltaAlgorithmImpl::GetTestResult(const changeset_ty &Changes,
+ const changeset_ty &Required) {
+ changeset_ty Extended(Required);
+ Extended.insert(Changes.begin(), Changes.end());
+ for (changeset_ty::const_iterator it = Changes.begin(),
+ ie = Changes.end(); it != ie; ++it)
+ Extended.insert(pred_closure_begin(*it), pred_closure_end(*it));
+
+ if (FailedTestsCache.count(Extended))
+ return false;
+
+ bool Result = ExecuteOneTest(Extended);
+ if (!Result)
+ FailedTestsCache.insert(Extended);
+
+ return Result;
+}
+
+DAGDeltaAlgorithm::changeset_ty
+DAGDeltaAlgorithmImpl::Run() {
+ // The current set of changes we are minimizing, starting at the roots.
+ changeset_ty CurrentSet(Roots.begin(), Roots.end());
+
+ // The set of required changes.
+ changeset_ty Required;
+
+ // Iterate until the active set of changes is empty. Convergence is guaranteed
+ // assuming input was a DAG.
+ //
+ // Invariant: CurrentSet intersect Required == {}
+ // Invariant: Required == (Required union succ*(Required))
+ while (!CurrentSet.empty()) {
+ DEBUG({
+ llvm::errs() << "DAG_DD - " << CurrentSet.size() << " active changes, "
+ << Required.size() << " required changes\n";
+ });
+
+ // Minimize the current set of changes.
+ DeltaActiveSetHelper Helper(*this, Required);
+ changeset_ty CurrentMinSet = Helper.Run(CurrentSet);
+
+ // Update the set of required changes. Since
+ // CurrentMinSet subset CurrentSet
+ // and after the last iteration,
+ // succ(CurrentSet) subset Required
+ // then
+ // succ(CurrentMinSet) subset Required
+ // and our invariant on Required is maintained.
+ Required.insert(CurrentMinSet.begin(), CurrentMinSet.end());
+
+ // Replace the current set with the predecssors of the minimized set of
+ // active changes.
+ CurrentSet.clear();
+ for (changeset_ty::const_iterator it = CurrentMinSet.begin(),
+ ie = CurrentMinSet.end(); it != ie; ++it)
+ CurrentSet.insert(pred_begin(*it), pred_end(*it));
+
+ // FIXME: We could enforce CurrentSet intersect Required == {} here if we
+ // wanted to protect against cyclic graphs.
+ }
+
+ return Required;
+}
+
+void DAGDeltaAlgorithm::anchor() {
+}
+
+DAGDeltaAlgorithm::changeset_ty
+DAGDeltaAlgorithm::Run(const changeset_ty &Changes,
+ const std::vector<edge_ty> &Dependencies) {
+ return DAGDeltaAlgorithmImpl(*this, Changes, Dependencies).Run();
+}
diff --git a/contrib/llvm/lib/Support/DataExtractor.cpp b/contrib/llvm/lib/Support/DataExtractor.cpp
new file mode 100644
index 000000000000..5d6d60a87fbf
--- /dev/null
+++ b/contrib/llvm/lib/Support/DataExtractor.cpp
@@ -0,0 +1,175 @@
+//===-- DataExtractor.cpp -------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/DataExtractor.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/Host.h"
+#include "llvm/Support/SwapByteOrder.h"
+using namespace llvm;
+
+template <typename T>
+static T getU(uint32_t *offset_ptr, const DataExtractor *de,
+ bool isLittleEndian, const char *Data) {
+ T val = 0;
+ uint32_t offset = *offset_ptr;
+ if (de->isValidOffsetForDataOfSize(offset, sizeof(val))) {
+ std::memcpy(&val, &Data[offset], sizeof(val));
+ if (sys::IsLittleEndianHost != isLittleEndian)
+ sys::swapByteOrder(val);
+
+ // Advance the offset
+ *offset_ptr += sizeof(val);
+ }
+ return val;
+}
+
+template <typename T>
+static T *getUs(uint32_t *offset_ptr, T *dst, uint32_t count,
+ const DataExtractor *de, bool isLittleEndian, const char *Data){
+ uint32_t offset = *offset_ptr;
+
+ if (count > 0 && de->isValidOffsetForDataOfSize(offset, sizeof(*dst)*count)) {
+ for (T *value_ptr = dst, *end = dst + count; value_ptr != end;
+ ++value_ptr, offset += sizeof(*dst))
+ *value_ptr = getU<T>(offset_ptr, de, isLittleEndian, Data);
+ // Advance the offset
+ *offset_ptr = offset;
+ // Return a non-NULL pointer to the converted data as an indicator of
+ // success
+ return dst;
+ }
+ return nullptr;
+}
+
+uint8_t DataExtractor::getU8(uint32_t *offset_ptr) const {
+ return getU<uint8_t>(offset_ptr, this, IsLittleEndian, Data.data());
+}
+
+uint8_t *
+DataExtractor::getU8(uint32_t *offset_ptr, uint8_t *dst, uint32_t count) const {
+ return getUs<uint8_t>(offset_ptr, dst, count, this, IsLittleEndian,
+ Data.data());
+}
+
+
+uint16_t DataExtractor::getU16(uint32_t *offset_ptr) const {
+ return getU<uint16_t>(offset_ptr, this, IsLittleEndian, Data.data());
+}
+
+uint16_t *DataExtractor::getU16(uint32_t *offset_ptr, uint16_t *dst,
+ uint32_t count) const {
+ return getUs<uint16_t>(offset_ptr, dst, count, this, IsLittleEndian,
+ Data.data());
+}
+
+uint32_t DataExtractor::getU32(uint32_t *offset_ptr) const {
+ return getU<uint32_t>(offset_ptr, this, IsLittleEndian, Data.data());
+}
+
+uint32_t *DataExtractor::getU32(uint32_t *offset_ptr, uint32_t *dst,
+ uint32_t count) const {
+ return getUs<uint32_t>(offset_ptr, dst, count, this, IsLittleEndian,
+ Data.data());
+}
+
+uint64_t DataExtractor::getU64(uint32_t *offset_ptr) const {
+ return getU<uint64_t>(offset_ptr, this, IsLittleEndian, Data.data());
+}
+
+uint64_t *DataExtractor::getU64(uint32_t *offset_ptr, uint64_t *dst,
+ uint32_t count) const {
+ return getUs<uint64_t>(offset_ptr, dst, count, this, IsLittleEndian,
+ Data.data());
+}
+
+uint64_t
+DataExtractor::getUnsigned(uint32_t *offset_ptr, uint32_t byte_size) const {
+ switch (byte_size) {
+ case 1:
+ return getU8(offset_ptr);
+ case 2:
+ return getU16(offset_ptr);
+ case 4:
+ return getU32(offset_ptr);
+ case 8:
+ return getU64(offset_ptr);
+ }
+ llvm_unreachable("getUnsigned unhandled case!");
+}
+
+int64_t
+DataExtractor::getSigned(uint32_t *offset_ptr, uint32_t byte_size) const {
+ switch (byte_size) {
+ case 1:
+ return (int8_t)getU8(offset_ptr);
+ case 2:
+ return (int16_t)getU16(offset_ptr);
+ case 4:
+ return (int32_t)getU32(offset_ptr);
+ case 8:
+ return (int64_t)getU64(offset_ptr);
+ }
+ llvm_unreachable("getSigned unhandled case!");
+}
+
+const char *DataExtractor::getCStr(uint32_t *offset_ptr) const {
+ uint32_t offset = *offset_ptr;
+ StringRef::size_type pos = Data.find('\0', offset);
+ if (pos != StringRef::npos) {
+ *offset_ptr = pos + 1;
+ return Data.data() + offset;
+ }
+ return nullptr;
+}
+
+uint64_t DataExtractor::getULEB128(uint32_t *offset_ptr) const {
+ uint64_t result = 0;
+ if (Data.empty())
+ return 0;
+
+ unsigned shift = 0;
+ uint32_t offset = *offset_ptr;
+ uint8_t byte = 0;
+
+ while (isValidOffset(offset)) {
+ byte = Data[offset++];
+ result |= uint64_t(byte & 0x7f) << shift;
+ shift += 7;
+ if ((byte & 0x80) == 0)
+ break;
+ }
+
+ *offset_ptr = offset;
+ return result;
+}
+
+int64_t DataExtractor::getSLEB128(uint32_t *offset_ptr) const {
+ int64_t result = 0;
+ if (Data.empty())
+ return 0;
+
+ unsigned shift = 0;
+ uint32_t offset = *offset_ptr;
+ uint8_t byte = 0;
+
+ while (isValidOffset(offset)) {
+ byte = Data[offset++];
+ result |= uint64_t(byte & 0x7f) << shift;
+ shift += 7;
+ if ((byte & 0x80) == 0)
+ break;
+ }
+
+ // Sign bit of byte is 2nd high order bit (0x40)
+ if (shift < 64 && (byte & 0x40))
+ result |= -(1ULL << shift);
+
+ *offset_ptr = offset;
+ return result;
+}
diff --git a/contrib/llvm/lib/Support/DataStream.cpp b/contrib/llvm/lib/Support/DataStream.cpp
new file mode 100644
index 000000000000..ad05494f9c67
--- /dev/null
+++ b/contrib/llvm/lib/Support/DataStream.cpp
@@ -0,0 +1,86 @@
+//===--- llvm/Support/DataStream.cpp - Lazy streamed data -----------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements DataStreamer, which fetches bytes of Data from
+// a stream source. It provides support for streaming (lazy reading) of
+// bitcode. An example implementation of streaming from a file or stdin
+// is included.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/DataStream.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Program.h"
+#include <string>
+#include <system_error>
+#if !defined(_MSC_VER) && !defined(__MINGW32__)
+#include <unistd.h>
+#else
+#include <io.h>
+#endif
+using namespace llvm;
+
+#define DEBUG_TYPE "Data-stream"
+
+// Interface goals:
+// * StreamingMemoryObject doesn't care about complexities like using
+// threads/async callbacks to actually overlap download+compile
+// * Don't want to duplicate Data in memory
+// * Don't need to know total Data len in advance
+// Non-goals:
+// StreamingMemoryObject already has random access so this interface only does
+// in-order streaming (no arbitrary seeking, else we'd have to buffer all the
+// Data here in addition to MemoryObject). This also means that if we want
+// to be able to to free Data, BitstreamBytes/BitcodeReader will implement it
+
+STATISTIC(NumStreamFetches, "Number of calls to Data stream fetch");
+
+namespace llvm {
+DataStreamer::~DataStreamer() {}
+}
+
+namespace {
+
+// Very simple stream backed by a file. Mostly useful for stdin and debugging;
+// actual file access is probably still best done with mmap.
+class DataFileStreamer : public DataStreamer {
+ int Fd;
+public:
+ DataFileStreamer() : Fd(0) {}
+ ~DataFileStreamer() override { close(Fd); }
+ size_t GetBytes(unsigned char *buf, size_t len) override {
+ NumStreamFetches++;
+ return read(Fd, buf, len);
+ }
+
+ std::error_code OpenFile(const std::string &Filename) {
+ if (Filename == "-") {
+ Fd = 0;
+ sys::ChangeStdinToBinary();
+ return std::error_code();
+ }
+
+ return sys::fs::openFileForRead(Filename, Fd);
+ }
+};
+
+} // namespace
+
+std::unique_ptr<DataStreamer>
+llvm::getDataFileStreamer(const std::string &Filename, std::string *StrError) {
+ std::unique_ptr<DataFileStreamer> s = make_unique<DataFileStreamer>();
+ if (std::error_code e = s->OpenFile(Filename)) {
+ *StrError = std::string("Could not open ") + Filename + ": " +
+ e.message() + "\n";
+ return nullptr;
+ }
+ return std::move(s);
+}
diff --git a/contrib/llvm/lib/Support/Debug.cpp b/contrib/llvm/lib/Support/Debug.cpp
new file mode 100644
index 000000000000..2052662ab1bf
--- /dev/null
+++ b/contrib/llvm/lib/Support/Debug.cpp
@@ -0,0 +1,156 @@
+//===-- Debug.cpp - An easy way to add debug output to your code ----------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file 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 without assertions, the -debug-* options and all code in
+// DEBUG() statements disappears, so it does not affect the runtime of the code.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/Signals.h"
+#include "llvm/Support/circular_raw_ostream.h"
+#include "llvm/Support/raw_ostream.h"
+
+#undef isCurrentDebugType
+#undef setCurrentDebugType
+
+using namespace llvm;
+
+// Even though LLVM might be built with NDEBUG, define symbols that the code
+// built without NDEBUG can depend on via the llvm/Support/Debug.h header.
+namespace llvm {
+/// Exported boolean set by the -debug option.
+bool DebugFlag = false;
+
+static ManagedStatic<std::vector<std::string>> CurrentDebugType;
+
+/// 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 *DebugType) {
+ if (CurrentDebugType->empty())
+ return true;
+ // See if DebugType is in list. Note: do not use find() as that forces us to
+ // unnecessarily create an std::string instance.
+ for (auto &d : *CurrentDebugType) {
+ if (d == DebugType)
+ return true;
+ }
+ return false;
+}
+
+/// Set the current debug type, as if the -debug-only=X
+/// option were specified. Note that DebugFlag also needs to be set to true for
+/// debug output to be produced.
+///
+void setCurrentDebugType(const char *Type) {
+ CurrentDebugType->clear();
+ CurrentDebugType->push_back(Type);
+}
+
+} // namespace llvm
+
+// All Debug.h functionality is a no-op in NDEBUG mode.
+#ifndef NDEBUG
+
+// -debug - Command line option to enable the DEBUG statements in the passes.
+// This flag may only be enabled in debug builds.
+static cl::opt<bool, true>
+Debug("debug", cl::desc("Enable debug output"), cl::Hidden,
+ cl::location(DebugFlag));
+
+// -debug-buffer-size - Buffer the last N characters of debug output
+//until program termination.
+static cl::opt<unsigned>
+DebugBufferSize("debug-buffer-size",
+ cl::desc("Buffer the last N characters of debug output "
+ "until program termination. "
+ "[default 0 -- immediate print-out]"),
+ cl::Hidden,
+ cl::init(0));
+
+namespace {
+
+struct DebugOnlyOpt {
+ void operator=(const std::string &Val) const {
+ if (Val.empty())
+ return;
+ DebugFlag = true;
+ CurrentDebugType->push_back(Val);
+ }
+};
+
+} // namespace
+
+static DebugOnlyOpt DebugOnlyOptLoc;
+
+static cl::opt<DebugOnlyOpt, true, cl::parser<std::string> >
+DebugOnly("debug-only", cl::desc("Enable a specific type of debug output"),
+ cl::Hidden, cl::ZeroOrMore, cl::value_desc("debug string"),
+ cl::location(DebugOnlyOptLoc), cl::ValueRequired);
+
+// Signal handlers - dump debug output on termination.
+static void debug_user_sig_handler(void *Cookie) {
+ // This is a bit sneaky. Since this is under #ifndef NDEBUG, we
+ // know that debug mode is enabled and dbgs() really is a
+ // circular_raw_ostream. If NDEBUG is defined, then dbgs() ==
+ // errs() but this will never be invoked.
+ llvm::circular_raw_ostream &dbgout =
+ static_cast<circular_raw_ostream &>(llvm::dbgs());
+ dbgout.flushBufferWithBanner();
+}
+
+/// dbgs - Return a circular-buffered debug stream.
+raw_ostream &llvm::dbgs() {
+ // Do one-time initialization in a thread-safe way.
+ static struct dbgstream {
+ circular_raw_ostream strm;
+
+ dbgstream() :
+ strm(errs(), "*** Debug Log Output ***\n",
+ (!EnableDebugBuffering || !DebugFlag) ? 0 : DebugBufferSize) {
+ if (EnableDebugBuffering && DebugFlag && DebugBufferSize != 0)
+ // TODO: Add a handler for SIGUSER1-type signals so the user can
+ // force a debug dump.
+ sys::AddSignalHandler(&debug_user_sig_handler, nullptr);
+ // Otherwise we've already set the debug stream buffer size to
+ // zero, disabling buffering so it will output directly to errs().
+ }
+ } thestrm;
+
+ return thestrm.strm;
+}
+
+#else
+// Avoid "has no symbols" warning.
+namespace llvm {
+ /// dbgs - Return errs().
+ raw_ostream &dbgs() {
+ return errs();
+ }
+}
+
+#endif
+
+/// EnableDebugBuffering - Turn on signal handler installation.
+///
+bool llvm::EnableDebugBuffering = false;
diff --git a/contrib/llvm/lib/Support/DeltaAlgorithm.cpp b/contrib/llvm/lib/Support/DeltaAlgorithm.cpp
new file mode 100644
index 000000000000..9e52874de832
--- /dev/null
+++ b/contrib/llvm/lib/Support/DeltaAlgorithm.cpp
@@ -0,0 +1,114 @@
+//===--- DeltaAlgorithm.cpp - A Set Minimization Algorithm -----*- C++ -*--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/DeltaAlgorithm.h"
+#include <algorithm>
+#include <iterator>
+using namespace llvm;
+
+DeltaAlgorithm::~DeltaAlgorithm() {
+}
+
+bool DeltaAlgorithm::GetTestResult(const changeset_ty &Changes) {
+ if (FailedTestsCache.count(Changes))
+ return false;
+
+ bool Result = ExecuteOneTest(Changes);
+ if (!Result)
+ FailedTestsCache.insert(Changes);
+
+ return Result;
+}
+
+void DeltaAlgorithm::Split(const changeset_ty &S, changesetlist_ty &Res) {
+ // FIXME: Allow clients to provide heuristics for improved splitting.
+
+ // FIXME: This is really slow.
+ changeset_ty LHS, RHS;
+ unsigned idx = 0, N = S.size() / 2;
+ for (changeset_ty::const_iterator it = S.begin(),
+ ie = S.end(); it != ie; ++it, ++idx)
+ ((idx < N) ? LHS : RHS).insert(*it);
+ if (!LHS.empty())
+ Res.push_back(LHS);
+ if (!RHS.empty())
+ Res.push_back(RHS);
+}
+
+DeltaAlgorithm::changeset_ty
+DeltaAlgorithm::Delta(const changeset_ty &Changes,
+ const changesetlist_ty &Sets) {
+ // Invariant: union(Res) == Changes
+ UpdatedSearchState(Changes, Sets);
+
+ // If there is nothing left we can remove, we are done.
+ if (Sets.size() <= 1)
+ return Changes;
+
+ // Look for a passing subset.
+ changeset_ty Res;
+ if (Search(Changes, Sets, Res))
+ return Res;
+
+ // Otherwise, partition the sets if possible; if not we are done.
+ changesetlist_ty SplitSets;
+ for (changesetlist_ty::const_iterator it = Sets.begin(),
+ ie = Sets.end(); it != ie; ++it)
+ Split(*it, SplitSets);
+ if (SplitSets.size() == Sets.size())
+ return Changes;
+
+ return Delta(Changes, SplitSets);
+}
+
+bool DeltaAlgorithm::Search(const changeset_ty &Changes,
+ const changesetlist_ty &Sets,
+ changeset_ty &Res) {
+ // FIXME: Parallelize.
+ for (changesetlist_ty::const_iterator it = Sets.begin(),
+ ie = Sets.end(); it != ie; ++it) {
+ // If the test passes on this subset alone, recurse.
+ if (GetTestResult(*it)) {
+ changesetlist_ty Sets;
+ Split(*it, Sets);
+ Res = Delta(*it, Sets);
+ return true;
+ }
+
+ // Otherwise, if we have more than two sets, see if test passes on the
+ // complement.
+ if (Sets.size() > 2) {
+ // FIXME: This is really slow.
+ changeset_ty Complement;
+ std::set_difference(
+ Changes.begin(), Changes.end(), it->begin(), it->end(),
+ std::insert_iterator<changeset_ty>(Complement, Complement.begin()));
+ if (GetTestResult(Complement)) {
+ changesetlist_ty ComplementSets;
+ ComplementSets.insert(ComplementSets.end(), Sets.begin(), it);
+ ComplementSets.insert(ComplementSets.end(), it + 1, Sets.end());
+ Res = Delta(Complement, ComplementSets);
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+DeltaAlgorithm::changeset_ty DeltaAlgorithm::Run(const changeset_ty &Changes) {
+ // Check empty set first to quickly find poor test functions.
+ if (GetTestResult(changeset_ty()))
+ return changeset_ty();
+
+ // Otherwise run the real delta algorithm.
+ changesetlist_ty Sets;
+ Split(Changes, Sets);
+
+ return Delta(Changes, Sets);
+}
diff --git a/contrib/llvm/lib/Support/Dwarf.cpp b/contrib/llvm/lib/Support/Dwarf.cpp
new file mode 100644
index 000000000000..6229825a8ee2
--- /dev/null
+++ b/contrib/llvm/lib/Support/Dwarf.cpp
@@ -0,0 +1,590 @@
+//===-- llvm/Support/Dwarf.cpp - Dwarf Framework ----------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains support for generic dwarf information.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/Dwarf.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Support/ErrorHandling.h"
+
+using namespace llvm;
+using namespace dwarf;
+
+const char *llvm::dwarf::TagString(unsigned Tag) {
+ switch (Tag) {
+ default: return nullptr;
+#define HANDLE_DW_TAG(ID, NAME) \
+ case DW_TAG_##NAME: \
+ return "DW_TAG_" #NAME;
+#include "llvm/Support/Dwarf.def"
+ }
+}
+
+unsigned llvm::dwarf::getTag(StringRef TagString) {
+ return StringSwitch<unsigned>(TagString)
+#define HANDLE_DW_TAG(ID, NAME) .Case("DW_TAG_" #NAME, DW_TAG_##NAME)
+#include "llvm/Support/Dwarf.def"
+ .Default(DW_TAG_invalid);
+}
+
+const char *llvm::dwarf::ChildrenString(unsigned Children) {
+ switch (Children) {
+ case DW_CHILDREN_no: return "DW_CHILDREN_no";
+ case DW_CHILDREN_yes: return "DW_CHILDREN_yes";
+ }
+ return nullptr;
+}
+
+const char *llvm::dwarf::AttributeString(unsigned Attribute) {
+ switch (Attribute) {
+ case DW_AT_sibling: return "DW_AT_sibling";
+ case DW_AT_location: return "DW_AT_location";
+ case DW_AT_name: return "DW_AT_name";
+ case DW_AT_ordering: return "DW_AT_ordering";
+ case DW_AT_byte_size: return "DW_AT_byte_size";
+ case DW_AT_bit_offset: return "DW_AT_bit_offset";
+ case DW_AT_bit_size: return "DW_AT_bit_size";
+ case DW_AT_stmt_list: return "DW_AT_stmt_list";
+ case DW_AT_low_pc: return "DW_AT_low_pc";
+ case DW_AT_high_pc: return "DW_AT_high_pc";
+ case DW_AT_language: return "DW_AT_language";
+ case DW_AT_discr: return "DW_AT_discr";
+ case DW_AT_discr_value: return "DW_AT_discr_value";
+ case DW_AT_visibility: return "DW_AT_visibility";
+ case DW_AT_import: return "DW_AT_import";
+ case DW_AT_string_length: return "DW_AT_string_length";
+ case DW_AT_common_reference: return "DW_AT_common_reference";
+ case DW_AT_comp_dir: return "DW_AT_comp_dir";
+ case DW_AT_const_value: return "DW_AT_const_value";
+ case DW_AT_containing_type: return "DW_AT_containing_type";
+ case DW_AT_default_value: return "DW_AT_default_value";
+ case DW_AT_inline: return "DW_AT_inline";
+ case DW_AT_is_optional: return "DW_AT_is_optional";
+ case DW_AT_lower_bound: return "DW_AT_lower_bound";
+ case DW_AT_producer: return "DW_AT_producer";
+ case DW_AT_prototyped: return "DW_AT_prototyped";
+ case DW_AT_return_addr: return "DW_AT_return_addr";
+ case DW_AT_start_scope: return "DW_AT_start_scope";
+ case DW_AT_bit_stride: return "DW_AT_bit_stride";
+ case DW_AT_upper_bound: return "DW_AT_upper_bound";
+ case DW_AT_abstract_origin: return "DW_AT_abstract_origin";
+ case DW_AT_accessibility: return "DW_AT_accessibility";
+ case DW_AT_address_class: return "DW_AT_address_class";
+ case DW_AT_artificial: return "DW_AT_artificial";
+ case DW_AT_base_types: return "DW_AT_base_types";
+ case DW_AT_calling_convention: return "DW_AT_calling_convention";
+ case DW_AT_count: return "DW_AT_count";
+ case DW_AT_data_member_location: return "DW_AT_data_member_location";
+ case DW_AT_decl_column: return "DW_AT_decl_column";
+ case DW_AT_decl_file: return "DW_AT_decl_file";
+ case DW_AT_decl_line: return "DW_AT_decl_line";
+ case DW_AT_declaration: return "DW_AT_declaration";
+ case DW_AT_discr_list: return "DW_AT_discr_list";
+ case DW_AT_encoding: return "DW_AT_encoding";
+ case DW_AT_external: return "DW_AT_external";
+ case DW_AT_frame_base: return "DW_AT_frame_base";
+ case DW_AT_friend: return "DW_AT_friend";
+ case DW_AT_identifier_case: return "DW_AT_identifier_case";
+ case DW_AT_macro_info: return "DW_AT_macro_info";
+ case DW_AT_namelist_item: return "DW_AT_namelist_item";
+ case DW_AT_priority: return "DW_AT_priority";
+ case DW_AT_segment: return "DW_AT_segment";
+ case DW_AT_specification: return "DW_AT_specification";
+ case DW_AT_static_link: return "DW_AT_static_link";
+ case DW_AT_type: return "DW_AT_type";
+ case DW_AT_use_location: return "DW_AT_use_location";
+ case DW_AT_variable_parameter: return "DW_AT_variable_parameter";
+ case DW_AT_virtuality: return "DW_AT_virtuality";
+ case DW_AT_vtable_elem_location: return "DW_AT_vtable_elem_location";
+ case DW_AT_allocated: return "DW_AT_allocated";
+ case DW_AT_associated: return "DW_AT_associated";
+ case DW_AT_data_location: return "DW_AT_data_location";
+ case DW_AT_byte_stride: return "DW_AT_byte_stride";
+ case DW_AT_entry_pc: return "DW_AT_entry_pc";
+ case DW_AT_use_UTF8: return "DW_AT_use_UTF8";
+ case DW_AT_extension: return "DW_AT_extension";
+ case DW_AT_ranges: return "DW_AT_ranges";
+ case DW_AT_trampoline: return "DW_AT_trampoline";
+ case DW_AT_call_column: return "DW_AT_call_column";
+ case DW_AT_call_file: return "DW_AT_call_file";
+ case DW_AT_call_line: return "DW_AT_call_line";
+ case DW_AT_description: return "DW_AT_description";
+ case DW_AT_binary_scale: return "DW_AT_binary_scale";
+ case DW_AT_decimal_scale: return "DW_AT_decimal_scale";
+ case DW_AT_small: return "DW_AT_small";
+ case DW_AT_decimal_sign: return "DW_AT_decimal_sign";
+ case DW_AT_digit_count: return "DW_AT_digit_count";
+ case DW_AT_picture_string: return "DW_AT_picture_string";
+ case DW_AT_mutable: return "DW_AT_mutable";
+ case DW_AT_threads_scaled: return "DW_AT_threads_scaled";
+ case DW_AT_explicit: return "DW_AT_explicit";
+ case DW_AT_object_pointer: return "DW_AT_object_pointer";
+ case DW_AT_endianity: return "DW_AT_endianity";
+ case DW_AT_elemental: return "DW_AT_elemental";
+ case DW_AT_pure: return "DW_AT_pure";
+ case DW_AT_recursive: return "DW_AT_recursive";
+ case DW_AT_signature: return "DW_AT_signature";
+ case DW_AT_main_subprogram: return "DW_AT_main_subprogram";
+ case DW_AT_data_bit_offset: return "DW_AT_data_bit_offset";
+ case DW_AT_const_expr: return "DW_AT_const_expr";
+ case DW_AT_enum_class: return "DW_AT_enum_class";
+ case DW_AT_linkage_name: return "DW_AT_linkage_name";
+ case DW_AT_string_length_bit_size: return "DW_AT_string_length_bit_size";
+ case DW_AT_string_length_byte_size: return "DW_AT_string_length_byte_size";
+ case DW_AT_rank: return "DW_AT_rank";
+ case DW_AT_str_offsets_base: return "DW_AT_str_offsets_base";
+ case DW_AT_addr_base: return "DW_AT_addr_base";
+ case DW_AT_ranges_base: return "DW_AT_ranges_base";
+ case DW_AT_dwo_id: return "DW_AT_dwo_id";
+ case DW_AT_dwo_name: return "DW_AT_dwo_name";
+ case DW_AT_reference: return "DW_AT_reference";
+ case DW_AT_rvalue_reference: return "DW_AT_rvalue_reference";
+ case DW_AT_MIPS_loop_begin: return "DW_AT_MIPS_loop_begin";
+ case DW_AT_MIPS_tail_loop_begin: return "DW_AT_MIPS_tail_loop_begin";
+ case DW_AT_MIPS_epilog_begin: return "DW_AT_MIPS_epilog_begin";
+ case DW_AT_MIPS_loop_unroll_factor: return "DW_AT_MIPS_loop_unroll_factor";
+ case DW_AT_MIPS_software_pipeline_depth:
+ return "DW_AT_MIPS_software_pipeline_depth";
+ case DW_AT_MIPS_linkage_name: return "DW_AT_MIPS_linkage_name";
+ case DW_AT_MIPS_stride: return "DW_AT_MIPS_stride";
+ case DW_AT_MIPS_abstract_name: return "DW_AT_MIPS_abstract_name";
+ case DW_AT_MIPS_clone_origin: return "DW_AT_MIPS_clone_origin";
+ case DW_AT_MIPS_has_inlines: return "DW_AT_MIPS_has_inlines";
+ case DW_AT_MIPS_stride_byte: return "DW_AT_MIPS_stride_byte";
+ case DW_AT_MIPS_stride_elem: return "DW_AT_MIPS_stride_elem";
+ case DW_AT_MIPS_ptr_dopetype: return "DW_AT_MIPS_ptr_dopetype";
+ case DW_AT_MIPS_allocatable_dopetype:
+ return "DW_AT_MIPS_allocatable_dopetype";
+ case DW_AT_MIPS_assumed_shape_dopetype:
+ return "DW_AT_MIPS_assumed_shape_dopetype";
+ case DW_AT_sf_names: return "DW_AT_sf_names";
+ case DW_AT_src_info: return "DW_AT_src_info";
+ case DW_AT_mac_info: return "DW_AT_mac_info";
+ case DW_AT_src_coords: return "DW_AT_src_coords";
+ case DW_AT_body_begin: return "DW_AT_body_begin";
+ case DW_AT_body_end: return "DW_AT_body_end";
+ case DW_AT_GNU_vector: return "DW_AT_GNU_vector";
+ case DW_AT_GNU_template_name: return "DW_AT_GNU_template_name";
+ case DW_AT_GNU_odr_signature: return "DW_AT_GNU_odr_signature";
+ case DW_AT_MIPS_assumed_size: return "DW_AT_MIPS_assumed_size";
+ case DW_AT_lo_user: return "DW_AT_lo_user";
+ case DW_AT_hi_user: return "DW_AT_hi_user";
+ case DW_AT_APPLE_optimized: return "DW_AT_APPLE_optimized";
+ case DW_AT_APPLE_flags: return "DW_AT_APPLE_flags";
+ case DW_AT_APPLE_isa: return "DW_AT_APPLE_isa";
+ case DW_AT_APPLE_block: return "DW_AT_APPLE_block";
+ case DW_AT_APPLE_major_runtime_vers: return "DW_AT_APPLE_major_runtime_vers";
+ case DW_AT_APPLE_runtime_class: return "DW_AT_APPLE_runtime_class";
+ case DW_AT_APPLE_omit_frame_ptr: return "DW_AT_APPLE_omit_frame_ptr";
+ case DW_AT_APPLE_property_name: return "DW_AT_APPLE_property_name";
+ case DW_AT_APPLE_property_getter: return "DW_AT_APPLE_property_getter";
+ case DW_AT_APPLE_property_setter: return "DW_AT_APPLE_property_setter";
+ case DW_AT_APPLE_property_attribute: return "DW_AT_APPLE_property_attribute";
+ case DW_AT_APPLE_property: return "DW_AT_APPLE_property";
+ case DW_AT_APPLE_objc_complete_type: return "DW_AT_APPLE_objc_complete_type";
+
+ // DWARF5 Fission Extension Attribute
+ case DW_AT_GNU_dwo_name: return "DW_AT_GNU_dwo_name";
+ case DW_AT_GNU_dwo_id: return "DW_AT_GNU_dwo_id";
+ case DW_AT_GNU_ranges_base: return "DW_AT_GNU_ranges_base";
+ case DW_AT_GNU_addr_base: return "DW_AT_GNU_addr_base";
+ case DW_AT_GNU_pubnames: return "DW_AT_GNU_pubnames";
+ case DW_AT_GNU_pubtypes: return "DW_AT_GNU_pubtypes";
+ }
+ return nullptr;
+}
+
+const char *llvm::dwarf::FormEncodingString(unsigned Encoding) {
+ switch (Encoding) {
+ case DW_FORM_addr: return "DW_FORM_addr";
+ case DW_FORM_block2: return "DW_FORM_block2";
+ case DW_FORM_block4: return "DW_FORM_block4";
+ case DW_FORM_data2: return "DW_FORM_data2";
+ case DW_FORM_data4: return "DW_FORM_data4";
+ case DW_FORM_data8: return "DW_FORM_data8";
+ case DW_FORM_string: return "DW_FORM_string";
+ case DW_FORM_block: return "DW_FORM_block";
+ case DW_FORM_block1: return "DW_FORM_block1";
+ case DW_FORM_data1: return "DW_FORM_data1";
+ case DW_FORM_flag: return "DW_FORM_flag";
+ case DW_FORM_sdata: return "DW_FORM_sdata";
+ case DW_FORM_strp: return "DW_FORM_strp";
+ case DW_FORM_udata: return "DW_FORM_udata";
+ case DW_FORM_ref_addr: return "DW_FORM_ref_addr";
+ case DW_FORM_ref1: return "DW_FORM_ref1";
+ case DW_FORM_ref2: return "DW_FORM_ref2";
+ case DW_FORM_ref4: return "DW_FORM_ref4";
+ case DW_FORM_ref8: return "DW_FORM_ref8";
+ case DW_FORM_ref_udata: return "DW_FORM_ref_udata";
+ case DW_FORM_indirect: return "DW_FORM_indirect";
+ case DW_FORM_sec_offset: return "DW_FORM_sec_offset";
+ case DW_FORM_exprloc: return "DW_FORM_exprloc";
+ case DW_FORM_flag_present: return "DW_FORM_flag_present";
+ case DW_FORM_ref_sig8: return "DW_FORM_ref_sig8";
+
+ // DWARF5 Fission Extension Forms
+ case DW_FORM_GNU_addr_index: return "DW_FORM_GNU_addr_index";
+ case DW_FORM_GNU_str_index: return "DW_FORM_GNU_str_index";
+
+ // Alternate debug sections proposal (output of "dwz" tool).
+ case DW_FORM_GNU_ref_alt: return "DW_FORM_GNU_ref_alt";
+ case DW_FORM_GNU_strp_alt: return "DW_FORM_GNU_strp_alt";
+ }
+ return nullptr;
+}
+
+const char *llvm::dwarf::OperationEncodingString(unsigned Encoding) {
+ switch (Encoding) {
+ default: return nullptr;
+#define HANDLE_DW_OP(ID, NAME) \
+ case DW_OP_##NAME: \
+ return "DW_OP_" #NAME;
+#include "llvm/Support/Dwarf.def"
+ }
+}
+
+unsigned llvm::dwarf::getOperationEncoding(StringRef OperationEncodingString) {
+ return StringSwitch<unsigned>(OperationEncodingString)
+#define HANDLE_DW_OP(ID, NAME) .Case("DW_OP_" #NAME, DW_OP_##NAME)
+#include "llvm/Support/Dwarf.def"
+ .Default(0);
+}
+
+const char *llvm::dwarf::AttributeEncodingString(unsigned Encoding) {
+ switch (Encoding) {
+ default: return nullptr;
+#define HANDLE_DW_ATE(ID, NAME) \
+ case DW_ATE_##NAME: \
+ return "DW_ATE_" #NAME;
+#include "llvm/Support/Dwarf.def"
+ }
+}
+
+unsigned llvm::dwarf::getAttributeEncoding(StringRef EncodingString) {
+ return StringSwitch<unsigned>(EncodingString)
+#define HANDLE_DW_ATE(ID, NAME) .Case("DW_ATE_" #NAME, DW_ATE_##NAME)
+#include "llvm/Support/Dwarf.def"
+ .Default(0);
+}
+
+const char *llvm::dwarf::DecimalSignString(unsigned Sign) {
+ switch (Sign) {
+ case DW_DS_unsigned: return "DW_DS_unsigned";
+ case DW_DS_leading_overpunch: return "DW_DS_leading_overpunch";
+ case DW_DS_trailing_overpunch: return "DW_DS_trailing_overpunch";
+ case DW_DS_leading_separate: return "DW_DS_leading_separate";
+ case DW_DS_trailing_separate: return "DW_DS_trailing_separate";
+ }
+ return nullptr;
+}
+
+const char *llvm::dwarf::EndianityString(unsigned Endian) {
+ switch (Endian) {
+ case DW_END_default: return "DW_END_default";
+ case DW_END_big: return "DW_END_big";
+ case DW_END_little: return "DW_END_little";
+ case DW_END_lo_user: return "DW_END_lo_user";
+ case DW_END_hi_user: return "DW_END_hi_user";
+ }
+ return nullptr;
+}
+
+const char *llvm::dwarf::AccessibilityString(unsigned Access) {
+ switch (Access) {
+ // Accessibility codes
+ case DW_ACCESS_public: return "DW_ACCESS_public";
+ case DW_ACCESS_protected: return "DW_ACCESS_protected";
+ case DW_ACCESS_private: return "DW_ACCESS_private";
+ }
+ return nullptr;
+}
+
+const char *llvm::dwarf::VisibilityString(unsigned Visibility) {
+ switch (Visibility) {
+ case DW_VIS_local: return "DW_VIS_local";
+ case DW_VIS_exported: return "DW_VIS_exported";
+ case DW_VIS_qualified: return "DW_VIS_qualified";
+ }
+ return nullptr;
+}
+
+const char *llvm::dwarf::VirtualityString(unsigned Virtuality) {
+ switch (Virtuality) {
+ default:
+ return nullptr;
+#define HANDLE_DW_VIRTUALITY(ID, NAME) \
+ case DW_VIRTUALITY_##NAME: \
+ return "DW_VIRTUALITY_" #NAME;
+#include "llvm/Support/Dwarf.def"
+ }
+}
+
+unsigned llvm::dwarf::getVirtuality(StringRef VirtualityString) {
+ return StringSwitch<unsigned>(VirtualityString)
+#define HANDLE_DW_VIRTUALITY(ID, NAME) \
+ .Case("DW_VIRTUALITY_" #NAME, DW_VIRTUALITY_##NAME)
+#include "llvm/Support/Dwarf.def"
+ .Default(DW_VIRTUALITY_invalid);
+}
+
+const char *llvm::dwarf::LanguageString(unsigned Language) {
+ switch (Language) {
+ default:
+ return nullptr;
+#define HANDLE_DW_LANG(ID, NAME) \
+ case DW_LANG_##NAME: \
+ return "DW_LANG_" #NAME;
+#include "llvm/Support/Dwarf.def"
+ }
+}
+
+unsigned llvm::dwarf::getLanguage(StringRef LanguageString) {
+ return StringSwitch<unsigned>(LanguageString)
+#define HANDLE_DW_LANG(ID, NAME) .Case("DW_LANG_" #NAME, DW_LANG_##NAME)
+#include "llvm/Support/Dwarf.def"
+ .Default(0);
+}
+
+const char *llvm::dwarf::CaseString(unsigned Case) {
+ switch (Case) {
+ case DW_ID_case_sensitive: return "DW_ID_case_sensitive";
+ case DW_ID_up_case: return "DW_ID_up_case";
+ case DW_ID_down_case: return "DW_ID_down_case";
+ case DW_ID_case_insensitive: return "DW_ID_case_insensitive";
+ }
+ return nullptr;
+}
+
+const char *llvm::dwarf::ConventionString(unsigned Convention) {
+ switch (Convention) {
+ case DW_CC_normal: return "DW_CC_normal";
+ case DW_CC_program: return "DW_CC_program";
+ case DW_CC_nocall: return "DW_CC_nocall";
+ case DW_CC_lo_user: return "DW_CC_lo_user";
+ case DW_CC_hi_user: return "DW_CC_hi_user";
+ }
+ return nullptr;
+}
+
+const char *llvm::dwarf::InlineCodeString(unsigned Code) {
+ switch (Code) {
+ case DW_INL_not_inlined: return "DW_INL_not_inlined";
+ case DW_INL_inlined: return "DW_INL_inlined";
+ case DW_INL_declared_not_inlined: return "DW_INL_declared_not_inlined";
+ case DW_INL_declared_inlined: return "DW_INL_declared_inlined";
+ }
+ return nullptr;
+}
+
+const char *llvm::dwarf::ArrayOrderString(unsigned Order) {
+ switch (Order) {
+ case DW_ORD_row_major: return "DW_ORD_row_major";
+ case DW_ORD_col_major: return "DW_ORD_col_major";
+ }
+ return nullptr;
+}
+
+const char *llvm::dwarf::DiscriminantString(unsigned Discriminant) {
+ switch (Discriminant) {
+ case DW_DSC_label: return "DW_DSC_label";
+ case DW_DSC_range: return "DW_DSC_range";
+ }
+ return nullptr;
+}
+
+const char *llvm::dwarf::LNStandardString(unsigned Standard) {
+ switch (Standard) {
+ case DW_LNS_copy: return "DW_LNS_copy";
+ case DW_LNS_advance_pc: return "DW_LNS_advance_pc";
+ case DW_LNS_advance_line: return "DW_LNS_advance_line";
+ case DW_LNS_set_file: return "DW_LNS_set_file";
+ case DW_LNS_set_column: return "DW_LNS_set_column";
+ case DW_LNS_negate_stmt: return "DW_LNS_negate_stmt";
+ case DW_LNS_set_basic_block: return "DW_LNS_set_basic_block";
+ case DW_LNS_const_add_pc: return "DW_LNS_const_add_pc";
+ case DW_LNS_fixed_advance_pc: return "DW_LNS_fixed_advance_pc";
+ case DW_LNS_set_prologue_end: return "DW_LNS_set_prologue_end";
+ case DW_LNS_set_epilogue_begin: return "DW_LNS_set_epilogue_begin";
+ case DW_LNS_set_isa: return "DW_LNS_set_isa";
+ }
+ return nullptr;
+}
+
+const char *llvm::dwarf::LNExtendedString(unsigned Encoding) {
+ switch (Encoding) {
+ // Line Number Extended Opcode Encodings
+ case DW_LNE_end_sequence: return "DW_LNE_end_sequence";
+ case DW_LNE_set_address: return "DW_LNE_set_address";
+ case DW_LNE_define_file: return "DW_LNE_define_file";
+ case DW_LNE_set_discriminator: return "DW_LNE_set_discriminator";
+ case DW_LNE_lo_user: return "DW_LNE_lo_user";
+ case DW_LNE_hi_user: return "DW_LNE_hi_user";
+ }
+ return nullptr;
+}
+
+const char *llvm::dwarf::MacinfoString(unsigned Encoding) {
+ switch (Encoding) {
+ // Macinfo Type Encodings
+ case DW_MACINFO_define: return "DW_MACINFO_define";
+ case DW_MACINFO_undef: return "DW_MACINFO_undef";
+ case DW_MACINFO_start_file: return "DW_MACINFO_start_file";
+ case DW_MACINFO_end_file: return "DW_MACINFO_end_file";
+ case DW_MACINFO_vendor_ext: return "DW_MACINFO_vendor_ext";
+ }
+ return nullptr;
+}
+
+const char *llvm::dwarf::CallFrameString(unsigned Encoding) {
+ switch (Encoding) {
+ case DW_CFA_nop: return "DW_CFA_nop";
+ case DW_CFA_advance_loc: return "DW_CFA_advance_loc";
+ case DW_CFA_offset: return "DW_CFA_offset";
+ case DW_CFA_restore: return "DW_CFA_restore";
+ case DW_CFA_set_loc: return "DW_CFA_set_loc";
+ case DW_CFA_advance_loc1: return "DW_CFA_advance_loc1";
+ case DW_CFA_advance_loc2: return "DW_CFA_advance_loc2";
+ case DW_CFA_advance_loc4: return "DW_CFA_advance_loc4";
+ case DW_CFA_offset_extended: return "DW_CFA_offset_extended";
+ case DW_CFA_restore_extended: return "DW_CFA_restore_extended";
+ case DW_CFA_undefined: return "DW_CFA_undefined";
+ case DW_CFA_same_value: return "DW_CFA_same_value";
+ case DW_CFA_register: return "DW_CFA_register";
+ case DW_CFA_remember_state: return "DW_CFA_remember_state";
+ case DW_CFA_restore_state: return "DW_CFA_restore_state";
+ case DW_CFA_def_cfa: return "DW_CFA_def_cfa";
+ case DW_CFA_def_cfa_register: return "DW_CFA_def_cfa_register";
+ case DW_CFA_def_cfa_offset: return "DW_CFA_def_cfa_offset";
+ case DW_CFA_def_cfa_expression: return "DW_CFA_def_cfa_expression";
+ case DW_CFA_expression: return "DW_CFA_expression";
+ case DW_CFA_offset_extended_sf: return "DW_CFA_offset_extended_sf";
+ case DW_CFA_def_cfa_sf: return "DW_CFA_def_cfa_sf";
+ case DW_CFA_def_cfa_offset_sf: return "DW_CFA_def_cfa_offset_sf";
+ case DW_CFA_val_offset: return "DW_CFA_val_offset";
+ case DW_CFA_val_offset_sf: return "DW_CFA_val_offset_sf";
+ case DW_CFA_val_expression: return "DW_CFA_val_expression";
+ case DW_CFA_MIPS_advance_loc8: return "DW_CFA_MIPS_advance_loc8";
+ case DW_CFA_GNU_window_save: return "DW_CFA_GNU_window_save";
+ case DW_CFA_GNU_args_size: return "DW_CFA_GNU_args_size";
+ case DW_CFA_lo_user: return "DW_CFA_lo_user";
+ case DW_CFA_hi_user: return "DW_CFA_hi_user";
+ }
+ return nullptr;
+}
+
+const char *llvm::dwarf::ApplePropertyString(unsigned Prop) {
+ switch (Prop) {
+ case DW_APPLE_PROPERTY_readonly:
+ return "DW_APPLE_PROPERTY_readonly";
+ case DW_APPLE_PROPERTY_getter:
+ return "DW_APPLE_PROPERTY_getter";
+ case DW_APPLE_PROPERTY_assign:
+ return "DW_APPLE_PROPERTY_assign";
+ case DW_APPLE_PROPERTY_readwrite:
+ return "DW_APPLE_PROPERTY_readwrite";
+ case DW_APPLE_PROPERTY_retain:
+ return "DW_APPLE_PROPERTY_retain";
+ case DW_APPLE_PROPERTY_copy:
+ return "DW_APPLE_PROPERTY_copy";
+ case DW_APPLE_PROPERTY_nonatomic:
+ return "DW_APPLE_PROPERTY_nonatomic";
+ case DW_APPLE_PROPERTY_setter:
+ return "DW_APPLE_PROPERTY_setter";
+ case DW_APPLE_PROPERTY_atomic:
+ return "DW_APPLE_PROPERTY_atomic";
+ case DW_APPLE_PROPERTY_weak:
+ return "DW_APPLE_PROPERTY_weak";
+ case DW_APPLE_PROPERTY_strong:
+ return "DW_APPLE_PROPERTY_strong";
+ case DW_APPLE_PROPERTY_unsafe_unretained:
+ return "DW_APPLE_PROPERTY_unsafe_unretained";
+ }
+ return nullptr;
+}
+
+const char *llvm::dwarf::AtomTypeString(unsigned AT) {
+ switch (AT) {
+ case dwarf::DW_ATOM_null:
+ return "DW_ATOM_null";
+ case dwarf::DW_ATOM_die_offset:
+ return "DW_ATOM_die_offset";
+ case DW_ATOM_cu_offset:
+ return "DW_ATOM_cu_offset";
+ case DW_ATOM_die_tag:
+ return "DW_ATOM_die_tag";
+ case DW_ATOM_type_flags:
+ return "DW_ATOM_type_flags";
+ }
+ return nullptr;
+}
+
+const char *llvm::dwarf::GDBIndexEntryKindString(GDBIndexEntryKind Kind) {
+ switch (Kind) {
+ case GIEK_NONE:
+ return "NONE";
+ case GIEK_TYPE:
+ return "TYPE";
+ case GIEK_VARIABLE:
+ return "VARIABLE";
+ case GIEK_FUNCTION:
+ return "FUNCTION";
+ case GIEK_OTHER:
+ return "OTHER";
+ case GIEK_UNUSED5:
+ return "UNUSED5";
+ case GIEK_UNUSED6:
+ return "UNUSED6";
+ case GIEK_UNUSED7:
+ return "UNUSED7";
+ }
+ llvm_unreachable("Unknown GDBIndexEntryKind value");
+}
+
+const char *llvm::dwarf::GDBIndexEntryLinkageString(GDBIndexEntryLinkage Linkage) {
+ switch (Linkage) {
+ case GIEL_EXTERNAL:
+ return "EXTERNAL";
+ case GIEL_STATIC:
+ return "STATIC";
+ }
+ llvm_unreachable("Unknown GDBIndexEntryLinkage value");
+}
+
+const char *llvm::dwarf::AttributeValueString(uint16_t Attr, unsigned Val) {
+ switch (Attr) {
+ case DW_AT_accessibility:
+ return AccessibilityString(Val);
+ case DW_AT_virtuality:
+ return VirtualityString(Val);
+ case DW_AT_language:
+ return LanguageString(Val);
+ case DW_AT_encoding:
+ return AttributeEncodingString(Val);
+ case DW_AT_decimal_sign:
+ return DecimalSignString(Val);
+ case DW_AT_endianity:
+ return EndianityString(Val);
+ case DW_AT_visibility:
+ return VisibilityString(Val);
+ case DW_AT_identifier_case:
+ return CaseString(Val);
+ case DW_AT_calling_convention:
+ return ConventionString(Val);
+ case DW_AT_inline:
+ return InlineCodeString(Val);
+ case DW_AT_ordering:
+ return ArrayOrderString(Val);
+ case DW_AT_discr_value:
+ return DiscriminantString(Val);
+ }
+
+ return nullptr;
+}
diff --git a/contrib/llvm/lib/Support/DynamicLibrary.cpp b/contrib/llvm/lib/Support/DynamicLibrary.cpp
new file mode 100644
index 000000000000..9a7aeb50a216
--- /dev/null
+++ b/contrib/llvm/lib/Support/DynamicLibrary.cpp
@@ -0,0 +1,189 @@
+//===-- DynamicLibrary.cpp - Runtime link/load libraries --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the operating system DynamicLibrary concept.
+//
+// FIXME: This file leaks ExplicitSymbols and OpenedHandles!
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/DynamicLibrary.h"
+#include "llvm-c/Support.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/Config/config.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/Mutex.h"
+#include <cstdio>
+#include <cstring>
+
+// Collection of symbol name/value pairs to be searched prior to any libraries.
+static llvm::ManagedStatic<llvm::StringMap<void *> > ExplicitSymbols;
+static llvm::ManagedStatic<llvm::sys::SmartMutex<true> > SymbolsMutex;
+
+void llvm::sys::DynamicLibrary::AddSymbol(StringRef symbolName,
+ void *symbolValue) {
+ SmartScopedLock<true> lock(*SymbolsMutex);
+ (*ExplicitSymbols)[symbolName] = symbolValue;
+}
+
+char llvm::sys::DynamicLibrary::Invalid = 0;
+
+#ifdef LLVM_ON_WIN32
+
+#include "Windows/DynamicLibrary.inc"
+
+#else
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+using namespace llvm;
+using namespace llvm::sys;
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only TRULY operating system
+//=== independent code.
+//===----------------------------------------------------------------------===//
+
+static DenseSet<void *> *OpenedHandles = nullptr;
+
+DynamicLibrary DynamicLibrary::getPermanentLibrary(const char *filename,
+ std::string *errMsg) {
+ SmartScopedLock<true> lock(*SymbolsMutex);
+
+ void *handle = dlopen(filename, RTLD_LAZY|RTLD_GLOBAL);
+ if (!handle) {
+ if (errMsg) *errMsg = dlerror();
+ return DynamicLibrary();
+ }
+
+#ifdef __CYGWIN__
+ // Cygwin searches symbols only in the main
+ // with the handle of dlopen(NULL, RTLD_GLOBAL).
+ if (!filename)
+ handle = RTLD_DEFAULT;
+#endif
+
+ if (!OpenedHandles)
+ OpenedHandles = new DenseSet<void *>();
+
+ // If we've already loaded this library, dlclose() the handle in order to
+ // keep the internal refcount at +1.
+ if (!OpenedHandles->insert(handle).second)
+ dlclose(handle);
+
+ return DynamicLibrary(handle);
+}
+
+void *DynamicLibrary::getAddressOfSymbol(const char *symbolName) {
+ if (!isValid())
+ return nullptr;
+ return dlsym(Data, symbolName);
+}
+
+#else
+
+using namespace llvm;
+using namespace llvm::sys;
+
+DynamicLibrary DynamicLibrary::getPermanentLibrary(const char *filename,
+ std::string *errMsg) {
+ if (errMsg) *errMsg = "dlopen() not supported on this platform";
+ return DynamicLibrary();
+}
+
+void *DynamicLibrary::getAddressOfSymbol(const char *symbolName) {
+ return NULL;
+}
+
+#endif
+
+namespace llvm {
+void *SearchForAddressOfSpecialSymbol(const char* symbolName);
+}
+
+void* DynamicLibrary::SearchForAddressOfSymbol(const char *symbolName) {
+ SmartScopedLock<true> Lock(*SymbolsMutex);
+
+ // First check symbols added via AddSymbol().
+ if (ExplicitSymbols.isConstructed()) {
+ StringMap<void *>::iterator i = ExplicitSymbols->find(symbolName);
+
+ if (i != ExplicitSymbols->end())
+ return i->second;
+ }
+
+#if HAVE_DLFCN_H
+ // Now search the libraries.
+ if (OpenedHandles) {
+ for (DenseSet<void *>::iterator I = OpenedHandles->begin(),
+ E = OpenedHandles->end(); I != E; ++I) {
+ //lt_ptr ptr = lt_dlsym(*I, symbolName);
+ void *ptr = dlsym(*I, symbolName);
+ if (ptr) {
+ return ptr;
+ }
+ }
+ }
+#endif
+
+ if (void *Result = llvm::SearchForAddressOfSpecialSymbol(symbolName))
+ return Result;
+
+// This macro returns the address of a well-known, explicit symbol
+#define EXPLICIT_SYMBOL(SYM) \
+ if (!strcmp(symbolName, #SYM)) return &SYM
+
+// On linux we have a weird situation. The stderr/out/in symbols are both
+// macros and global variables because of standards requirements. So, we
+// boldly use the EXPLICIT_SYMBOL macro without checking for a #define first.
+#if defined(__linux__) and !defined(__ANDROID__)
+ {
+ EXPLICIT_SYMBOL(stderr);
+ EXPLICIT_SYMBOL(stdout);
+ EXPLICIT_SYMBOL(stdin);
+ }
+#else
+ // For everything else, we want to check to make sure the symbol isn't defined
+ // as a macro before using EXPLICIT_SYMBOL.
+ {
+#ifndef stdin
+ EXPLICIT_SYMBOL(stdin);
+#endif
+#ifndef stdout
+ EXPLICIT_SYMBOL(stdout);
+#endif
+#ifndef stderr
+ EXPLICIT_SYMBOL(stderr);
+#endif
+ }
+#endif
+#undef EXPLICIT_SYMBOL
+
+ return nullptr;
+}
+
+#endif // LLVM_ON_WIN32
+
+//===----------------------------------------------------------------------===//
+// C API.
+//===----------------------------------------------------------------------===//
+
+LLVMBool LLVMLoadLibraryPermanently(const char* Filename) {
+ return llvm::sys::DynamicLibrary::LoadLibraryPermanently(Filename);
+}
+
+void *LLVMSearchForAddressOfSymbol(const char *symbolName) {
+ return llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(symbolName);
+}
+
+void LLVMAddSymbol(const char *symbolName, void *symbolValue) {
+ return llvm::sys::DynamicLibrary::AddSymbol(symbolName, symbolValue);
+}
+
diff --git a/contrib/llvm/lib/Support/Errno.cpp b/contrib/llvm/lib/Support/Errno.cpp
new file mode 100644
index 000000000000..3ba2a1277d05
--- /dev/null
+++ b/contrib/llvm/lib/Support/Errno.cpp
@@ -0,0 +1,76 @@
+//===- Errno.cpp - errno support --------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the errno wrappers.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/Errno.h"
+#include "llvm/Config/config.h" // Get autoconf configuration settings
+#include "llvm/Support/raw_ostream.h"
+#include <string.h>
+
+#if HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only TRULY operating system
+//=== independent code.
+//===----------------------------------------------------------------------===//
+
+namespace llvm {
+namespace sys {
+
+#if HAVE_ERRNO_H
+std::string StrError() {
+ return StrError(errno);
+}
+#endif // HAVE_ERRNO_H
+
+std::string StrError(int errnum) {
+ std::string str;
+ if (errnum == 0)
+ return str;
+#if defined(HAVE_STRERROR_R) || HAVE_DECL_STRERROR_S
+ const int MaxErrStrLen = 2000;
+ char buffer[MaxErrStrLen];
+ buffer[0] = '\0';
+#endif
+
+#ifdef HAVE_STRERROR_R
+ // strerror_r is thread-safe.
+#if defined(__GLIBC__) && defined(_GNU_SOURCE)
+ // glibc defines its own incompatible version of strerror_r
+ // which may not use the buffer supplied.
+ str = strerror_r(errnum, buffer, MaxErrStrLen - 1);
+#else
+ strerror_r(errnum, buffer, MaxErrStrLen - 1);
+ str = buffer;
+#endif
+#elif HAVE_DECL_STRERROR_S // "Windows Secure API"
+ strerror_s(buffer, MaxErrStrLen - 1, errnum);
+ str = buffer;
+#elif defined(HAVE_STRERROR)
+ // Copy the thread un-safe result of strerror into
+ // the buffer as fast as possible to minimize impact
+ // of collision of strerror in multiple threads.
+ str = strerror(errnum);
+#else
+ // Strange that this system doesn't even have strerror
+ // but, oh well, just use a generic message
+ raw_string_ostream stream(str);
+ stream << "Error #" << errnum;
+ stream.flush();
+#endif
+ return str;
+}
+
+} // namespace sys
+} // namespace llvm
diff --git a/contrib/llvm/lib/Support/ErrorHandling.cpp b/contrib/llvm/lib/Support/ErrorHandling.cpp
new file mode 100644
index 000000000000..a25e21ae043e
--- /dev/null
+++ b/contrib/llvm/lib/Support/ErrorHandling.cpp
@@ -0,0 +1,206 @@
+//===- lib/Support/ErrorHandling.cpp - Callbacks for errors ---------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines an API used to indicate fatal error conditions. Non-fatal
+// errors (most of them) should be handled through LLVMContext.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm-c/Core.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Config/config.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/Errc.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/Mutex.h"
+#include "llvm/Support/MutexGuard.h"
+#include "llvm/Support/Signals.h"
+#include "llvm/Support/Threading.h"
+#include "llvm/Support/WindowsError.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cassert>
+#include <cstdlib>
+
+#if defined(HAVE_UNISTD_H)
+# include <unistd.h>
+#endif
+#if defined(_MSC_VER)
+# include <io.h>
+# include <fcntl.h>
+#endif
+
+using namespace llvm;
+
+static fatal_error_handler_t ErrorHandler = nullptr;
+static void *ErrorHandlerUserData = nullptr;
+
+static ManagedStatic<sys::Mutex> ErrorHandlerMutex;
+
+void llvm::install_fatal_error_handler(fatal_error_handler_t handler,
+ void *user_data) {
+ llvm::MutexGuard Lock(*ErrorHandlerMutex);
+ assert(!ErrorHandler && "Error handler already registered!\n");
+ ErrorHandler = handler;
+ ErrorHandlerUserData = user_data;
+}
+
+void llvm::remove_fatal_error_handler() {
+ llvm::MutexGuard Lock(*ErrorHandlerMutex);
+ ErrorHandler = nullptr;
+ ErrorHandlerUserData = nullptr;
+}
+
+void llvm::report_fatal_error(const char *Reason, bool GenCrashDiag) {
+ report_fatal_error(Twine(Reason), GenCrashDiag);
+}
+
+void llvm::report_fatal_error(const std::string &Reason, bool GenCrashDiag) {
+ report_fatal_error(Twine(Reason), GenCrashDiag);
+}
+
+void llvm::report_fatal_error(StringRef Reason, bool GenCrashDiag) {
+ report_fatal_error(Twine(Reason), GenCrashDiag);
+}
+
+void llvm::report_fatal_error(const Twine &Reason, bool GenCrashDiag) {
+ llvm::fatal_error_handler_t handler = nullptr;
+ void* handlerData = nullptr;
+ {
+ // Only acquire the mutex while reading the handler, so as not to invoke a
+ // user-supplied callback under a lock.
+ llvm::MutexGuard Lock(*ErrorHandlerMutex);
+ handler = ErrorHandler;
+ handlerData = ErrorHandlerUserData;
+ }
+
+ if (handler) {
+ handler(handlerData, Reason.str(), GenCrashDiag);
+ } else {
+ // Blast the result out to stderr. We don't try hard to make sure this
+ // succeeds (e.g. handling EINTR) and we can't use errs() here because
+ // raw ostreams can call report_fatal_error.
+ SmallVector<char, 64> Buffer;
+ raw_svector_ostream OS(Buffer);
+ OS << "LLVM ERROR: " << Reason << "\n";
+ StringRef MessageStr = OS.str();
+ ssize_t written = ::write(2, MessageStr.data(), MessageStr.size());
+ (void)written; // If something went wrong, we deliberately just give up.
+ }
+
+ // If we reached here, we are failing ungracefully. Run the interrupt handlers
+ // to make sure any special cleanups get done, in particular that we remove
+ // files registered with RemoveFileOnSignal.
+ sys::RunInterruptHandlers();
+
+ exit(1);
+}
+
+void llvm::llvm_unreachable_internal(const char *msg, const char *file,
+ unsigned line) {
+ // This code intentionally doesn't call the ErrorHandler callback, because
+ // llvm_unreachable is intended to be used to indicate "impossible"
+ // situations, and not legitimate runtime errors.
+ if (msg)
+ dbgs() << msg << "\n";
+ dbgs() << "UNREACHABLE executed";
+ if (file)
+ dbgs() << " at " << file << ":" << line;
+ dbgs() << "!\n";
+ abort();
+#ifdef LLVM_BUILTIN_UNREACHABLE
+ // Windows systems and possibly others don't declare abort() to be noreturn,
+ // so use the unreachable builtin to avoid a Clang self-host warning.
+ LLVM_BUILTIN_UNREACHABLE;
+#endif
+}
+
+static void bindingsErrorHandler(void *user_data, const std::string& reason,
+ bool gen_crash_diag) {
+ LLVMFatalErrorHandler handler =
+ LLVM_EXTENSION reinterpret_cast<LLVMFatalErrorHandler>(user_data);
+ handler(reason.c_str());
+}
+
+void LLVMInstallFatalErrorHandler(LLVMFatalErrorHandler Handler) {
+ install_fatal_error_handler(bindingsErrorHandler,
+ LLVM_EXTENSION reinterpret_cast<void *>(Handler));
+}
+
+void LLVMResetFatalErrorHandler() {
+ remove_fatal_error_handler();
+}
+
+#ifdef LLVM_ON_WIN32
+
+#include <winerror.h>
+
+// I'd rather not double the line count of the following.
+#define MAP_ERR_TO_COND(x, y) \
+ case x: \
+ return make_error_code(errc::y)
+
+std::error_code llvm::mapWindowsError(unsigned EV) {
+ switch (EV) {
+ MAP_ERR_TO_COND(ERROR_ACCESS_DENIED, permission_denied);
+ MAP_ERR_TO_COND(ERROR_ALREADY_EXISTS, file_exists);
+ MAP_ERR_TO_COND(ERROR_BAD_UNIT, no_such_device);
+ MAP_ERR_TO_COND(ERROR_BUFFER_OVERFLOW, filename_too_long);
+ MAP_ERR_TO_COND(ERROR_BUSY, device_or_resource_busy);
+ MAP_ERR_TO_COND(ERROR_BUSY_DRIVE, device_or_resource_busy);
+ MAP_ERR_TO_COND(ERROR_CANNOT_MAKE, permission_denied);
+ MAP_ERR_TO_COND(ERROR_CANTOPEN, io_error);
+ MAP_ERR_TO_COND(ERROR_CANTREAD, io_error);
+ MAP_ERR_TO_COND(ERROR_CANTWRITE, io_error);
+ MAP_ERR_TO_COND(ERROR_CURRENT_DIRECTORY, permission_denied);
+ MAP_ERR_TO_COND(ERROR_DEV_NOT_EXIST, no_such_device);
+ MAP_ERR_TO_COND(ERROR_DEVICE_IN_USE, device_or_resource_busy);
+ MAP_ERR_TO_COND(ERROR_DIR_NOT_EMPTY, directory_not_empty);
+ MAP_ERR_TO_COND(ERROR_DIRECTORY, invalid_argument);
+ MAP_ERR_TO_COND(ERROR_DISK_FULL, no_space_on_device);
+ MAP_ERR_TO_COND(ERROR_FILE_EXISTS, file_exists);
+ MAP_ERR_TO_COND(ERROR_FILE_NOT_FOUND, no_such_file_or_directory);
+ MAP_ERR_TO_COND(ERROR_HANDLE_DISK_FULL, no_space_on_device);
+ MAP_ERR_TO_COND(ERROR_INVALID_ACCESS, permission_denied);
+ MAP_ERR_TO_COND(ERROR_INVALID_DRIVE, no_such_device);
+ MAP_ERR_TO_COND(ERROR_INVALID_FUNCTION, function_not_supported);
+ MAP_ERR_TO_COND(ERROR_INVALID_HANDLE, invalid_argument);
+ MAP_ERR_TO_COND(ERROR_INVALID_NAME, invalid_argument);
+ MAP_ERR_TO_COND(ERROR_LOCK_VIOLATION, no_lock_available);
+ MAP_ERR_TO_COND(ERROR_LOCKED, no_lock_available);
+ MAP_ERR_TO_COND(ERROR_NEGATIVE_SEEK, invalid_argument);
+ MAP_ERR_TO_COND(ERROR_NOACCESS, permission_denied);
+ MAP_ERR_TO_COND(ERROR_NOT_ENOUGH_MEMORY, not_enough_memory);
+ MAP_ERR_TO_COND(ERROR_NOT_READY, resource_unavailable_try_again);
+ MAP_ERR_TO_COND(ERROR_OPEN_FAILED, io_error);
+ MAP_ERR_TO_COND(ERROR_OPEN_FILES, device_or_resource_busy);
+ MAP_ERR_TO_COND(ERROR_OUTOFMEMORY, not_enough_memory);
+ MAP_ERR_TO_COND(ERROR_PATH_NOT_FOUND, no_such_file_or_directory);
+ MAP_ERR_TO_COND(ERROR_BAD_NETPATH, no_such_file_or_directory);
+ MAP_ERR_TO_COND(ERROR_READ_FAULT, io_error);
+ MAP_ERR_TO_COND(ERROR_RETRY, resource_unavailable_try_again);
+ MAP_ERR_TO_COND(ERROR_SEEK, io_error);
+ MAP_ERR_TO_COND(ERROR_SHARING_VIOLATION, permission_denied);
+ MAP_ERR_TO_COND(ERROR_TOO_MANY_OPEN_FILES, too_many_files_open);
+ MAP_ERR_TO_COND(ERROR_WRITE_FAULT, io_error);
+ MAP_ERR_TO_COND(ERROR_WRITE_PROTECT, permission_denied);
+ MAP_ERR_TO_COND(WSAEACCES, permission_denied);
+ MAP_ERR_TO_COND(WSAEBADF, bad_file_descriptor);
+ MAP_ERR_TO_COND(WSAEFAULT, bad_address);
+ MAP_ERR_TO_COND(WSAEINTR, interrupted);
+ MAP_ERR_TO_COND(WSAEINVAL, invalid_argument);
+ MAP_ERR_TO_COND(WSAEMFILE, too_many_files_open);
+ MAP_ERR_TO_COND(WSAENAMETOOLONG, filename_too_long);
+ default:
+ return std::error_code(EV, std::system_category());
+ }
+}
+
+#endif
diff --git a/contrib/llvm/lib/Support/FileOutputBuffer.cpp b/contrib/llvm/lib/Support/FileOutputBuffer.cpp
new file mode 100644
index 000000000000..6f064c983611
--- /dev/null
+++ b/contrib/llvm/lib/Support/FileOutputBuffer.cpp
@@ -0,0 +1,112 @@
+//===- FileOutputBuffer.cpp - File Output Buffer ----------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Utility for creating a in-memory buffer that will be written to a file.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/FileOutputBuffer.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/Errc.h"
+#include <system_error>
+
+#if !defined(_MSC_VER) && !defined(__MINGW32__)
+#include <unistd.h>
+#else
+#include <io.h>
+#endif
+
+using llvm::sys::fs::mapped_file_region;
+
+namespace llvm {
+FileOutputBuffer::FileOutputBuffer(std::unique_ptr<mapped_file_region> R,
+ StringRef Path, StringRef TmpPath)
+ : Region(std::move(R)), FinalPath(Path), TempPath(TmpPath) {}
+
+FileOutputBuffer::~FileOutputBuffer() {
+ sys::fs::remove(Twine(TempPath));
+}
+
+std::error_code
+FileOutputBuffer::create(StringRef FilePath, size_t Size,
+ std::unique_ptr<FileOutputBuffer> &Result,
+ unsigned Flags) {
+ // If file already exists, it must be a regular file (to be mappable).
+ sys::fs::file_status Stat;
+ std::error_code EC = sys::fs::status(FilePath, Stat);
+ switch (Stat.type()) {
+ case sys::fs::file_type::file_not_found:
+ // If file does not exist, we'll create one.
+ break;
+ case sys::fs::file_type::regular_file: {
+ // If file is not currently writable, error out.
+ // FIXME: There is no sys::fs:: api for checking this.
+ // FIXME: In posix, you use the access() call to check this.
+ }
+ break;
+ default:
+ if (EC)
+ return EC;
+ else
+ return make_error_code(errc::operation_not_permitted);
+ }
+
+ // Delete target file.
+ EC = sys::fs::remove(FilePath);
+ if (EC)
+ return EC;
+
+ unsigned Mode = sys::fs::all_read | sys::fs::all_write;
+ // If requested, make the output file executable.
+ if (Flags & F_executable)
+ Mode |= sys::fs::all_exe;
+
+ // Create new file in same directory but with random name.
+ SmallString<128> TempFilePath;
+ int FD;
+ EC = sys::fs::createUniqueFile(Twine(FilePath) + ".tmp%%%%%%%", FD,
+ TempFilePath, Mode);
+ if (EC)
+ return EC;
+
+#ifndef LLVM_ON_WIN32
+ // On Windows, CreateFileMapping (the mmap function on Windows)
+ // automatically extends the underlying file. We don't need to
+ // extend the file beforehand. _chsize (ftruncate on Windows) is
+ // pretty slow just like it writes specified amount of bytes,
+ // so we should avoid calling that.
+ EC = sys::fs::resize_file(FD, Size);
+ if (EC)
+ return EC;
+#endif
+
+ auto MappedFile = llvm::make_unique<mapped_file_region>(
+ FD, mapped_file_region::readwrite, Size, 0, EC);
+ int Ret = close(FD);
+ if (EC)
+ return EC;
+ if (Ret)
+ return std::error_code(errno, std::generic_category());
+
+ Result.reset(
+ new FileOutputBuffer(std::move(MappedFile), FilePath, TempFilePath));
+
+ return std::error_code();
+}
+
+std::error_code FileOutputBuffer::commit() {
+ // Unmap buffer, letting OS flush dirty pages to file on disk.
+ Region.reset();
+
+
+ // Rename file to final name.
+ return sys::fs::rename(Twine(TempPath), Twine(FinalPath));
+}
+} // namespace llvm
diff --git a/contrib/llvm/lib/Support/FileUtilities.cpp b/contrib/llvm/lib/Support/FileUtilities.cpp
new file mode 100644
index 000000000000..5316f049a38a
--- /dev/null
+++ b/contrib/llvm/lib/Support/FileUtilities.cpp
@@ -0,0 +1,261 @@
+//===- Support/FileUtilities.cpp - File System Utilities ------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a family of utility functions which are useful for doing
+// various things with files.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/FileUtilities.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cctype>
+#include <cstdlib>
+#include <cstring>
+#include <system_error>
+using namespace llvm;
+
+static bool isSignedChar(char C) {
+ return (C == '+' || C == '-');
+}
+
+static bool isExponentChar(char C) {
+ switch (C) {
+ case 'D': // Strange exponential notation.
+ case 'd': // Strange exponential notation.
+ case 'e':
+ case 'E': return true;
+ default: return false;
+ }
+}
+
+static bool isNumberChar(char C) {
+ switch (C) {
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ case '.': return true;
+ default: return isSignedChar(C) || isExponentChar(C);
+ }
+}
+
+static const char *BackupNumber(const char *Pos, const char *FirstChar) {
+ // If we didn't stop in the middle of a number, don't backup.
+ if (!isNumberChar(*Pos)) return Pos;
+
+ // Otherwise, return to the start of the number.
+ bool HasPeriod = false;
+ while (Pos > FirstChar && isNumberChar(Pos[-1])) {
+ // Backup over at most one period.
+ if (Pos[-1] == '.') {
+ if (HasPeriod)
+ break;
+ HasPeriod = true;
+ }
+
+ --Pos;
+ if (Pos > FirstChar && isSignedChar(Pos[0]) && !isExponentChar(Pos[-1]))
+ break;
+ }
+ return Pos;
+}
+
+/// EndOfNumber - Return the first character that is not part of the specified
+/// number. This assumes that the buffer is null terminated, so it won't fall
+/// off the end.
+static const char *EndOfNumber(const char *Pos) {
+ while (isNumberChar(*Pos))
+ ++Pos;
+ return Pos;
+}
+
+/// CompareNumbers - compare two numbers, returning true if they are different.
+static bool CompareNumbers(const char *&F1P, const char *&F2P,
+ const char *F1End, const char *F2End,
+ double AbsTolerance, double RelTolerance,
+ std::string *ErrorMsg) {
+ const char *F1NumEnd, *F2NumEnd;
+ double V1 = 0.0, V2 = 0.0;
+
+ // If one of the positions is at a space and the other isn't, chomp up 'til
+ // the end of the space.
+ while (isspace(static_cast<unsigned char>(*F1P)) && F1P != F1End)
+ ++F1P;
+ while (isspace(static_cast<unsigned char>(*F2P)) && F2P != F2End)
+ ++F2P;
+
+ // If we stop on numbers, compare their difference.
+ if (!isNumberChar(*F1P) || !isNumberChar(*F2P)) {
+ // The diff failed.
+ F1NumEnd = F1P;
+ F2NumEnd = F2P;
+ } else {
+ // Note that some ugliness is built into this to permit support for numbers
+ // that use "D" or "d" as their exponential marker, e.g. "1.234D45". This
+ // occurs in 200.sixtrack in spec2k.
+ V1 = strtod(F1P, const_cast<char**>(&F1NumEnd));
+ V2 = strtod(F2P, const_cast<char**>(&F2NumEnd));
+
+ if (*F1NumEnd == 'D' || *F1NumEnd == 'd') {
+ // Copy string into tmp buffer to replace the 'D' with an 'e'.
+ SmallString<200> StrTmp(F1P, EndOfNumber(F1NumEnd)+1);
+ // Strange exponential notation!
+ StrTmp[static_cast<unsigned>(F1NumEnd-F1P)] = 'e';
+
+ V1 = strtod(&StrTmp[0], const_cast<char**>(&F1NumEnd));
+ F1NumEnd = F1P + (F1NumEnd-&StrTmp[0]);
+ }
+
+ if (*F2NumEnd == 'D' || *F2NumEnd == 'd') {
+ // Copy string into tmp buffer to replace the 'D' with an 'e'.
+ SmallString<200> StrTmp(F2P, EndOfNumber(F2NumEnd)+1);
+ // Strange exponential notation!
+ StrTmp[static_cast<unsigned>(F2NumEnd-F2P)] = 'e';
+
+ V2 = strtod(&StrTmp[0], const_cast<char**>(&F2NumEnd));
+ F2NumEnd = F2P + (F2NumEnd-&StrTmp[0]);
+ }
+ }
+
+ if (F1NumEnd == F1P || F2NumEnd == F2P) {
+ if (ErrorMsg) {
+ *ErrorMsg = "FP Comparison failed, not a numeric difference between '";
+ *ErrorMsg += F1P[0];
+ *ErrorMsg += "' and '";
+ *ErrorMsg += F2P[0];
+ *ErrorMsg += "'";
+ }
+ return true;
+ }
+
+ // Check to see if these are inside the absolute tolerance
+ if (AbsTolerance < std::abs(V1-V2)) {
+ // Nope, check the relative tolerance...
+ double Diff;
+ if (V2)
+ Diff = std::abs(V1/V2 - 1.0);
+ else if (V1)
+ Diff = std::abs(V2/V1 - 1.0);
+ else
+ Diff = 0; // Both zero.
+ if (Diff > RelTolerance) {
+ if (ErrorMsg) {
+ raw_string_ostream(*ErrorMsg)
+ << "Compared: " << V1 << " and " << V2 << '\n'
+ << "abs. diff = " << std::abs(V1-V2) << " rel.diff = " << Diff << '\n'
+ << "Out of tolerance: rel/abs: " << RelTolerance << '/'
+ << AbsTolerance;
+ }
+ return true;
+ }
+ }
+
+ // Otherwise, advance our read pointers to the end of the numbers.
+ F1P = F1NumEnd; F2P = F2NumEnd;
+ return false;
+}
+
+/// 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 differs from DiffFiles in that you can 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, allowing the caller to distinguish between a failed diff and a
+/// file system error.
+///
+int llvm::DiffFilesWithTolerance(StringRef NameA,
+ StringRef NameB,
+ double AbsTol, double RelTol,
+ std::string *Error) {
+ // Now its safe to mmap the files into memory because both files
+ // have a non-zero size.
+ ErrorOr<std::unique_ptr<MemoryBuffer>> F1OrErr = MemoryBuffer::getFile(NameA);
+ if (std::error_code EC = F1OrErr.getError()) {
+ if (Error)
+ *Error = EC.message();
+ return 2;
+ }
+ MemoryBuffer &F1 = *F1OrErr.get();
+
+ ErrorOr<std::unique_ptr<MemoryBuffer>> F2OrErr = MemoryBuffer::getFile(NameB);
+ if (std::error_code EC = F2OrErr.getError()) {
+ if (Error)
+ *Error = EC.message();
+ return 2;
+ }
+ MemoryBuffer &F2 = *F2OrErr.get();
+
+ // Okay, now that we opened the files, scan them for the first difference.
+ const char *File1Start = F1.getBufferStart();
+ const char *File2Start = F2.getBufferStart();
+ const char *File1End = F1.getBufferEnd();
+ const char *File2End = F2.getBufferEnd();
+ const char *F1P = File1Start;
+ const char *F2P = File2Start;
+ uint64_t A_size = F1.getBufferSize();
+ uint64_t B_size = F2.getBufferSize();
+
+ // Are the buffers identical? Common case: Handle this efficiently.
+ if (A_size == B_size &&
+ std::memcmp(File1Start, File2Start, A_size) == 0)
+ return 0;
+
+ // Otherwise, we are done a tolerances are set.
+ if (AbsTol == 0 && RelTol == 0) {
+ if (Error)
+ *Error = "Files differ without tolerance allowance";
+ return 1; // Files different!
+ }
+
+ bool CompareFailed = false;
+ while (1) {
+ // Scan for the end of file or next difference.
+ while (F1P < File1End && F2P < File2End && *F1P == *F2P)
+ ++F1P, ++F2P;
+
+ if (F1P >= File1End || F2P >= File2End) break;
+
+ // Okay, we must have found a difference. Backup to the start of the
+ // current number each stream is at so that we can compare from the
+ // beginning.
+ F1P = BackupNumber(F1P, File1Start);
+ F2P = BackupNumber(F2P, File2Start);
+
+ // Now that we are at the start of the numbers, compare them, exiting if
+ // they don't match.
+ if (CompareNumbers(F1P, F2P, File1End, File2End, AbsTol, RelTol, Error)) {
+ CompareFailed = true;
+ break;
+ }
+ }
+
+ // Okay, we reached the end of file. If both files are at the end, we
+ // succeeded.
+ bool F1AtEnd = F1P >= File1End;
+ bool F2AtEnd = F2P >= File2End;
+ if (!CompareFailed && (!F1AtEnd || !F2AtEnd)) {
+ // Else, we might have run off the end due to a number: backup and retry.
+ if (F1AtEnd && isNumberChar(F1P[-1])) --F1P;
+ if (F2AtEnd && isNumberChar(F2P[-1])) --F2P;
+ F1P = BackupNumber(F1P, File1Start);
+ F2P = BackupNumber(F2P, File2Start);
+
+ // Now that we are at the start of the numbers, compare them, exiting if
+ // they don't match.
+ if (CompareNumbers(F1P, F2P, File1End, File2End, AbsTol, RelTol, Error))
+ CompareFailed = true;
+
+ // If we found the end, we succeeded.
+ if (F1P < File1End || F2P < File2End)
+ CompareFailed = true;
+ }
+
+ return CompareFailed;
+}
diff --git a/contrib/llvm/lib/Support/FoldingSet.cpp b/contrib/llvm/lib/Support/FoldingSet.cpp
new file mode 100644
index 000000000000..b8538ffe1f9f
--- /dev/null
+++ b/contrib/llvm/lib/Support/FoldingSet.cpp
@@ -0,0 +1,427 @@
+//===-- Support/FoldingSet.cpp - Uniquing Hash Set --------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a hash set that can be used to remove duplication of
+// nodes in a graph.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/Hashing.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/Host.h"
+#include "llvm/Support/MathExtras.h"
+#include <cassert>
+#include <cstring>
+using namespace llvm;
+
+//===----------------------------------------------------------------------===//
+// FoldingSetNodeIDRef Implementation
+
+/// ComputeHash - Compute a strong hash value for this FoldingSetNodeIDRef,
+/// used to lookup the node in the FoldingSetImpl.
+unsigned FoldingSetNodeIDRef::ComputeHash() const {
+ return static_cast<unsigned>(hash_combine_range(Data, Data+Size));
+}
+
+bool FoldingSetNodeIDRef::operator==(FoldingSetNodeIDRef RHS) const {
+ if (Size != RHS.Size) return false;
+ return memcmp(Data, RHS.Data, Size*sizeof(*Data)) == 0;
+}
+
+/// Used to compare the "ordering" of two nodes as defined by the
+/// profiled bits and their ordering defined by memcmp().
+bool FoldingSetNodeIDRef::operator<(FoldingSetNodeIDRef RHS) const {
+ if (Size != RHS.Size)
+ return Size < RHS.Size;
+ return memcmp(Data, RHS.Data, Size*sizeof(*Data)) < 0;
+}
+
+//===----------------------------------------------------------------------===//
+// FoldingSetNodeID Implementation
+
+/// Add* - Add various data types to Bit data.
+///
+void FoldingSetNodeID::AddPointer(const void *Ptr) {
+ // Note: this adds pointers to the hash using sizes and endianness that
+ // depend on the host. It doesn't matter, however, because hashing on
+ // pointer values is inherently unstable. Nothing should depend on the
+ // ordering of nodes in the folding set.
+ Bits.append(reinterpret_cast<unsigned *>(&Ptr),
+ reinterpret_cast<unsigned *>(&Ptr+1));
+}
+void FoldingSetNodeID::AddInteger(signed I) {
+ Bits.push_back(I);
+}
+void FoldingSetNodeID::AddInteger(unsigned I) {
+ Bits.push_back(I);
+}
+void FoldingSetNodeID::AddInteger(long I) {
+ AddInteger((unsigned long)I);
+}
+void FoldingSetNodeID::AddInteger(unsigned long I) {
+ if (sizeof(long) == sizeof(int))
+ AddInteger(unsigned(I));
+ else if (sizeof(long) == sizeof(long long)) {
+ AddInteger((unsigned long long)I);
+ } else {
+ llvm_unreachable("unexpected sizeof(long)");
+ }
+}
+void FoldingSetNodeID::AddInteger(long long I) {
+ AddInteger((unsigned long long)I);
+}
+void FoldingSetNodeID::AddInteger(unsigned long long I) {
+ AddInteger(unsigned(I));
+ if ((uint64_t)(unsigned)I != I)
+ Bits.push_back(unsigned(I >> 32));
+}
+
+void FoldingSetNodeID::AddString(StringRef String) {
+ unsigned Size = String.size();
+ Bits.push_back(Size);
+ if (!Size) return;
+
+ unsigned Units = Size / 4;
+ unsigned Pos = 0;
+ const unsigned *Base = (const unsigned*) String.data();
+
+ // If the string is aligned do a bulk transfer.
+ if (!((intptr_t)Base & 3)) {
+ Bits.append(Base, Base + Units);
+ Pos = (Units + 1) * 4;
+ } else {
+ // Otherwise do it the hard way.
+ // To be compatible with above bulk transfer, we need to take endianness
+ // into account.
+ static_assert(sys::IsBigEndianHost || sys::IsLittleEndianHost,
+ "Unexpected host endianness");
+ if (sys::IsBigEndianHost) {
+ for (Pos += 4; Pos <= Size; Pos += 4) {
+ unsigned V = ((unsigned char)String[Pos - 4] << 24) |
+ ((unsigned char)String[Pos - 3] << 16) |
+ ((unsigned char)String[Pos - 2] << 8) |
+ (unsigned char)String[Pos - 1];
+ Bits.push_back(V);
+ }
+ } else { // Little-endian host
+ for (Pos += 4; Pos <= Size; Pos += 4) {
+ unsigned V = ((unsigned char)String[Pos - 1] << 24) |
+ ((unsigned char)String[Pos - 2] << 16) |
+ ((unsigned char)String[Pos - 3] << 8) |
+ (unsigned char)String[Pos - 4];
+ Bits.push_back(V);
+ }
+ }
+ }
+
+ // With the leftover bits.
+ unsigned V = 0;
+ // Pos will have overshot size by 4 - #bytes left over.
+ // No need to take endianness into account here - this is always executed.
+ switch (Pos - Size) {
+ case 1: V = (V << 8) | (unsigned char)String[Size - 3]; // Fall thru.
+ case 2: V = (V << 8) | (unsigned char)String[Size - 2]; // Fall thru.
+ case 3: V = (V << 8) | (unsigned char)String[Size - 1]; break;
+ default: return; // Nothing left.
+ }
+
+ Bits.push_back(V);
+}
+
+// AddNodeID - Adds the Bit data of another ID to *this.
+void FoldingSetNodeID::AddNodeID(const FoldingSetNodeID &ID) {
+ Bits.append(ID.Bits.begin(), ID.Bits.end());
+}
+
+/// ComputeHash - Compute a strong hash value for this FoldingSetNodeID, used to
+/// lookup the node in the FoldingSetImpl.
+unsigned FoldingSetNodeID::ComputeHash() const {
+ return FoldingSetNodeIDRef(Bits.data(), Bits.size()).ComputeHash();
+}
+
+/// operator== - Used to compare two nodes to each other.
+///
+bool FoldingSetNodeID::operator==(const FoldingSetNodeID &RHS) const {
+ return *this == FoldingSetNodeIDRef(RHS.Bits.data(), RHS.Bits.size());
+}
+
+/// operator== - Used to compare two nodes to each other.
+///
+bool FoldingSetNodeID::operator==(FoldingSetNodeIDRef RHS) const {
+ return FoldingSetNodeIDRef(Bits.data(), Bits.size()) == RHS;
+}
+
+/// Used to compare the "ordering" of two nodes as defined by the
+/// profiled bits and their ordering defined by memcmp().
+bool FoldingSetNodeID::operator<(const FoldingSetNodeID &RHS) const {
+ return *this < FoldingSetNodeIDRef(RHS.Bits.data(), RHS.Bits.size());
+}
+
+bool FoldingSetNodeID::operator<(FoldingSetNodeIDRef RHS) const {
+ return FoldingSetNodeIDRef(Bits.data(), Bits.size()) < RHS;
+}
+
+/// Intern - Copy this node's data to a memory region allocated from the
+/// given allocator and return a FoldingSetNodeIDRef describing the
+/// interned data.
+FoldingSetNodeIDRef
+FoldingSetNodeID::Intern(BumpPtrAllocator &Allocator) const {
+ unsigned *New = Allocator.Allocate<unsigned>(Bits.size());
+ std::uninitialized_copy(Bits.begin(), Bits.end(), New);
+ return FoldingSetNodeIDRef(New, Bits.size());
+}
+
+//===----------------------------------------------------------------------===//
+/// Helper functions for FoldingSetImpl.
+
+/// GetNextPtr - In order to save space, each bucket is a
+/// singly-linked-list. In order to make deletion more efficient, we make
+/// the list circular, so we can delete a node without computing its hash.
+/// The problem with this is that the start of the hash buckets are not
+/// Nodes. If NextInBucketPtr is a bucket pointer, this method returns null:
+/// use GetBucketPtr when this happens.
+static FoldingSetImpl::Node *GetNextPtr(void *NextInBucketPtr) {
+ // The low bit is set if this is the pointer back to the bucket.
+ if (reinterpret_cast<intptr_t>(NextInBucketPtr) & 1)
+ return nullptr;
+
+ return static_cast<FoldingSetImpl::Node*>(NextInBucketPtr);
+}
+
+
+/// testing.
+static void **GetBucketPtr(void *NextInBucketPtr) {
+ intptr_t Ptr = reinterpret_cast<intptr_t>(NextInBucketPtr);
+ assert((Ptr & 1) && "Not a bucket pointer");
+ return reinterpret_cast<void**>(Ptr & ~intptr_t(1));
+}
+
+/// GetBucketFor - Hash the specified node ID and return the hash bucket for
+/// the specified ID.
+static void **GetBucketFor(unsigned Hash, void **Buckets, unsigned NumBuckets) {
+ // NumBuckets is always a power of 2.
+ unsigned BucketNum = Hash & (NumBuckets-1);
+ return Buckets + BucketNum;
+}
+
+/// AllocateBuckets - Allocated initialized bucket memory.
+static void **AllocateBuckets(unsigned NumBuckets) {
+ void **Buckets = static_cast<void**>(calloc(NumBuckets+1, sizeof(void*)));
+ // Set the very last bucket to be a non-null "pointer".
+ Buckets[NumBuckets] = reinterpret_cast<void*>(-1);
+ return Buckets;
+}
+
+//===----------------------------------------------------------------------===//
+// FoldingSetImpl Implementation
+
+void FoldingSetImpl::anchor() {}
+
+FoldingSetImpl::FoldingSetImpl(unsigned Log2InitSize) {
+ assert(5 < Log2InitSize && Log2InitSize < 32 &&
+ "Initial hash table size out of range");
+ NumBuckets = 1 << Log2InitSize;
+ Buckets = AllocateBuckets(NumBuckets);
+ NumNodes = 0;
+}
+FoldingSetImpl::~FoldingSetImpl() {
+ free(Buckets);
+}
+void FoldingSetImpl::clear() {
+ // Set all but the last bucket to null pointers.
+ memset(Buckets, 0, NumBuckets*sizeof(void*));
+
+ // Set the very last bucket to be a non-null "pointer".
+ Buckets[NumBuckets] = reinterpret_cast<void*>(-1);
+
+ // Reset the node count to zero.
+ NumNodes = 0;
+}
+
+/// GrowHashTable - Double the size of the hash table and rehash everything.
+///
+void FoldingSetImpl::GrowHashTable() {
+ void **OldBuckets = Buckets;
+ unsigned OldNumBuckets = NumBuckets;
+ NumBuckets <<= 1;
+
+ // Clear out new buckets.
+ Buckets = AllocateBuckets(NumBuckets);
+ NumNodes = 0;
+
+ // Walk the old buckets, rehashing nodes into their new place.
+ FoldingSetNodeID TempID;
+ for (unsigned i = 0; i != OldNumBuckets; ++i) {
+ void *Probe = OldBuckets[i];
+ if (!Probe) continue;
+ while (Node *NodeInBucket = GetNextPtr(Probe)) {
+ // Figure out the next link, remove NodeInBucket from the old link.
+ Probe = NodeInBucket->getNextInBucket();
+ NodeInBucket->SetNextInBucket(nullptr);
+
+ // Insert the node into the new bucket, after recomputing the hash.
+ InsertNode(NodeInBucket,
+ GetBucketFor(ComputeNodeHash(NodeInBucket, TempID),
+ Buckets, NumBuckets));
+ TempID.clear();
+ }
+ }
+
+ free(OldBuckets);
+}
+
+/// FindNodeOrInsertPos - Look up the node specified by ID. If it exists,
+/// return it. If not, return the insertion token that will make insertion
+/// faster.
+FoldingSetImpl::Node
+*FoldingSetImpl::FindNodeOrInsertPos(const FoldingSetNodeID &ID,
+ void *&InsertPos) {
+ unsigned IDHash = ID.ComputeHash();
+ void **Bucket = GetBucketFor(IDHash, Buckets, NumBuckets);
+ void *Probe = *Bucket;
+
+ InsertPos = nullptr;
+
+ FoldingSetNodeID TempID;
+ while (Node *NodeInBucket = GetNextPtr(Probe)) {
+ if (NodeEquals(NodeInBucket, ID, IDHash, TempID))
+ return NodeInBucket;
+ TempID.clear();
+
+ Probe = NodeInBucket->getNextInBucket();
+ }
+
+ // Didn't find the node, return null with the bucket as the InsertPos.
+ InsertPos = Bucket;
+ return nullptr;
+}
+
+/// InsertNode - Insert the specified node into the folding set, knowing that it
+/// is not already in the map. InsertPos must be obtained from
+/// FindNodeOrInsertPos.
+void FoldingSetImpl::InsertNode(Node *N, void *InsertPos) {
+ assert(!N->getNextInBucket());
+ // Do we need to grow the hashtable?
+ if (NumNodes+1 > NumBuckets*2) {
+ GrowHashTable();
+ FoldingSetNodeID TempID;
+ InsertPos = GetBucketFor(ComputeNodeHash(N, TempID), Buckets, NumBuckets);
+ }
+
+ ++NumNodes;
+
+ /// The insert position is actually a bucket pointer.
+ void **Bucket = static_cast<void**>(InsertPos);
+
+ void *Next = *Bucket;
+
+ // If this is the first insertion into this bucket, its next pointer will be
+ // null. Pretend as if it pointed to itself, setting the low bit to indicate
+ // that it is a pointer to the bucket.
+ if (!Next)
+ Next = reinterpret_cast<void*>(reinterpret_cast<intptr_t>(Bucket)|1);
+
+ // Set the node's next pointer, and make the bucket point to the node.
+ N->SetNextInBucket(Next);
+ *Bucket = 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 FoldingSetImpl::RemoveNode(Node *N) {
+ // Because each bucket is a circular list, we don't need to compute N's hash
+ // to remove it.
+ void *Ptr = N->getNextInBucket();
+ if (!Ptr) return false; // Not in folding set.
+
+ --NumNodes;
+ N->SetNextInBucket(nullptr);
+
+ // Remember what N originally pointed to, either a bucket or another node.
+ void *NodeNextPtr = Ptr;
+
+ // Chase around the list until we find the node (or bucket) which points to N.
+ while (true) {
+ if (Node *NodeInBucket = GetNextPtr(Ptr)) {
+ // Advance pointer.
+ Ptr = NodeInBucket->getNextInBucket();
+
+ // We found a node that points to N, change it to point to N's next node,
+ // removing N from the list.
+ if (Ptr == N) {
+ NodeInBucket->SetNextInBucket(NodeNextPtr);
+ return true;
+ }
+ } else {
+ void **Bucket = GetBucketPtr(Ptr);
+ Ptr = *Bucket;
+
+ // If we found that the bucket points to N, update the bucket to point to
+ // whatever is next.
+ if (Ptr == N) {
+ *Bucket = NodeNextPtr;
+ return true;
+ }
+ }
+ }
+}
+
+/// GetOrInsertNode - If there is an existing simple Node exactly
+/// equal to the specified node, return it. Otherwise, insert 'N' and it
+/// instead.
+FoldingSetImpl::Node *FoldingSetImpl::GetOrInsertNode(FoldingSetImpl::Node *N) {
+ FoldingSetNodeID ID;
+ GetNodeProfile(N, ID);
+ void *IP;
+ if (Node *E = FindNodeOrInsertPos(ID, IP))
+ return E;
+ InsertNode(N, IP);
+ return N;
+}
+
+//===----------------------------------------------------------------------===//
+// FoldingSetIteratorImpl Implementation
+
+FoldingSetIteratorImpl::FoldingSetIteratorImpl(void **Bucket) {
+ // Skip to the first non-null non-self-cycle bucket.
+ while (*Bucket != reinterpret_cast<void*>(-1) &&
+ (!*Bucket || !GetNextPtr(*Bucket)))
+ ++Bucket;
+
+ NodePtr = static_cast<FoldingSetNode*>(*Bucket);
+}
+
+void FoldingSetIteratorImpl::advance() {
+ // If there is another link within this bucket, go to it.
+ void *Probe = NodePtr->getNextInBucket();
+
+ if (FoldingSetNode *NextNodeInBucket = GetNextPtr(Probe))
+ NodePtr = NextNodeInBucket;
+ else {
+ // Otherwise, this is the last link in this bucket.
+ void **Bucket = GetBucketPtr(Probe);
+
+ // Skip to the next non-null non-self-cycle bucket.
+ do {
+ ++Bucket;
+ } while (*Bucket != reinterpret_cast<void*>(-1) &&
+ (!*Bucket || !GetNextPtr(*Bucket)));
+
+ NodePtr = static_cast<FoldingSetNode*>(*Bucket);
+ }
+}
+
+//===----------------------------------------------------------------------===//
+// FoldingSetBucketIteratorImpl Implementation
+
+FoldingSetBucketIteratorImpl::FoldingSetBucketIteratorImpl(void **Bucket) {
+ Ptr = (!*Bucket || !GetNextPtr(*Bucket)) ? (void*) Bucket : *Bucket;
+}
diff --git a/contrib/llvm/lib/Support/FormattedStream.cpp b/contrib/llvm/lib/Support/FormattedStream.cpp
new file mode 100644
index 000000000000..2ed71c7e4311
--- /dev/null
+++ b/contrib/llvm/lib/Support/FormattedStream.cpp
@@ -0,0 +1,107 @@
+//===-- llvm/Support/FormattedStream.cpp - Formatted streams ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the implementation of formatted_raw_ostream.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/FormattedStream.h"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+
+using namespace llvm;
+
+/// UpdatePosition - Examine the given char sequence and figure out which
+/// column we end up in after output, and how many line breaks are contained.
+///
+static void UpdatePosition(std::pair<unsigned, unsigned> &Position, const char *Ptr, size_t Size) {
+ unsigned &Column = Position.first;
+ unsigned &Line = Position.second;
+
+ // Keep track of the current column and line by scanning the string for
+ // special characters
+ for (const char *End = Ptr + Size; Ptr != End; ++Ptr) {
+ ++Column;
+ switch (*Ptr) {
+ case '\n':
+ Line += 1;
+ case '\r':
+ Column = 0;
+ break;
+ case '\t':
+ // Assumes tab stop = 8 characters.
+ Column += (8 - (Column & 0x7)) & 0x7;
+ break;
+ }
+ }
+}
+
+/// ComputePosition - Examine the current output and update line and column
+/// counts.
+void formatted_raw_ostream::ComputePosition(const char *Ptr, size_t Size) {
+ // If our previous scan pointer is inside the buffer, assume we already
+ // scanned those bytes. This depends on raw_ostream to not change our buffer
+ // in unexpected ways.
+ if (Ptr <= Scanned && Scanned <= Ptr + Size)
+ // Scan all characters added since our last scan to determine the new
+ // column.
+ UpdatePosition(Position, Scanned, Size - (Scanned - Ptr));
+ else
+ UpdatePosition(Position, Ptr, Size);
+
+ // Update the scanning pointer.
+ Scanned = Ptr + Size;
+}
+
+/// PadToColumn - Align the output to some column number.
+///
+/// \param NewCol - The column to move to.
+///
+formatted_raw_ostream &formatted_raw_ostream::PadToColumn(unsigned NewCol) {
+ // Figure out what's in the buffer and add it to the column count.
+ ComputePosition(getBufferStart(), GetNumBytesInBuffer());
+
+ // Output spaces until we reach the desired column.
+ indent(std::max(int(NewCol - getColumn()), 1));
+ return *this;
+}
+
+void formatted_raw_ostream::write_impl(const char *Ptr, size_t Size) {
+ // Figure out what's in the buffer and add it to the column count.
+ ComputePosition(Ptr, Size);
+
+ // Write the data to the underlying stream (which is unbuffered, so
+ // the data will be immediately written out).
+ TheStream->write(Ptr, Size);
+
+ // Reset the scanning pointer.
+ Scanned = nullptr;
+}
+
+/// fouts() - This returns a reference to a formatted_raw_ostream for
+/// standard output. Use it like: fouts() << "foo" << "bar";
+formatted_raw_ostream &llvm::fouts() {
+ static formatted_raw_ostream S(outs());
+ return S;
+}
+
+/// ferrs() - This returns a reference to a formatted_raw_ostream for
+/// standard error. Use it like: ferrs() << "foo" << "bar";
+formatted_raw_ostream &llvm::ferrs() {
+ static formatted_raw_ostream S(errs());
+ return S;
+}
+
+/// fdbgs() - This returns a reference to a formatted_raw_ostream for
+/// the debug stream. Use it like: fdbgs() << "foo" << "bar";
+formatted_raw_ostream &llvm::fdbgs() {
+ static formatted_raw_ostream S(dbgs());
+ return S;
+}
diff --git a/contrib/llvm/lib/Support/GraphWriter.cpp b/contrib/llvm/lib/Support/GraphWriter.cpp
new file mode 100644
index 000000000000..97aedc88473a
--- /dev/null
+++ b/contrib/llvm/lib/Support/GraphWriter.cpp
@@ -0,0 +1,267 @@
+//===-- GraphWriter.cpp - Implements GraphWriter support routines ---------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements misc. GraphWriter support routines.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/GraphWriter.h"
+#include "llvm/Config/config.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Program.h"
+using namespace llvm;
+
+static cl::opt<bool> ViewBackground("view-background", cl::Hidden,
+ cl::desc("Execute graph viewer in the background. Creates tmp file litter."));
+
+std::string llvm::DOT::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())
+ switch (Str[i+1]) {
+ case 'l': continue; // don't disturb \l
+ case '|': case '{': case '}':
+ Str.erase(Str.begin()+i); continue;
+ default: break;
+ }
+ case '{': case '}':
+ case '<': case '>':
+ case '|': case '"':
+ Str.insert(Str.begin()+i, '\\'); // Escape character...
+ ++i; // don't infinite loop
+ break;
+ }
+ return Str;
+}
+
+/// \brief Get a color string for this node number. Simply round-robin selects
+/// from a reasonable number of colors.
+StringRef llvm::DOT::getColorString(unsigned ColorNumber) {
+ static const int NumColors = 20;
+ static const char* Colors[NumColors] = {
+ "aaaaaa", "aa0000", "00aa00", "aa5500", "0055ff", "aa00aa", "00aaaa",
+ "555555", "ff5555", "55ff55", "ffff55", "5555ff", "ff55ff", "55ffff",
+ "ffaaaa", "aaffaa", "ffffaa", "aaaaff", "ffaaff", "aaffff"};
+ return Colors[ColorNumber % NumColors];
+}
+
+std::string llvm::createGraphFilename(const Twine &Name, int &FD) {
+ FD = -1;
+ SmallString<128> Filename;
+ std::error_code EC = sys::fs::createTemporaryFile(Name, "dot", FD, Filename);
+ if (EC) {
+ errs() << "Error: " << EC.message() << "\n";
+ return "";
+ }
+
+ errs() << "Writing '" << Filename << "'... ";
+ return Filename.str();
+}
+
+// Execute the graph viewer. Return true if there were errors.
+static bool ExecGraphViewer(StringRef ExecPath, std::vector<const char *> &args,
+ StringRef Filename, bool wait,
+ std::string &ErrMsg) {
+ assert(args.back() == nullptr);
+ if (wait) {
+ if (sys::ExecuteAndWait(ExecPath, args.data(), nullptr, nullptr, 0, 0,
+ &ErrMsg)) {
+ errs() << "Error: " << ErrMsg << "\n";
+ return true;
+ }
+ sys::fs::remove(Filename);
+ errs() << " done. \n";
+ } else {
+ sys::ExecuteNoWait(ExecPath, args.data(), nullptr, nullptr, 0, &ErrMsg);
+ errs() << "Remember to erase graph file: " << Filename << "\n";
+ }
+ return false;
+}
+
+namespace {
+struct GraphSession {
+ std::string LogBuffer;
+ bool TryFindProgram(StringRef Names, std::string &ProgramPath) {
+ raw_string_ostream Log(LogBuffer);
+ SmallVector<StringRef, 8> parts;
+ Names.split(parts, "|");
+ for (auto Name : parts) {
+ if (ErrorOr<std::string> P = sys::findProgramByName(Name)) {
+ ProgramPath = *P;
+ return true;
+ }
+ Log << " Tried '" << Name << "'\n";
+ }
+ return false;
+ }
+};
+} // namespace
+
+static const char *getProgramName(GraphProgram::Name program) {
+ switch (program) {
+ case GraphProgram::DOT:
+ return "dot";
+ case GraphProgram::FDP:
+ return "fdp";
+ case GraphProgram::NEATO:
+ return "neato";
+ case GraphProgram::TWOPI:
+ return "twopi";
+ case GraphProgram::CIRCO:
+ return "circo";
+ }
+ llvm_unreachable("bad kind");
+}
+
+bool llvm::DisplayGraph(StringRef FilenameRef, bool wait,
+ GraphProgram::Name program) {
+ std::string Filename = FilenameRef;
+ wait &= !ViewBackground;
+ std::string ErrMsg;
+ std::string ViewerPath;
+ GraphSession S;
+
+#ifdef __APPLE__
+ if (S.TryFindProgram("open", ViewerPath)) {
+ std::vector<const char *> args;
+ args.push_back(ViewerPath.c_str());
+ if (wait)
+ args.push_back("-W");
+ args.push_back(Filename.c_str());
+ args.push_back(nullptr);
+ errs() << "Trying 'open' program... ";
+ if (!ExecGraphViewer(ViewerPath, args, Filename, wait, ErrMsg))
+ return false;
+ }
+#endif
+ if (S.TryFindProgram("xdg-open", ViewerPath)) {
+ std::vector<const char *> args;
+ args.push_back(ViewerPath.c_str());
+ args.push_back(Filename.c_str());
+ args.push_back(nullptr);
+ errs() << "Trying 'xdg-open' program... ";
+ if (!ExecGraphViewer(ViewerPath, args, Filename, wait, ErrMsg))
+ return false;
+ }
+
+ // Graphviz
+ if (S.TryFindProgram("Graphviz", ViewerPath)) {
+ std::vector<const char *> args;
+ args.push_back(ViewerPath.c_str());
+ args.push_back(Filename.c_str());
+ args.push_back(nullptr);
+
+ errs() << "Running 'Graphviz' program... ";
+ return ExecGraphViewer(ViewerPath, args, Filename, wait, ErrMsg);
+ }
+
+ // xdot
+ if (S.TryFindProgram("xdot|xdot.py", ViewerPath)) {
+ std::vector<const char *> args;
+ args.push_back(ViewerPath.c_str());
+ args.push_back(Filename.c_str());
+
+ args.push_back("-f");
+ args.push_back(getProgramName(program));
+
+ args.push_back(nullptr);
+
+ errs() << "Running 'xdot.py' program... ";
+ return ExecGraphViewer(ViewerPath, args, Filename, wait, ErrMsg);
+ }
+
+ enum PSViewerKind { PSV_None, PSV_OSXOpen, PSV_XDGOpen, PSV_Ghostview };
+ PSViewerKind PSViewer = PSV_None;
+#ifdef __APPLE__
+ if (!PSViewer && S.TryFindProgram("open", ViewerPath))
+ PSViewer = PSV_OSXOpen;
+#endif
+ if (!PSViewer && S.TryFindProgram("gv", ViewerPath))
+ PSViewer = PSV_Ghostview;
+ if (!PSViewer && S.TryFindProgram("xdg-open", ViewerPath))
+ PSViewer = PSV_XDGOpen;
+
+ // PostScript graph generator + PostScript viewer
+ std::string GeneratorPath;
+ if (PSViewer &&
+ (S.TryFindProgram(getProgramName(program), GeneratorPath) ||
+ S.TryFindProgram("dot|fdp|neato|twopi|circo", GeneratorPath))) {
+ std::string PSFilename = Filename + ".ps";
+
+ std::vector<const char *> args;
+ args.push_back(GeneratorPath.c_str());
+ args.push_back("-Tps");
+ args.push_back("-Nfontname=Courier");
+ args.push_back("-Gsize=7.5,10");
+ args.push_back(Filename.c_str());
+ args.push_back("-o");
+ args.push_back(PSFilename.c_str());
+ args.push_back(nullptr);
+
+ errs() << "Running '" << GeneratorPath << "' program... ";
+
+ if (ExecGraphViewer(GeneratorPath, args, Filename, wait, ErrMsg))
+ return true;
+
+ args.clear();
+ args.push_back(ViewerPath.c_str());
+ switch (PSViewer) {
+ case PSV_OSXOpen:
+ args.push_back("-W");
+ args.push_back(PSFilename.c_str());
+ break;
+ case PSV_XDGOpen:
+ wait = false;
+ args.push_back(PSFilename.c_str());
+ break;
+ case PSV_Ghostview:
+ args.push_back("--spartan");
+ args.push_back(PSFilename.c_str());
+ break;
+ case PSV_None:
+ llvm_unreachable("Invalid viewer");
+ }
+ args.push_back(nullptr);
+
+ ErrMsg.clear();
+ return ExecGraphViewer(ViewerPath, args, PSFilename, wait, ErrMsg);
+ }
+
+ // dotty
+ if (S.TryFindProgram("dotty", ViewerPath)) {
+ std::vector<const char *> args;
+ args.push_back(ViewerPath.c_str());
+ args.push_back(Filename.c_str());
+ args.push_back(nullptr);
+
+// Dotty spawns another app and doesn't wait until it returns
+#ifdef LLVM_ON_WIN32
+ wait = false;
+#endif
+ errs() << "Running 'dotty' program... ";
+ return ExecGraphViewer(ViewerPath, args, Filename, wait, ErrMsg);
+ }
+
+ errs() << "Error: Couldn't find a usable graph viewer program:\n";
+ errs() << S.LogBuffer << "\n";
+ return true;
+}
diff --git a/contrib/llvm/lib/Support/Hashing.cpp b/contrib/llvm/lib/Support/Hashing.cpp
new file mode 100644
index 000000000000..c69efb7c3cc9
--- /dev/null
+++ b/contrib/llvm/lib/Support/Hashing.cpp
@@ -0,0 +1,29 @@
+//===-------------- lib/Support/Hashing.cpp -------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides implementation bits for the LLVM common hashing
+// infrastructure. Documentation and most of the other information is in the
+// header file.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/Hashing.h"
+
+using namespace llvm;
+
+// Provide a definition and static initializer for the fixed seed. This
+// initializer should always be zero to ensure its value can never appear to be
+// non-zero, even during dynamic initialization.
+size_t llvm::hashing::detail::fixed_seed_override = 0;
+
+// Implement the function for forced setting of the fixed seed.
+// FIXME: Use atomic operations here so that there is no data race.
+void llvm::set_fixed_execution_hash_seed(size_t fixed_value) {
+ hashing::detail::fixed_seed_override = fixed_value;
+}
diff --git a/contrib/llvm/lib/Support/Host.cpp b/contrib/llvm/lib/Support/Host.cpp
new file mode 100644
index 000000000000..1bd1fe2bea0e
--- /dev/null
+++ b/contrib/llvm/lib/Support/Host.cpp
@@ -0,0 +1,907 @@
+//===-- Host.cpp - Implement OS Host Concept --------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the operating system Host concept.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/Host.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Config/config.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/raw_ostream.h"
+#include <string.h>
+
+// Include the platform-specific parts of this class.
+#ifdef LLVM_ON_UNIX
+#include "Unix/Host.inc"
+#endif
+#ifdef LLVM_ON_WIN32
+#include "Windows/Host.inc"
+#endif
+#ifdef _MSC_VER
+#include <intrin.h>
+#endif
+#if defined(__APPLE__) && (defined(__ppc__) || defined(__powerpc__))
+#include <mach/mach.h>
+#include <mach/mach_host.h>
+#include <mach/host_info.h>
+#include <mach/machine.h>
+#endif
+
+#define DEBUG_TYPE "host-detection"
+
+//===----------------------------------------------------------------------===//
+//
+// Implementations of the CPU detection routines
+//
+//===----------------------------------------------------------------------===//
+
+using namespace llvm;
+
+#if defined(__linux__)
+static ssize_t LLVM_ATTRIBUTE_UNUSED readCpuInfo(void *Buf, size_t Size) {
+ // Note: We cannot mmap /proc/cpuinfo here and then process the resulting
+ // memory buffer because the 'file' has 0 size (it can be read from only
+ // as a stream).
+
+ int FD;
+ std::error_code EC = sys::fs::openFileForRead("/proc/cpuinfo", FD);
+ if (EC) {
+ DEBUG(dbgs() << "Unable to open /proc/cpuinfo: " << EC.message() << "\n");
+ return -1;
+ }
+ int Ret = read(FD, Buf, Size);
+ int CloseStatus = close(FD);
+ if (CloseStatus)
+ return -1;
+ return Ret;
+}
+#endif
+
+#if defined(i386) || defined(__i386__) || defined(__x86__) || defined(_M_IX86)\
+ || defined(__x86_64__) || defined(_M_AMD64) || defined (_M_X64)
+
+/// GetX86CpuIDAndInfo - Execute the specified cpuid and return the 4 values in the
+/// specified arguments. If we can't run cpuid on the host, return true.
+static bool GetX86CpuIDAndInfo(unsigned value, unsigned *rEAX, unsigned *rEBX,
+ unsigned *rECX, unsigned *rEDX) {
+#if defined(__GNUC__) || defined(__clang__)
+ #if defined(__x86_64__) || defined(_M_AMD64) || defined (_M_X64)
+ // gcc doesn't know cpuid would clobber ebx/rbx. Preseve it manually.
+ asm ("movq\t%%rbx, %%rsi\n\t"
+ "cpuid\n\t"
+ "xchgq\t%%rbx, %%rsi\n\t"
+ : "=a" (*rEAX),
+ "=S" (*rEBX),
+ "=c" (*rECX),
+ "=d" (*rEDX)
+ : "a" (value));
+ return false;
+ #elif defined(i386) || defined(__i386__) || defined(__x86__) || defined(_M_IX86)
+ asm ("movl\t%%ebx, %%esi\n\t"
+ "cpuid\n\t"
+ "xchgl\t%%ebx, %%esi\n\t"
+ : "=a" (*rEAX),
+ "=S" (*rEBX),
+ "=c" (*rECX),
+ "=d" (*rEDX)
+ : "a" (value));
+ return false;
+// pedantic #else returns to appease -Wunreachable-code (so we don't generate
+// postprocessed code that looks like "return true; return false;")
+ #else
+ return true;
+ #endif
+#elif defined(_MSC_VER)
+ // The MSVC intrinsic is portable across x86 and x64.
+ int registers[4];
+ __cpuid(registers, value);
+ *rEAX = registers[0];
+ *rEBX = registers[1];
+ *rECX = registers[2];
+ *rEDX = registers[3];
+ return false;
+#else
+ return true;
+#endif
+}
+
+/// GetX86CpuIDAndInfoEx - Execute the specified cpuid with subleaf and return the
+/// 4 values in the specified arguments. If we can't run cpuid on the host,
+/// return true.
+static bool GetX86CpuIDAndInfoEx(unsigned value, unsigned subleaf,
+ unsigned *rEAX, unsigned *rEBX, unsigned *rECX,
+ unsigned *rEDX) {
+#if defined(__x86_64__) || defined(_M_AMD64) || defined (_M_X64)
+ #if defined(__GNUC__)
+ // gcc doesn't know cpuid would clobber ebx/rbx. Preseve it manually.
+ asm ("movq\t%%rbx, %%rsi\n\t"
+ "cpuid\n\t"
+ "xchgq\t%%rbx, %%rsi\n\t"
+ : "=a" (*rEAX),
+ "=S" (*rEBX),
+ "=c" (*rECX),
+ "=d" (*rEDX)
+ : "a" (value),
+ "c" (subleaf));
+ return false;
+ #elif defined(_MSC_VER)
+ int registers[4];
+ __cpuidex(registers, value, subleaf);
+ *rEAX = registers[0];
+ *rEBX = registers[1];
+ *rECX = registers[2];
+ *rEDX = registers[3];
+ return false;
+ #else
+ return true;
+ #endif
+#elif defined(i386) || defined(__i386__) || defined(__x86__) || defined(_M_IX86)
+ #if defined(__GNUC__)
+ asm ("movl\t%%ebx, %%esi\n\t"
+ "cpuid\n\t"
+ "xchgl\t%%ebx, %%esi\n\t"
+ : "=a" (*rEAX),
+ "=S" (*rEBX),
+ "=c" (*rECX),
+ "=d" (*rEDX)
+ : "a" (value),
+ "c" (subleaf));
+ return false;
+ #elif defined(_MSC_VER)
+ __asm {
+ mov eax,value
+ mov ecx,subleaf
+ cpuid
+ mov esi,rEAX
+ mov dword ptr [esi],eax
+ mov esi,rEBX
+ mov dword ptr [esi],ebx
+ mov esi,rECX
+ mov dword ptr [esi],ecx
+ mov esi,rEDX
+ mov dword ptr [esi],edx
+ }
+ return false;
+ #else
+ return true;
+ #endif
+#else
+ return true;
+#endif
+}
+
+static bool GetX86XCR0(unsigned *rEAX, unsigned *rEDX) {
+#if defined(__GNUC__)
+ // Check xgetbv; this uses a .byte sequence instead of the instruction
+ // directly because older assemblers do not include support for xgetbv and
+ // there is no easy way to conditionally compile based on the assembler used.
+ __asm__ (".byte 0x0f, 0x01, 0xd0" : "=a" (*rEAX), "=d" (*rEDX) : "c" (0));
+ return false;
+#elif defined(_MSC_FULL_VER) && defined(_XCR_XFEATURE_ENABLED_MASK)
+ unsigned long long Result = _xgetbv(_XCR_XFEATURE_ENABLED_MASK);
+ *rEAX = Result;
+ *rEDX = Result >> 32;
+ return false;
+#else
+ return true;
+#endif
+}
+
+static void DetectX86FamilyModel(unsigned EAX, unsigned &Family,
+ unsigned &Model) {
+ Family = (EAX >> 8) & 0xf; // Bits 8 - 11
+ Model = (EAX >> 4) & 0xf; // Bits 4 - 7
+ if (Family == 6 || Family == 0xf) {
+ if (Family == 0xf)
+ // Examine extended family ID if family ID is F.
+ Family += (EAX >> 20) & 0xff; // Bits 20 - 27
+ // Examine extended model ID if family ID is 6 or F.
+ Model += ((EAX >> 16) & 0xf) << 4; // Bits 16 - 19
+ }
+}
+
+StringRef sys::getHostCPUName() {
+ unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
+ if (GetX86CpuIDAndInfo(0x1, &EAX, &EBX, &ECX, &EDX))
+ return "generic";
+ unsigned Family = 0;
+ unsigned Model = 0;
+ DetectX86FamilyModel(EAX, Family, Model);
+
+ union {
+ unsigned u[3];
+ char c[12];
+ } text;
+
+ unsigned MaxLeaf;
+ GetX86CpuIDAndInfo(0, &MaxLeaf, text.u+0, text.u+2, text.u+1);
+
+ bool HasMMX = (EDX >> 23) & 1;
+ bool HasSSE = (EDX >> 25) & 1;
+ bool HasSSE2 = (EDX >> 26) & 1;
+ bool HasSSE3 = (ECX >> 0) & 1;
+ bool HasSSSE3 = (ECX >> 9) & 1;
+ bool HasSSE41 = (ECX >> 19) & 1;
+ bool HasSSE42 = (ECX >> 20) & 1;
+ bool HasMOVBE = (ECX >> 22) & 1;
+ // If CPUID indicates support for XSAVE, XRESTORE and AVX, and XGETBV
+ // indicates that the AVX registers will be saved and restored on context
+ // switch, then we have full AVX support.
+ const unsigned AVXBits = (1 << 27) | (1 << 28);
+ bool HasAVX = ((ECX & AVXBits) == AVXBits) && !GetX86XCR0(&EAX, &EDX) &&
+ ((EAX & 0x6) == 0x6);
+ bool HasAVX512Save = HasAVX && ((EAX & 0xe0) == 0xe0);
+ bool HasLeaf7 = MaxLeaf >= 0x7 &&
+ !GetX86CpuIDAndInfoEx(0x7, 0x0, &EAX, &EBX, &ECX, &EDX);
+ bool HasADX = HasLeaf7 && ((EBX >> 19) & 1);
+ bool HasAVX2 = HasAVX && HasLeaf7 && (EBX & 0x20);
+ bool HasAVX512 = HasLeaf7 && HasAVX512Save && ((EBX >> 16) & 1);
+
+ GetX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX);
+ bool Em64T = (EDX >> 29) & 0x1;
+ bool HasTBM = (ECX >> 21) & 0x1;
+
+ if (memcmp(text.c, "GenuineIntel", 12) == 0) {
+ switch (Family) {
+ case 3:
+ return "i386";
+ case 4:
+ switch (Model) {
+ case 0: // Intel486 DX processors
+ case 1: // Intel486 DX processors
+ case 2: // Intel486 SX processors
+ case 3: // Intel487 processors, IntelDX2 OverDrive processors,
+ // IntelDX2 processors
+ case 4: // Intel486 SL processor
+ case 5: // IntelSX2 processors
+ case 7: // Write-Back Enhanced IntelDX2 processors
+ case 8: // IntelDX4 OverDrive processors, IntelDX4 processors
+ default: return "i486";
+ }
+ case 5:
+ switch (Model) {
+ case 1: // Pentium OverDrive processor for Pentium processor (60, 66),
+ // Pentium processors (60, 66)
+ case 2: // Pentium OverDrive processor for Pentium processor (75, 90,
+ // 100, 120, 133), Pentium processors (75, 90, 100, 120, 133,
+ // 150, 166, 200)
+ case 3: // Pentium OverDrive processors for Intel486 processor-based
+ // systems
+ return "pentium";
+
+ case 4: // Pentium OverDrive processor with MMX technology for Pentium
+ // processor (75, 90, 100, 120, 133), Pentium processor with
+ // MMX technology (166, 200)
+ return "pentium-mmx";
+
+ default: return "pentium";
+ }
+ case 6:
+ switch (Model) {
+ case 1: // Pentium Pro processor
+ return "pentiumpro";
+
+ case 3: // Intel Pentium II OverDrive processor, Pentium II processor,
+ // model 03
+ case 5: // Pentium II processor, model 05, Pentium II Xeon processor,
+ // model 05, and Intel Celeron processor, model 05
+ case 6: // Celeron processor, model 06
+ return "pentium2";
+
+ case 7: // Pentium III processor, model 07, and Pentium III Xeon
+ // processor, model 07
+ case 8: // Pentium III processor, model 08, Pentium III Xeon processor,
+ // model 08, and Celeron processor, model 08
+ case 10: // Pentium III Xeon processor, model 0Ah
+ case 11: // Pentium III processor, model 0Bh
+ return "pentium3";
+
+ case 9: // Intel Pentium M processor, Intel Celeron M processor model 09.
+ case 13: // Intel Pentium M processor, Intel Celeron M processor, model
+ // 0Dh. All processors are manufactured using the 90 nm process.
+ case 21: // Intel EP80579 Integrated Processor and Intel EP80579
+ // Integrated Processor with Intel QuickAssist Technology
+ return "pentium-m";
+
+ case 14: // Intel Core Duo processor, Intel Core Solo processor, model
+ // 0Eh. All processors are manufactured using the 65 nm process.
+ return "yonah";
+
+ case 15: // Intel Core 2 Duo processor, Intel Core 2 Duo mobile
+ // processor, Intel Core 2 Quad processor, Intel Core 2 Quad
+ // mobile processor, Intel Core 2 Extreme processor, Intel
+ // Pentium Dual-Core processor, Intel Xeon processor, model
+ // 0Fh. All processors are manufactured using the 65 nm process.
+ case 22: // Intel Celeron processor model 16h. All processors are
+ // manufactured using the 65 nm process
+ return "core2";
+
+ case 23: // Intel Core 2 Extreme processor, Intel Xeon processor, model
+ // 17h. All processors are manufactured using the 45 nm process.
+ //
+ // 45nm: Penryn , Wolfdale, Yorkfield (XE)
+ case 29: // Intel Xeon processor MP. All processors are manufactured using
+ // the 45 nm process.
+ return "penryn";
+
+ case 26: // Intel Core i7 processor and Intel Xeon processor. All
+ // processors are manufactured using the 45 nm process.
+ case 30: // Intel(R) Core(TM) i7 CPU 870 @ 2.93GHz.
+ // As found in a Summer 2010 model iMac.
+ case 46: // Nehalem EX
+ return "nehalem";
+ case 37: // Intel Core i7, laptop version.
+ case 44: // Intel Core i7 processor and Intel Xeon processor. All
+ // processors are manufactured using the 32 nm process.
+ case 47: // Westmere EX
+ return "westmere";
+
+ // SandyBridge:
+ case 42: // Intel Core i7 processor. All processors are manufactured
+ // using the 32 nm process.
+ case 45:
+ return "sandybridge";
+
+ // Ivy Bridge:
+ case 58:
+ case 62: // Ivy Bridge EP
+ return "ivybridge";
+
+ // Haswell:
+ case 60:
+ case 63:
+ case 69:
+ case 70:
+ return "haswell";
+
+ // Broadwell:
+ case 61:
+ return "broadwell";
+
+ case 28: // Most 45 nm Intel Atom processors
+ case 38: // 45 nm Atom Lincroft
+ case 39: // 32 nm Atom Medfield
+ case 53: // 32 nm Atom Midview
+ case 54: // 32 nm Atom Midview
+ return "bonnell";
+
+ // Atom Silvermont codes from the Intel software optimization guide.
+ case 55:
+ case 74:
+ case 77:
+ return "silvermont";
+
+ default: // Unknown family 6 CPU, try to guess.
+ if (HasAVX512)
+ return "knl";
+ if (HasADX)
+ return "broadwell";
+ if (HasAVX2)
+ return "haswell";
+ if (HasAVX)
+ return "sandybridge";
+ if (HasSSE42)
+ return HasMOVBE ? "silvermont" : "nehalem";
+ if (HasSSE41)
+ return "penryn";
+ if (HasSSSE3)
+ return HasMOVBE ? "bonnell" : "core2";
+ if (Em64T)
+ return "x86-64";
+ if (HasSSE2)
+ return "pentium-m";
+ if (HasSSE)
+ return "pentium3";
+ if (HasMMX)
+ return "pentium2";
+ return "pentiumpro";
+ }
+ case 15: {
+ switch (Model) {
+ case 0: // Pentium 4 processor, Intel Xeon processor. All processors are
+ // model 00h and manufactured using the 0.18 micron process.
+ case 1: // Pentium 4 processor, Intel Xeon processor, Intel Xeon
+ // processor MP, and Intel Celeron processor. All processors are
+ // model 01h and manufactured using the 0.18 micron process.
+ case 2: // Pentium 4 processor, Mobile Intel Pentium 4 processor - M,
+ // Intel Xeon processor, Intel Xeon processor MP, Intel Celeron
+ // processor, and Mobile Intel Celeron processor. All processors
+ // are model 02h and manufactured using the 0.13 micron process.
+ return (Em64T) ? "x86-64" : "pentium4";
+
+ case 3: // Pentium 4 processor, Intel Xeon processor, Intel Celeron D
+ // processor. All processors are model 03h and manufactured using
+ // the 90 nm process.
+ case 4: // Pentium 4 processor, Pentium 4 processor Extreme Edition,
+ // Pentium D processor, Intel Xeon processor, Intel Xeon
+ // processor MP, Intel Celeron D processor. All processors are
+ // model 04h and manufactured using the 90 nm process.
+ case 6: // Pentium 4 processor, Pentium D processor, Pentium processor
+ // Extreme Edition, Intel Xeon processor, Intel Xeon processor
+ // MP, Intel Celeron D processor. All processors are model 06h
+ // and manufactured using the 65 nm process.
+ return (Em64T) ? "nocona" : "prescott";
+
+ default:
+ return (Em64T) ? "x86-64" : "pentium4";
+ }
+ }
+
+ default:
+ return "generic";
+ }
+ } else if (memcmp(text.c, "AuthenticAMD", 12) == 0) {
+ // FIXME: this poorly matches the generated SubtargetFeatureKV table. There
+ // appears to be no way to generate the wide variety of AMD-specific targets
+ // from the information returned from CPUID.
+ switch (Family) {
+ case 4:
+ return "i486";
+ case 5:
+ switch (Model) {
+ case 6:
+ case 7: return "k6";
+ case 8: return "k6-2";
+ case 9:
+ case 13: return "k6-3";
+ case 10: return "geode";
+ default: return "pentium";
+ }
+ case 6:
+ switch (Model) {
+ case 4: return "athlon-tbird";
+ case 6:
+ case 7:
+ case 8: return "athlon-mp";
+ case 10: return "athlon-xp";
+ default: return "athlon";
+ }
+ case 15:
+ if (HasSSE3)
+ return "k8-sse3";
+ switch (Model) {
+ case 1: return "opteron";
+ case 5: return "athlon-fx"; // also opteron
+ default: return "athlon64";
+ }
+ case 16:
+ return "amdfam10";
+ case 20:
+ return "btver1";
+ case 21:
+ if (!HasAVX) // If the OS doesn't support AVX provide a sane fallback.
+ return "btver1";
+ if (Model >= 0x50)
+ return "bdver4"; // 50h-6Fh: Excavator
+ if (Model >= 0x30)
+ return "bdver3"; // 30h-3Fh: Steamroller
+ if (Model >= 0x10 || HasTBM)
+ return "bdver2"; // 10h-1Fh: Piledriver
+ return "bdver1"; // 00h-0Fh: Bulldozer
+ case 22:
+ if (!HasAVX) // If the OS doesn't support AVX provide a sane fallback.
+ return "btver1";
+ return "btver2";
+ default:
+ return "generic";
+ }
+ }
+ return "generic";
+}
+#elif defined(__APPLE__) && (defined(__ppc__) || defined(__powerpc__))
+StringRef sys::getHostCPUName() {
+ host_basic_info_data_t hostInfo;
+ mach_msg_type_number_t infoCount;
+
+ infoCount = HOST_BASIC_INFO_COUNT;
+ host_info(mach_host_self(), HOST_BASIC_INFO, (host_info_t)&hostInfo,
+ &infoCount);
+
+ if (hostInfo.cpu_type != CPU_TYPE_POWERPC) return "generic";
+
+ switch(hostInfo.cpu_subtype) {
+ case CPU_SUBTYPE_POWERPC_601: return "601";
+ case CPU_SUBTYPE_POWERPC_602: return "602";
+ case CPU_SUBTYPE_POWERPC_603: return "603";
+ case CPU_SUBTYPE_POWERPC_603e: return "603e";
+ case CPU_SUBTYPE_POWERPC_603ev: return "603ev";
+ case CPU_SUBTYPE_POWERPC_604: return "604";
+ case CPU_SUBTYPE_POWERPC_604e: return "604e";
+ case CPU_SUBTYPE_POWERPC_620: return "620";
+ case CPU_SUBTYPE_POWERPC_750: return "750";
+ case CPU_SUBTYPE_POWERPC_7400: return "7400";
+ case CPU_SUBTYPE_POWERPC_7450: return "7450";
+ case CPU_SUBTYPE_POWERPC_970: return "970";
+ default: ;
+ }
+
+ return "generic";
+}
+#elif defined(__linux__) && (defined(__ppc__) || defined(__powerpc__))
+StringRef sys::getHostCPUName() {
+ // Access to the Processor Version Register (PVR) on PowerPC is privileged,
+ // and so we must use an operating-system interface to determine the current
+ // processor type. On Linux, this is exposed through the /proc/cpuinfo file.
+ const char *generic = "generic";
+
+ // The cpu line is second (after the 'processor: 0' line), so if this
+ // buffer is too small then something has changed (or is wrong).
+ char buffer[1024];
+ ssize_t CPUInfoSize = readCpuInfo(buffer, sizeof(buffer));
+ if (CPUInfoSize == -1)
+ return generic;
+
+ const char *CPUInfoStart = buffer;
+ const char *CPUInfoEnd = buffer + CPUInfoSize;
+
+ const char *CIP = CPUInfoStart;
+
+ const char *CPUStart = 0;
+ size_t CPULen = 0;
+
+ // We need to find the first line which starts with cpu, spaces, and a colon.
+ // After the colon, there may be some additional spaces and then the cpu type.
+ while (CIP < CPUInfoEnd && CPUStart == 0) {
+ if (CIP < CPUInfoEnd && *CIP == '\n')
+ ++CIP;
+
+ if (CIP < CPUInfoEnd && *CIP == 'c') {
+ ++CIP;
+ if (CIP < CPUInfoEnd && *CIP == 'p') {
+ ++CIP;
+ if (CIP < CPUInfoEnd && *CIP == 'u') {
+ ++CIP;
+ while (CIP < CPUInfoEnd && (*CIP == ' ' || *CIP == '\t'))
+ ++CIP;
+
+ if (CIP < CPUInfoEnd && *CIP == ':') {
+ ++CIP;
+ while (CIP < CPUInfoEnd && (*CIP == ' ' || *CIP == '\t'))
+ ++CIP;
+
+ if (CIP < CPUInfoEnd) {
+ CPUStart = CIP;
+ while (CIP < CPUInfoEnd && (*CIP != ' ' && *CIP != '\t' &&
+ *CIP != ',' && *CIP != '\n'))
+ ++CIP;
+ CPULen = CIP - CPUStart;
+ }
+ }
+ }
+ }
+ }
+
+ if (CPUStart == 0)
+ while (CIP < CPUInfoEnd && *CIP != '\n')
+ ++CIP;
+ }
+
+ if (CPUStart == 0)
+ return generic;
+
+ return StringSwitch<const char *>(StringRef(CPUStart, CPULen))
+ .Case("604e", "604e")
+ .Case("604", "604")
+ .Case("7400", "7400")
+ .Case("7410", "7400")
+ .Case("7447", "7400")
+ .Case("7455", "7450")
+ .Case("G4", "g4")
+ .Case("POWER4", "970")
+ .Case("PPC970FX", "970")
+ .Case("PPC970MP", "970")
+ .Case("G5", "g5")
+ .Case("POWER5", "g5")
+ .Case("A2", "a2")
+ .Case("POWER6", "pwr6")
+ .Case("POWER7", "pwr7")
+ .Case("POWER8", "pwr8")
+ .Case("POWER8E", "pwr8")
+ .Default(generic);
+}
+#elif defined(__linux__) && defined(__arm__)
+StringRef sys::getHostCPUName() {
+ // The cpuid register on arm is not accessible from user space. On Linux,
+ // it is exposed through the /proc/cpuinfo file.
+
+ // Read 1024 bytes from /proc/cpuinfo, which should contain the CPU part line
+ // in all cases.
+ char buffer[1024];
+ ssize_t CPUInfoSize = readCpuInfo(buffer, sizeof(buffer));
+ if (CPUInfoSize == -1)
+ return "generic";
+
+ StringRef Str(buffer, CPUInfoSize);
+
+ SmallVector<StringRef, 32> Lines;
+ Str.split(Lines, "\n");
+
+ // Look for the CPU implementer line.
+ StringRef Implementer;
+ for (unsigned I = 0, E = Lines.size(); I != E; ++I)
+ if (Lines[I].startswith("CPU implementer"))
+ Implementer = Lines[I].substr(15).ltrim("\t :");
+
+ if (Implementer == "0x41") // ARM Ltd.
+ // Look for the CPU part line.
+ for (unsigned I = 0, E = Lines.size(); I != E; ++I)
+ if (Lines[I].startswith("CPU part"))
+ // The CPU part is a 3 digit hexadecimal number with a 0x prefix. The
+ // values correspond to the "Part number" in the CP15/c0 register. The
+ // contents are specified in the various processor manuals.
+ return StringSwitch<const char *>(Lines[I].substr(8).ltrim("\t :"))
+ .Case("0x926", "arm926ej-s")
+ .Case("0xb02", "mpcore")
+ .Case("0xb36", "arm1136j-s")
+ .Case("0xb56", "arm1156t2-s")
+ .Case("0xb76", "arm1176jz-s")
+ .Case("0xc08", "cortex-a8")
+ .Case("0xc09", "cortex-a9")
+ .Case("0xc0f", "cortex-a15")
+ .Case("0xc20", "cortex-m0")
+ .Case("0xc23", "cortex-m3")
+ .Case("0xc24", "cortex-m4")
+ .Default("generic");
+
+ if (Implementer == "0x51") // Qualcomm Technologies, Inc.
+ // Look for the CPU part line.
+ for (unsigned I = 0, E = Lines.size(); I != E; ++I)
+ if (Lines[I].startswith("CPU part"))
+ // The CPU part is a 3 digit hexadecimal number with a 0x prefix. The
+ // values correspond to the "Part number" in the CP15/c0 register. The
+ // contents are specified in the various processor manuals.
+ return StringSwitch<const char *>(Lines[I].substr(8).ltrim("\t :"))
+ .Case("0x06f", "krait") // APQ8064
+ .Default("generic");
+
+ return "generic";
+}
+#elif defined(__linux__) && defined(__s390x__)
+StringRef sys::getHostCPUName() {
+ // STIDP is a privileged operation, so use /proc/cpuinfo instead.
+
+ // The "processor 0:" line comes after a fair amount of other information,
+ // including a cache breakdown, but this should be plenty.
+ char buffer[2048];
+ ssize_t CPUInfoSize = readCpuInfo(buffer, sizeof(buffer));
+ if (CPUInfoSize == -1)
+ return "generic";
+
+ StringRef Str(buffer, CPUInfoSize);
+ SmallVector<StringRef, 32> Lines;
+ Str.split(Lines, "\n");
+
+ // Look for the CPU features.
+ SmallVector<StringRef, 32> CPUFeatures;
+ for (unsigned I = 0, E = Lines.size(); I != E; ++I)
+ if (Lines[I].startswith("features")) {
+ size_t Pos = Lines[I].find(":");
+ if (Pos != StringRef::npos) {
+ Lines[I].drop_front(Pos + 1).split(CPUFeatures, " ");
+ break;
+ }
+ }
+
+ // We need to check for the presence of vector support independently of
+ // the machine type, since we may only use the vector register set when
+ // supported by the kernel (and hypervisor).
+ bool HaveVectorSupport = false;
+ for (unsigned I = 0, E = CPUFeatures.size(); I != E; ++I) {
+ if (CPUFeatures[I] == "vx")
+ HaveVectorSupport = true;
+ }
+
+ // Now check the processor machine type.
+ for (unsigned I = 0, E = Lines.size(); I != E; ++I) {
+ if (Lines[I].startswith("processor ")) {
+ size_t Pos = Lines[I].find("machine = ");
+ if (Pos != StringRef::npos) {
+ Pos += sizeof("machine = ") - 1;
+ unsigned int Id;
+ if (!Lines[I].drop_front(Pos).getAsInteger(10, Id)) {
+ if (Id >= 2964 && HaveVectorSupport)
+ return "z13";
+ if (Id >= 2827)
+ return "zEC12";
+ if (Id >= 2817)
+ return "z196";
+ }
+ }
+ break;
+ }
+ }
+
+ return "generic";
+}
+#else
+StringRef sys::getHostCPUName() {
+ return "generic";
+}
+#endif
+
+#if defined(i386) || defined(__i386__) || defined(__x86__) || defined(_M_IX86)\
+ || defined(__x86_64__) || defined(_M_AMD64) || defined (_M_X64)
+bool sys::getHostCPUFeatures(StringMap<bool> &Features) {
+ unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
+ unsigned MaxLevel;
+ union {
+ unsigned u[3];
+ char c[12];
+ } text;
+
+ if (GetX86CpuIDAndInfo(0, &MaxLevel, text.u+0, text.u+2, text.u+1) ||
+ MaxLevel < 1)
+ return false;
+
+ GetX86CpuIDAndInfo(1, &EAX, &EBX, &ECX, &EDX);
+
+ Features["cmov"] = (EDX >> 15) & 1;
+ Features["mmx"] = (EDX >> 23) & 1;
+ Features["sse"] = (EDX >> 25) & 1;
+ Features["sse2"] = (EDX >> 26) & 1;
+ Features["sse3"] = (ECX >> 0) & 1;
+ Features["ssse3"] = (ECX >> 9) & 1;
+ Features["sse4.1"] = (ECX >> 19) & 1;
+ Features["sse4.2"] = (ECX >> 20) & 1;
+
+ Features["pclmul"] = (ECX >> 1) & 1;
+ Features["cx16"] = (ECX >> 13) & 1;
+ Features["movbe"] = (ECX >> 22) & 1;
+ Features["popcnt"] = (ECX >> 23) & 1;
+ Features["aes"] = (ECX >> 25) & 1;
+ Features["rdrnd"] = (ECX >> 30) & 1;
+
+ // If CPUID indicates support for XSAVE, XRESTORE and AVX, and XGETBV
+ // indicates that the AVX registers will be saved and restored on context
+ // switch, then we have full AVX support.
+ bool HasAVX = ((ECX >> 27) & 1) && ((ECX >> 28) & 1) &&
+ !GetX86XCR0(&EAX, &EDX) && ((EAX & 0x6) == 0x6);
+ Features["avx"] = HasAVX;
+ Features["fma"] = HasAVX && (ECX >> 12) & 1;
+ Features["f16c"] = HasAVX && (ECX >> 29) & 1;
+
+ // AVX512 requires additional context to be saved by the OS.
+ bool HasAVX512Save = HasAVX && ((EAX & 0xe0) == 0xe0);
+
+ unsigned MaxExtLevel;
+ GetX86CpuIDAndInfo(0x80000000, &MaxExtLevel, &EBX, &ECX, &EDX);
+
+ bool HasExtLeaf1 = MaxExtLevel >= 0x80000001 &&
+ !GetX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX);
+ Features["lzcnt"] = HasExtLeaf1 && ((ECX >> 5) & 1);
+ Features["sse4a"] = HasExtLeaf1 && ((ECX >> 6) & 1);
+ Features["prfchw"] = HasExtLeaf1 && ((ECX >> 8) & 1);
+ Features["xop"] = HasAVX && HasExtLeaf1 && ((ECX >> 11) & 1);
+ Features["fma4"] = HasAVX && HasExtLeaf1 && ((ECX >> 16) & 1);
+ Features["tbm"] = HasExtLeaf1 && ((ECX >> 21) & 1);
+
+ bool HasLeaf7 = MaxLevel >= 7 &&
+ !GetX86CpuIDAndInfoEx(0x7, 0x0, &EAX, &EBX, &ECX, &EDX);
+
+ // AVX2 is only supported if we have the OS save support from AVX.
+ Features["avx2"] = HasAVX && HasLeaf7 && (EBX >> 5) & 1;
+
+ Features["fsgsbase"] = HasLeaf7 && ((EBX >> 0) & 1);
+ Features["bmi"] = HasLeaf7 && ((EBX >> 3) & 1);
+ Features["hle"] = HasLeaf7 && ((EBX >> 4) & 1);
+ Features["bmi2"] = HasLeaf7 && ((EBX >> 8) & 1);
+ Features["rtm"] = HasLeaf7 && ((EBX >> 11) & 1);
+ Features["rdseed"] = HasLeaf7 && ((EBX >> 18) & 1);
+ Features["adx"] = HasLeaf7 && ((EBX >> 19) & 1);
+ Features["sha"] = HasLeaf7 && ((EBX >> 29) & 1);
+
+ // AVX512 is only supported if the OS supports the context save for it.
+ Features["avx512f"] = HasLeaf7 && ((EBX >> 16) & 1) && HasAVX512Save;
+ Features["avx512dq"] = HasLeaf7 && ((EBX >> 17) & 1) && HasAVX512Save;
+ Features["avx512pf"] = HasLeaf7 && ((EBX >> 26) & 1) && HasAVX512Save;
+ Features["avx512er"] = HasLeaf7 && ((EBX >> 27) & 1) && HasAVX512Save;
+ Features["avx512cd"] = HasLeaf7 && ((EBX >> 28) & 1) && HasAVX512Save;
+ Features["avx512bw"] = HasLeaf7 && ((EBX >> 30) & 1) && HasAVX512Save;
+ Features["avx512vl"] = HasLeaf7 && ((EBX >> 31) & 1) && HasAVX512Save;
+
+ return true;
+}
+#elif defined(__linux__) && (defined(__arm__) || defined(__aarch64__))
+bool sys::getHostCPUFeatures(StringMap<bool> &Features) {
+ // Read 1024 bytes from /proc/cpuinfo, which should contain the Features line
+ // in all cases.
+ char buffer[1024];
+ ssize_t CPUInfoSize = readCpuInfo(buffer, sizeof(buffer));
+ if (CPUInfoSize == -1)
+ return false;
+
+ StringRef Str(buffer, CPUInfoSize);
+
+ SmallVector<StringRef, 32> Lines;
+ Str.split(Lines, "\n");
+
+ SmallVector<StringRef, 32> CPUFeatures;
+
+ // Look for the CPU features.
+ for (unsigned I = 0, E = Lines.size(); I != E; ++I)
+ if (Lines[I].startswith("Features")) {
+ Lines[I].split(CPUFeatures, " ");
+ break;
+ }
+
+#if defined(__aarch64__)
+ // Keep track of which crypto features we have seen
+ enum {
+ CAP_AES = 0x1,
+ CAP_PMULL = 0x2,
+ CAP_SHA1 = 0x4,
+ CAP_SHA2 = 0x8
+ };
+ uint32_t crypto = 0;
+#endif
+
+ for (unsigned I = 0, E = CPUFeatures.size(); I != E; ++I) {
+ StringRef LLVMFeatureStr = StringSwitch<StringRef>(CPUFeatures[I])
+#if defined(__aarch64__)
+ .Case("asimd", "neon")
+ .Case("fp", "fp-armv8")
+ .Case("crc32", "crc")
+#else
+ .Case("half", "fp16")
+ .Case("neon", "neon")
+ .Case("vfpv3", "vfp3")
+ .Case("vfpv3d16", "d16")
+ .Case("vfpv4", "vfp4")
+ .Case("idiva", "hwdiv-arm")
+ .Case("idivt", "hwdiv")
+#endif
+ .Default("");
+
+#if defined(__aarch64__)
+ // We need to check crypto separately since we need all of the crypto
+ // extensions to enable the subtarget feature
+ if (CPUFeatures[I] == "aes")
+ crypto |= CAP_AES;
+ else if (CPUFeatures[I] == "pmull")
+ crypto |= CAP_PMULL;
+ else if (CPUFeatures[I] == "sha1")
+ crypto |= CAP_SHA1;
+ else if (CPUFeatures[I] == "sha2")
+ crypto |= CAP_SHA2;
+#endif
+
+ if (LLVMFeatureStr != "")
+ Features[LLVMFeatureStr] = true;
+ }
+
+#if defined(__aarch64__)
+ // If we have all crypto bits we can add the feature
+ if (crypto == (CAP_AES | CAP_PMULL | CAP_SHA1 | CAP_SHA2))
+ Features["crypto"] = true;
+#endif
+
+ return true;
+}
+#else
+bool sys::getHostCPUFeatures(StringMap<bool> &Features){
+ return false;
+}
+#endif
+
+std::string sys::getProcessTriple() {
+ Triple PT(Triple::normalize(LLVM_HOST_TRIPLE));
+
+ if (sizeof(void *) == 8 && PT.isArch32Bit())
+ PT = PT.get64BitArchVariant();
+ if (sizeof(void *) == 4 && PT.isArch64Bit())
+ PT = PT.get32BitArchVariant();
+
+ return PT.str();
+}
diff --git a/contrib/llvm/lib/Support/IntEqClasses.cpp b/contrib/llvm/lib/Support/IntEqClasses.cpp
new file mode 100644
index 000000000000..11344956e4c9
--- /dev/null
+++ b/contrib/llvm/lib/Support/IntEqClasses.cpp
@@ -0,0 +1,70 @@
+//===-- llvm/ADT/IntEqClasses.cpp - Equivalence Classes of Integers -------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Equivalence classes for small integers. This is a mapping of the integers
+// 0 .. N-1 into M equivalence classes numbered 0 .. M-1.
+//
+// Initially each integer has its own equivalence class. Classes are joined by
+// passing a representative member of each class to join().
+//
+// Once the classes are built, compress() will number them 0 .. M-1 and prevent
+// further changes.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/IntEqClasses.h"
+
+using namespace llvm;
+
+void IntEqClasses::grow(unsigned N) {
+ assert(NumClasses == 0 && "grow() called after compress().");
+ EC.reserve(N);
+ while (EC.size() < N)
+ EC.push_back(EC.size());
+}
+
+void IntEqClasses::join(unsigned a, unsigned b) {
+ assert(NumClasses == 0 && "join() called after compress().");
+ unsigned eca = EC[a];
+ unsigned ecb = EC[b];
+ // Update pointers while searching for the leaders, compressing the paths
+ // incrementally. The larger leader will eventually be updated, joining the
+ // classes.
+ while (eca != ecb)
+ if (eca < ecb)
+ EC[b] = eca, b = ecb, ecb = EC[b];
+ else
+ EC[a] = ecb, a = eca, eca = EC[a];
+}
+
+unsigned IntEqClasses::findLeader(unsigned a) const {
+ assert(NumClasses == 0 && "findLeader() called after compress().");
+ while (a != EC[a])
+ a = EC[a];
+ return a;
+}
+
+void IntEqClasses::compress() {
+ if (NumClasses)
+ return;
+ for (unsigned i = 0, e = EC.size(); i != e; ++i)
+ EC[i] = (EC[i] == i) ? NumClasses++ : EC[EC[i]];
+}
+
+void IntEqClasses::uncompress() {
+ if (!NumClasses)
+ return;
+ SmallVector<unsigned, 8> Leader;
+ for (unsigned i = 0, e = EC.size(); i != e; ++i)
+ if (EC[i] < Leader.size())
+ EC[i] = Leader[EC[i]];
+ else
+ Leader.push_back(EC[i] = i);
+ NumClasses = 0;
+}
diff --git a/contrib/llvm/lib/Support/IntervalMap.cpp b/contrib/llvm/lib/Support/IntervalMap.cpp
new file mode 100644
index 000000000000..e11a7f2eb843
--- /dev/null
+++ b/contrib/llvm/lib/Support/IntervalMap.cpp
@@ -0,0 +1,161 @@
+//===- lib/Support/IntervalMap.cpp - A sorted interval map ----------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the few non-templated functions in IntervalMap.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/IntervalMap.h"
+
+namespace llvm {
+namespace IntervalMapImpl {
+
+void Path::replaceRoot(void *Root, unsigned Size, IdxPair Offsets) {
+ assert(!path.empty() && "Can't replace missing root");
+ path.front() = Entry(Root, Size, Offsets.first);
+ path.insert(path.begin() + 1, Entry(subtree(0), Offsets.second));
+}
+
+NodeRef Path::getLeftSibling(unsigned Level) const {
+ // The root has no siblings.
+ if (Level == 0)
+ return NodeRef();
+
+ // Go up the tree until we can go left.
+ unsigned l = Level - 1;
+ while (l && path[l].offset == 0)
+ --l;
+
+ // We can't go left.
+ if (path[l].offset == 0)
+ return NodeRef();
+
+ // NR is the subtree containing our left sibling.
+ NodeRef NR = path[l].subtree(path[l].offset - 1);
+
+ // Keep right all the way down.
+ for (++l; l != Level; ++l)
+ NR = NR.subtree(NR.size() - 1);
+ return NR;
+}
+
+void Path::moveLeft(unsigned Level) {
+ assert(Level != 0 && "Cannot move the root node");
+
+ // Go up the tree until we can go left.
+ unsigned l = 0;
+ if (valid()) {
+ l = Level - 1;
+ while (path[l].offset == 0) {
+ assert(l != 0 && "Cannot move beyond begin()");
+ --l;
+ }
+ } else if (height() < Level)
+ // end() may have created a height=0 path.
+ path.resize(Level + 1, Entry(nullptr, 0, 0));
+
+ // NR is the subtree containing our left sibling.
+ --path[l].offset;
+ NodeRef NR = subtree(l);
+
+ // Get the rightmost node in the subtree.
+ for (++l; l != Level; ++l) {
+ path[l] = Entry(NR, NR.size() - 1);
+ NR = NR.subtree(NR.size() - 1);
+ }
+ path[l] = Entry(NR, NR.size() - 1);
+}
+
+NodeRef Path::getRightSibling(unsigned Level) const {
+ // The root has no siblings.
+ if (Level == 0)
+ return NodeRef();
+
+ // Go up the tree until we can go right.
+ unsigned l = Level - 1;
+ while (l && atLastEntry(l))
+ --l;
+
+ // We can't go right.
+ if (atLastEntry(l))
+ return NodeRef();
+
+ // NR is the subtree containing our right sibling.
+ NodeRef NR = path[l].subtree(path[l].offset + 1);
+
+ // Keep left all the way down.
+ for (++l; l != Level; ++l)
+ NR = NR.subtree(0);
+ return NR;
+}
+
+void Path::moveRight(unsigned Level) {
+ assert(Level != 0 && "Cannot move the root node");
+
+ // Go up the tree until we can go right.
+ unsigned l = Level - 1;
+ while (l && atLastEntry(l))
+ --l;
+
+ // NR is the subtree containing our right sibling. If we hit end(), we have
+ // offset(0) == node(0).size().
+ if (++path[l].offset == path[l].size)
+ return;
+ NodeRef NR = subtree(l);
+
+ for (++l; l != Level; ++l) {
+ path[l] = Entry(NR, 0);
+ NR = NR.subtree(0);
+ }
+ path[l] = Entry(NR, 0);
+}
+
+
+IdxPair distribute(unsigned Nodes, unsigned Elements, unsigned Capacity,
+ const unsigned *CurSize, unsigned NewSize[],
+ unsigned Position, bool Grow) {
+ assert(Elements + Grow <= Nodes * Capacity && "Not enough room for elements");
+ assert(Position <= Elements && "Invalid position");
+ if (!Nodes)
+ return IdxPair();
+
+ // Trivial algorithm: left-leaning even distribution.
+ const unsigned PerNode = (Elements + Grow) / Nodes;
+ const unsigned Extra = (Elements + Grow) % Nodes;
+ IdxPair PosPair = IdxPair(Nodes, 0);
+ unsigned Sum = 0;
+ for (unsigned n = 0; n != Nodes; ++n) {
+ Sum += NewSize[n] = PerNode + (n < Extra);
+ if (PosPair.first == Nodes && Sum > Position)
+ PosPair = IdxPair(n, Position - (Sum - NewSize[n]));
+ }
+ assert(Sum == Elements + Grow && "Bad distribution sum");
+
+ // Subtract the Grow element that was added.
+ if (Grow) {
+ assert(PosPair.first < Nodes && "Bad algebra");
+ assert(NewSize[PosPair.first] && "Too few elements to need Grow");
+ --NewSize[PosPair.first];
+ }
+
+#ifndef NDEBUG
+ Sum = 0;
+ for (unsigned n = 0; n != Nodes; ++n) {
+ assert(NewSize[n] <= Capacity && "Overallocated node");
+ Sum += NewSize[n];
+ }
+ assert(Sum == Elements && "Bad distribution sum");
+#endif
+
+ return PosPair;
+}
+
+} // namespace IntervalMapImpl
+} // namespace llvm
+
diff --git a/contrib/llvm/lib/Support/IntrusiveRefCntPtr.cpp b/contrib/llvm/lib/Support/IntrusiveRefCntPtr.cpp
new file mode 100644
index 000000000000..a8b45593ae70
--- /dev/null
+++ b/contrib/llvm/lib/Support/IntrusiveRefCntPtr.cpp
@@ -0,0 +1,14 @@
+//== IntrusiveRefCntPtr.cpp - Smart Refcounting Pointer ----------*- C++ -*-==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+
+using namespace llvm;
+
+void RefCountedBaseVPTR::anchor() { }
diff --git a/contrib/llvm/lib/Support/LEB128.cpp b/contrib/llvm/lib/Support/LEB128.cpp
new file mode 100644
index 000000000000..449626f2d451
--- /dev/null
+++ b/contrib/llvm/lib/Support/LEB128.cpp
@@ -0,0 +1,44 @@
+//===- LEB128.cpp - LEB128 utility functions implementation -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements some utility functions for encoding SLEB128 and
+// ULEB128 values.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/LEB128.h"
+
+namespace llvm {
+
+/// Utility function to get the size of the ULEB128-encoded value.
+unsigned getULEB128Size(uint64_t Value) {
+ unsigned Size = 0;
+ do {
+ Value >>= 7;
+ Size += sizeof(int8_t);
+ } while (Value);
+ return Size;
+}
+
+/// Utility function to get the size of the SLEB128-encoded value.
+unsigned getSLEB128Size(int64_t Value) {
+ unsigned Size = 0;
+ int Sign = Value >> (8 * sizeof(Value) - 1);
+ bool IsMore;
+
+ do {
+ unsigned Byte = Value & 0x7f;
+ Value >>= 7;
+ IsMore = Value != Sign || ((Byte ^ Sign) & 0x40) != 0;
+ Size += sizeof(int8_t);
+ } while (IsMore);
+ return Size;
+}
+
+} // namespace llvm
diff --git a/contrib/llvm/lib/Support/LineIterator.cpp b/contrib/llvm/lib/Support/LineIterator.cpp
new file mode 100644
index 000000000000..5baa1a37f385
--- /dev/null
+++ b/contrib/llvm/lib/Support/LineIterator.cpp
@@ -0,0 +1,94 @@
+//===- LineIterator.cpp - Implementation of line iteration ----------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/LineIterator.h"
+#include "llvm/Support/MemoryBuffer.h"
+
+using namespace llvm;
+
+static bool isAtLineEnd(const char *P) {
+ if (*P == '\n')
+ return true;
+ if (*P == '\r' && *(P + 1) == '\n')
+ return true;
+ return false;
+}
+
+static bool skipIfAtLineEnd(const char *&P) {
+ if (*P == '\n') {
+ ++P;
+ return true;
+ }
+ if (*P == '\r' && *(P + 1) == '\n') {
+ P += 2;
+ return true;
+ }
+ return false;
+}
+
+line_iterator::line_iterator(const MemoryBuffer &Buffer, bool SkipBlanks,
+ char CommentMarker)
+ : Buffer(Buffer.getBufferSize() ? &Buffer : nullptr),
+ CommentMarker(CommentMarker), SkipBlanks(SkipBlanks), LineNumber(1),
+ CurrentLine(Buffer.getBufferSize() ? Buffer.getBufferStart() : nullptr,
+ 0) {
+ // Ensure that if we are constructed on a non-empty memory buffer that it is
+ // a null terminated buffer.
+ if (Buffer.getBufferSize()) {
+ assert(Buffer.getBufferEnd()[0] == '\0');
+ // Make sure we don't skip a leading newline if we're keeping blanks
+ if (SkipBlanks || !isAtLineEnd(Buffer.getBufferStart()))
+ advance();
+ }
+}
+
+void line_iterator::advance() {
+ assert(Buffer && "Cannot advance past the end!");
+
+ const char *Pos = CurrentLine.end();
+ assert(Pos == Buffer->getBufferStart() || isAtLineEnd(Pos) || *Pos == '\0');
+
+ if (skipIfAtLineEnd(Pos))
+ ++LineNumber;
+ if (!SkipBlanks && isAtLineEnd(Pos)) {
+ // Nothing to do for a blank line.
+ } else if (CommentMarker == '\0') {
+ // If we're not stripping comments, this is simpler.
+ while (skipIfAtLineEnd(Pos))
+ ++LineNumber;
+ } else {
+ // Skip comments and count line numbers, which is a bit more complex.
+ for (;;) {
+ if (isAtLineEnd(Pos) && !SkipBlanks)
+ break;
+ if (*Pos == CommentMarker)
+ do {
+ ++Pos;
+ } while (*Pos != '\0' && !isAtLineEnd(Pos));
+ if (!skipIfAtLineEnd(Pos))
+ break;
+ ++LineNumber;
+ }
+ }
+
+ if (*Pos == '\0') {
+ // We've hit the end of the buffer, reset ourselves to the end state.
+ Buffer = nullptr;
+ CurrentLine = StringRef();
+ return;
+ }
+
+ // Measure the line.
+ size_t Length = 0;
+ while (Pos[Length] != '\0' && !isAtLineEnd(&Pos[Length])) {
+ ++Length;
+ }
+
+ CurrentLine = StringRef(Pos, Length);
+}
diff --git a/contrib/llvm/lib/Support/Locale.cpp b/contrib/llvm/lib/Support/Locale.cpp
new file mode 100644
index 000000000000..d5cb72b5db3a
--- /dev/null
+++ b/contrib/llvm/lib/Support/Locale.cpp
@@ -0,0 +1,31 @@
+#include "llvm/Support/Locale.h"
+#include "llvm/Support/Unicode.h"
+
+namespace llvm {
+namespace sys {
+namespace locale {
+
+int columnWidth(StringRef Text) {
+#if LLVM_ON_WIN32
+ return Text.size();
+#else
+ return llvm::sys::unicode::columnWidthUTF8(Text);
+#endif
+}
+
+bool isPrint(int UCS) {
+#if LLVM_ON_WIN32
+ // Restrict characters that we'll try to print to the lower part of ASCII
+ // except for the control characters (0x20 - 0x7E). In general one can not
+ // reliably output code points U+0080 and higher using narrow character C/C++
+ // output functions in Windows, because the meaning of the upper 128 codes is
+ // determined by the active code page in the console.
+ return ' ' <= UCS && UCS <= '~';
+#else
+ return llvm::sys::unicode::isPrintable(UCS);
+#endif
+}
+
+} // namespace locale
+} // namespace sys
+} // namespace llvm
diff --git a/contrib/llvm/lib/Support/LockFileManager.cpp b/contrib/llvm/lib/Support/LockFileManager.cpp
new file mode 100644
index 000000000000..d07c5f0f682f
--- /dev/null
+++ b/contrib/llvm/lib/Support/LockFileManager.cpp
@@ -0,0 +1,238 @@
+//===--- LockFileManager.cpp - File-level Locking Utility------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "llvm/Support/LockFileManager.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/Errc.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
+#include <sys/stat.h>
+#include <sys/types.h>
+#if LLVM_ON_WIN32
+#include <windows.h>
+#endif
+#if LLVM_ON_UNIX
+#include <unistd.h>
+#endif
+using namespace llvm;
+
+/// \brief Attempt to read the lock file with the given name, if it exists.
+///
+/// \param LockFileName The name of the lock file to read.
+///
+/// \returns The process ID of the process that owns this lock file
+Optional<std::pair<std::string, int> >
+LockFileManager::readLockFile(StringRef LockFileName) {
+ // Read the owning host and PID out of the lock file. If it appears that the
+ // owning process is dead, the lock file is invalid.
+ ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr =
+ MemoryBuffer::getFile(LockFileName);
+ if (!MBOrErr) {
+ sys::fs::remove(LockFileName);
+ return None;
+ }
+ MemoryBuffer &MB = *MBOrErr.get();
+
+ StringRef Hostname;
+ StringRef PIDStr;
+ std::tie(Hostname, PIDStr) = getToken(MB.getBuffer(), " ");
+ PIDStr = PIDStr.substr(PIDStr.find_first_not_of(" "));
+ int PID;
+ if (!PIDStr.getAsInteger(10, PID)) {
+ auto Owner = std::make_pair(std::string(Hostname), PID);
+ if (processStillExecuting(Owner.first, Owner.second))
+ return Owner;
+ }
+
+ // Delete the lock file. It's invalid anyway.
+ sys::fs::remove(LockFileName);
+ return None;
+}
+
+bool LockFileManager::processStillExecuting(StringRef Hostname, int PID) {
+#if LLVM_ON_UNIX && !defined(__ANDROID__)
+ char MyHostname[256];
+ MyHostname[255] = 0;
+ MyHostname[0] = 0;
+ gethostname(MyHostname, 255);
+ // Check whether the process is dead. If so, we're done.
+ if (MyHostname == Hostname && getsid(PID) == -1 && errno == ESRCH)
+ return false;
+#endif
+
+ return true;
+}
+
+LockFileManager::LockFileManager(StringRef FileName)
+{
+ this->FileName = FileName;
+ if (std::error_code EC = sys::fs::make_absolute(this->FileName)) {
+ Error = EC;
+ return;
+ }
+ LockFileName = this->FileName;
+ LockFileName += ".lock";
+
+ // If the lock file already exists, don't bother to try to create our own
+ // lock file; it won't work anyway. Just figure out who owns this lock file.
+ if ((Owner = readLockFile(LockFileName)))
+ return;
+
+ // Create a lock file that is unique to this instance.
+ UniqueLockFileName = LockFileName;
+ UniqueLockFileName += "-%%%%%%%%";
+ int UniqueLockFileID;
+ if (std::error_code EC = sys::fs::createUniqueFile(
+ UniqueLockFileName, UniqueLockFileID, UniqueLockFileName)) {
+ Error = EC;
+ return;
+ }
+
+ // Write our process ID to our unique lock file.
+ {
+ raw_fd_ostream Out(UniqueLockFileID, /*shouldClose=*/true);
+
+#if LLVM_ON_UNIX
+ // FIXME: move getpid() call into LLVM
+ char hostname[256];
+ hostname[255] = 0;
+ hostname[0] = 0;
+ gethostname(hostname, 255);
+ Out << hostname << ' ' << getpid();
+#else
+ Out << "localhost 1";
+#endif
+ Out.close();
+
+ if (Out.has_error()) {
+ // We failed to write out PID, so make up an excuse, remove the
+ // unique lock file, and fail.
+ Error = make_error_code(errc::no_space_on_device);
+ sys::fs::remove(UniqueLockFileName);
+ return;
+ }
+ }
+
+ while (1) {
+ // Create a link from the lock file name. If this succeeds, we're done.
+ std::error_code EC =
+ sys::fs::create_link(UniqueLockFileName, LockFileName);
+ if (!EC)
+ return;
+
+ if (EC != errc::file_exists) {
+ Error = EC;
+ return;
+ }
+
+ // Someone else managed to create the lock file first. Read the process ID
+ // from the lock file.
+ if ((Owner = readLockFile(LockFileName))) {
+ // Wipe out our unique lock file (it's useless now)
+ sys::fs::remove(UniqueLockFileName);
+ return;
+ }
+
+ if (!sys::fs::exists(LockFileName)) {
+ // The previous owner released the lock file before we could read it.
+ // Try to get ownership again.
+ continue;
+ }
+
+ // There is a lock file that nobody owns; try to clean it up and get
+ // ownership.
+ if ((EC = sys::fs::remove(LockFileName))) {
+ Error = EC;
+ return;
+ }
+ }
+}
+
+LockFileManager::LockFileState LockFileManager::getState() const {
+ if (Owner)
+ return LFS_Shared;
+
+ if (Error)
+ return LFS_Error;
+
+ return LFS_Owned;
+}
+
+LockFileManager::~LockFileManager() {
+ if (getState() != LFS_Owned)
+ return;
+
+ // Since we own the lock, remove the lock file and our own unique lock file.
+ sys::fs::remove(LockFileName);
+ sys::fs::remove(UniqueLockFileName);
+}
+
+LockFileManager::WaitForUnlockResult LockFileManager::waitForUnlock() {
+ if (getState() != LFS_Shared)
+ return Res_Success;
+
+#if LLVM_ON_WIN32
+ unsigned long Interval = 1;
+#else
+ struct timespec Interval;
+ Interval.tv_sec = 0;
+ Interval.tv_nsec = 1000000;
+#endif
+ // Don't wait more than five minutes per iteration. Total timeout for the file
+ // to appear is ~8.5 mins.
+ const unsigned MaxSeconds = 5*60;
+ do {
+ // Sleep for the designated interval, to allow the owning process time to
+ // finish up and remove the lock file.
+ // FIXME: Should we hook in to system APIs to get a notification when the
+ // lock file is deleted?
+#if LLVM_ON_WIN32
+ Sleep(Interval);
+#else
+ nanosleep(&Interval, nullptr);
+#endif
+
+ if (sys::fs::access(LockFileName.c_str(), sys::fs::AccessMode::Exist) ==
+ errc::no_such_file_or_directory) {
+ // If the original file wasn't created, somone thought the lock was dead.
+ if (!sys::fs::exists(FileName))
+ return Res_OwnerDied;
+ return Res_Success;
+ }
+
+ // If the process owning the lock died without cleaning up, just bail out.
+ if (!processStillExecuting((*Owner).first, (*Owner).second))
+ return Res_OwnerDied;
+
+ // Exponentially increase the time we wait for the lock to be removed.
+#if LLVM_ON_WIN32
+ Interval *= 2;
+#else
+ Interval.tv_sec *= 2;
+ Interval.tv_nsec *= 2;
+ if (Interval.tv_nsec >= 1000000000) {
+ ++Interval.tv_sec;
+ Interval.tv_nsec -= 1000000000;
+ }
+#endif
+ } while (
+#if LLVM_ON_WIN32
+ Interval < MaxSeconds * 1000
+#else
+ Interval.tv_sec < (time_t)MaxSeconds
+#endif
+ );
+
+ // Give up.
+ return Res_Timeout;
+}
+
+std::error_code LockFileManager::unsafeRemoveLockFile() {
+ return sys::fs::remove(LockFileName);
+}
diff --git a/contrib/llvm/lib/Support/MD5.cpp b/contrib/llvm/lib/Support/MD5.cpp
new file mode 100644
index 000000000000..6ed81fbe49e0
--- /dev/null
+++ b/contrib/llvm/lib/Support/MD5.cpp
@@ -0,0 +1,286 @@
+/*
+ * This code is derived from (original license follows):
+ *
+ * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
+ * MD5 Message-Digest Algorithm (RFC 1321).
+ *
+ * Homepage:
+ * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5
+ *
+ * Author:
+ * Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
+ *
+ * This software was written by Alexander Peslyak in 2001. No copyright is
+ * claimed, and the software is hereby placed in the public domain.
+ * In case this attempt to disclaim copyright and place the software in the
+ * public domain is deemed null and void, then the software is
+ * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the
+ * general public under the following terms:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted.
+ *
+ * There's ABSOLUTELY NO WARRANTY, express or implied.
+ *
+ * (This is a heavily cut-down "BSD license".)
+ *
+ * This differs from Colin Plumb's older public domain implementation in that
+ * no exactly 32-bit integer data type is required (any 32-bit or wider
+ * unsigned integer data type will do), there's no compile-time endianness
+ * configuration, and the function prototypes match OpenSSL's. No code from
+ * Colin Plumb's implementation has been reused; this comment merely compares
+ * the properties of the two independent implementations.
+ *
+ * The primary goals of this implementation are portability and ease of use.
+ * It is meant to be fast, but not as fast as possible. Some known
+ * optimizations are not included to reduce source code size and avoid
+ * compile-time configuration.
+ */
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/MD5.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cstring>
+
+// The basic MD5 functions.
+
+// F and G are optimized compared to their RFC 1321 definitions for
+// architectures that lack an AND-NOT instruction, just like in Colin Plumb's
+// implementation.
+#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
+#define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y))))
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define I(x, y, z) ((y) ^ ((x) | ~(z)))
+
+// The MD5 transformation for all four rounds.
+#define STEP(f, a, b, c, d, x, t, s) \
+ (a) += f((b), (c), (d)) + (x) + (t); \
+ (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \
+ (a) += (b);
+
+// SET reads 4 input bytes in little-endian byte order and stores them
+// in a properly aligned word in host byte order.
+#define SET(n) \
+ (block[(n)] = \
+ (MD5_u32plus) ptr[(n) * 4] | ((MD5_u32plus) ptr[(n) * 4 + 1] << 8) | \
+ ((MD5_u32plus) ptr[(n) * 4 + 2] << 16) | \
+ ((MD5_u32plus) ptr[(n) * 4 + 3] << 24))
+#define GET(n) (block[(n)])
+
+namespace llvm {
+
+/// \brief This processes one or more 64-byte data blocks, but does NOT update
+///the bit counters. There are no alignment requirements.
+const uint8_t *MD5::body(ArrayRef<uint8_t> Data) {
+ const uint8_t *ptr;
+ MD5_u32plus a, b, c, d;
+ MD5_u32plus saved_a, saved_b, saved_c, saved_d;
+ unsigned long Size = Data.size();
+
+ ptr = Data.data();
+
+ a = this->a;
+ b = this->b;
+ c = this->c;
+ d = this->d;
+
+ do {
+ saved_a = a;
+ saved_b = b;
+ saved_c = c;
+ saved_d = d;
+
+ // Round 1
+ STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7)
+ STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12)
+ STEP(F, c, d, a, b, SET(2), 0x242070db, 17)
+ STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22)
+ STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7)
+ STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12)
+ STEP(F, c, d, a, b, SET(6), 0xa8304613, 17)
+ STEP(F, b, c, d, a, SET(7), 0xfd469501, 22)
+ STEP(F, a, b, c, d, SET(8), 0x698098d8, 7)
+ STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12)
+ STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17)
+ STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22)
+ STEP(F, a, b, c, d, SET(12), 0x6b901122, 7)
+ STEP(F, d, a, b, c, SET(13), 0xfd987193, 12)
+ STEP(F, c, d, a, b, SET(14), 0xa679438e, 17)
+ STEP(F, b, c, d, a, SET(15), 0x49b40821, 22)
+
+ // Round 2
+ STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5)
+ STEP(G, d, a, b, c, GET(6), 0xc040b340, 9)
+ STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14)
+ STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20)
+ STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5)
+ STEP(G, d, a, b, c, GET(10), 0x02441453, 9)
+ STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14)
+ STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20)
+ STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5)
+ STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9)
+ STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14)
+ STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20)
+ STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5)
+ STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9)
+ STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14)
+ STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20)
+
+ // Round 3
+ STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4)
+ STEP(H, d, a, b, c, GET(8), 0x8771f681, 11)
+ STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16)
+ STEP(H, b, c, d, a, GET(14), 0xfde5380c, 23)
+ STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4)
+ STEP(H, d, a, b, c, GET(4), 0x4bdecfa9, 11)
+ STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16)
+ STEP(H, b, c, d, a, GET(10), 0xbebfbc70, 23)
+ STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4)
+ STEP(H, d, a, b, c, GET(0), 0xeaa127fa, 11)
+ STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16)
+ STEP(H, b, c, d, a, GET(6), 0x04881d05, 23)
+ STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4)
+ STEP(H, d, a, b, c, GET(12), 0xe6db99e5, 11)
+ STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16)
+ STEP(H, b, c, d, a, GET(2), 0xc4ac5665, 23)
+
+ // Round 4
+ STEP(I, a, b, c, d, GET(0), 0xf4292244, 6)
+ STEP(I, d, a, b, c, GET(7), 0x432aff97, 10)
+ STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15)
+ STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21)
+ STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6)
+ STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10)
+ STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15)
+ STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21)
+ STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6)
+ STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10)
+ STEP(I, c, d, a, b, GET(6), 0xa3014314, 15)
+ STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21)
+ STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6)
+ STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10)
+ STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15)
+ STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21)
+
+ a += saved_a;
+ b += saved_b;
+ c += saved_c;
+ d += saved_d;
+
+ ptr += 64;
+ } while (Size -= 64);
+
+ this->a = a;
+ this->b = b;
+ this->c = c;
+ this->d = d;
+
+ return ptr;
+}
+
+MD5::MD5()
+ : a(0x67452301), b(0xefcdab89), c(0x98badcfe), d(0x10325476), hi(0), lo(0) {
+}
+
+/// Incrementally add the bytes in \p Data to the hash.
+void MD5::update(ArrayRef<uint8_t> Data) {
+ MD5_u32plus saved_lo;
+ unsigned long used, free;
+ const uint8_t *Ptr = Data.data();
+ unsigned long Size = Data.size();
+
+ saved_lo = lo;
+ if ((lo = (saved_lo + Size) & 0x1fffffff) < saved_lo)
+ hi++;
+ hi += Size >> 29;
+
+ used = saved_lo & 0x3f;
+
+ if (used) {
+ free = 64 - used;
+
+ if (Size < free) {
+ memcpy(&buffer[used], Ptr, Size);
+ return;
+ }
+
+ memcpy(&buffer[used], Ptr, free);
+ Ptr = Ptr + free;
+ Size -= free;
+ body(makeArrayRef(buffer, 64));
+ }
+
+ if (Size >= 64) {
+ Ptr = body(makeArrayRef(Ptr, Size & ~(unsigned long) 0x3f));
+ Size &= 0x3f;
+ }
+
+ memcpy(buffer, Ptr, Size);
+}
+
+/// Add the bytes in the StringRef \p Str to the hash.
+// Note that this isn't a string and so this won't include any trailing NULL
+// bytes.
+void MD5::update(StringRef Str) {
+ ArrayRef<uint8_t> SVal((const uint8_t *)Str.data(), Str.size());
+ update(SVal);
+}
+
+/// \brief Finish the hash and place the resulting hash into \p result.
+/// \param result is assumed to be a minimum of 16-bytes in size.
+void MD5::final(MD5Result &Result) {
+ unsigned long used, free;
+
+ used = lo & 0x3f;
+
+ buffer[used++] = 0x80;
+
+ free = 64 - used;
+
+ if (free < 8) {
+ memset(&buffer[used], 0, free);
+ body(makeArrayRef(buffer, 64));
+ used = 0;
+ free = 64;
+ }
+
+ memset(&buffer[used], 0, free - 8);
+
+ lo <<= 3;
+ buffer[56] = lo;
+ buffer[57] = lo >> 8;
+ buffer[58] = lo >> 16;
+ buffer[59] = lo >> 24;
+ buffer[60] = hi;
+ buffer[61] = hi >> 8;
+ buffer[62] = hi >> 16;
+ buffer[63] = hi >> 24;
+
+ body(makeArrayRef(buffer, 64));
+
+ Result[0] = a;
+ Result[1] = a >> 8;
+ Result[2] = a >> 16;
+ Result[3] = a >> 24;
+ Result[4] = b;
+ Result[5] = b >> 8;
+ Result[6] = b >> 16;
+ Result[7] = b >> 24;
+ Result[8] = c;
+ Result[9] = c >> 8;
+ Result[10] = c >> 16;
+ Result[11] = c >> 24;
+ Result[12] = d;
+ Result[13] = d >> 8;
+ Result[14] = d >> 16;
+ Result[15] = d >> 24;
+}
+
+void MD5::stringifyResult(MD5Result &Result, SmallString<32> &Str) {
+ raw_svector_ostream Res(Str);
+ for (int i = 0; i < 16; ++i)
+ Res << format("%.2x", Result[i]);
+}
+
+} // namespace llvm
diff --git a/contrib/llvm/lib/Support/ManagedStatic.cpp b/contrib/llvm/lib/Support/ManagedStatic.cpp
new file mode 100644
index 000000000000..b8fb2841e525
--- /dev/null
+++ b/contrib/llvm/lib/Support/ManagedStatic.cpp
@@ -0,0 +1,90 @@
+//===-- ManagedStatic.cpp - Static Global wrapper -------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the ManagedStatic class and llvm_shutdown().
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Config/config.h"
+#include "llvm/Support/Atomic.h"
+#include "llvm/Support/Mutex.h"
+#include "llvm/Support/MutexGuard.h"
+#include <cassert>
+using namespace llvm;
+
+static const ManagedStaticBase *StaticList = nullptr;
+
+static sys::Mutex& getManagedStaticMutex() {
+ // We need to use a function local static here, since this can get called
+ // during a static constructor and we need to guarantee that it's initialized
+ // correctly.
+ static sys::Mutex ManagedStaticMutex;
+ return ManagedStaticMutex;
+}
+
+void ManagedStaticBase::RegisterManagedStatic(void *(*Creator)(),
+ void (*Deleter)(void*)) const {
+ assert(Creator);
+ if (llvm_is_multithreaded()) {
+ MutexGuard Lock(getManagedStaticMutex());
+
+ if (!Ptr) {
+ void* tmp = Creator();
+
+ TsanHappensBefore(this);
+ sys::MemoryFence();
+
+ // This write is racy against the first read in the ManagedStatic
+ // accessors. The race is benign because it does a second read after a
+ // memory fence, at which point it isn't possible to get a partial value.
+ TsanIgnoreWritesBegin();
+ Ptr = tmp;
+ TsanIgnoreWritesEnd();
+ DeleterFn = Deleter;
+
+ // Add to list of managed statics.
+ Next = StaticList;
+ StaticList = this;
+ }
+ } else {
+ assert(!Ptr && !DeleterFn && !Next &&
+ "Partially initialized ManagedStatic!?");
+ Ptr = Creator();
+ DeleterFn = Deleter;
+
+ // Add to list of managed statics.
+ Next = StaticList;
+ StaticList = this;
+ }
+}
+
+void ManagedStaticBase::destroy() const {
+ assert(DeleterFn && "ManagedStatic not initialized correctly!");
+ assert(StaticList == this &&
+ "Not destroyed in reverse order of construction?");
+ // Unlink from list.
+ StaticList = Next;
+ Next = nullptr;
+
+ // Destroy memory.
+ DeleterFn(Ptr);
+
+ // Cleanup.
+ Ptr = nullptr;
+ DeleterFn = nullptr;
+}
+
+/// llvm_shutdown - Deallocate and destroy all ManagedStatic variables.
+void llvm::llvm_shutdown() {
+ MutexGuard Lock(getManagedStaticMutex());
+
+ while (StaticList)
+ StaticList->destroy();
+}
diff --git a/contrib/llvm/lib/Support/MathExtras.cpp b/contrib/llvm/lib/Support/MathExtras.cpp
new file mode 100644
index 000000000000..9265a43d38c3
--- /dev/null
+++ b/contrib/llvm/lib/Support/MathExtras.cpp
@@ -0,0 +1,32 @@
+//===-- MathExtras.cpp - Implement the MathExtras header --------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the MathExtras.h header
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/MathExtras.h"
+
+#ifdef _MSC_VER
+#include <limits>
+#else
+#include <math.h>
+#endif
+
+namespace llvm {
+
+#if defined(_MSC_VER)
+ // Visual Studio defines the HUGE_VAL class of macros using purposeful
+ // constant arithmetic overflow, which it then warns on when encountered.
+ const float huge_valf = std::numeric_limits<float>::infinity();
+#else
+ const float huge_valf = HUGE_VALF;
+#endif
+
+} // namespace llvm
diff --git a/contrib/llvm/lib/Support/Memory.cpp b/contrib/llvm/lib/Support/Memory.cpp
new file mode 100644
index 000000000000..f9a4903ad015
--- /dev/null
+++ b/contrib/llvm/lib/Support/Memory.cpp
@@ -0,0 +1,25 @@
+//===- Memory.cpp - Memory Handling Support ---------------------*- 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 some helpful functions for allocating memory and dealing
+// with memory mapped files
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/Memory.h"
+#include "llvm/Config/config.h"
+#include "llvm/Support/Valgrind.h"
+
+// Include the platform-specific parts of this class.
+#ifdef LLVM_ON_UNIX
+#include "Unix/Memory.inc"
+#endif
+#ifdef LLVM_ON_WIN32
+#include "Windows/Memory.inc"
+#endif
diff --git a/contrib/llvm/lib/Support/MemoryBuffer.cpp b/contrib/llvm/lib/Support/MemoryBuffer.cpp
new file mode 100644
index 000000000000..1d69b9692c24
--- /dev/null
+++ b/contrib/llvm/lib/Support/MemoryBuffer.cpp
@@ -0,0 +1,435 @@
+//===--- MemoryBuffer.cpp - Memory Buffer implementation ------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the MemoryBuffer interface.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/Config/config.h"
+#include "llvm/Support/Errc.h"
+#include "llvm/Support/Errno.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/Process.h"
+#include "llvm/Support/Program.h"
+#include <cassert>
+#include <cerrno>
+#include <cstring>
+#include <new>
+#include <sys/types.h>
+#include <system_error>
+#if !defined(_MSC_VER) && !defined(__MINGW32__)
+#include <unistd.h>
+#else
+#include <io.h>
+#endif
+using namespace llvm;
+
+//===----------------------------------------------------------------------===//
+// MemoryBuffer implementation itself.
+//===----------------------------------------------------------------------===//
+
+MemoryBuffer::~MemoryBuffer() { }
+
+/// init - Initialize this MemoryBuffer as a reference to externally allocated
+/// memory, memory that we know is already null terminated.
+void MemoryBuffer::init(const char *BufStart, const char *BufEnd,
+ bool RequiresNullTerminator) {
+ assert((!RequiresNullTerminator || BufEnd[0] == 0) &&
+ "Buffer is not null terminated!");
+ BufferStart = BufStart;
+ BufferEnd = BufEnd;
+}
+
+//===----------------------------------------------------------------------===//
+// MemoryBufferMem implementation.
+//===----------------------------------------------------------------------===//
+
+/// CopyStringRef - Copies contents of a StringRef into a block of memory and
+/// null-terminates it.
+static void CopyStringRef(char *Memory, StringRef Data) {
+ memcpy(Memory, Data.data(), Data.size());
+ Memory[Data.size()] = 0; // Null terminate string.
+}
+
+namespace {
+struct NamedBufferAlloc {
+ const Twine &Name;
+ NamedBufferAlloc(const Twine &Name) : Name(Name) {}
+};
+}
+
+void *operator new(size_t N, const NamedBufferAlloc &Alloc) {
+ SmallString<256> NameBuf;
+ StringRef NameRef = Alloc.Name.toStringRef(NameBuf);
+
+ char *Mem = static_cast<char *>(operator new(N + NameRef.size() + 1));
+ CopyStringRef(Mem + N, NameRef);
+ return Mem;
+}
+
+namespace {
+/// MemoryBufferMem - Named MemoryBuffer pointing to a block of memory.
+class MemoryBufferMem : public MemoryBuffer {
+public:
+ MemoryBufferMem(StringRef InputData, bool RequiresNullTerminator) {
+ init(InputData.begin(), InputData.end(), RequiresNullTerminator);
+ }
+
+ const char *getBufferIdentifier() const override {
+ // The name is stored after the class itself.
+ return reinterpret_cast<const char*>(this + 1);
+ }
+
+ BufferKind getBufferKind() const override {
+ return MemoryBuffer_Malloc;
+ }
+};
+} // namespace
+
+static ErrorOr<std::unique_ptr<MemoryBuffer>>
+getFileAux(const Twine &Filename, int64_t FileSize, uint64_t MapSize,
+ uint64_t Offset, bool RequiresNullTerminator, bool IsVolatileSize);
+
+std::unique_ptr<MemoryBuffer>
+MemoryBuffer::getMemBuffer(StringRef InputData, StringRef BufferName,
+ bool RequiresNullTerminator) {
+ auto *Ret = new (NamedBufferAlloc(BufferName))
+ MemoryBufferMem(InputData, RequiresNullTerminator);
+ return std::unique_ptr<MemoryBuffer>(Ret);
+}
+
+std::unique_ptr<MemoryBuffer>
+MemoryBuffer::getMemBuffer(MemoryBufferRef Ref, bool RequiresNullTerminator) {
+ return std::unique_ptr<MemoryBuffer>(getMemBuffer(
+ Ref.getBuffer(), Ref.getBufferIdentifier(), RequiresNullTerminator));
+}
+
+std::unique_ptr<MemoryBuffer>
+MemoryBuffer::getMemBufferCopy(StringRef InputData, const Twine &BufferName) {
+ std::unique_ptr<MemoryBuffer> Buf =
+ getNewUninitMemBuffer(InputData.size(), BufferName);
+ if (!Buf)
+ return nullptr;
+ memcpy(const_cast<char*>(Buf->getBufferStart()), InputData.data(),
+ InputData.size());
+ return Buf;
+}
+
+std::unique_ptr<MemoryBuffer>
+MemoryBuffer::getNewUninitMemBuffer(size_t Size, const Twine &BufferName) {
+ // Allocate space for the MemoryBuffer, the data and the name. It is important
+ // that MemoryBuffer and data are aligned so PointerIntPair works with them.
+ // TODO: Is 16-byte alignment enough? We copy small object files with large
+ // alignment expectations into this buffer.
+ SmallString<256> NameBuf;
+ StringRef NameRef = BufferName.toStringRef(NameBuf);
+ size_t AlignedStringLen =
+ RoundUpToAlignment(sizeof(MemoryBufferMem) + NameRef.size() + 1, 16);
+ size_t RealLen = AlignedStringLen + Size + 1;
+ char *Mem = static_cast<char*>(operator new(RealLen, std::nothrow));
+ if (!Mem)
+ return nullptr;
+
+ // The name is stored after the class itself.
+ CopyStringRef(Mem + sizeof(MemoryBufferMem), NameRef);
+
+ // The buffer begins after the name and must be aligned.
+ char *Buf = Mem + AlignedStringLen;
+ Buf[Size] = 0; // Null terminate buffer.
+
+ auto *Ret = new (Mem) MemoryBufferMem(StringRef(Buf, Size), true);
+ return std::unique_ptr<MemoryBuffer>(Ret);
+}
+
+std::unique_ptr<MemoryBuffer>
+MemoryBuffer::getNewMemBuffer(size_t Size, StringRef BufferName) {
+ std::unique_ptr<MemoryBuffer> SB = getNewUninitMemBuffer(Size, BufferName);
+ if (!SB)
+ return nullptr;
+ memset(const_cast<char*>(SB->getBufferStart()), 0, Size);
+ return SB;
+}
+
+ErrorOr<std::unique_ptr<MemoryBuffer>>
+MemoryBuffer::getFileOrSTDIN(const Twine &Filename, int64_t FileSize) {
+ SmallString<256> NameBuf;
+ StringRef NameRef = Filename.toStringRef(NameBuf);
+
+ if (NameRef == "-")
+ return getSTDIN();
+ return getFile(Filename, FileSize);
+}
+
+ErrorOr<std::unique_ptr<MemoryBuffer>>
+MemoryBuffer::getFileSlice(const Twine &FilePath, uint64_t MapSize,
+ uint64_t Offset) {
+ return getFileAux(FilePath, -1, MapSize, Offset, false, false);
+}
+
+
+//===----------------------------------------------------------------------===//
+// MemoryBuffer::getFile implementation.
+//===----------------------------------------------------------------------===//
+
+namespace {
+/// \brief Memory maps a file descriptor using sys::fs::mapped_file_region.
+///
+/// This handles converting the offset into a legal offset on the platform.
+class MemoryBufferMMapFile : public MemoryBuffer {
+ sys::fs::mapped_file_region MFR;
+
+ static uint64_t getLegalMapOffset(uint64_t Offset) {
+ return Offset & ~(sys::fs::mapped_file_region::alignment() - 1);
+ }
+
+ static uint64_t getLegalMapSize(uint64_t Len, uint64_t Offset) {
+ return Len + (Offset - getLegalMapOffset(Offset));
+ }
+
+ const char *getStart(uint64_t Len, uint64_t Offset) {
+ return MFR.const_data() + (Offset - getLegalMapOffset(Offset));
+ }
+
+public:
+ MemoryBufferMMapFile(bool RequiresNullTerminator, int FD, uint64_t Len,
+ uint64_t Offset, std::error_code &EC)
+ : MFR(FD, sys::fs::mapped_file_region::readonly,
+ getLegalMapSize(Len, Offset), getLegalMapOffset(Offset), EC) {
+ if (!EC) {
+ const char *Start = getStart(Len, Offset);
+ init(Start, Start + Len, RequiresNullTerminator);
+ }
+ }
+
+ const char *getBufferIdentifier() const override {
+ // The name is stored after the class itself.
+ return reinterpret_cast<const char *>(this + 1);
+ }
+
+ BufferKind getBufferKind() const override {
+ return MemoryBuffer_MMap;
+ }
+};
+} // namespace
+
+static ErrorOr<std::unique_ptr<MemoryBuffer>>
+getMemoryBufferForStream(int FD, const Twine &BufferName) {
+ const ssize_t ChunkSize = 4096*4;
+ SmallString<ChunkSize> Buffer;
+ ssize_t ReadBytes;
+ // Read into Buffer until we hit EOF.
+ do {
+ Buffer.reserve(Buffer.size() + ChunkSize);
+ ReadBytes = read(FD, Buffer.end(), ChunkSize);
+ if (ReadBytes == -1) {
+ if (errno == EINTR) continue;
+ return std::error_code(errno, std::generic_category());
+ }
+ Buffer.set_size(Buffer.size() + ReadBytes);
+ } while (ReadBytes != 0);
+
+ return MemoryBuffer::getMemBufferCopy(Buffer, BufferName);
+}
+
+
+ErrorOr<std::unique_ptr<MemoryBuffer>>
+MemoryBuffer::getFile(const Twine &Filename, int64_t FileSize,
+ bool RequiresNullTerminator, bool IsVolatileSize) {
+ return getFileAux(Filename, FileSize, FileSize, 0,
+ RequiresNullTerminator, IsVolatileSize);
+}
+
+static ErrorOr<std::unique_ptr<MemoryBuffer>>
+getOpenFileImpl(int FD, const Twine &Filename, uint64_t FileSize,
+ uint64_t MapSize, int64_t Offset, bool RequiresNullTerminator,
+ bool IsVolatileSize);
+
+static ErrorOr<std::unique_ptr<MemoryBuffer>>
+getFileAux(const Twine &Filename, int64_t FileSize, uint64_t MapSize,
+ uint64_t Offset, bool RequiresNullTerminator, bool IsVolatileSize) {
+ int FD;
+ std::error_code EC = sys::fs::openFileForRead(Filename, FD);
+ if (EC)
+ return EC;
+
+ ErrorOr<std::unique_ptr<MemoryBuffer>> Ret =
+ getOpenFileImpl(FD, Filename, FileSize, MapSize, Offset,
+ RequiresNullTerminator, IsVolatileSize);
+ close(FD);
+ return Ret;
+}
+
+static bool shouldUseMmap(int FD,
+ size_t FileSize,
+ size_t MapSize,
+ off_t Offset,
+ bool RequiresNullTerminator,
+ int PageSize,
+ bool IsVolatileSize) {
+ // mmap may leave the buffer without null terminator if the file size changed
+ // by the time the last page is mapped in, so avoid it if the file size is
+ // likely to change.
+ if (IsVolatileSize)
+ return false;
+
+ // We don't use mmap for small files because this can severely fragment our
+ // address space.
+ if (MapSize < 4 * 4096 || MapSize < (unsigned)PageSize)
+ return false;
+
+ if (!RequiresNullTerminator)
+ return true;
+
+
+ // If we don't know the file size, use fstat to find out. fstat on an open
+ // file descriptor is cheaper than stat on a random path.
+ // FIXME: this chunk of code is duplicated, but it avoids a fstat when
+ // RequiresNullTerminator = false and MapSize != -1.
+ if (FileSize == size_t(-1)) {
+ sys::fs::file_status Status;
+ if (sys::fs::status(FD, Status))
+ return false;
+ FileSize = Status.getSize();
+ }
+
+ // If we need a null terminator and the end of the map is inside the file,
+ // we cannot use mmap.
+ size_t End = Offset + MapSize;
+ assert(End <= FileSize);
+ if (End != FileSize)
+ return false;
+
+ // Don't try to map files that are exactly a multiple of the system page size
+ // if we need a null terminator.
+ if ((FileSize & (PageSize -1)) == 0)
+ return false;
+
+#if defined(__CYGWIN__)
+ // Don't try to map files that are exactly a multiple of the physical page size
+ // if we need a null terminator.
+ // FIXME: We should reorganize again getPageSize() on Win32.
+ if ((FileSize & (4096 - 1)) == 0)
+ return false;
+#endif
+
+ return true;
+}
+
+static ErrorOr<std::unique_ptr<MemoryBuffer>>
+getOpenFileImpl(int FD, const Twine &Filename, uint64_t FileSize,
+ uint64_t MapSize, int64_t Offset, bool RequiresNullTerminator,
+ bool IsVolatileSize) {
+ static int PageSize = sys::Process::getPageSize();
+
+ // Default is to map the full file.
+ if (MapSize == uint64_t(-1)) {
+ // If we don't know the file size, use fstat to find out. fstat on an open
+ // file descriptor is cheaper than stat on a random path.
+ if (FileSize == uint64_t(-1)) {
+ sys::fs::file_status Status;
+ std::error_code EC = sys::fs::status(FD, Status);
+ if (EC)
+ return EC;
+
+ // If this not a file or a block device (e.g. it's a named pipe
+ // or character device), we can't trust the size. Create the memory
+ // buffer by copying off the stream.
+ sys::fs::file_type Type = Status.type();
+ if (Type != sys::fs::file_type::regular_file &&
+ Type != sys::fs::file_type::block_file)
+ return getMemoryBufferForStream(FD, Filename);
+
+ FileSize = Status.getSize();
+ }
+ MapSize = FileSize;
+ }
+
+ if (shouldUseMmap(FD, FileSize, MapSize, Offset, RequiresNullTerminator,
+ PageSize, IsVolatileSize)) {
+ std::error_code EC;
+ std::unique_ptr<MemoryBuffer> Result(
+ new (NamedBufferAlloc(Filename))
+ MemoryBufferMMapFile(RequiresNullTerminator, FD, MapSize, Offset, EC));
+ if (!EC)
+ return std::move(Result);
+ }
+
+ std::unique_ptr<MemoryBuffer> Buf =
+ MemoryBuffer::getNewUninitMemBuffer(MapSize, Filename);
+ if (!Buf) {
+ // Failed to create a buffer. The only way it can fail is if
+ // new(std::nothrow) returns 0.
+ return make_error_code(errc::not_enough_memory);
+ }
+
+ char *BufPtr = const_cast<char *>(Buf->getBufferStart());
+
+ size_t BytesLeft = MapSize;
+#ifndef HAVE_PREAD
+ if (lseek(FD, Offset, SEEK_SET) == -1)
+ return std::error_code(errno, std::generic_category());
+#endif
+
+ while (BytesLeft) {
+#ifdef HAVE_PREAD
+ ssize_t NumRead = ::pread(FD, BufPtr, BytesLeft, MapSize-BytesLeft+Offset);
+#else
+ ssize_t NumRead = ::read(FD, BufPtr, BytesLeft);
+#endif
+ if (NumRead == -1) {
+ if (errno == EINTR)
+ continue;
+ // Error while reading.
+ return std::error_code(errno, std::generic_category());
+ }
+ if (NumRead == 0) {
+ memset(BufPtr, 0, BytesLeft); // zero-initialize rest of the buffer.
+ break;
+ }
+ BytesLeft -= NumRead;
+ BufPtr += NumRead;
+ }
+
+ return std::move(Buf);
+}
+
+ErrorOr<std::unique_ptr<MemoryBuffer>>
+MemoryBuffer::getOpenFile(int FD, const Twine &Filename, uint64_t FileSize,
+ bool RequiresNullTerminator, bool IsVolatileSize) {
+ return getOpenFileImpl(FD, Filename, FileSize, FileSize, 0,
+ RequiresNullTerminator, IsVolatileSize);
+}
+
+ErrorOr<std::unique_ptr<MemoryBuffer>>
+MemoryBuffer::getOpenFileSlice(int FD, const Twine &Filename, uint64_t MapSize,
+ int64_t Offset) {
+ assert(MapSize != uint64_t(-1));
+ return getOpenFileImpl(FD, Filename, -1, MapSize, Offset, false,
+ /*IsVolatileSize*/ false);
+}
+
+ErrorOr<std::unique_ptr<MemoryBuffer>> MemoryBuffer::getSTDIN() {
+ // Read in all of the data from stdin, we cannot mmap stdin.
+ //
+ // FIXME: That isn't necessarily true, we should try to mmap stdin and
+ // fallback if it fails.
+ sys::ChangeStdinToBinary();
+
+ return getMemoryBufferForStream(0, "<stdin>");
+}
+
+MemoryBufferRef MemoryBuffer::getMemBufferRef() const {
+ StringRef Data = getBuffer();
+ StringRef Identifier = getBufferIdentifier();
+ return MemoryBufferRef(Data, Identifier);
+}
diff --git a/contrib/llvm/lib/Support/MemoryObject.cpp b/contrib/llvm/lib/Support/MemoryObject.cpp
new file mode 100644
index 000000000000..d796acfa90e7
--- /dev/null
+++ b/contrib/llvm/lib/Support/MemoryObject.cpp
@@ -0,0 +1,14 @@
+//===- MemoryObject.cpp - Abstract memory interface -----------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/MemoryObject.h"
+using namespace llvm;
+
+MemoryObject::~MemoryObject() {
+}
diff --git a/contrib/llvm/lib/Support/Mutex.cpp b/contrib/llvm/lib/Support/Mutex.cpp
new file mode 100644
index 000000000000..42867c94b737
--- /dev/null
+++ b/contrib/llvm/lib/Support/Mutex.cpp
@@ -0,0 +1,122 @@
+//===- Mutex.cpp - Mutual Exclusion Lock ------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the llvm::sys::Mutex class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Config/config.h"
+#include "llvm/Support/Mutex.h"
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only TRULY operating system
+//=== independent code.
+//===----------------------------------------------------------------------===//
+
+#if !defined(LLVM_ENABLE_THREADS) || LLVM_ENABLE_THREADS == 0
+// Define all methods as no-ops if threading is explicitly disabled
+namespace llvm {
+using namespace sys;
+MutexImpl::MutexImpl( bool recursive) { }
+MutexImpl::~MutexImpl() { }
+bool MutexImpl::acquire() { return true; }
+bool MutexImpl::release() { return true; }
+bool MutexImpl::tryacquire() { return true; }
+}
+#else
+
+#if defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_MUTEX_LOCK)
+
+#include <cassert>
+#include <pthread.h>
+#include <stdlib.h>
+
+namespace llvm {
+using namespace sys;
+
+// Construct a Mutex using pthread calls
+MutexImpl::MutexImpl( bool recursive)
+ : data_(nullptr)
+{
+ // Declare the pthread_mutex data structures
+ pthread_mutex_t* mutex =
+ static_cast<pthread_mutex_t*>(malloc(sizeof(pthread_mutex_t)));
+ pthread_mutexattr_t attr;
+
+ // Initialize the mutex attributes
+ int errorcode = pthread_mutexattr_init(&attr);
+ assert(errorcode == 0); (void)errorcode;
+
+ // Initialize the mutex as a recursive mutex, if requested, or normal
+ // otherwise.
+ int kind = ( recursive ? PTHREAD_MUTEX_RECURSIVE : PTHREAD_MUTEX_NORMAL );
+ errorcode = pthread_mutexattr_settype(&attr, kind);
+ assert(errorcode == 0);
+
+ // Initialize the mutex
+ errorcode = pthread_mutex_init(mutex, &attr);
+ assert(errorcode == 0);
+
+ // Destroy the attributes
+ errorcode = pthread_mutexattr_destroy(&attr);
+ assert(errorcode == 0);
+
+ // Assign the data member
+ data_ = mutex;
+}
+
+// Destruct a Mutex
+MutexImpl::~MutexImpl()
+{
+ pthread_mutex_t* mutex = static_cast<pthread_mutex_t*>(data_);
+ assert(mutex != nullptr);
+ pthread_mutex_destroy(mutex);
+ free(mutex);
+}
+
+bool
+MutexImpl::acquire()
+{
+ pthread_mutex_t* mutex = static_cast<pthread_mutex_t*>(data_);
+ assert(mutex != nullptr);
+
+ int errorcode = pthread_mutex_lock(mutex);
+ return errorcode == 0;
+}
+
+bool
+MutexImpl::release()
+{
+ pthread_mutex_t* mutex = static_cast<pthread_mutex_t*>(data_);
+ assert(mutex != nullptr);
+
+ int errorcode = pthread_mutex_unlock(mutex);
+ return errorcode == 0;
+}
+
+bool
+MutexImpl::tryacquire()
+{
+ pthread_mutex_t* mutex = static_cast<pthread_mutex_t*>(data_);
+ assert(mutex != nullptr);
+
+ int errorcode = pthread_mutex_trylock(mutex);
+ return errorcode == 0;
+}
+
+} // namespace llvm
+
+#elif defined(LLVM_ON_UNIX)
+#include "Unix/Mutex.inc"
+#elif defined( LLVM_ON_WIN32)
+#include "Windows/Mutex.inc"
+#else
+#warning Neither LLVM_ON_UNIX nor LLVM_ON_WIN32 was set in Support/Mutex.cpp
+#endif
+#endif
diff --git a/contrib/llvm/lib/Support/Options.cpp b/contrib/llvm/lib/Support/Options.cpp
new file mode 100644
index 000000000000..71258450efa6
--- /dev/null
+++ b/contrib/llvm/lib/Support/Options.cpp
@@ -0,0 +1,33 @@
+//===- llvm/Support/Options.cpp - Debug options support ---------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the helper objects for defining debug options using the
+// new API built on cl::opt, but not requiring the use of static globals.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/Options.h"
+#include "llvm/Support/ManagedStatic.h"
+
+using namespace llvm;
+
+OptionRegistry::~OptionRegistry() {
+ for (auto IT = Options.begin(); IT != Options.end(); ++IT)
+ delete IT->second;
+}
+
+void OptionRegistry::addOption(void *Key, cl::Option *O) {
+ assert(Options.find(Key) == Options.end() &&
+ "Argument with this key already registerd");
+ Options.insert(std::make_pair(Key, O));
+}
+
+static ManagedStatic<OptionRegistry> OR;
+
+OptionRegistry &OptionRegistry::instance() { return *OR; }
diff --git a/contrib/llvm/lib/Support/Path.cpp b/contrib/llvm/lib/Support/Path.cpp
new file mode 100644
index 000000000000..cf467381db8c
--- /dev/null
+++ b/contrib/llvm/lib/Support/Path.cpp
@@ -0,0 +1,1076 @@
+//===-- Path.cpp - Implement OS Path Concept ------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the operating system Path API.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/COFF.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Errc.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/Process.h"
+#include <cctype>
+#include <cstring>
+
+#if !defined(_MSC_VER) && !defined(__MINGW32__)
+#include <unistd.h>
+#else
+#include <io.h>
+#endif
+
+using namespace llvm;
+using namespace llvm::support::endian;
+
+namespace {
+ using llvm::StringRef;
+ using llvm::sys::path::is_separator;
+
+#ifdef LLVM_ON_WIN32
+ const char *separators = "\\/";
+ const char preferred_separator = '\\';
+#else
+ const char separators = '/';
+ const char preferred_separator = '/';
+#endif
+
+ StringRef find_first_component(StringRef path) {
+ // Look for this first component in the following order.
+ // * empty (in this case we return an empty string)
+ // * either C: or {//,\\}net.
+ // * {/,\}
+ // * {file,directory}name
+
+ if (path.empty())
+ return path;
+
+#ifdef LLVM_ON_WIN32
+ // C:
+ if (path.size() >= 2 && std::isalpha(static_cast<unsigned char>(path[0])) &&
+ path[1] == ':')
+ return path.substr(0, 2);
+#endif
+
+ // //net
+ if ((path.size() > 2) &&
+ is_separator(path[0]) &&
+ path[0] == path[1] &&
+ !is_separator(path[2])) {
+ // Find the next directory separator.
+ size_t end = path.find_first_of(separators, 2);
+ return path.substr(0, end);
+ }
+
+ // {/,\}
+ if (is_separator(path[0]))
+ return path.substr(0, 1);
+
+ // * {file,directory}name
+ size_t end = path.find_first_of(separators);
+ return path.substr(0, end);
+ }
+
+ size_t filename_pos(StringRef str) {
+ if (str.size() == 2 &&
+ is_separator(str[0]) &&
+ str[0] == str[1])
+ return 0;
+
+ if (str.size() > 0 && is_separator(str[str.size() - 1]))
+ return str.size() - 1;
+
+ size_t pos = str.find_last_of(separators, str.size() - 1);
+
+#ifdef LLVM_ON_WIN32
+ if (pos == StringRef::npos)
+ pos = str.find_last_of(':', str.size() - 2);
+#endif
+
+ if (pos == StringRef::npos ||
+ (pos == 1 && is_separator(str[0])))
+ return 0;
+
+ return pos + 1;
+ }
+
+ size_t root_dir_start(StringRef str) {
+ // case "c:/"
+#ifdef LLVM_ON_WIN32
+ if (str.size() > 2 &&
+ str[1] == ':' &&
+ is_separator(str[2]))
+ return 2;
+#endif
+
+ // case "//"
+ if (str.size() == 2 &&
+ is_separator(str[0]) &&
+ str[0] == str[1])
+ return StringRef::npos;
+
+ // case "//net"
+ if (str.size() > 3 &&
+ is_separator(str[0]) &&
+ str[0] == str[1] &&
+ !is_separator(str[2])) {
+ return str.find_first_of(separators, 2);
+ }
+
+ // case "/"
+ if (str.size() > 0 && is_separator(str[0]))
+ return 0;
+
+ return StringRef::npos;
+ }
+
+ size_t parent_path_end(StringRef path) {
+ size_t end_pos = filename_pos(path);
+
+ bool filename_was_sep = path.size() > 0 && is_separator(path[end_pos]);
+
+ // Skip separators except for root dir.
+ size_t root_dir_pos = root_dir_start(path.substr(0, end_pos));
+
+ while(end_pos > 0 &&
+ (end_pos - 1) != root_dir_pos &&
+ is_separator(path[end_pos - 1]))
+ --end_pos;
+
+ if (end_pos == 1 && root_dir_pos == 0 && filename_was_sep)
+ return StringRef::npos;
+
+ return end_pos;
+ }
+} // end unnamed namespace
+
+enum FSEntity {
+ FS_Dir,
+ FS_File,
+ FS_Name
+};
+
+static std::error_code createUniqueEntity(const Twine &Model, int &ResultFD,
+ SmallVectorImpl<char> &ResultPath,
+ bool MakeAbsolute, unsigned Mode,
+ FSEntity Type) {
+ SmallString<128> ModelStorage;
+ Model.toVector(ModelStorage);
+
+ if (MakeAbsolute) {
+ // Make model absolute by prepending a temp directory if it's not already.
+ if (!sys::path::is_absolute(Twine(ModelStorage))) {
+ SmallString<128> TDir;
+ sys::path::system_temp_directory(true, TDir);
+ sys::path::append(TDir, Twine(ModelStorage));
+ ModelStorage.swap(TDir);
+ }
+ }
+
+ // From here on, DO NOT modify model. It may be needed if the randomly chosen
+ // path already exists.
+ ResultPath = ModelStorage;
+ // Null terminate.
+ ResultPath.push_back(0);
+ ResultPath.pop_back();
+
+retry_random_path:
+ // Replace '%' with random chars.
+ for (unsigned i = 0, e = ModelStorage.size(); i != e; ++i) {
+ if (ModelStorage[i] == '%')
+ ResultPath[i] = "0123456789abcdef"[sys::Process::GetRandomNumber() & 15];
+ }
+
+ // Try to open + create the file.
+ switch (Type) {
+ case FS_File: {
+ if (std::error_code EC =
+ sys::fs::openFileForWrite(Twine(ResultPath.begin()), ResultFD,
+ sys::fs::F_RW | sys::fs::F_Excl, Mode)) {
+ if (EC == errc::file_exists)
+ goto retry_random_path;
+ return EC;
+ }
+
+ return std::error_code();
+ }
+
+ case FS_Name: {
+ std::error_code EC =
+ sys::fs::access(ResultPath.begin(), sys::fs::AccessMode::Exist);
+ if (EC == errc::no_such_file_or_directory)
+ return std::error_code();
+ if (EC)
+ return EC;
+ goto retry_random_path;
+ }
+
+ case FS_Dir: {
+ if (std::error_code EC =
+ sys::fs::create_directory(ResultPath.begin(), false)) {
+ if (EC == errc::file_exists)
+ goto retry_random_path;
+ return EC;
+ }
+ return std::error_code();
+ }
+ }
+ llvm_unreachable("Invalid Type");
+}
+
+namespace llvm {
+namespace sys {
+namespace path {
+
+const_iterator begin(StringRef path) {
+ const_iterator i;
+ i.Path = path;
+ i.Component = find_first_component(path);
+ i.Position = 0;
+ return i;
+}
+
+const_iterator end(StringRef path) {
+ const_iterator i;
+ i.Path = path;
+ i.Position = path.size();
+ return i;
+}
+
+const_iterator &const_iterator::operator++() {
+ assert(Position < Path.size() && "Tried to increment past end!");
+
+ // Increment Position to past the current component
+ Position += Component.size();
+
+ // Check for end.
+ if (Position == Path.size()) {
+ Component = StringRef();
+ return *this;
+ }
+
+ // Both POSIX and Windows treat paths that begin with exactly two separators
+ // specially.
+ bool was_net = Component.size() > 2 &&
+ is_separator(Component[0]) &&
+ Component[1] == Component[0] &&
+ !is_separator(Component[2]);
+
+ // Handle separators.
+ if (is_separator(Path[Position])) {
+ // Root dir.
+ if (was_net
+#ifdef LLVM_ON_WIN32
+ // c:/
+ || Component.endswith(":")
+#endif
+ ) {
+ Component = Path.substr(Position, 1);
+ return *this;
+ }
+
+ // Skip extra separators.
+ while (Position != Path.size() &&
+ is_separator(Path[Position])) {
+ ++Position;
+ }
+
+ // Treat trailing '/' as a '.'.
+ if (Position == Path.size()) {
+ --Position;
+ Component = ".";
+ return *this;
+ }
+ }
+
+ // Find next component.
+ size_t end_pos = Path.find_first_of(separators, Position);
+ Component = Path.slice(Position, end_pos);
+
+ return *this;
+}
+
+bool const_iterator::operator==(const const_iterator &RHS) const {
+ return Path.begin() == RHS.Path.begin() && Position == RHS.Position;
+}
+
+ptrdiff_t const_iterator::operator-(const const_iterator &RHS) const {
+ return Position - RHS.Position;
+}
+
+reverse_iterator rbegin(StringRef Path) {
+ reverse_iterator I;
+ I.Path = Path;
+ I.Position = Path.size();
+ return ++I;
+}
+
+reverse_iterator rend(StringRef Path) {
+ reverse_iterator I;
+ I.Path = Path;
+ I.Component = Path.substr(0, 0);
+ I.Position = 0;
+ return I;
+}
+
+reverse_iterator &reverse_iterator::operator++() {
+ // If we're at the end and the previous char was a '/', return '.' unless
+ // we are the root path.
+ size_t root_dir_pos = root_dir_start(Path);
+ if (Position == Path.size() &&
+ Path.size() > root_dir_pos + 1 &&
+ is_separator(Path[Position - 1])) {
+ --Position;
+ Component = ".";
+ return *this;
+ }
+
+ // Skip separators unless it's the root directory.
+ size_t end_pos = Position;
+
+ while(end_pos > 0 &&
+ (end_pos - 1) != root_dir_pos &&
+ is_separator(Path[end_pos - 1]))
+ --end_pos;
+
+ // Find next separator.
+ size_t start_pos = filename_pos(Path.substr(0, end_pos));
+ Component = Path.slice(start_pos, end_pos);
+ Position = start_pos;
+ return *this;
+}
+
+bool reverse_iterator::operator==(const reverse_iterator &RHS) const {
+ return Path.begin() == RHS.Path.begin() && Component == RHS.Component &&
+ Position == RHS.Position;
+}
+
+StringRef root_path(StringRef path) {
+ const_iterator b = begin(path),
+ pos = b,
+ e = end(path);
+ if (b != e) {
+ bool has_net = b->size() > 2 && is_separator((*b)[0]) && (*b)[1] == (*b)[0];
+ bool has_drive =
+#ifdef LLVM_ON_WIN32
+ b->endswith(":");
+#else
+ false;
+#endif
+
+ if (has_net || has_drive) {
+ if ((++pos != e) && is_separator((*pos)[0])) {
+ // {C:/,//net/}, so get the first two components.
+ return path.substr(0, b->size() + pos->size());
+ } else {
+ // just {C:,//net}, return the first component.
+ return *b;
+ }
+ }
+
+ // POSIX style root directory.
+ if (is_separator((*b)[0])) {
+ return *b;
+ }
+ }
+
+ return StringRef();
+}
+
+StringRef root_name(StringRef path) {
+ const_iterator b = begin(path),
+ e = end(path);
+ if (b != e) {
+ bool has_net = b->size() > 2 && is_separator((*b)[0]) && (*b)[1] == (*b)[0];
+ bool has_drive =
+#ifdef LLVM_ON_WIN32
+ b->endswith(":");
+#else
+ false;
+#endif
+
+ if (has_net || has_drive) {
+ // just {C:,//net}, return the first component.
+ return *b;
+ }
+ }
+
+ // No path or no name.
+ return StringRef();
+}
+
+StringRef root_directory(StringRef path) {
+ const_iterator b = begin(path),
+ pos = b,
+ e = end(path);
+ if (b != e) {
+ bool has_net = b->size() > 2 && is_separator((*b)[0]) && (*b)[1] == (*b)[0];
+ bool has_drive =
+#ifdef LLVM_ON_WIN32
+ b->endswith(":");
+#else
+ false;
+#endif
+
+ if ((has_net || has_drive) &&
+ // {C:,//net}, skip to the next component.
+ (++pos != e) && is_separator((*pos)[0])) {
+ return *pos;
+ }
+
+ // POSIX style root directory.
+ if (!has_net && is_separator((*b)[0])) {
+ return *b;
+ }
+ }
+
+ // No path or no root.
+ return StringRef();
+}
+
+StringRef relative_path(StringRef path) {
+ StringRef root = root_path(path);
+ return path.substr(root.size());
+}
+
+void append(SmallVectorImpl<char> &path, const Twine &a,
+ const Twine &b,
+ const Twine &c,
+ const Twine &d) {
+ SmallString<32> a_storage;
+ SmallString<32> b_storage;
+ SmallString<32> c_storage;
+ SmallString<32> d_storage;
+
+ SmallVector<StringRef, 4> components;
+ if (!a.isTriviallyEmpty()) components.push_back(a.toStringRef(a_storage));
+ if (!b.isTriviallyEmpty()) components.push_back(b.toStringRef(b_storage));
+ if (!c.isTriviallyEmpty()) components.push_back(c.toStringRef(c_storage));
+ if (!d.isTriviallyEmpty()) components.push_back(d.toStringRef(d_storage));
+
+ for (SmallVectorImpl<StringRef>::const_iterator i = components.begin(),
+ e = components.end();
+ i != e; ++i) {
+ bool path_has_sep = !path.empty() && is_separator(path[path.size() - 1]);
+ bool component_has_sep = !i->empty() && is_separator((*i)[0]);
+ bool is_root_name = has_root_name(*i);
+
+ if (path_has_sep) {
+ // Strip separators from beginning of component.
+ size_t loc = i->find_first_not_of(separators);
+ StringRef c = i->substr(loc);
+
+ // Append it.
+ path.append(c.begin(), c.end());
+ continue;
+ }
+
+ if (!component_has_sep && !(path.empty() || is_root_name)) {
+ // Add a separator.
+ path.push_back(preferred_separator);
+ }
+
+ path.append(i->begin(), i->end());
+ }
+}
+
+void append(SmallVectorImpl<char> &path,
+ const_iterator begin, const_iterator end) {
+ for (; begin != end; ++begin)
+ path::append(path, *begin);
+}
+
+StringRef parent_path(StringRef path) {
+ size_t end_pos = parent_path_end(path);
+ if (end_pos == StringRef::npos)
+ return StringRef();
+ else
+ return path.substr(0, end_pos);
+}
+
+void remove_filename(SmallVectorImpl<char> &path) {
+ size_t end_pos = parent_path_end(StringRef(path.begin(), path.size()));
+ if (end_pos != StringRef::npos)
+ path.set_size(end_pos);
+}
+
+void replace_extension(SmallVectorImpl<char> &path, const Twine &extension) {
+ StringRef p(path.begin(), path.size());
+ SmallString<32> ext_storage;
+ StringRef ext = extension.toStringRef(ext_storage);
+
+ // Erase existing extension.
+ size_t pos = p.find_last_of('.');
+ if (pos != StringRef::npos && pos >= filename_pos(p))
+ path.set_size(pos);
+
+ // Append '.' if needed.
+ if (ext.size() > 0 && ext[0] != '.')
+ path.push_back('.');
+
+ // Append extension.
+ path.append(ext.begin(), ext.end());
+}
+
+void native(const Twine &path, SmallVectorImpl<char> &result) {
+ assert((!path.isSingleStringRef() ||
+ path.getSingleStringRef().data() != result.data()) &&
+ "path and result are not allowed to overlap!");
+ // Clear result.
+ result.clear();
+ path.toVector(result);
+ native(result);
+}
+
+void native(SmallVectorImpl<char> &Path) {
+#ifdef LLVM_ON_WIN32
+ std::replace(Path.begin(), Path.end(), '/', '\\');
+#else
+ for (auto PI = Path.begin(), PE = Path.end(); PI < PE; ++PI) {
+ if (*PI == '\\') {
+ auto PN = PI + 1;
+ if (PN < PE && *PN == '\\')
+ ++PI; // increment once, the for loop will move over the escaped slash
+ else
+ *PI = '/';
+ }
+ }
+#endif
+}
+
+StringRef filename(StringRef path) {
+ return *rbegin(path);
+}
+
+StringRef stem(StringRef path) {
+ StringRef fname = filename(path);
+ size_t pos = fname.find_last_of('.');
+ if (pos == StringRef::npos)
+ return fname;
+ else
+ if ((fname.size() == 1 && fname == ".") ||
+ (fname.size() == 2 && fname == ".."))
+ return fname;
+ else
+ return fname.substr(0, pos);
+}
+
+StringRef extension(StringRef path) {
+ StringRef fname = filename(path);
+ size_t pos = fname.find_last_of('.');
+ if (pos == StringRef::npos)
+ return StringRef();
+ else
+ if ((fname.size() == 1 && fname == ".") ||
+ (fname.size() == 2 && fname == ".."))
+ return StringRef();
+ else
+ return fname.substr(pos);
+}
+
+bool is_separator(char value) {
+ switch(value) {
+#ifdef LLVM_ON_WIN32
+ case '\\': // fall through
+#endif
+ case '/': return true;
+ default: return false;
+ }
+}
+
+static const char preferred_separator_string[] = { preferred_separator, '\0' };
+
+StringRef get_separator() {
+ return preferred_separator_string;
+}
+
+bool has_root_name(const Twine &path) {
+ SmallString<128> path_storage;
+ StringRef p = path.toStringRef(path_storage);
+
+ return !root_name(p).empty();
+}
+
+bool has_root_directory(const Twine &path) {
+ SmallString<128> path_storage;
+ StringRef p = path.toStringRef(path_storage);
+
+ return !root_directory(p).empty();
+}
+
+bool has_root_path(const Twine &path) {
+ SmallString<128> path_storage;
+ StringRef p = path.toStringRef(path_storage);
+
+ return !root_path(p).empty();
+}
+
+bool has_relative_path(const Twine &path) {
+ SmallString<128> path_storage;
+ StringRef p = path.toStringRef(path_storage);
+
+ return !relative_path(p).empty();
+}
+
+bool has_filename(const Twine &path) {
+ SmallString<128> path_storage;
+ StringRef p = path.toStringRef(path_storage);
+
+ return !filename(p).empty();
+}
+
+bool has_parent_path(const Twine &path) {
+ SmallString<128> path_storage;
+ StringRef p = path.toStringRef(path_storage);
+
+ return !parent_path(p).empty();
+}
+
+bool has_stem(const Twine &path) {
+ SmallString<128> path_storage;
+ StringRef p = path.toStringRef(path_storage);
+
+ return !stem(p).empty();
+}
+
+bool has_extension(const Twine &path) {
+ SmallString<128> path_storage;
+ StringRef p = path.toStringRef(path_storage);
+
+ return !extension(p).empty();
+}
+
+bool is_absolute(const Twine &path) {
+ SmallString<128> path_storage;
+ StringRef p = path.toStringRef(path_storage);
+
+ bool rootDir = has_root_directory(p),
+#ifdef LLVM_ON_WIN32
+ rootName = has_root_name(p);
+#else
+ rootName = true;
+#endif
+
+ return rootDir && rootName;
+}
+
+bool is_relative(const Twine &path) {
+ return !is_absolute(path);
+}
+
+} // end namespace path
+
+namespace fs {
+
+std::error_code getUniqueID(const Twine Path, UniqueID &Result) {
+ file_status Status;
+ std::error_code EC = status(Path, Status);
+ if (EC)
+ return EC;
+ Result = Status.getUniqueID();
+ return std::error_code();
+}
+
+std::error_code createUniqueFile(const Twine &Model, int &ResultFd,
+ SmallVectorImpl<char> &ResultPath,
+ unsigned Mode) {
+ return createUniqueEntity(Model, ResultFd, ResultPath, false, Mode, FS_File);
+}
+
+std::error_code createUniqueFile(const Twine &Model,
+ SmallVectorImpl<char> &ResultPath) {
+ int Dummy;
+ return createUniqueEntity(Model, Dummy, ResultPath, false, 0, FS_Name);
+}
+
+static std::error_code
+createTemporaryFile(const Twine &Model, int &ResultFD,
+ llvm::SmallVectorImpl<char> &ResultPath, FSEntity Type) {
+ SmallString<128> Storage;
+ StringRef P = Model.toNullTerminatedStringRef(Storage);
+ assert(P.find_first_of(separators) == StringRef::npos &&
+ "Model must be a simple filename.");
+ // Use P.begin() so that createUniqueEntity doesn't need to recreate Storage.
+ return createUniqueEntity(P.begin(), ResultFD, ResultPath,
+ true, owner_read | owner_write, Type);
+}
+
+static std::error_code
+createTemporaryFile(const Twine &Prefix, StringRef Suffix, int &ResultFD,
+ llvm::SmallVectorImpl<char> &ResultPath, FSEntity Type) {
+ const char *Middle = Suffix.empty() ? "-%%%%%%" : "-%%%%%%.";
+ return createTemporaryFile(Prefix + Middle + Suffix, ResultFD, ResultPath,
+ Type);
+}
+
+std::error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix,
+ int &ResultFD,
+ SmallVectorImpl<char> &ResultPath) {
+ return createTemporaryFile(Prefix, Suffix, ResultFD, ResultPath, FS_File);
+}
+
+std::error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix,
+ SmallVectorImpl<char> &ResultPath) {
+ int Dummy;
+ return createTemporaryFile(Prefix, Suffix, Dummy, ResultPath, FS_Name);
+}
+
+
+// This is a mkdtemp with a different pattern. We use createUniqueEntity mostly
+// for consistency. We should try using mkdtemp.
+std::error_code createUniqueDirectory(const Twine &Prefix,
+ SmallVectorImpl<char> &ResultPath) {
+ int Dummy;
+ return createUniqueEntity(Prefix + "-%%%%%%", Dummy, ResultPath,
+ true, 0, FS_Dir);
+}
+
+std::error_code make_absolute(SmallVectorImpl<char> &path) {
+ StringRef p(path.data(), path.size());
+
+ bool rootDirectory = path::has_root_directory(p),
+#ifdef LLVM_ON_WIN32
+ rootName = path::has_root_name(p);
+#else
+ rootName = true;
+#endif
+
+ // Already absolute.
+ if (rootName && rootDirectory)
+ return std::error_code();
+
+ // All of the following conditions will need the current directory.
+ SmallString<128> current_dir;
+ if (std::error_code ec = current_path(current_dir))
+ return ec;
+
+ // Relative path. Prepend the current directory.
+ if (!rootName && !rootDirectory) {
+ // Append path to the current directory.
+ path::append(current_dir, p);
+ // Set path to the result.
+ path.swap(current_dir);
+ return std::error_code();
+ }
+
+ if (!rootName && rootDirectory) {
+ StringRef cdrn = path::root_name(current_dir);
+ SmallString<128> curDirRootName(cdrn.begin(), cdrn.end());
+ path::append(curDirRootName, p);
+ // Set path to the result.
+ path.swap(curDirRootName);
+ return std::error_code();
+ }
+
+ if (rootName && !rootDirectory) {
+ StringRef pRootName = path::root_name(p);
+ StringRef bRootDirectory = path::root_directory(current_dir);
+ StringRef bRelativePath = path::relative_path(current_dir);
+ StringRef pRelativePath = path::relative_path(p);
+
+ SmallString<128> res;
+ path::append(res, pRootName, bRootDirectory, bRelativePath, pRelativePath);
+ path.swap(res);
+ return std::error_code();
+ }
+
+ llvm_unreachable("All rootName and rootDirectory combinations should have "
+ "occurred above!");
+}
+
+std::error_code create_directories(const Twine &Path, bool IgnoreExisting) {
+ SmallString<128> PathStorage;
+ StringRef P = Path.toStringRef(PathStorage);
+
+ // Be optimistic and try to create the directory
+ std::error_code EC = create_directory(P, IgnoreExisting);
+ // If we succeeded, or had any error other than the parent not existing, just
+ // return it.
+ if (EC != errc::no_such_file_or_directory)
+ return EC;
+
+ // We failed because of a no_such_file_or_directory, try to create the
+ // parent.
+ StringRef Parent = path::parent_path(P);
+ if (Parent.empty())
+ return EC;
+
+ if ((EC = create_directories(Parent)))
+ return EC;
+
+ return create_directory(P, IgnoreExisting);
+}
+
+std::error_code copy_file(const Twine &From, const Twine &To) {
+ int ReadFD, WriteFD;
+ if (std::error_code EC = openFileForRead(From, ReadFD))
+ return EC;
+ if (std::error_code EC = openFileForWrite(To, WriteFD, F_None)) {
+ close(ReadFD);
+ return EC;
+ }
+
+ const size_t BufSize = 4096;
+ char *Buf = new char[BufSize];
+ int BytesRead = 0, BytesWritten = 0;
+ for (;;) {
+ BytesRead = read(ReadFD, Buf, BufSize);
+ if (BytesRead <= 0)
+ break;
+ while (BytesRead) {
+ BytesWritten = write(WriteFD, Buf, BytesRead);
+ if (BytesWritten < 0)
+ break;
+ BytesRead -= BytesWritten;
+ }
+ if (BytesWritten < 0)
+ break;
+ }
+ close(ReadFD);
+ close(WriteFD);
+ delete[] Buf;
+
+ if (BytesRead < 0 || BytesWritten < 0)
+ return std::error_code(errno, std::generic_category());
+ return std::error_code();
+}
+
+bool exists(file_status status) {
+ return status_known(status) && status.type() != file_type::file_not_found;
+}
+
+bool status_known(file_status s) {
+ return s.type() != file_type::status_error;
+}
+
+bool is_directory(file_status status) {
+ return status.type() == file_type::directory_file;
+}
+
+std::error_code is_directory(const Twine &path, bool &result) {
+ file_status st;
+ if (std::error_code ec = status(path, st))
+ return ec;
+ result = is_directory(st);
+ return std::error_code();
+}
+
+bool is_regular_file(file_status status) {
+ return status.type() == file_type::regular_file;
+}
+
+std::error_code is_regular_file(const Twine &path, bool &result) {
+ file_status st;
+ if (std::error_code ec = status(path, st))
+ return ec;
+ result = is_regular_file(st);
+ return std::error_code();
+}
+
+bool is_other(file_status status) {
+ return exists(status) &&
+ !is_regular_file(status) &&
+ !is_directory(status);
+}
+
+std::error_code is_other(const Twine &Path, bool &Result) {
+ file_status FileStatus;
+ if (std::error_code EC = status(Path, FileStatus))
+ return EC;
+ Result = is_other(FileStatus);
+ return std::error_code();
+}
+
+void directory_entry::replace_filename(const Twine &filename, file_status st) {
+ SmallString<128> path(Path.begin(), Path.end());
+ path::remove_filename(path);
+ path::append(path, filename);
+ Path = path.str();
+ Status = st;
+}
+
+/// @brief Identify the magic in magic.
+file_magic identify_magic(StringRef Magic) {
+ if (Magic.size() < 4)
+ return file_magic::unknown;
+ switch ((unsigned char)Magic[0]) {
+ case 0x00: {
+ // COFF bigobj or short import library file
+ if (Magic[1] == (char)0x00 && Magic[2] == (char)0xff &&
+ Magic[3] == (char)0xff) {
+ size_t MinSize = offsetof(COFF::BigObjHeader, UUID) + sizeof(COFF::BigObjMagic);
+ if (Magic.size() < MinSize)
+ return file_magic::coff_import_library;
+
+ int BigObjVersion = read16le(
+ Magic.data() + offsetof(COFF::BigObjHeader, Version));
+ if (BigObjVersion < COFF::BigObjHeader::MinBigObjectVersion)
+ return file_magic::coff_import_library;
+
+ const char *Start = Magic.data() + offsetof(COFF::BigObjHeader, UUID);
+ if (memcmp(Start, COFF::BigObjMagic, sizeof(COFF::BigObjMagic)) != 0)
+ return file_magic::coff_import_library;
+ return file_magic::coff_object;
+ }
+ // Windows resource file
+ const char Expected[] = { 0, 0, 0, 0, '\x20', 0, 0, 0, '\xff' };
+ if (Magic.size() >= sizeof(Expected) &&
+ memcmp(Magic.data(), Expected, sizeof(Expected)) == 0)
+ return file_magic::windows_resource;
+ // 0x0000 = COFF unknown machine type
+ if (Magic[1] == 0)
+ return file_magic::coff_object;
+ break;
+ }
+ case 0xDE: // 0x0B17C0DE = BC wraper
+ if (Magic[1] == (char)0xC0 && Magic[2] == (char)0x17 &&
+ Magic[3] == (char)0x0B)
+ return file_magic::bitcode;
+ break;
+ case 'B':
+ if (Magic[1] == 'C' && Magic[2] == (char)0xC0 && Magic[3] == (char)0xDE)
+ return file_magic::bitcode;
+ break;
+ case '!':
+ if (Magic.size() >= 8)
+ if (memcmp(Magic.data(),"!<arch>\n",8) == 0)
+ return file_magic::archive;
+ break;
+
+ case '\177':
+ if (Magic.size() >= 18 && Magic[1] == 'E' && Magic[2] == 'L' &&
+ Magic[3] == 'F') {
+ bool Data2MSB = Magic[5] == 2;
+ unsigned high = Data2MSB ? 16 : 17;
+ unsigned low = Data2MSB ? 17 : 16;
+ if (Magic[high] == 0)
+ switch (Magic[low]) {
+ default: return file_magic::elf;
+ case 1: return file_magic::elf_relocatable;
+ case 2: return file_magic::elf_executable;
+ case 3: return file_magic::elf_shared_object;
+ case 4: return file_magic::elf_core;
+ }
+ else
+ // It's still some type of ELF file.
+ return file_magic::elf;
+ }
+ break;
+
+ case 0xCA:
+ if (Magic[1] == char(0xFE) && Magic[2] == char(0xBA) &&
+ Magic[3] == char(0xBE)) {
+ // This is complicated by an overlap with Java class files.
+ // See the Mach-O section in /usr/share/file/magic for details.
+ if (Magic.size() >= 8 && Magic[7] < 43)
+ return file_magic::macho_universal_binary;
+ }
+ break;
+
+ // The two magic numbers for mach-o are:
+ // 0xfeedface - 32-bit mach-o
+ // 0xfeedfacf - 64-bit mach-o
+ case 0xFE:
+ case 0xCE:
+ case 0xCF: {
+ uint16_t type = 0;
+ if (Magic[0] == char(0xFE) && Magic[1] == char(0xED) &&
+ Magic[2] == char(0xFA) &&
+ (Magic[3] == char(0xCE) || Magic[3] == char(0xCF))) {
+ /* Native endian */
+ if (Magic.size() >= 16) type = Magic[14] << 8 | Magic[15];
+ } else if ((Magic[0] == char(0xCE) || Magic[0] == char(0xCF)) &&
+ Magic[1] == char(0xFA) && Magic[2] == char(0xED) &&
+ Magic[3] == char(0xFE)) {
+ /* Reverse endian */
+ if (Magic.size() >= 14) type = Magic[13] << 8 | Magic[12];
+ }
+ switch (type) {
+ default: break;
+ case 1: return file_magic::macho_object;
+ case 2: return file_magic::macho_executable;
+ case 3: return file_magic::macho_fixed_virtual_memory_shared_lib;
+ case 4: return file_magic::macho_core;
+ case 5: return file_magic::macho_preload_executable;
+ case 6: return file_magic::macho_dynamically_linked_shared_lib;
+ case 7: return file_magic::macho_dynamic_linker;
+ case 8: return file_magic::macho_bundle;
+ case 9: return file_magic::macho_dynamically_linked_shared_lib_stub;
+ case 10: return file_magic::macho_dsym_companion;
+ case 11: return file_magic::macho_kext_bundle;
+ }
+ break;
+ }
+ case 0xF0: // PowerPC Windows
+ case 0x83: // Alpha 32-bit
+ case 0x84: // Alpha 64-bit
+ case 0x66: // MPS R4000 Windows
+ case 0x50: // mc68K
+ case 0x4c: // 80386 Windows
+ case 0xc4: // ARMNT Windows
+ if (Magic[1] == 0x01)
+ return file_magic::coff_object;
+
+ case 0x90: // PA-RISC Windows
+ case 0x68: // mc68K Windows
+ if (Magic[1] == 0x02)
+ return file_magic::coff_object;
+ break;
+
+ case 'M': // Possible MS-DOS stub on Windows PE file
+ if (Magic[1] == 'Z') {
+ uint32_t off = read32le(Magic.data() + 0x3c);
+ // PE/COFF file, either EXE or DLL.
+ if (off < Magic.size() &&
+ memcmp(Magic.data()+off, COFF::PEMagic, sizeof(COFF::PEMagic)) == 0)
+ return file_magic::pecoff_executable;
+ }
+ break;
+
+ case 0x64: // x86-64 Windows.
+ if (Magic[1] == char(0x86))
+ return file_magic::coff_object;
+ break;
+
+ default:
+ break;
+ }
+ return file_magic::unknown;
+}
+
+std::error_code identify_magic(const Twine &Path, file_magic &Result) {
+ int FD;
+ if (std::error_code EC = openFileForRead(Path, FD))
+ return EC;
+
+ char Buffer[32];
+ int Length = read(FD, Buffer, sizeof(Buffer));
+ if (close(FD) != 0 || Length < 0)
+ return std::error_code(errno, std::generic_category());
+
+ Result = identify_magic(StringRef(Buffer, Length));
+ return std::error_code();
+}
+
+std::error_code directory_entry::status(file_status &result) const {
+ return fs::status(Path, result);
+}
+
+} // end namespace fs
+} // end namespace sys
+} // end namespace llvm
+
+// Include the truly platform-specific parts.
+#if defined(LLVM_ON_UNIX)
+#include "Unix/Path.inc"
+#endif
+#if defined(LLVM_ON_WIN32)
+#include "Windows/Path.inc"
+#endif
diff --git a/contrib/llvm/lib/Support/PluginLoader.cpp b/contrib/llvm/lib/Support/PluginLoader.cpp
new file mode 100644
index 000000000000..358137f08f5f
--- /dev/null
+++ b/contrib/llvm/lib/Support/PluginLoader.cpp
@@ -0,0 +1,47 @@
+//===-- PluginLoader.cpp - Implement -load command line option ------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the -load <plugin> command line option handler.
+//
+//===----------------------------------------------------------------------===//
+
+#define DONT_GET_PLUGIN_LOADER_OPTION
+#include "llvm/Support/PluginLoader.h"
+#include "llvm/Support/DynamicLibrary.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/Mutex.h"
+#include "llvm/Support/raw_ostream.h"
+#include <vector>
+using namespace llvm;
+
+static ManagedStatic<std::vector<std::string> > Plugins;
+static ManagedStatic<sys::SmartMutex<true> > PluginsLock;
+
+void PluginLoader::operator=(const std::string &Filename) {
+ sys::SmartScopedLock<true> Lock(*PluginsLock);
+ std::string Error;
+ if (sys::DynamicLibrary::LoadLibraryPermanently(Filename.c_str(), &Error)) {
+ errs() << "Error opening '" << Filename << "': " << Error
+ << "\n -load request ignored.\n";
+ } else {
+ Plugins->push_back(Filename);
+ }
+}
+
+unsigned PluginLoader::getNumPlugins() {
+ sys::SmartScopedLock<true> Lock(*PluginsLock);
+ return Plugins.isConstructed() ? Plugins->size() : 0;
+}
+
+std::string &PluginLoader::getPlugin(unsigned num) {
+ sys::SmartScopedLock<true> Lock(*PluginsLock);
+ assert(Plugins.isConstructed() && num < Plugins->size() &&
+ "Asking for an out of bounds plugin");
+ return (*Plugins)[num];
+}
diff --git a/contrib/llvm/lib/Support/PrettyStackTrace.cpp b/contrib/llvm/lib/Support/PrettyStackTrace.cpp
new file mode 100644
index 000000000000..f9f8cab9d933
--- /dev/null
+++ b/contrib/llvm/lib/Support/PrettyStackTrace.cpp
@@ -0,0 +1,159 @@
+//===- PrettyStackTrace.cpp - Pretty Crash Handling -----------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file 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 occurring while your program is running.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/PrettyStackTrace.h"
+#include "llvm-c/Core.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/Config/config.h" // Get autoconf configuration settings
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Signals.h"
+#include "llvm/Support/Watchdog.h"
+#include "llvm/Support/raw_ostream.h"
+
+#ifdef HAVE_CRASHREPORTERCLIENT_H
+#include <CrashReporterClient.h>
+#endif
+
+using namespace llvm;
+
+// If backtrace support is not enabled, compile out support for pretty stack
+// traces. This has the secondary effect of not requiring thread local storage
+// when backtrace support is disabled.
+#if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
+
+// We need a thread local pointer to manage the stack of our stack trace
+// objects, but we *really* cannot tolerate destructors running and do not want
+// to pay any overhead of synchronizing. As a consequence, we use a raw
+// thread-local variable.
+static LLVM_THREAD_LOCAL const PrettyStackTraceEntry *PrettyStackTraceHead =
+ nullptr;
+
+static unsigned PrintStack(const PrettyStackTraceEntry *Entry, raw_ostream &OS){
+ unsigned NextID = 0;
+ if (Entry->getNextEntry())
+ NextID = PrintStack(Entry->getNextEntry(), OS);
+ OS << NextID << ".\t";
+ {
+ sys::Watchdog W(5);
+ Entry->print(OS);
+ }
+
+ return NextID+1;
+}
+
+/// PrintCurStackTrace - Print the current stack trace to the specified stream.
+static void PrintCurStackTrace(raw_ostream &OS) {
+ // Don't print an empty trace.
+ if (!PrettyStackTraceHead) return;
+
+ // If there are pretty stack frames registered, walk and emit them.
+ OS << "Stack dump:\n";
+
+ PrintStack(PrettyStackTraceHead, OS);
+ OS.flush();
+}
+
+// Integrate with crash reporter libraries.
+#if defined (__APPLE__) && HAVE_CRASHREPORTERCLIENT_H
+// If any clients of llvm try to link to libCrashReporterClient.a themselves,
+// only one crash info struct will be used.
+extern "C" {
+CRASH_REPORTER_CLIENT_HIDDEN
+struct crashreporter_annotations_t gCRAnnotations
+ __attribute__((section("__DATA," CRASHREPORTER_ANNOTATIONS_SECTION)))
+ = { CRASHREPORTER_ANNOTATIONS_VERSION, 0, 0, 0, 0, 0, 0 };
+}
+#elif defined (__APPLE__) && HAVE_CRASHREPORTER_INFO
+static const char *__crashreporter_info__ = 0;
+asm(".desc ___crashreporter_info__, 0x10");
+#endif
+
+
+/// CrashHandler - This callback is run if a fatal signal is delivered to the
+/// process, it prints the pretty stack trace.
+static void CrashHandler(void *) {
+#ifndef __APPLE__
+ // On non-apple systems, just emit the crash stack trace to stderr.
+ PrintCurStackTrace(errs());
+#else
+ // Otherwise, emit to a smallvector of chars, send *that* to stderr, but also
+ // put it into __crashreporter_info__.
+ SmallString<2048> TmpStr;
+ {
+ raw_svector_ostream Stream(TmpStr);
+ PrintCurStackTrace(Stream);
+ }
+
+ if (!TmpStr.empty()) {
+#ifdef HAVE_CRASHREPORTERCLIENT_H
+ // Cast to void to avoid warning.
+ (void)CRSetCrashLogMessage(std::string(TmpStr.str()).c_str());
+#elif HAVE_CRASHREPORTER_INFO
+ __crashreporter_info__ = strdup(std::string(TmpStr.str()).c_str());
+#endif
+ errs() << TmpStr.str();
+ }
+
+#endif
+}
+
+// defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
+#endif
+
+PrettyStackTraceEntry::PrettyStackTraceEntry() {
+#if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
+ // Link ourselves.
+ NextEntry = PrettyStackTraceHead;
+ PrettyStackTraceHead = this;
+#endif
+}
+
+PrettyStackTraceEntry::~PrettyStackTraceEntry() {
+#if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
+ assert(PrettyStackTraceHead == this &&
+ "Pretty stack trace entry destruction is out of order");
+ PrettyStackTraceHead = getNextEntry();
+#endif
+}
+
+void PrettyStackTraceString::print(raw_ostream &OS) const {
+ OS << Str << "\n";
+}
+
+void PrettyStackTraceProgram::print(raw_ostream &OS) const {
+ OS << "Program arguments: ";
+ // Print the argument list.
+ for (unsigned i = 0, e = ArgC; i != e; ++i)
+ OS << ArgV[i] << ' ';
+ OS << '\n';
+}
+
+#if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
+static bool RegisterCrashPrinter() {
+ sys::AddSignalHandler(CrashHandler, nullptr);
+ return false;
+}
+#endif
+
+void llvm::EnablePrettyStackTrace() {
+#if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
+ // The first time this is called, we register the crash printer.
+ static bool HandlerRegistered = RegisterCrashPrinter();
+ (void)HandlerRegistered;
+#endif
+}
+
+void LLVMEnablePrettyStackTrace() {
+ EnablePrettyStackTrace();
+}
diff --git a/contrib/llvm/lib/Support/Process.cpp b/contrib/llvm/lib/Support/Process.cpp
new file mode 100644
index 000000000000..6dcbb47e87d0
--- /dev/null
+++ b/contrib/llvm/lib/Support/Process.cpp
@@ -0,0 +1,82 @@
+//===-- Process.cpp - Implement OS Process Concept --------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the operating system Process concept.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Config/config.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/Process.h"
+#include "llvm/Support/Program.h"
+
+using namespace llvm;
+using namespace sys;
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only TRULY operating system
+//=== independent code.
+//===----------------------------------------------------------------------===//
+
+Optional<std::string> Process::FindInEnvPath(const std::string& EnvName,
+ const std::string& FileName)
+{
+ assert(!path::is_absolute(FileName));
+ Optional<std::string> FoundPath;
+ Optional<std::string> OptPath = Process::GetEnv(EnvName);
+ if (!OptPath.hasValue())
+ return FoundPath;
+
+ const char EnvPathSeparatorStr[] = {EnvPathSeparator, '\0'};
+ SmallVector<StringRef, 8> Dirs;
+ SplitString(OptPath.getValue(), Dirs, EnvPathSeparatorStr);
+
+ for (const auto &Dir : Dirs) {
+ if (Dir.empty())
+ continue;
+
+ SmallString<128> FilePath(Dir);
+ path::append(FilePath, FileName);
+ if (fs::exists(Twine(FilePath))) {
+ FoundPath = FilePath.str();
+ break;
+ }
+ }
+
+ return FoundPath;
+}
+
+
+#define COLOR(FGBG, CODE, BOLD) "\033[0;" BOLD FGBG CODE "m"
+
+#define ALLCOLORS(FGBG,BOLD) {\
+ COLOR(FGBG, "0", BOLD),\
+ COLOR(FGBG, "1", BOLD),\
+ COLOR(FGBG, "2", BOLD),\
+ COLOR(FGBG, "3", BOLD),\
+ COLOR(FGBG, "4", BOLD),\
+ COLOR(FGBG, "5", BOLD),\
+ COLOR(FGBG, "6", BOLD),\
+ COLOR(FGBG, "7", BOLD)\
+ }
+
+static const char colorcodes[2][2][8][10] = {
+ { ALLCOLORS("3",""), ALLCOLORS("3","1;") },
+ { ALLCOLORS("4",""), ALLCOLORS("4","1;") }
+};
+
+// Include the platform-specific parts of this class.
+#ifdef LLVM_ON_UNIX
+#include "Unix/Process.inc"
+#endif
+#ifdef LLVM_ON_WIN32
+#include "Windows/Process.inc"
+#endif
diff --git a/contrib/llvm/lib/Support/Program.cpp b/contrib/llvm/lib/Support/Program.cpp
new file mode 100644
index 000000000000..34e336b354d6
--- /dev/null
+++ b/contrib/llvm/lib/Support/Program.cpp
@@ -0,0 +1,69 @@
+//===-- Program.cpp - Implement OS Program Concept --------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the operating system Program concept.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/Program.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Config/config.h"
+#include <system_error>
+using namespace llvm;
+using namespace sys;
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only TRULY operating system
+//=== independent code.
+//===----------------------------------------------------------------------===//
+
+static bool Execute(ProcessInfo &PI, StringRef Program, const char **args,
+ const char **env, const StringRef **Redirects,
+ unsigned memoryLimit, std::string *ErrMsg);
+
+int sys::ExecuteAndWait(StringRef Program, const char **args, const char **envp,
+ const StringRef **redirects, unsigned secondsToWait,
+ unsigned memoryLimit, std::string *ErrMsg,
+ bool *ExecutionFailed) {
+ ProcessInfo PI;
+ if (Execute(PI, Program, args, envp, redirects, memoryLimit, ErrMsg)) {
+ if (ExecutionFailed)
+ *ExecutionFailed = false;
+ ProcessInfo Result = Wait(
+ PI, secondsToWait, /*WaitUntilTerminates=*/secondsToWait == 0, ErrMsg);
+ return Result.ReturnCode;
+ }
+
+ if (ExecutionFailed)
+ *ExecutionFailed = true;
+
+ return -1;
+}
+
+ProcessInfo sys::ExecuteNoWait(StringRef Program, const char **args,
+ const char **envp, const StringRef **redirects,
+ unsigned memoryLimit, std::string *ErrMsg,
+ bool *ExecutionFailed) {
+ ProcessInfo PI;
+ if (ExecutionFailed)
+ *ExecutionFailed = false;
+ if (!Execute(PI, Program, args, envp, redirects, memoryLimit, ErrMsg))
+ if (ExecutionFailed)
+ *ExecutionFailed = true;
+
+ return PI;
+}
+
+// Include the platform-specific parts of this class.
+#ifdef LLVM_ON_UNIX
+#include "Unix/Program.inc"
+#endif
+#ifdef LLVM_ON_WIN32
+#include "Windows/Program.inc"
+#endif
diff --git a/contrib/llvm/lib/Support/RWMutex.cpp b/contrib/llvm/lib/Support/RWMutex.cpp
new file mode 100644
index 000000000000..21ba5a428e6f
--- /dev/null
+++ b/contrib/llvm/lib/Support/RWMutex.cpp
@@ -0,0 +1,125 @@
+//===- RWMutex.cpp - Reader/Writer Mutual Exclusion Lock --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the llvm::sys::RWMutex class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Config/config.h"
+#include "llvm/Support/RWMutex.h"
+#include <cstring>
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only TRULY operating system
+//=== independent code.
+//===----------------------------------------------------------------------===//
+
+#if !defined(LLVM_ENABLE_THREADS) || LLVM_ENABLE_THREADS == 0
+// Define all methods as no-ops if threading is explicitly disabled
+namespace llvm {
+using namespace sys;
+RWMutexImpl::RWMutexImpl() { }
+RWMutexImpl::~RWMutexImpl() { }
+bool RWMutexImpl::reader_acquire() { return true; }
+bool RWMutexImpl::reader_release() { return true; }
+bool RWMutexImpl::writer_acquire() { return true; }
+bool RWMutexImpl::writer_release() { return true; }
+}
+#else
+
+#if defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_RWLOCK_INIT)
+
+#include <cassert>
+#include <pthread.h>
+#include <stdlib.h>
+
+namespace llvm {
+using namespace sys;
+
+// Construct a RWMutex using pthread calls
+RWMutexImpl::RWMutexImpl()
+ : data_(nullptr)
+{
+ // Declare the pthread_rwlock data structures
+ pthread_rwlock_t* rwlock =
+ static_cast<pthread_rwlock_t*>(malloc(sizeof(pthread_rwlock_t)));
+
+#ifdef __APPLE__
+ // Workaround a bug/mis-feature in Darwin's pthread_rwlock_init.
+ bzero(rwlock, sizeof(pthread_rwlock_t));
+#endif
+
+ // Initialize the rwlock
+ int errorcode = pthread_rwlock_init(rwlock, nullptr);
+ (void)errorcode;
+ assert(errorcode == 0);
+
+ // Assign the data member
+ data_ = rwlock;
+}
+
+// Destruct a RWMutex
+RWMutexImpl::~RWMutexImpl()
+{
+ pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_);
+ assert(rwlock != nullptr);
+ pthread_rwlock_destroy(rwlock);
+ free(rwlock);
+}
+
+bool
+RWMutexImpl::reader_acquire()
+{
+ pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_);
+ assert(rwlock != nullptr);
+
+ int errorcode = pthread_rwlock_rdlock(rwlock);
+ return errorcode == 0;
+}
+
+bool
+RWMutexImpl::reader_release()
+{
+ pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_);
+ assert(rwlock != nullptr);
+
+ int errorcode = pthread_rwlock_unlock(rwlock);
+ return errorcode == 0;
+}
+
+bool
+RWMutexImpl::writer_acquire()
+{
+ pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_);
+ assert(rwlock != nullptr);
+
+ int errorcode = pthread_rwlock_wrlock(rwlock);
+ return errorcode == 0;
+}
+
+bool
+RWMutexImpl::writer_release()
+{
+ pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_);
+ assert(rwlock != nullptr);
+
+ int errorcode = pthread_rwlock_unlock(rwlock);
+ return errorcode == 0;
+}
+
+} // namespace llvm
+
+#elif defined(LLVM_ON_UNIX)
+#include "Unix/RWMutex.inc"
+#elif defined( LLVM_ON_WIN32)
+#include "Windows/RWMutex.inc"
+#else
+#warning Neither LLVM_ON_UNIX nor LLVM_ON_WIN32 was set in Support/Mutex.cpp
+#endif
+#endif
diff --git a/contrib/llvm/lib/Support/RandomNumberGenerator.cpp b/contrib/llvm/lib/Support/RandomNumberGenerator.cpp
new file mode 100644
index 000000000000..81d0411d60b4
--- /dev/null
+++ b/contrib/llvm/lib/Support/RandomNumberGenerator.cpp
@@ -0,0 +1,57 @@
+//===-- RandomNumberGenerator.cpp - Implement RNG class -------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements deterministic random number generation (RNG).
+// The current implementation is NOT cryptographically secure as it uses
+// the C++11 <random> facilities.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/RandomNumberGenerator.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "rng"
+
+// Tracking BUG: 19665
+// http://llvm.org/bugs/show_bug.cgi?id=19665
+//
+// Do not change to cl::opt<uint64_t> since this silently breaks argument parsing.
+static cl::opt<unsigned long long>
+Seed("rng-seed", cl::value_desc("seed"),
+ cl::desc("Seed for the random number generator"), cl::init(0));
+
+RandomNumberGenerator::RandomNumberGenerator(StringRef Salt) {
+ DEBUG(
+ if (Seed == 0)
+ dbgs() << "Warning! Using unseeded random number generator.\n"
+ );
+
+ // Combine seed and salts using std::seed_seq.
+ // Data: Seed-low, Seed-high, Salt
+ // Note: std::seed_seq can only store 32-bit values, even though we
+ // are using a 64-bit RNG. This isn't a problem since the Mersenne
+ // twister constructor copies these correctly into its initial state.
+ std::vector<uint32_t> Data;
+ Data.reserve(2 + Salt.size());
+ Data.push_back(Seed);
+ Data.push_back(Seed >> 32);
+
+ std::copy(Salt.begin(), Salt.end(), Data.end());
+
+ std::seed_seq SeedSeq(Data.begin(), Data.end());
+ Generator.seed(SeedSeq);
+}
+
+uint_fast64_t RandomNumberGenerator::operator()() {
+ return Generator();
+}
diff --git a/contrib/llvm/lib/Support/Regex.cpp b/contrib/llvm/lib/Support/Regex.cpp
new file mode 100644
index 000000000000..e8344ef74d9c
--- /dev/null
+++ b/contrib/llvm/lib/Support/Regex.cpp
@@ -0,0 +1,193 @@
+//===-- Regex.cpp - Regular Expression matcher implementation -------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a POSIX regular expression matcher.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/Regex.h"
+#include "regex_impl.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Twine.h"
+#include <string>
+using namespace llvm;
+
+Regex::Regex(StringRef regex, unsigned Flags) {
+ unsigned flags = 0;
+ preg = new llvm_regex();
+ preg->re_endp = regex.end();
+ if (Flags & IgnoreCase)
+ flags |= REG_ICASE;
+ if (Flags & Newline)
+ flags |= REG_NEWLINE;
+ if (!(Flags & BasicRegex))
+ flags |= REG_EXTENDED;
+ error = llvm_regcomp(preg, regex.data(), flags|REG_PEND);
+}
+
+Regex::~Regex() {
+ if (preg) {
+ llvm_regfree(preg);
+ delete preg;
+ }
+}
+
+bool Regex::isValid(std::string &Error) {
+ if (!error)
+ return true;
+
+ size_t len = llvm_regerror(error, preg, nullptr, 0);
+
+ Error.resize(len - 1);
+ llvm_regerror(error, preg, &Error[0], len);
+ return false;
+}
+
+/// getNumMatches - In a valid regex, return the number of parenthesized
+/// matches it contains.
+unsigned Regex::getNumMatches() const {
+ return preg->re_nsub;
+}
+
+bool Regex::match(StringRef String, SmallVectorImpl<StringRef> *Matches){
+ unsigned nmatch = Matches ? preg->re_nsub+1 : 0;
+
+ // pmatch needs to have at least one element.
+ SmallVector<llvm_regmatch_t, 8> pm;
+ pm.resize(nmatch > 0 ? nmatch : 1);
+ pm[0].rm_so = 0;
+ pm[0].rm_eo = String.size();
+
+ int rc = llvm_regexec(preg, String.data(), nmatch, pm.data(), REG_STARTEND);
+
+ if (rc == REG_NOMATCH)
+ return false;
+ if (rc != 0) {
+ // regexec can fail due to invalid pattern or running out of memory.
+ error = rc;
+ return false;
+ }
+
+ // There was a match.
+
+ if (Matches) { // match position requested
+ Matches->clear();
+
+ for (unsigned i = 0; i != nmatch; ++i) {
+ if (pm[i].rm_so == -1) {
+ // this group didn't match
+ Matches->push_back(StringRef());
+ continue;
+ }
+ assert(pm[i].rm_eo >= pm[i].rm_so);
+ Matches->push_back(StringRef(String.data()+pm[i].rm_so,
+ pm[i].rm_eo-pm[i].rm_so));
+ }
+ }
+
+ return true;
+}
+
+std::string Regex::sub(StringRef Repl, StringRef String,
+ std::string *Error) {
+ SmallVector<StringRef, 8> Matches;
+
+ // Reset error, if given.
+ if (Error && !Error->empty()) *Error = "";
+
+ // Return the input if there was no match.
+ if (!match(String, &Matches))
+ return String;
+
+ // Otherwise splice in the replacement string, starting with the prefix before
+ // the match.
+ std::string Res(String.begin(), Matches[0].begin());
+
+ // Then the replacement string, honoring possible substitutions.
+ while (!Repl.empty()) {
+ // Skip to the next escape.
+ std::pair<StringRef, StringRef> Split = Repl.split('\\');
+
+ // Add the skipped substring.
+ Res += Split.first;
+
+ // Check for terminimation and trailing backslash.
+ if (Split.second.empty()) {
+ if (Repl.size() != Split.first.size() &&
+ Error && Error->empty())
+ *Error = "replacement string contained trailing backslash";
+ break;
+ }
+
+ // Otherwise update the replacement string and interpret escapes.
+ Repl = Split.second;
+
+ // FIXME: We should have a StringExtras function for mapping C99 escapes.
+ switch (Repl[0]) {
+ // Treat all unrecognized characters as self-quoting.
+ default:
+ Res += Repl[0];
+ Repl = Repl.substr(1);
+ break;
+
+ // Single character escapes.
+ case 't':
+ Res += '\t';
+ Repl = Repl.substr(1);
+ break;
+ case 'n':
+ Res += '\n';
+ Repl = Repl.substr(1);
+ break;
+
+ // Decimal escapes are backreferences.
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9': {
+ // Extract the backreference number.
+ StringRef Ref = Repl.slice(0, Repl.find_first_not_of("0123456789"));
+ Repl = Repl.substr(Ref.size());
+
+ unsigned RefValue;
+ if (!Ref.getAsInteger(10, RefValue) &&
+ RefValue < Matches.size())
+ Res += Matches[RefValue];
+ else if (Error && Error->empty())
+ *Error = ("invalid backreference string '" + Twine(Ref) + "'").str();
+ break;
+ }
+ }
+ }
+
+ // And finally the suffix.
+ Res += StringRef(Matches[0].end(), String.end() - Matches[0].end());
+
+ return Res;
+}
+
+// These are the special characters matched in functions like "p_ere_exp".
+static const char RegexMetachars[] = "()^$|*+?.[]\\{}";
+
+bool Regex::isLiteralERE(StringRef Str) {
+ // Check for regex metacharacters. This list was derived from our regex
+ // implementation in regcomp.c and double checked against the POSIX extended
+ // regular expression specification.
+ return Str.find_first_of(RegexMetachars) == StringRef::npos;
+}
+
+std::string Regex::escape(StringRef String) {
+ std::string RegexStr;
+ for (unsigned i = 0, e = String.size(); i != e; ++i) {
+ if (strchr(RegexMetachars, String[i]))
+ RegexStr += '\\';
+ RegexStr += String[i];
+ }
+
+ return RegexStr;
+}
diff --git a/contrib/llvm/lib/Support/ScaledNumber.cpp b/contrib/llvm/lib/Support/ScaledNumber.cpp
new file mode 100644
index 000000000000..987c2d803b7e
--- /dev/null
+++ b/contrib/llvm/lib/Support/ScaledNumber.cpp
@@ -0,0 +1,323 @@
+//==- lib/Support/ScaledNumber.cpp - Support for scaled numbers -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Implementation of some scaled number algorithms.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/ScaledNumber.h"
+#include "llvm/ADT/APFloat.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace llvm;
+using namespace llvm::ScaledNumbers;
+
+std::pair<uint64_t, int16_t> ScaledNumbers::multiply64(uint64_t LHS,
+ uint64_t RHS) {
+ // Separate into two 32-bit digits (U.L).
+ auto getU = [](uint64_t N) { return N >> 32; };
+ auto getL = [](uint64_t N) { return N & UINT32_MAX; };
+ uint64_t UL = getU(LHS), LL = getL(LHS), UR = getU(RHS), LR = getL(RHS);
+
+ // Compute cross products.
+ uint64_t P1 = UL * UR, P2 = UL * LR, P3 = LL * UR, P4 = LL * LR;
+
+ // Sum into two 64-bit digits.
+ uint64_t Upper = P1, Lower = P4;
+ auto addWithCarry = [&](uint64_t N) {
+ uint64_t NewLower = Lower + (getL(N) << 32);
+ Upper += getU(N) + (NewLower < Lower);
+ Lower = NewLower;
+ };
+ addWithCarry(P2);
+ addWithCarry(P3);
+
+ // Check whether the upper digit is empty.
+ if (!Upper)
+ return std::make_pair(Lower, 0);
+
+ // Shift as little as possible to maximize precision.
+ unsigned LeadingZeros = countLeadingZeros(Upper);
+ int Shift = 64 - LeadingZeros;
+ if (LeadingZeros)
+ Upper = Upper << LeadingZeros | Lower >> Shift;
+ return getRounded(Upper, Shift,
+ Shift && (Lower & UINT64_C(1) << (Shift - 1)));
+}
+
+static uint64_t getHalf(uint64_t N) { return (N >> 1) + (N & 1); }
+
+std::pair<uint32_t, int16_t> ScaledNumbers::divide32(uint32_t Dividend,
+ uint32_t Divisor) {
+ assert(Dividend && "expected non-zero dividend");
+ assert(Divisor && "expected non-zero divisor");
+
+ // Use 64-bit math and canonicalize the dividend to gain precision.
+ uint64_t Dividend64 = Dividend;
+ int Shift = 0;
+ if (int Zeros = countLeadingZeros(Dividend64)) {
+ Shift -= Zeros;
+ Dividend64 <<= Zeros;
+ }
+ uint64_t Quotient = Dividend64 / Divisor;
+ uint64_t Remainder = Dividend64 % Divisor;
+
+ // If Quotient needs to be shifted, leave the rounding to getAdjusted().
+ if (Quotient > UINT32_MAX)
+ return getAdjusted<uint32_t>(Quotient, Shift);
+
+ // Round based on the value of the next bit.
+ return getRounded<uint32_t>(Quotient, Shift, Remainder >= getHalf(Divisor));
+}
+
+std::pair<uint64_t, int16_t> ScaledNumbers::divide64(uint64_t Dividend,
+ uint64_t Divisor) {
+ assert(Dividend && "expected non-zero dividend");
+ assert(Divisor && "expected non-zero divisor");
+
+ // Minimize size of divisor.
+ int Shift = 0;
+ if (int Zeros = countTrailingZeros(Divisor)) {
+ Shift -= Zeros;
+ Divisor >>= Zeros;
+ }
+
+ // Check for powers of two.
+ if (Divisor == 1)
+ return std::make_pair(Dividend, Shift);
+
+ // Maximize size of dividend.
+ if (int Zeros = countLeadingZeros(Dividend)) {
+ Shift -= Zeros;
+ Dividend <<= Zeros;
+ }
+
+ // Start with the result of a divide.
+ uint64_t Quotient = Dividend / Divisor;
+ Dividend %= Divisor;
+
+ // Continue building the quotient with long division.
+ while (!(Quotient >> 63) && Dividend) {
+ // Shift Dividend and check for overflow.
+ bool IsOverflow = Dividend >> 63;
+ Dividend <<= 1;
+ --Shift;
+
+ // Get the next bit of Quotient.
+ Quotient <<= 1;
+ if (IsOverflow || Divisor <= Dividend) {
+ Quotient |= 1;
+ Dividend -= Divisor;
+ }
+ }
+
+ return getRounded(Quotient, Shift, Dividend >= getHalf(Divisor));
+}
+
+int ScaledNumbers::compareImpl(uint64_t L, uint64_t R, int ScaleDiff) {
+ assert(ScaleDiff >= 0 && "wrong argument order");
+ assert(ScaleDiff < 64 && "numbers too far apart");
+
+ uint64_t L_adjusted = L >> ScaleDiff;
+ if (L_adjusted < R)
+ return -1;
+ if (L_adjusted > R)
+ return 1;
+
+ return L > L_adjusted << ScaleDiff ? 1 : 0;
+}
+
+static void appendDigit(std::string &Str, unsigned D) {
+ assert(D < 10);
+ Str += '0' + D % 10;
+}
+
+static void appendNumber(std::string &Str, uint64_t N) {
+ while (N) {
+ appendDigit(Str, N % 10);
+ N /= 10;
+ }
+}
+
+static bool doesRoundUp(char Digit) {
+ switch (Digit) {
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ return true;
+ default:
+ return false;
+ }
+}
+
+static std::string toStringAPFloat(uint64_t D, int E, unsigned Precision) {
+ assert(E >= ScaledNumbers::MinScale);
+ assert(E <= ScaledNumbers::MaxScale);
+
+ // Find a new E, but don't let it increase past MaxScale.
+ int LeadingZeros = ScaledNumberBase::countLeadingZeros64(D);
+ int NewE = std::min(ScaledNumbers::MaxScale, E + 63 - LeadingZeros);
+ int Shift = 63 - (NewE - E);
+ assert(Shift <= LeadingZeros);
+ assert(Shift == LeadingZeros || NewE == ScaledNumbers::MaxScale);
+ assert(Shift >= 0 && Shift < 64 && "undefined behavior");
+ D <<= Shift;
+ E = NewE;
+
+ // Check for a denormal.
+ unsigned AdjustedE = E + 16383;
+ if (!(D >> 63)) {
+ assert(E == ScaledNumbers::MaxScale);
+ AdjustedE = 0;
+ }
+
+ // Build the float and print it.
+ uint64_t RawBits[2] = {D, AdjustedE};
+ APFloat Float(APFloat::x87DoubleExtended, APInt(80, RawBits));
+ SmallVector<char, 24> Chars;
+ Float.toString(Chars, Precision, 0);
+ return std::string(Chars.begin(), Chars.end());
+}
+
+static std::string stripTrailingZeros(const std::string &Float) {
+ size_t NonZero = Float.find_last_not_of('0');
+ assert(NonZero != std::string::npos && "no . in floating point string");
+
+ if (Float[NonZero] == '.')
+ ++NonZero;
+
+ return Float.substr(0, NonZero + 1);
+}
+
+std::string ScaledNumberBase::toString(uint64_t D, int16_t E, int Width,
+ unsigned Precision) {
+ if (!D)
+ return "0.0";
+
+ // Canonicalize exponent and digits.
+ uint64_t Above0 = 0;
+ uint64_t Below0 = 0;
+ uint64_t Extra = 0;
+ int ExtraShift = 0;
+ if (E == 0) {
+ Above0 = D;
+ } else if (E > 0) {
+ if (int Shift = std::min(int16_t(countLeadingZeros64(D)), E)) {
+ D <<= Shift;
+ E -= Shift;
+
+ if (!E)
+ Above0 = D;
+ }
+ } else if (E > -64) {
+ Above0 = D >> -E;
+ Below0 = D << (64 + E);
+ } else if (E == -64) {
+ // Special case: shift by 64 bits is undefined behavior.
+ Below0 = D;
+ } else if (E > -120) {
+ Below0 = D >> (-E - 64);
+ Extra = D << (128 + E);
+ ExtraShift = -64 - E;
+ }
+
+ // Fall back on APFloat for very small and very large numbers.
+ if (!Above0 && !Below0)
+ return toStringAPFloat(D, E, Precision);
+
+ // Append the digits before the decimal.
+ std::string Str;
+ size_t DigitsOut = 0;
+ if (Above0) {
+ appendNumber(Str, Above0);
+ DigitsOut = Str.size();
+ } else
+ appendDigit(Str, 0);
+ std::reverse(Str.begin(), Str.end());
+
+ // Return early if there's nothing after the decimal.
+ if (!Below0)
+ return Str + ".0";
+
+ // Append the decimal and beyond.
+ Str += '.';
+ uint64_t Error = UINT64_C(1) << (64 - Width);
+
+ // We need to shift Below0 to the right to make space for calculating
+ // digits. Save the precision we're losing in Extra.
+ Extra = (Below0 & 0xf) << 56 | (Extra >> 8);
+ Below0 >>= 4;
+ size_t SinceDot = 0;
+ size_t AfterDot = Str.size();
+ do {
+ if (ExtraShift) {
+ --ExtraShift;
+ Error *= 5;
+ } else
+ Error *= 10;
+
+ Below0 *= 10;
+ Extra *= 10;
+ Below0 += (Extra >> 60);
+ Extra = Extra & (UINT64_MAX >> 4);
+ appendDigit(Str, Below0 >> 60);
+ Below0 = Below0 & (UINT64_MAX >> 4);
+ if (DigitsOut || Str.back() != '0')
+ ++DigitsOut;
+ ++SinceDot;
+ } while (Error && (Below0 << 4 | Extra >> 60) >= Error / 2 &&
+ (!Precision || DigitsOut <= Precision || SinceDot < 2));
+
+ // Return early for maximum precision.
+ if (!Precision || DigitsOut <= Precision)
+ return stripTrailingZeros(Str);
+
+ // Find where to truncate.
+ size_t Truncate =
+ std::max(Str.size() - (DigitsOut - Precision), AfterDot + 1);
+
+ // Check if there's anything to truncate.
+ if (Truncate >= Str.size())
+ return stripTrailingZeros(Str);
+
+ bool Carry = doesRoundUp(Str[Truncate]);
+ if (!Carry)
+ return stripTrailingZeros(Str.substr(0, Truncate));
+
+ // Round with the first truncated digit.
+ for (std::string::reverse_iterator I(Str.begin() + Truncate), E = Str.rend();
+ I != E; ++I) {
+ if (*I == '.')
+ continue;
+ if (*I == '9') {
+ *I = '0';
+ continue;
+ }
+
+ ++*I;
+ Carry = false;
+ break;
+ }
+
+ // Add "1" in front if we still need to carry.
+ return stripTrailingZeros(std::string(Carry, '1') + Str.substr(0, Truncate));
+}
+
+raw_ostream &ScaledNumberBase::print(raw_ostream &OS, uint64_t D, int16_t E,
+ int Width, unsigned Precision) {
+ return OS << toString(D, E, Width, Precision);
+}
+
+void ScaledNumberBase::dump(uint64_t D, int16_t E, int Width) {
+ print(dbgs(), D, E, Width, 0) << "[" << Width << ":" << D << "*2^" << E
+ << "]";
+}
diff --git a/contrib/llvm/lib/Support/SearchForAddressOfSpecialSymbol.cpp b/contrib/llvm/lib/Support/SearchForAddressOfSpecialSymbol.cpp
new file mode 100644
index 000000000000..55f3320f640f
--- /dev/null
+++ b/contrib/llvm/lib/Support/SearchForAddressOfSpecialSymbol.cpp
@@ -0,0 +1,58 @@
+//===- SearchForAddressOfSpecialSymbol.cpp - Function addresses -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file pulls the addresses of certain symbols out of the linker. It must
+// include as few header files as possible because it declares the symbols as
+// void*, which would conflict with the actual symbol type if any header
+// declared it.
+//
+//===----------------------------------------------------------------------===//
+
+#include <string.h>
+
+// Must declare the symbols in the global namespace.
+static void *DoSearch(const char* symbolName) {
+#define EXPLICIT_SYMBOL(SYM) \
+ extern void *SYM; if (!strcmp(symbolName, #SYM)) return &SYM
+
+ // If this is darwin, it has some funky issues, try to solve them here. Some
+ // important symbols are marked 'private external' which doesn't allow
+ // SearchForAddressOfSymbol to find them. As such, we special case them here,
+ // there is only a small handful of them.
+
+#ifdef __APPLE__
+ {
+ // __eprintf is sometimes used for assert() handling on x86.
+ //
+ // FIXME: Currently disabled when using Clang, as we don't always have our
+ // runtime support libraries available.
+#ifndef __clang__
+#ifdef __i386__
+ EXPLICIT_SYMBOL(__eprintf);
+#endif
+#endif
+ }
+#endif
+
+#ifdef __CYGWIN__
+ {
+ EXPLICIT_SYMBOL(_alloca);
+ EXPLICIT_SYMBOL(__main);
+ }
+#endif
+
+#undef EXPLICIT_SYMBOL
+ return nullptr;
+}
+
+namespace llvm {
+void *SearchForAddressOfSpecialSymbol(const char* symbolName) {
+ return DoSearch(symbolName);
+}
+} // namespace llvm
diff --git a/contrib/llvm/lib/Support/Signals.cpp b/contrib/llvm/lib/Support/Signals.cpp
new file mode 100644
index 000000000000..a11789372d93
--- /dev/null
+++ b/contrib/llvm/lib/Support/Signals.cpp
@@ -0,0 +1,34 @@
+//===- Signals.cpp - Signal Handling support --------------------*- 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 some helpful functions for dealing with the possibility of
+// Unix signals occurring while your program is running.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/Signals.h"
+#include "llvm/Config/config.h"
+
+namespace llvm {
+using namespace sys;
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only TRULY operating system
+//=== independent code.
+//===----------------------------------------------------------------------===//
+
+}
+
+// Include the platform-specific parts of this class.
+#ifdef LLVM_ON_UNIX
+#include "Unix/Signals.inc"
+#endif
+#ifdef LLVM_ON_WIN32
+#include "Windows/Signals.inc"
+#endif
diff --git a/contrib/llvm/lib/Support/SmallPtrSet.cpp b/contrib/llvm/lib/Support/SmallPtrSet.cpp
new file mode 100644
index 000000000000..358c8e8abbe9
--- /dev/null
+++ b/contrib/llvm/lib/Support/SmallPtrSet.cpp
@@ -0,0 +1,338 @@
+//===- llvm/ADT/SmallPtrSet.cpp - 'Normally small' pointer set ------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the SmallPtrSet class. See SmallPtrSet.h for an
+// overview of the algorithm.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/DenseMapInfo.h"
+#include "llvm/Support/MathExtras.h"
+#include <algorithm>
+#include <cstdlib>
+
+using namespace llvm;
+
+void SmallPtrSetImplBase::shrink_and_clear() {
+ assert(!isSmall() && "Can't shrink a small set!");
+ free(CurArray);
+
+ // Reduce the number of buckets.
+ CurArraySize = NumElements > 16 ? 1 << (Log2_32_Ceil(NumElements) + 1) : 32;
+ NumElements = NumTombstones = 0;
+
+ // Install the new array. Clear all the buckets to empty.
+ CurArray = (const void**)malloc(sizeof(void*) * CurArraySize);
+ assert(CurArray && "Failed to allocate memory?");
+ memset(CurArray, -1, CurArraySize*sizeof(void*));
+}
+
+std::pair<const void *const *, bool>
+SmallPtrSetImplBase::insert_imp(const void *Ptr) {
+ if (isSmall()) {
+ // Check to see if it is already in the set.
+ for (const void **APtr = SmallArray, **E = SmallArray+NumElements;
+ APtr != E; ++APtr)
+ if (*APtr == Ptr)
+ return std::make_pair(APtr, false);
+
+ // Nope, there isn't. If we stay small, just 'pushback' now.
+ if (NumElements < CurArraySize) {
+ SmallArray[NumElements++] = Ptr;
+ return std::make_pair(SmallArray + (NumElements - 1), true);
+ }
+ // Otherwise, hit the big set case, which will call grow.
+ }
+
+ if (LLVM_UNLIKELY(NumElements * 4 >= CurArraySize * 3)) {
+ // If more than 3/4 of the array is full, grow.
+ Grow(CurArraySize < 64 ? 128 : CurArraySize*2);
+ } else if (LLVM_UNLIKELY(CurArraySize - (NumElements + NumTombstones) <
+ CurArraySize / 8)) {
+ // If fewer of 1/8 of the array is empty (meaning that many are filled with
+ // tombstones), rehash.
+ Grow(CurArraySize);
+ }
+
+ // Okay, we know we have space. Find a hash bucket.
+ const void **Bucket = const_cast<const void**>(FindBucketFor(Ptr));
+ if (*Bucket == Ptr)
+ return std::make_pair(Bucket, false); // Already inserted, good.
+
+ // Otherwise, insert it!
+ if (*Bucket == getTombstoneMarker())
+ --NumTombstones;
+ *Bucket = Ptr;
+ ++NumElements; // Track density.
+ return std::make_pair(Bucket, true);
+}
+
+bool SmallPtrSetImplBase::erase_imp(const void * Ptr) {
+ if (isSmall()) {
+ // Check to see if it is in the set.
+ for (const void **APtr = SmallArray, **E = SmallArray+NumElements;
+ APtr != E; ++APtr)
+ if (*APtr == Ptr) {
+ // If it is in the set, replace this element.
+ *APtr = E[-1];
+ E[-1] = getEmptyMarker();
+ --NumElements;
+ return true;
+ }
+
+ return false;
+ }
+
+ // Okay, we know we have space. Find a hash bucket.
+ void **Bucket = const_cast<void**>(FindBucketFor(Ptr));
+ if (*Bucket != Ptr) return false; // Not in the set?
+
+ // Set this as a tombstone.
+ *Bucket = getTombstoneMarker();
+ --NumElements;
+ ++NumTombstones;
+ return true;
+}
+
+const void * const *SmallPtrSetImplBase::FindBucketFor(const void *Ptr) const {
+ unsigned Bucket = DenseMapInfo<void *>::getHashValue(Ptr) & (CurArraySize-1);
+ unsigned ArraySize = CurArraySize;
+ unsigned ProbeAmt = 1;
+ const void *const *Array = CurArray;
+ const void *const *Tombstone = nullptr;
+ while (1) {
+ // If we found an empty bucket, the pointer doesn't exist in the set.
+ // Return a tombstone if we've seen one so far, or the empty bucket if
+ // not.
+ if (LLVM_LIKELY(Array[Bucket] == getEmptyMarker()))
+ return Tombstone ? Tombstone : Array+Bucket;
+
+ // Found Ptr's bucket?
+ if (LLVM_LIKELY(Array[Bucket] == Ptr))
+ return Array+Bucket;
+
+ // If this is a tombstone, remember it. If Ptr ends up not in the set, we
+ // prefer to return it than something that would require more probing.
+ if (Array[Bucket] == getTombstoneMarker() && !Tombstone)
+ Tombstone = Array+Bucket; // Remember the first tombstone found.
+
+ // It's a hash collision or a tombstone. Reprobe.
+ Bucket = (Bucket + ProbeAmt++) & (ArraySize-1);
+ }
+}
+
+/// Grow - Allocate a larger backing store for the buckets and move it over.
+///
+void SmallPtrSetImplBase::Grow(unsigned NewSize) {
+ // Allocate at twice as many buckets, but at least 128.
+ unsigned OldSize = CurArraySize;
+
+ const void **OldBuckets = CurArray;
+ bool WasSmall = isSmall();
+
+ // Install the new array. Clear all the buckets to empty.
+ CurArray = (const void**)malloc(sizeof(void*) * NewSize);
+ assert(CurArray && "Failed to allocate memory?");
+ CurArraySize = NewSize;
+ memset(CurArray, -1, NewSize*sizeof(void*));
+
+ // Copy over all the elements.
+ if (WasSmall) {
+ // Small sets store their elements in order.
+ for (const void **BucketPtr = OldBuckets, **E = OldBuckets+NumElements;
+ BucketPtr != E; ++BucketPtr) {
+ const void *Elt = *BucketPtr;
+ *const_cast<void**>(FindBucketFor(Elt)) = const_cast<void*>(Elt);
+ }
+ } else {
+ // Copy over all valid entries.
+ for (const void **BucketPtr = OldBuckets, **E = OldBuckets+OldSize;
+ BucketPtr != E; ++BucketPtr) {
+ // Copy over the element if it is valid.
+ const void *Elt = *BucketPtr;
+ if (Elt != getTombstoneMarker() && Elt != getEmptyMarker())
+ *const_cast<void**>(FindBucketFor(Elt)) = const_cast<void*>(Elt);
+ }
+
+ free(OldBuckets);
+ NumTombstones = 0;
+ }
+}
+
+SmallPtrSetImplBase::SmallPtrSetImplBase(const void **SmallStorage,
+ const SmallPtrSetImplBase& that) {
+ SmallArray = SmallStorage;
+
+ // If we're becoming small, prepare to insert into our stack space
+ if (that.isSmall()) {
+ CurArray = SmallArray;
+ // Otherwise, allocate new heap space (unless we were the same size)
+ } else {
+ CurArray = (const void**)malloc(sizeof(void*) * that.CurArraySize);
+ assert(CurArray && "Failed to allocate memory?");
+ }
+
+ // Copy over the new array size
+ CurArraySize = that.CurArraySize;
+
+ // Copy over the contents from the other set
+ memcpy(CurArray, that.CurArray, sizeof(void*)*CurArraySize);
+
+ NumElements = that.NumElements;
+ NumTombstones = that.NumTombstones;
+}
+
+SmallPtrSetImplBase::SmallPtrSetImplBase(const void **SmallStorage,
+ unsigned SmallSize,
+ SmallPtrSetImplBase &&that) {
+ SmallArray = SmallStorage;
+
+ // Copy over the basic members.
+ CurArraySize = that.CurArraySize;
+ NumElements = that.NumElements;
+ NumTombstones = that.NumTombstones;
+
+ // When small, just copy into our small buffer.
+ if (that.isSmall()) {
+ CurArray = SmallArray;
+ memcpy(CurArray, that.CurArray, sizeof(void *) * CurArraySize);
+ } else {
+ // Otherwise, we steal the large memory allocation and no copy is needed.
+ CurArray = that.CurArray;
+ that.CurArray = that.SmallArray;
+ }
+
+ // Make the "that" object small and empty.
+ that.CurArraySize = SmallSize;
+ assert(that.CurArray == that.SmallArray);
+ that.NumElements = 0;
+ that.NumTombstones = 0;
+}
+
+/// CopyFrom - implement operator= from a smallptrset that has the same pointer
+/// type, but may have a different small size.
+void SmallPtrSetImplBase::CopyFrom(const SmallPtrSetImplBase &RHS) {
+ assert(&RHS != this && "Self-copy should be handled by the caller.");
+
+ if (isSmall() && RHS.isSmall())
+ assert(CurArraySize == RHS.CurArraySize &&
+ "Cannot assign sets with different small sizes");
+
+ // If we're becoming small, prepare to insert into our stack space
+ if (RHS.isSmall()) {
+ if (!isSmall())
+ free(CurArray);
+ CurArray = SmallArray;
+ // Otherwise, allocate new heap space (unless we were the same size)
+ } else if (CurArraySize != RHS.CurArraySize) {
+ if (isSmall())
+ CurArray = (const void**)malloc(sizeof(void*) * RHS.CurArraySize);
+ else {
+ const void **T = (const void**)realloc(CurArray,
+ sizeof(void*) * RHS.CurArraySize);
+ if (!T)
+ free(CurArray);
+ CurArray = T;
+ }
+ assert(CurArray && "Failed to allocate memory?");
+ }
+
+ // Copy over the new array size
+ CurArraySize = RHS.CurArraySize;
+
+ // Copy over the contents from the other set
+ memcpy(CurArray, RHS.CurArray, sizeof(void*)*CurArraySize);
+
+ NumElements = RHS.NumElements;
+ NumTombstones = RHS.NumTombstones;
+}
+
+void SmallPtrSetImplBase::MoveFrom(unsigned SmallSize,
+ SmallPtrSetImplBase &&RHS) {
+ assert(&RHS != this && "Self-move should be handled by the caller.");
+
+ if (!isSmall())
+ free(CurArray);
+
+ if (RHS.isSmall()) {
+ // Copy a small RHS rather than moving.
+ CurArray = SmallArray;
+ memcpy(CurArray, RHS.CurArray, sizeof(void*)*RHS.CurArraySize);
+ } else {
+ CurArray = RHS.CurArray;
+ RHS.CurArray = RHS.SmallArray;
+ }
+
+ // Copy the rest of the trivial members.
+ CurArraySize = RHS.CurArraySize;
+ NumElements = RHS.NumElements;
+ NumTombstones = RHS.NumTombstones;
+
+ // Make the RHS small and empty.
+ RHS.CurArraySize = SmallSize;
+ assert(RHS.CurArray == RHS.SmallArray);
+ RHS.NumElements = 0;
+ RHS.NumTombstones = 0;
+}
+
+void SmallPtrSetImplBase::swap(SmallPtrSetImplBase &RHS) {
+ if (this == &RHS) return;
+
+ // We can only avoid copying elements if neither set is small.
+ if (!this->isSmall() && !RHS.isSmall()) {
+ std::swap(this->CurArray, RHS.CurArray);
+ std::swap(this->CurArraySize, RHS.CurArraySize);
+ std::swap(this->NumElements, RHS.NumElements);
+ std::swap(this->NumTombstones, RHS.NumTombstones);
+ return;
+ }
+
+ // FIXME: From here on we assume that both sets have the same small size.
+
+ // If only RHS is small, copy the small elements into LHS and move the pointer
+ // from LHS to RHS.
+ if (!this->isSmall() && RHS.isSmall()) {
+ std::copy(RHS.SmallArray, RHS.SmallArray+RHS.CurArraySize,
+ this->SmallArray);
+ std::swap(this->NumElements, RHS.NumElements);
+ std::swap(this->CurArraySize, RHS.CurArraySize);
+ RHS.CurArray = this->CurArray;
+ RHS.NumTombstones = this->NumTombstones;
+ this->CurArray = this->SmallArray;
+ this->NumTombstones = 0;
+ return;
+ }
+
+ // If only LHS is small, copy the small elements into RHS and move the pointer
+ // from RHS to LHS.
+ if (this->isSmall() && !RHS.isSmall()) {
+ std::copy(this->SmallArray, this->SmallArray+this->CurArraySize,
+ RHS.SmallArray);
+ std::swap(RHS.NumElements, this->NumElements);
+ std::swap(RHS.CurArraySize, this->CurArraySize);
+ this->CurArray = RHS.CurArray;
+ this->NumTombstones = RHS.NumTombstones;
+ RHS.CurArray = RHS.SmallArray;
+ RHS.NumTombstones = 0;
+ return;
+ }
+
+ // Both a small, just swap the small elements.
+ assert(this->isSmall() && RHS.isSmall());
+ assert(this->CurArraySize == RHS.CurArraySize);
+ std::swap_ranges(this->SmallArray, this->SmallArray+this->CurArraySize,
+ RHS.SmallArray);
+ std::swap(this->NumElements, RHS.NumElements);
+}
+
+SmallPtrSetImplBase::~SmallPtrSetImplBase() {
+ if (!isSmall())
+ free(CurArray);
+}
diff --git a/contrib/llvm/lib/Support/SmallVector.cpp b/contrib/llvm/lib/Support/SmallVector.cpp
new file mode 100644
index 000000000000..b931505bd6a1
--- /dev/null
+++ b/contrib/llvm/lib/Support/SmallVector.cpp
@@ -0,0 +1,41 @@
+//===- llvm/ADT/SmallVector.cpp - 'Normally small' vectors ----------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the SmallVector class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/SmallVector.h"
+using namespace llvm;
+
+/// grow_pod - This is an implementation of the grow() method which only works
+/// on POD-like datatypes and is out of line to reduce code duplication.
+void SmallVectorBase::grow_pod(void *FirstEl, size_t MinSizeInBytes,
+ size_t TSize) {
+ size_t CurSizeBytes = size_in_bytes();
+ size_t NewCapacityInBytes = 2 * capacity_in_bytes() + TSize; // Always grow.
+ if (NewCapacityInBytes < MinSizeInBytes)
+ NewCapacityInBytes = MinSizeInBytes;
+
+ void *NewElts;
+ if (BeginX == FirstEl) {
+ NewElts = malloc(NewCapacityInBytes);
+
+ // Copy the elements over. No need to run dtors on PODs.
+ memcpy(NewElts, this->BeginX, CurSizeBytes);
+ } else {
+ // If this wasn't grown from the inline copy, grow the allocated space.
+ NewElts = realloc(this->BeginX, NewCapacityInBytes);
+ }
+ assert(NewElts && "Out of memory");
+
+ this->EndX = (char*)NewElts+CurSizeBytes;
+ this->BeginX = NewElts;
+ this->CapacityX = (char*)this->BeginX + NewCapacityInBytes;
+}
diff --git a/contrib/llvm/lib/Support/SourceMgr.cpp b/contrib/llvm/lib/Support/SourceMgr.cpp
new file mode 100644
index 000000000000..6d44a4d51f60
--- /dev/null
+++ b/contrib/llvm/lib/Support/SourceMgr.cpp
@@ -0,0 +1,483 @@
+//===- SourceMgr.cpp - Manager for Simple Source Buffers & Diagnostics ----===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the SourceMgr class. This class is used as a simple
+// substrate for diagnostics, #include handling, and other low level things for
+// simple parsers.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/SourceMgr.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Support/Locale.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace llvm;
+
+static const size_t TabStop = 8;
+
+namespace {
+ struct LineNoCacheTy {
+ unsigned LastQueryBufferID;
+ const char *LastQuery;
+ unsigned LineNoOfQuery;
+ };
+}
+
+static LineNoCacheTy *getCache(void *Ptr) {
+ return (LineNoCacheTy*)Ptr;
+}
+
+
+SourceMgr::~SourceMgr() {
+ // Delete the line # cache if allocated.
+ if (LineNoCacheTy *Cache = getCache(LineNoCache))
+ delete Cache;
+}
+
+unsigned SourceMgr::AddIncludeFile(const std::string &Filename,
+ SMLoc IncludeLoc,
+ std::string &IncludedFile) {
+ IncludedFile = Filename;
+ ErrorOr<std::unique_ptr<MemoryBuffer>> NewBufOrErr =
+ MemoryBuffer::getFile(IncludedFile);
+
+ // If the file didn't exist directly, see if it's in an include path.
+ for (unsigned i = 0, e = IncludeDirectories.size(); i != e && !NewBufOrErr;
+ ++i) {
+ IncludedFile =
+ IncludeDirectories[i] + sys::path::get_separator().data() + Filename;
+ NewBufOrErr = MemoryBuffer::getFile(IncludedFile);
+ }
+
+ if (!NewBufOrErr)
+ return 0;
+
+ return AddNewSourceBuffer(std::move(*NewBufOrErr), IncludeLoc);
+}
+
+unsigned SourceMgr::FindBufferContainingLoc(SMLoc Loc) const {
+ for (unsigned i = 0, e = Buffers.size(); i != e; ++i)
+ if (Loc.getPointer() >= Buffers[i].Buffer->getBufferStart() &&
+ // Use <= here so that a pointer to the null at the end of the buffer
+ // is included as part of the buffer.
+ Loc.getPointer() <= Buffers[i].Buffer->getBufferEnd())
+ return i + 1;
+ return 0;
+}
+
+std::pair<unsigned, unsigned>
+SourceMgr::getLineAndColumn(SMLoc Loc, unsigned BufferID) const {
+ if (!BufferID)
+ BufferID = FindBufferContainingLoc(Loc);
+ assert(BufferID && "Invalid Location!");
+
+ const MemoryBuffer *Buff = getMemoryBuffer(BufferID);
+
+ // Count the number of \n's between the start of the file and the specified
+ // location.
+ unsigned LineNo = 1;
+
+ const char *BufStart = Buff->getBufferStart();
+ const char *Ptr = BufStart;
+
+ // If we have a line number cache, and if the query is to a later point in the
+ // same file, start searching from the last query location. This optimizes
+ // for the case when multiple diagnostics come out of one file in order.
+ if (LineNoCacheTy *Cache = getCache(LineNoCache))
+ if (Cache->LastQueryBufferID == BufferID &&
+ Cache->LastQuery <= Loc.getPointer()) {
+ Ptr = Cache->LastQuery;
+ LineNo = Cache->LineNoOfQuery;
+ }
+
+ // Scan for the location being queried, keeping track of the number of lines
+ // we see.
+ for (; SMLoc::getFromPointer(Ptr) != Loc; ++Ptr)
+ if (*Ptr == '\n') ++LineNo;
+
+ // Allocate the line number cache if it doesn't exist.
+ if (!LineNoCache)
+ LineNoCache = new LineNoCacheTy();
+
+ // Update the line # cache.
+ LineNoCacheTy &Cache = *getCache(LineNoCache);
+ Cache.LastQueryBufferID = BufferID;
+ Cache.LastQuery = Ptr;
+ Cache.LineNoOfQuery = LineNo;
+
+ size_t NewlineOffs = StringRef(BufStart, Ptr-BufStart).find_last_of("\n\r");
+ if (NewlineOffs == StringRef::npos) NewlineOffs = ~(size_t)0;
+ return std::make_pair(LineNo, Ptr-BufStart-NewlineOffs);
+}
+
+void SourceMgr::PrintIncludeStack(SMLoc IncludeLoc, raw_ostream &OS) const {
+ if (IncludeLoc == SMLoc()) return; // Top of stack.
+
+ unsigned CurBuf = FindBufferContainingLoc(IncludeLoc);
+ assert(CurBuf && "Invalid or unspecified location!");
+
+ PrintIncludeStack(getBufferInfo(CurBuf).IncludeLoc, OS);
+
+ OS << "Included from "
+ << getBufferInfo(CurBuf).Buffer->getBufferIdentifier()
+ << ":" << FindLineNumber(IncludeLoc, CurBuf) << ":\n";
+}
+
+
+SMDiagnostic SourceMgr::GetMessage(SMLoc Loc, SourceMgr::DiagKind Kind,
+ const Twine &Msg,
+ ArrayRef<SMRange> Ranges,
+ ArrayRef<SMFixIt> FixIts) const {
+
+ // First thing to do: find the current buffer containing the specified
+ // location to pull out the source line.
+ SmallVector<std::pair<unsigned, unsigned>, 4> ColRanges;
+ std::pair<unsigned, unsigned> LineAndCol;
+ const char *BufferID = "<unknown>";
+ std::string LineStr;
+
+ if (Loc.isValid()) {
+ unsigned CurBuf = FindBufferContainingLoc(Loc);
+ assert(CurBuf && "Invalid or unspecified location!");
+
+ const MemoryBuffer *CurMB = getMemoryBuffer(CurBuf);
+ BufferID = CurMB->getBufferIdentifier();
+
+ // Scan backward to find the start of the line.
+ const char *LineStart = Loc.getPointer();
+ const char *BufStart = CurMB->getBufferStart();
+ while (LineStart != BufStart && LineStart[-1] != '\n' &&
+ LineStart[-1] != '\r')
+ --LineStart;
+
+ // Get the end of the line.
+ const char *LineEnd = Loc.getPointer();
+ const char *BufEnd = CurMB->getBufferEnd();
+ while (LineEnd != BufEnd && LineEnd[0] != '\n' && LineEnd[0] != '\r')
+ ++LineEnd;
+ LineStr = std::string(LineStart, LineEnd);
+
+ // Convert any ranges to column ranges that only intersect the line of the
+ // location.
+ for (unsigned i = 0, e = Ranges.size(); i != e; ++i) {
+ SMRange R = Ranges[i];
+ if (!R.isValid()) continue;
+
+ // If the line doesn't contain any part of the range, then ignore it.
+ if (R.Start.getPointer() > LineEnd || R.End.getPointer() < LineStart)
+ continue;
+
+ // Ignore pieces of the range that go onto other lines.
+ if (R.Start.getPointer() < LineStart)
+ R.Start = SMLoc::getFromPointer(LineStart);
+ if (R.End.getPointer() > LineEnd)
+ R.End = SMLoc::getFromPointer(LineEnd);
+
+ // Translate from SMLoc ranges to column ranges.
+ // FIXME: Handle multibyte characters.
+ ColRanges.push_back(std::make_pair(R.Start.getPointer()-LineStart,
+ R.End.getPointer()-LineStart));
+ }
+
+ LineAndCol = getLineAndColumn(Loc, CurBuf);
+ }
+
+ return SMDiagnostic(*this, Loc, BufferID, LineAndCol.first,
+ LineAndCol.second-1, Kind, Msg.str(),
+ LineStr, ColRanges, FixIts);
+}
+
+void SourceMgr::PrintMessage(raw_ostream &OS, const SMDiagnostic &Diagnostic,
+ bool ShowColors) const {
+ // Report the message with the diagnostic handler if present.
+ if (DiagHandler) {
+ DiagHandler(Diagnostic, DiagContext);
+ return;
+ }
+
+ if (Diagnostic.getLoc().isValid()) {
+ unsigned CurBuf = FindBufferContainingLoc(Diagnostic.getLoc());
+ assert(CurBuf && "Invalid or unspecified location!");
+ PrintIncludeStack(getBufferInfo(CurBuf).IncludeLoc, OS);
+ }
+
+ Diagnostic.print(nullptr, OS, ShowColors);
+}
+
+void SourceMgr::PrintMessage(raw_ostream &OS, SMLoc Loc,
+ SourceMgr::DiagKind Kind,
+ const Twine &Msg, ArrayRef<SMRange> Ranges,
+ ArrayRef<SMFixIt> FixIts, bool ShowColors) const {
+ PrintMessage(OS, GetMessage(Loc, Kind, Msg, Ranges, FixIts), ShowColors);
+}
+
+void SourceMgr::PrintMessage(SMLoc Loc, SourceMgr::DiagKind Kind,
+ const Twine &Msg, ArrayRef<SMRange> Ranges,
+ ArrayRef<SMFixIt> FixIts, bool ShowColors) const {
+ PrintMessage(llvm::errs(), Loc, Kind, Msg, Ranges, FixIts, ShowColors);
+}
+
+//===----------------------------------------------------------------------===//
+// SMDiagnostic Implementation
+//===----------------------------------------------------------------------===//
+
+SMDiagnostic::SMDiagnostic(const SourceMgr &sm, SMLoc L, StringRef FN,
+ int Line, int Col, SourceMgr::DiagKind Kind,
+ StringRef Msg, StringRef LineStr,
+ ArrayRef<std::pair<unsigned,unsigned> > Ranges,
+ ArrayRef<SMFixIt> Hints)
+ : SM(&sm), Loc(L), Filename(FN), LineNo(Line), ColumnNo(Col), Kind(Kind),
+ Message(Msg), LineContents(LineStr), Ranges(Ranges.vec()),
+ FixIts(Hints.begin(), Hints.end()) {
+ std::sort(FixIts.begin(), FixIts.end());
+}
+
+static void buildFixItLine(std::string &CaretLine, std::string &FixItLine,
+ ArrayRef<SMFixIt> FixIts, ArrayRef<char> SourceLine){
+ if (FixIts.empty())
+ return;
+
+ const char *LineStart = SourceLine.begin();
+ const char *LineEnd = SourceLine.end();
+
+ size_t PrevHintEndCol = 0;
+
+ for (ArrayRef<SMFixIt>::iterator I = FixIts.begin(), E = FixIts.end();
+ I != E; ++I) {
+ // If the fixit contains a newline or tab, ignore it.
+ if (I->getText().find_first_of("\n\r\t") != StringRef::npos)
+ continue;
+
+ SMRange R = I->getRange();
+
+ // If the line doesn't contain any part of the range, then ignore it.
+ if (R.Start.getPointer() > LineEnd || R.End.getPointer() < LineStart)
+ continue;
+
+ // Translate from SMLoc to column.
+ // Ignore pieces of the range that go onto other lines.
+ // FIXME: Handle multibyte characters in the source line.
+ unsigned FirstCol;
+ if (R.Start.getPointer() < LineStart)
+ FirstCol = 0;
+ else
+ FirstCol = R.Start.getPointer() - LineStart;
+
+ // If we inserted a long previous hint, push this one forwards, and add
+ // an extra space to show that this is not part of the previous
+ // completion. This is sort of the best we can do when two hints appear
+ // to overlap.
+ //
+ // Note that if this hint is located immediately after the previous
+ // hint, no space will be added, since the location is more important.
+ unsigned HintCol = FirstCol;
+ if (HintCol < PrevHintEndCol)
+ HintCol = PrevHintEndCol + 1;
+
+ // FIXME: This assertion is intended to catch unintended use of multibyte
+ // characters in fixits. If we decide to do this, we'll have to track
+ // separate byte widths for the source and fixit lines.
+ assert((size_t)llvm::sys::locale::columnWidth(I->getText()) ==
+ I->getText().size());
+
+ // This relies on one byte per column in our fixit hints.
+ unsigned LastColumnModified = HintCol + I->getText().size();
+ if (LastColumnModified > FixItLine.size())
+ FixItLine.resize(LastColumnModified, ' ');
+
+ std::copy(I->getText().begin(), I->getText().end(),
+ FixItLine.begin() + HintCol);
+
+ PrevHintEndCol = LastColumnModified;
+
+ // For replacements, mark the removal range with '~'.
+ // FIXME: Handle multibyte characters in the source line.
+ unsigned LastCol;
+ if (R.End.getPointer() >= LineEnd)
+ LastCol = LineEnd - LineStart;
+ else
+ LastCol = R.End.getPointer() - LineStart;
+
+ std::fill(&CaretLine[FirstCol], &CaretLine[LastCol], '~');
+ }
+}
+
+static void printSourceLine(raw_ostream &S, StringRef LineContents) {
+ // Print out the source line one character at a time, so we can expand tabs.
+ for (unsigned i = 0, e = LineContents.size(), OutCol = 0; i != e; ++i) {
+ if (LineContents[i] != '\t') {
+ S << LineContents[i];
+ ++OutCol;
+ continue;
+ }
+
+ // If we have a tab, emit at least one space, then round up to 8 columns.
+ do {
+ S << ' ';
+ ++OutCol;
+ } while ((OutCol % TabStop) != 0);
+ }
+ S << '\n';
+}
+
+static bool isNonASCII(char c) {
+ return c & 0x80;
+}
+
+void SMDiagnostic::print(const char *ProgName, raw_ostream &S, bool ShowColors,
+ bool ShowKindLabel) const {
+ // Display colors only if OS supports colors.
+ ShowColors &= S.has_colors();
+
+ if (ShowColors)
+ S.changeColor(raw_ostream::SAVEDCOLOR, true);
+
+ if (ProgName && ProgName[0])
+ S << ProgName << ": ";
+
+ if (!Filename.empty()) {
+ if (Filename == "-")
+ S << "<stdin>";
+ else
+ S << Filename;
+
+ if (LineNo != -1) {
+ S << ':' << LineNo;
+ if (ColumnNo != -1)
+ S << ':' << (ColumnNo+1);
+ }
+ S << ": ";
+ }
+
+ if (ShowKindLabel) {
+ switch (Kind) {
+ case SourceMgr::DK_Error:
+ if (ShowColors)
+ S.changeColor(raw_ostream::RED, true);
+ S << "error: ";
+ break;
+ case SourceMgr::DK_Warning:
+ if (ShowColors)
+ S.changeColor(raw_ostream::MAGENTA, true);
+ S << "warning: ";
+ break;
+ case SourceMgr::DK_Note:
+ if (ShowColors)
+ S.changeColor(raw_ostream::BLACK, true);
+ S << "note: ";
+ break;
+ }
+
+ if (ShowColors) {
+ S.resetColor();
+ S.changeColor(raw_ostream::SAVEDCOLOR, true);
+ }
+ }
+
+ S << Message << '\n';
+
+ if (ShowColors)
+ S.resetColor();
+
+ if (LineNo == -1 || ColumnNo == -1)
+ return;
+
+ // FIXME: If there are multibyte or multi-column characters in the source, all
+ // our ranges will be wrong. To do this properly, we'll need a byte-to-column
+ // map like Clang's TextDiagnostic. For now, we'll just handle tabs by
+ // expanding them later, and bail out rather than show incorrect ranges and
+ // misaligned fixits for any other odd characters.
+ if (std::find_if(LineContents.begin(), LineContents.end(), isNonASCII) !=
+ LineContents.end()) {
+ printSourceLine(S, LineContents);
+ return;
+ }
+ size_t NumColumns = LineContents.size();
+
+ // Build the line with the caret and ranges.
+ std::string CaretLine(NumColumns+1, ' ');
+
+ // Expand any ranges.
+ for (unsigned r = 0, e = Ranges.size(); r != e; ++r) {
+ std::pair<unsigned, unsigned> R = Ranges[r];
+ std::fill(&CaretLine[R.first],
+ &CaretLine[std::min((size_t)R.second, CaretLine.size())],
+ '~');
+ }
+
+ // Add any fix-its.
+ // FIXME: Find the beginning of the line properly for multibyte characters.
+ std::string FixItInsertionLine;
+ buildFixItLine(CaretLine, FixItInsertionLine, FixIts,
+ makeArrayRef(Loc.getPointer() - ColumnNo,
+ LineContents.size()));
+
+ // Finally, plop on the caret.
+ if (unsigned(ColumnNo) <= NumColumns)
+ CaretLine[ColumnNo] = '^';
+ else
+ CaretLine[NumColumns] = '^';
+
+ // ... and remove trailing whitespace so the output doesn't wrap for it. We
+ // know that the line isn't completely empty because it has the caret in it at
+ // least.
+ CaretLine.erase(CaretLine.find_last_not_of(' ')+1);
+
+ printSourceLine(S, LineContents);
+
+ if (ShowColors)
+ S.changeColor(raw_ostream::GREEN, true);
+
+ // Print out the caret line, matching tabs in the source line.
+ for (unsigned i = 0, e = CaretLine.size(), OutCol = 0; i != e; ++i) {
+ if (i >= LineContents.size() || LineContents[i] != '\t') {
+ S << CaretLine[i];
+ ++OutCol;
+ continue;
+ }
+
+ // Okay, we have a tab. Insert the appropriate number of characters.
+ do {
+ S << CaretLine[i];
+ ++OutCol;
+ } while ((OutCol % TabStop) != 0);
+ }
+ S << '\n';
+
+ if (ShowColors)
+ S.resetColor();
+
+ // Print out the replacement line, matching tabs in the source line.
+ if (FixItInsertionLine.empty())
+ return;
+
+ for (size_t i = 0, e = FixItInsertionLine.size(), OutCol = 0; i < e; ++i) {
+ if (i >= LineContents.size() || LineContents[i] != '\t') {
+ S << FixItInsertionLine[i];
+ ++OutCol;
+ continue;
+ }
+
+ // Okay, we have a tab. Insert the appropriate number of characters.
+ do {
+ S << FixItInsertionLine[i];
+ // FIXME: This is trying not to break up replacements, but then to re-sync
+ // with the tabs between replacements. This will fail, though, if two
+ // fix-it replacements are exactly adjacent, or if a fix-it contains a
+ // space. Really we should be precomputing column widths, which we'll
+ // need anyway for multibyte chars.
+ if (FixItInsertionLine[i] != ' ')
+ ++i;
+ ++OutCol;
+ } while (((OutCol % TabStop) != 0) && i != e);
+ }
+ S << '\n';
+}
diff --git a/contrib/llvm/lib/Support/SpecialCaseList.cpp b/contrib/llvm/lib/Support/SpecialCaseList.cpp
new file mode 100644
index 000000000000..ea417c41c0a7
--- /dev/null
+++ b/contrib/llvm/lib/Support/SpecialCaseList.cpp
@@ -0,0 +1,168 @@
+//===-- SpecialCaseList.cpp - special case list for sanitizers ------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This is a utility class for instrumentation passes (like AddressSanitizer
+// or ThreadSanitizer) to avoid instrumenting some functions or global
+// variables, or to instrument some functions or global variables in a specific
+// way, based on a user-supplied list.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/SpecialCaseList.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringSet.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Regex.h"
+#include <string>
+#include <system_error>
+#include <utility>
+
+namespace llvm {
+
+/// Represents a set of regular expressions. Regular expressions which are
+/// "literal" (i.e. no regex metacharacters) are stored in Strings, while all
+/// others are represented as a single pipe-separated regex in RegEx. The
+/// reason for doing so is efficiency; StringSet is much faster at matching
+/// literal strings than Regex.
+struct SpecialCaseList::Entry {
+ Entry() {}
+ Entry(Entry &&Other)
+ : Strings(std::move(Other.Strings)), RegEx(std::move(Other.RegEx)) {}
+
+ StringSet<> Strings;
+ std::unique_ptr<Regex> RegEx;
+
+ bool match(StringRef Query) const {
+ return Strings.count(Query) || (RegEx && RegEx->match(Query));
+ }
+};
+
+SpecialCaseList::SpecialCaseList() : Entries(), Regexps(), IsCompiled(false) {}
+
+std::unique_ptr<SpecialCaseList>
+SpecialCaseList::create(const std::vector<std::string> &Paths,
+ std::string &Error) {
+ std::unique_ptr<SpecialCaseList> SCL(new SpecialCaseList());
+ for (auto Path : Paths) {
+ ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
+ MemoryBuffer::getFile(Path);
+ if (std::error_code EC = FileOrErr.getError()) {
+ Error = (Twine("can't open file '") + Path + "': " + EC.message()).str();
+ return nullptr;
+ }
+ std::string ParseError;
+ if (!SCL->parse(FileOrErr.get().get(), ParseError)) {
+ Error = (Twine("error parsing file '") + Path + "': " + ParseError).str();
+ return nullptr;
+ }
+ }
+ SCL->compile();
+ return SCL;
+}
+
+std::unique_ptr<SpecialCaseList> SpecialCaseList::create(const MemoryBuffer *MB,
+ std::string &Error) {
+ std::unique_ptr<SpecialCaseList> SCL(new SpecialCaseList());
+ if (!SCL->parse(MB, Error))
+ return nullptr;
+ SCL->compile();
+ return SCL;
+}
+
+std::unique_ptr<SpecialCaseList>
+SpecialCaseList::createOrDie(const std::vector<std::string> &Paths) {
+ std::string Error;
+ if (auto SCL = create(Paths, Error))
+ return SCL;
+ report_fatal_error(Error);
+}
+
+bool SpecialCaseList::parse(const MemoryBuffer *MB, std::string &Error) {
+ // Iterate through each line in the blacklist file.
+ SmallVector<StringRef, 16> Lines;
+ SplitString(MB->getBuffer(), Lines, "\n\r");
+ int LineNo = 1;
+ for (auto I = Lines.begin(), E = Lines.end(); I != E; ++I, ++LineNo) {
+ // Ignore empty lines and lines starting with "#"
+ if (I->empty() || I->startswith("#"))
+ continue;
+ // Get our prefix and unparsed regexp.
+ std::pair<StringRef, StringRef> SplitLine = I->split(":");
+ StringRef Prefix = SplitLine.first;
+ if (SplitLine.second.empty()) {
+ // Missing ':' in the line.
+ Error = (Twine("malformed line ") + Twine(LineNo) + ": '" +
+ SplitLine.first + "'").str();
+ return false;
+ }
+
+ std::pair<StringRef, StringRef> SplitRegexp = SplitLine.second.split("=");
+ std::string Regexp = SplitRegexp.first;
+ StringRef Category = SplitRegexp.second;
+
+ // See if we can store Regexp in Strings.
+ if (Regex::isLiteralERE(Regexp)) {
+ Entries[Prefix][Category].Strings.insert(Regexp);
+ continue;
+ }
+
+ // Replace * with .*
+ for (size_t pos = 0; (pos = Regexp.find("*", pos)) != std::string::npos;
+ pos += strlen(".*")) {
+ Regexp.replace(pos, strlen("*"), ".*");
+ }
+
+ // Check that the regexp is valid.
+ Regex CheckRE(Regexp);
+ std::string REError;
+ if (!CheckRE.isValid(REError)) {
+ Error = (Twine("malformed regex in line ") + Twine(LineNo) + ": '" +
+ SplitLine.second + "': " + REError).str();
+ return false;
+ }
+
+ // Add this regexp into the proper group by its prefix.
+ if (!Regexps[Prefix][Category].empty())
+ Regexps[Prefix][Category] += "|";
+ Regexps[Prefix][Category] += "^" + Regexp + "$";
+ }
+ return true;
+}
+
+void SpecialCaseList::compile() {
+ assert(!IsCompiled && "compile() should only be called once");
+ // Iterate through each of the prefixes, and create Regexs for them.
+ for (StringMap<StringMap<std::string>>::const_iterator I = Regexps.begin(),
+ E = Regexps.end();
+ I != E; ++I) {
+ for (StringMap<std::string>::const_iterator II = I->second.begin(),
+ IE = I->second.end();
+ II != IE; ++II) {
+ Entries[I->getKey()][II->getKey()].RegEx.reset(new Regex(II->getValue()));
+ }
+ }
+ Regexps.clear();
+ IsCompiled = true;
+}
+
+SpecialCaseList::~SpecialCaseList() {}
+
+bool SpecialCaseList::inSection(StringRef Section, StringRef Query,
+ StringRef Category) const {
+ assert(IsCompiled && "SpecialCaseList::compile() was not called!");
+ StringMap<StringMap<Entry> >::const_iterator I = Entries.find(Section);
+ if (I == Entries.end()) return false;
+ StringMap<Entry>::const_iterator II = I->second.find(Category);
+ if (II == I->second.end()) return false;
+
+ return II->getValue().match(Query);
+}
+
+} // namespace llvm
diff --git a/contrib/llvm/lib/Support/Statistic.cpp b/contrib/llvm/lib/Support/Statistic.cpp
new file mode 100644
index 000000000000..90f5fdb019e7
--- /dev/null
+++ b/contrib/llvm/lib/Support/Statistic.cpp
@@ -0,0 +1,163 @@
+//===-- Statistic.cpp - Easy way to expose stats information --------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the 'Statistic' class, which is designed to be an easy
+// way to expose various success metrics from passes. These statistics are
+// printed at the end of a run, when the -stats command line option is enabled
+// 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 NumInstEliminated("GCSE", "Number of instructions killed");
+//
+// Later, in the code: ++NumInstEliminated;
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/Mutex.h"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <cstring>
+using namespace llvm;
+
+// CreateInfoOutputFile - Return a file stream to print our output on.
+namespace llvm { extern raw_ostream *CreateInfoOutputFile(); }
+
+/// -stats - Command line option to cause transformations to emit stats about
+/// what they did.
+///
+static cl::opt<bool>
+Enabled(
+ "stats",
+ cl::desc("Enable statistics output from program (available with Asserts)"));
+
+
+namespace {
+/// StatisticInfo - This class is used in a ManagedStatic so that it is created
+/// on demand (when the first statistic is bumped) and destroyed only when
+/// llvm_shutdown is called. We print statistics from the destructor.
+class StatisticInfo {
+ std::vector<const Statistic*> Stats;
+ friend void llvm::PrintStatistics();
+ friend void llvm::PrintStatistics(raw_ostream &OS);
+public:
+ ~StatisticInfo();
+
+ void addStatistic(const Statistic *S) {
+ Stats.push_back(S);
+ }
+};
+} // namespace
+
+static ManagedStatic<StatisticInfo> StatInfo;
+static ManagedStatic<sys::SmartMutex<true> > StatLock;
+
+/// RegisterStatistic - The first time a statistic is bumped, this method is
+/// called.
+void Statistic::RegisterStatistic() {
+ // If stats are enabled, inform StatInfo that this statistic should be
+ // printed.
+ sys::SmartScopedLock<true> Writer(*StatLock);
+ if (!Initialized) {
+ if (Enabled)
+ StatInfo->addStatistic(this);
+
+ TsanHappensBefore(this);
+ sys::MemoryFence();
+ // Remember we have been registered.
+ TsanIgnoreWritesBegin();
+ Initialized = true;
+ TsanIgnoreWritesEnd();
+ }
+}
+
+// Print information when destroyed, iff command line option is specified.
+StatisticInfo::~StatisticInfo() {
+ llvm::PrintStatistics();
+}
+
+void llvm::EnableStatistics() {
+ Enabled.setValue(true);
+}
+
+bool llvm::AreStatisticsEnabled() {
+ return Enabled;
+}
+
+void llvm::PrintStatistics(raw_ostream &OS) {
+ StatisticInfo &Stats = *StatInfo;
+
+ // Figure out how long the biggest Value and Name fields are.
+ unsigned MaxNameLen = 0, MaxValLen = 0;
+ for (size_t i = 0, e = Stats.Stats.size(); i != e; ++i) {
+ MaxValLen = std::max(MaxValLen,
+ (unsigned)utostr(Stats.Stats[i]->getValue()).size());
+ MaxNameLen = std::max(MaxNameLen,
+ (unsigned)std::strlen(Stats.Stats[i]->getName()));
+ }
+
+ // Sort the fields by name.
+ std::stable_sort(Stats.Stats.begin(), Stats.Stats.end(),
+ [](const Statistic *LHS, const Statistic *RHS) {
+ if (int Cmp = std::strcmp(LHS->getName(), RHS->getName()))
+ return Cmp < 0;
+
+ // Secondary key is the description.
+ return std::strcmp(LHS->getDesc(), RHS->getDesc()) < 0;
+ });
+
+ // Print out the statistics header...
+ OS << "===" << std::string(73, '-') << "===\n"
+ << " ... Statistics Collected ...\n"
+ << "===" << std::string(73, '-') << "===\n\n";
+
+ // Print all of the statistics.
+ for (size_t i = 0, e = Stats.Stats.size(); i != e; ++i)
+ OS << format("%*u %-*s - %s\n",
+ MaxValLen, Stats.Stats[i]->getValue(),
+ MaxNameLen, Stats.Stats[i]->getName(),
+ Stats.Stats[i]->getDesc());
+
+ OS << '\n'; // Flush the output stream.
+ OS.flush();
+
+}
+
+void llvm::PrintStatistics() {
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_STATS)
+ StatisticInfo &Stats = *StatInfo;
+
+ // Statistics not enabled?
+ if (Stats.Stats.empty()) return;
+
+ // Get the stream to write to.
+ raw_ostream &OutStream = *CreateInfoOutputFile();
+ PrintStatistics(OutStream);
+ delete &OutStream; // Close the file.
+#else
+ // Check if the -stats option is set instead of checking
+ // !Stats.Stats.empty(). In release builds, Statistics operators
+ // do nothing, so stats are never Registered.
+ if (Enabled) {
+ // Get the stream to write to.
+ raw_ostream &OutStream = *CreateInfoOutputFile();
+ OutStream << "Statistics are disabled. "
+ << "Build with asserts or with -DLLVM_ENABLE_STATS\n";
+ OutStream.flush();
+ delete &OutStream; // Close the file.
+ }
+#endif
+}
diff --git a/contrib/llvm/lib/Support/StreamingMemoryObject.cpp b/contrib/llvm/lib/Support/StreamingMemoryObject.cpp
new file mode 100644
index 000000000000..891aa665e2c5
--- /dev/null
+++ b/contrib/llvm/lib/Support/StreamingMemoryObject.cpp
@@ -0,0 +1,132 @@
+//===- StreamingMemoryObject.cpp - Streamable data interface -------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/StreamingMemoryObject.h"
+#include <cassert>
+#include <cstddef>
+#include <cstring>
+using namespace llvm;
+
+namespace {
+
+class RawMemoryObject : public MemoryObject {
+public:
+ RawMemoryObject(const unsigned char *Start, const unsigned char *End) :
+ FirstChar(Start), LastChar(End) {
+ assert(LastChar >= FirstChar && "Invalid start/end range");
+ }
+
+ uint64_t getExtent() const override {
+ return LastChar - FirstChar;
+ }
+ uint64_t readBytes(uint8_t *Buf, uint64_t Size,
+ uint64_t Address) const override;
+ const uint8_t *getPointer(uint64_t address, uint64_t size) const override;
+ bool isValidAddress(uint64_t address) const override {
+ return validAddress(address);
+ }
+
+private:
+ const uint8_t* const FirstChar;
+ const uint8_t* const LastChar;
+
+ // These are implemented as inline functions here to avoid multiple virtual
+ // calls per public function
+ bool validAddress(uint64_t address) const {
+ return static_cast<std::ptrdiff_t>(address) < LastChar - FirstChar;
+ }
+
+ RawMemoryObject(const RawMemoryObject&) = delete;
+ void operator=(const RawMemoryObject&) = delete;
+};
+
+uint64_t RawMemoryObject::readBytes(uint8_t *Buf, uint64_t Size,
+ uint64_t Address) const {
+ uint64_t BufferSize = LastChar - FirstChar;
+ if (Address >= BufferSize)
+ return 0;
+
+ uint64_t End = Address + Size;
+ if (End > BufferSize)
+ End = BufferSize;
+
+ assert(static_cast<int64_t>(End - Address) >= 0);
+ Size = End - Address;
+ memcpy(Buf, Address + FirstChar, Size);
+ return Size;
+}
+
+const uint8_t *RawMemoryObject::getPointer(uint64_t address,
+ uint64_t size) const {
+ return FirstChar + address;
+}
+} // anonymous namespace
+
+namespace llvm {
+// If the bitcode has a header, then its size is known, and we don't have to
+// block until we actually want to read it.
+bool StreamingMemoryObject::isValidAddress(uint64_t address) const {
+ if (ObjectSize && address < ObjectSize) return true;
+ return fetchToPos(address);
+}
+
+uint64_t StreamingMemoryObject::getExtent() const {
+ if (ObjectSize) return ObjectSize;
+ size_t pos = BytesRead + kChunkSize;
+ // keep fetching until we run out of bytes
+ while (fetchToPos(pos)) pos += kChunkSize;
+ return ObjectSize;
+}
+
+uint64_t StreamingMemoryObject::readBytes(uint8_t *Buf, uint64_t Size,
+ uint64_t Address) const {
+ fetchToPos(Address + Size - 1);
+ // Note: For wrapped bitcode files will set ObjectSize after the
+ // first call to fetchToPos. In such cases, ObjectSize can be
+ // smaller than BytesRead.
+ size_t MaxAddress =
+ (ObjectSize && ObjectSize < BytesRead) ? ObjectSize : BytesRead;
+ if (Address >= MaxAddress)
+ return 0;
+
+ uint64_t End = Address + Size;
+ if (End > MaxAddress)
+ End = MaxAddress;
+ assert(End >= Address);
+ Size = End - Address;
+ memcpy(Buf, &Bytes[Address + BytesSkipped], Size);
+ return Size;
+}
+
+bool StreamingMemoryObject::dropLeadingBytes(size_t s) {
+ if (BytesRead < s) return true;
+ BytesSkipped = s;
+ BytesRead -= s;
+ return false;
+}
+
+void StreamingMemoryObject::setKnownObjectSize(size_t size) {
+ ObjectSize = size;
+ Bytes.reserve(size);
+ if (ObjectSize <= BytesRead)
+ EOFReached = true;
+}
+
+MemoryObject *getNonStreamedMemoryObject(const unsigned char *Start,
+ const unsigned char *End) {
+ return new RawMemoryObject(Start, End);
+}
+
+StreamingMemoryObject::StreamingMemoryObject(
+ std::unique_ptr<DataStreamer> Streamer)
+ : Bytes(kChunkSize), Streamer(std::move(Streamer)), BytesRead(0),
+ BytesSkipped(0), ObjectSize(0), EOFReached(false) {
+ BytesRead = this->Streamer->GetBytes(&Bytes[0], kChunkSize);
+}
+} // namespace llvm
diff --git a/contrib/llvm/lib/Support/StringExtras.cpp b/contrib/llvm/lib/Support/StringExtras.cpp
new file mode 100644
index 000000000000..3e2420f67760
--- /dev/null
+++ b/contrib/llvm/lib/Support/StringExtras.cpp
@@ -0,0 +1,58 @@
+//===-- StringExtras.cpp - Implement the StringExtras header --------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the StringExtras.h header
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringExtras.h"
+using namespace llvm;
+
+/// StrInStrNoCase - Portable version of strcasestr. Locates the first
+/// occurrence of string 's1' in string 's2', ignoring case. Returns
+/// the offset of s2 in s1 or npos if s2 cannot be found.
+StringRef::size_type llvm::StrInStrNoCase(StringRef s1, StringRef s2) {
+ size_t N = s2.size(), M = s1.size();
+ if (N > M)
+ return StringRef::npos;
+ for (size_t i = 0, e = M - N + 1; i != e; ++i)
+ if (s1.substr(i, N).equals_lower(s2))
+ return i;
+ return StringRef::npos;
+}
+
+/// 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 function returns a pair containing the extracted token and the
+/// remaining tail string.
+std::pair<StringRef, StringRef> llvm::getToken(StringRef Source,
+ StringRef Delimiters) {
+ // Figure out where the token starts.
+ StringRef::size_type Start = Source.find_first_not_of(Delimiters);
+
+ // Find the next occurrence of the delimiter.
+ StringRef::size_type End = Source.find_first_of(Delimiters, Start);
+
+ return std::make_pair(Source.slice(Start, End), Source.substr(End));
+}
+
+/// SplitString - Split up the specified string according to the specified
+/// delimiters, appending the result fragments to the output list.
+void llvm::SplitString(StringRef Source,
+ SmallVectorImpl<StringRef> &OutFragments,
+ StringRef Delimiters) {
+ std::pair<StringRef, StringRef> S = getToken(Source, Delimiters);
+ while (!S.first.empty()) {
+ OutFragments.push_back(S.first);
+ S = getToken(S.second, Delimiters);
+ }
+}
diff --git a/contrib/llvm/lib/Support/StringMap.cpp b/contrib/llvm/lib/Support/StringMap.cpp
new file mode 100644
index 000000000000..7be946642d90
--- /dev/null
+++ b/contrib/llvm/lib/Support/StringMap.cpp
@@ -0,0 +1,245 @@
+//===--- StringMap.cpp - String Hash table map implementation -------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the StringMap class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/Compiler.h"
+#include <cassert>
+using namespace llvm;
+
+StringMapImpl::StringMapImpl(unsigned InitSize, unsigned itemSize) {
+ ItemSize = itemSize;
+
+ // If a size is specified, initialize the table with that many buckets.
+ if (InitSize) {
+ init(InitSize);
+ return;
+ }
+
+ // Otherwise, initialize it with zero buckets to avoid the allocation.
+ TheTable = nullptr;
+ NumBuckets = 0;
+ NumItems = 0;
+ NumTombstones = 0;
+}
+
+void StringMapImpl::init(unsigned InitSize) {
+ assert((InitSize & (InitSize-1)) == 0 &&
+ "Init Size must be a power of 2 or zero!");
+ NumBuckets = InitSize ? InitSize : 16;
+ NumItems = 0;
+ NumTombstones = 0;
+
+ TheTable = (StringMapEntryBase **)calloc(NumBuckets+1,
+ sizeof(StringMapEntryBase **) +
+ sizeof(unsigned));
+
+ // Allocate one extra bucket, set it to look filled so the iterators stop at
+ // end.
+ TheTable[NumBuckets] = (StringMapEntryBase*)2;
+}
+
+
+/// 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 StringMapImpl::LookupBucketFor(StringRef Name) {
+ unsigned HTSize = NumBuckets;
+ if (HTSize == 0) { // Hash table unallocated so far?
+ init(16);
+ HTSize = NumBuckets;
+ }
+ unsigned FullHashValue = HashString(Name);
+ unsigned BucketNo = FullHashValue & (HTSize-1);
+ unsigned *HashTable = (unsigned *)(TheTable + NumBuckets + 1);
+
+ unsigned ProbeAmt = 1;
+ int FirstTombstone = -1;
+ while (1) {
+ StringMapEntryBase *BucketItem = TheTable[BucketNo];
+ // If we found an empty bucket, this key isn't in the table yet, return it.
+ if (LLVM_LIKELY(!BucketItem)) {
+ // If we found a tombstone, we want to reuse the tombstone instead of an
+ // empty bucket. This reduces probing.
+ if (FirstTombstone != -1) {
+ HashTable[FirstTombstone] = FullHashValue;
+ return FirstTombstone;
+ }
+
+ HashTable[BucketNo] = FullHashValue;
+ return BucketNo;
+ }
+
+ if (BucketItem == getTombstoneVal()) {
+ // Skip over tombstones. However, remember the first one we see.
+ if (FirstTombstone == -1) FirstTombstone = BucketNo;
+ } else if (LLVM_LIKELY(HashTable[BucketNo] == FullHashValue)) {
+ // If the full hash value matches, check deeply for a match. The common
+ // case here is that we are only looking at the buckets (for item info
+ // being non-null and for the full hash value) not at the items. This
+ // is important for cache locality.
+
+ // Do the comparison like this because Name isn't necessarily
+ // null-terminated!
+ char *ItemStr = (char*)BucketItem+ItemSize;
+ if (Name == StringRef(ItemStr, BucketItem->getKeyLength())) {
+ // We found a match!
+ return BucketNo;
+ }
+ }
+
+ // Okay, we didn't find the item. Probe to the next bucket.
+ BucketNo = (BucketNo+ProbeAmt) & (HTSize-1);
+
+ // Use quadratic probing, it has fewer clumping artifacts than linear
+ // probing and has good cache behavior in the common case.
+ ++ProbeAmt;
+ }
+}
+
+
+/// 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 StringMapImpl::FindKey(StringRef Key) const {
+ unsigned HTSize = NumBuckets;
+ if (HTSize == 0) return -1; // Really empty table?
+ unsigned FullHashValue = HashString(Key);
+ unsigned BucketNo = FullHashValue & (HTSize-1);
+ unsigned *HashTable = (unsigned *)(TheTable + NumBuckets + 1);
+
+ unsigned ProbeAmt = 1;
+ while (1) {
+ StringMapEntryBase *BucketItem = TheTable[BucketNo];
+ // If we found an empty bucket, this key isn't in the table yet, return.
+ if (LLVM_LIKELY(!BucketItem))
+ return -1;
+
+ if (BucketItem == getTombstoneVal()) {
+ // Ignore tombstones.
+ } else if (LLVM_LIKELY(HashTable[BucketNo] == FullHashValue)) {
+ // If the full hash value matches, check deeply for a match. The common
+ // case here is that we are only looking at the buckets (for item info
+ // being non-null and for the full hash value) not at the items. This
+ // is important for cache locality.
+
+ // Do the comparison like this because NameStart isn't necessarily
+ // null-terminated!
+ char *ItemStr = (char*)BucketItem+ItemSize;
+ if (Key == StringRef(ItemStr, BucketItem->getKeyLength())) {
+ // We found a match!
+ return BucketNo;
+ }
+ }
+
+ // Okay, we didn't find the item. Probe to the next bucket.
+ BucketNo = (BucketNo+ProbeAmt) & (HTSize-1);
+
+ // Use quadratic probing, it has fewer clumping artifacts than linear
+ // probing and has good cache behavior in the common case.
+ ++ProbeAmt;
+ }
+}
+
+/// RemoveKey - Remove the specified StringMapEntry from the table, but do not
+/// delete it. This aborts if the value isn't in the table.
+void StringMapImpl::RemoveKey(StringMapEntryBase *V) {
+ const char *VStr = (char*)V + ItemSize;
+ StringMapEntryBase *V2 = RemoveKey(StringRef(VStr, V->getKeyLength()));
+ (void)V2;
+ assert(V == V2 && "Didn't find key?");
+}
+
+/// 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 *StringMapImpl::RemoveKey(StringRef Key) {
+ int Bucket = FindKey(Key);
+ if (Bucket == -1) return nullptr;
+
+ StringMapEntryBase *Result = TheTable[Bucket];
+ TheTable[Bucket] = getTombstoneVal();
+ --NumItems;
+ ++NumTombstones;
+ assert(NumItems + NumTombstones <= NumBuckets);
+
+ return Result;
+}
+
+
+
+/// RehashTable - Grow the table, redistributing values into the buckets with
+/// the appropriate mod-of-hashtable-size.
+unsigned StringMapImpl::RehashTable(unsigned BucketNo) {
+ unsigned NewSize;
+ unsigned *HashTable = (unsigned *)(TheTable + NumBuckets + 1);
+
+ // 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/rehash the table.
+ if (LLVM_UNLIKELY(NumItems * 4 > NumBuckets * 3)) {
+ NewSize = NumBuckets*2;
+ } else if (LLVM_UNLIKELY(NumBuckets - (NumItems + NumTombstones) <=
+ NumBuckets / 8)) {
+ NewSize = NumBuckets;
+ } else {
+ return BucketNo;
+ }
+
+ unsigned NewBucketNo = BucketNo;
+ // Allocate one extra bucket which will always be non-empty. This allows the
+ // iterators to stop at end.
+ StringMapEntryBase **NewTableArray =
+ (StringMapEntryBase **)calloc(NewSize+1, sizeof(StringMapEntryBase *) +
+ sizeof(unsigned));
+ unsigned *NewHashArray = (unsigned *)(NewTableArray + NewSize + 1);
+ NewTableArray[NewSize] = (StringMapEntryBase*)2;
+
+ // Rehash all the items into their new buckets. Luckily :) we already have
+ // the hash values available, so we don't have to rehash any strings.
+ for (unsigned I = 0, E = NumBuckets; I != E; ++I) {
+ StringMapEntryBase *Bucket = TheTable[I];
+ if (Bucket && Bucket != getTombstoneVal()) {
+ // Fast case, bucket available.
+ unsigned FullHash = HashTable[I];
+ unsigned NewBucket = FullHash & (NewSize-1);
+ if (!NewTableArray[NewBucket]) {
+ NewTableArray[FullHash & (NewSize-1)] = Bucket;
+ NewHashArray[FullHash & (NewSize-1)] = FullHash;
+ if (I == BucketNo)
+ NewBucketNo = NewBucket;
+ continue;
+ }
+
+ // Otherwise probe for a spot.
+ unsigned ProbeSize = 1;
+ do {
+ NewBucket = (NewBucket + ProbeSize++) & (NewSize-1);
+ } while (NewTableArray[NewBucket]);
+
+ // Finally found a slot. Fill it in.
+ NewTableArray[NewBucket] = Bucket;
+ NewHashArray[NewBucket] = FullHash;
+ if (I == BucketNo)
+ NewBucketNo = NewBucket;
+ }
+ }
+
+ free(TheTable);
+
+ TheTable = NewTableArray;
+ NumBuckets = NewSize;
+ NumTombstones = 0;
+ return NewBucketNo;
+}
diff --git a/contrib/llvm/lib/Support/StringPool.cpp b/contrib/llvm/lib/Support/StringPool.cpp
new file mode 100644
index 000000000000..76faabc92bb5
--- /dev/null
+++ b/contrib/llvm/lib/Support/StringPool.cpp
@@ -0,0 +1,35 @@
+//===-- StringPool.cpp - Interned string pool -----------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the StringPool class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/StringPool.h"
+#include "llvm/ADT/StringRef.h"
+
+using namespace llvm;
+
+StringPool::StringPool() {}
+
+StringPool::~StringPool() {
+ assert(InternTable.empty() && "PooledStringPtr leaked!");
+}
+
+PooledStringPtr StringPool::intern(StringRef Key) {
+ table_t::iterator I = InternTable.find(Key);
+ if (I != InternTable.end())
+ return PooledStringPtr(&*I);
+
+ entry_t *S = entry_t::Create(Key);
+ S->getValue().Pool = this;
+ InternTable.insert(S);
+
+ return PooledStringPtr(S);
+}
diff --git a/contrib/llvm/lib/Support/StringRef.cpp b/contrib/llvm/lib/Support/StringRef.cpp
new file mode 100644
index 000000000000..ddece087a9e7
--- /dev/null
+++ b/contrib/llvm/lib/Support/StringRef.cpp
@@ -0,0 +1,485 @@
+//===-- StringRef.cpp - Lightweight String References ---------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/APInt.h"
+#include "llvm/ADT/Hashing.h"
+#include "llvm/ADT/edit_distance.h"
+#include <bitset>
+
+using namespace llvm;
+
+// MSVC emits references to this into the translation units which reference it.
+#ifndef _MSC_VER
+const size_t StringRef::npos;
+#endif
+
+static char ascii_tolower(char x) {
+ if (x >= 'A' && x <= 'Z')
+ return x - 'A' + 'a';
+ return x;
+}
+
+static char ascii_toupper(char x) {
+ if (x >= 'a' && x <= 'z')
+ return x - 'a' + 'A';
+ return x;
+}
+
+static bool ascii_isdigit(char x) {
+ return x >= '0' && x <= '9';
+}
+
+// strncasecmp() is not available on non-POSIX systems, so define an
+// alternative function here.
+static int ascii_strncasecmp(const char *LHS, const char *RHS, size_t Length) {
+ for (size_t I = 0; I < Length; ++I) {
+ unsigned char LHC = ascii_tolower(LHS[I]);
+ unsigned char RHC = ascii_tolower(RHS[I]);
+ if (LHC != RHC)
+ return LHC < RHC ? -1 : 1;
+ }
+ return 0;
+}
+
+/// compare_lower - Compare strings, ignoring case.
+int StringRef::compare_lower(StringRef RHS) const {
+ if (int Res = ascii_strncasecmp(Data, RHS.Data, std::min(Length, RHS.Length)))
+ return Res;
+ if (Length == RHS.Length)
+ return 0;
+ return Length < RHS.Length ? -1 : 1;
+}
+
+/// Check if this string starts with the given \p Prefix, ignoring case.
+bool StringRef::startswith_lower(StringRef Prefix) const {
+ return Length >= Prefix.Length &&
+ ascii_strncasecmp(Data, Prefix.Data, Prefix.Length) == 0;
+}
+
+/// Check if this string ends with the given \p Suffix, ignoring case.
+bool StringRef::endswith_lower(StringRef Suffix) const {
+ return Length >= Suffix.Length &&
+ ascii_strncasecmp(end() - Suffix.Length, Suffix.Data, Suffix.Length) == 0;
+}
+
+/// compare_numeric - Compare strings, handle embedded numbers.
+int StringRef::compare_numeric(StringRef RHS) const {
+ for (size_t I = 0, E = std::min(Length, RHS.Length); I != E; ++I) {
+ // Check for sequences of digits.
+ if (ascii_isdigit(Data[I]) && ascii_isdigit(RHS.Data[I])) {
+ // The longer sequence of numbers is considered larger.
+ // This doesn't really handle prefixed zeros well.
+ size_t J;
+ for (J = I + 1; J != E + 1; ++J) {
+ bool ld = J < Length && ascii_isdigit(Data[J]);
+ bool rd = J < RHS.Length && ascii_isdigit(RHS.Data[J]);
+ if (ld != rd)
+ return rd ? -1 : 1;
+ if (!rd)
+ break;
+ }
+ // The two number sequences have the same length (J-I), just memcmp them.
+ if (int Res = compareMemory(Data + I, RHS.Data + I, J - I))
+ return Res < 0 ? -1 : 1;
+ // Identical number sequences, continue search after the numbers.
+ I = J - 1;
+ continue;
+ }
+ if (Data[I] != RHS.Data[I])
+ return (unsigned char)Data[I] < (unsigned char)RHS.Data[I] ? -1 : 1;
+ }
+ if (Length == RHS.Length)
+ return 0;
+ return Length < RHS.Length ? -1 : 1;
+}
+
+// Compute the edit distance between the two given strings.
+unsigned StringRef::edit_distance(llvm::StringRef Other,
+ bool AllowReplacements,
+ unsigned MaxEditDistance) const {
+ return llvm::ComputeEditDistance(
+ makeArrayRef(data(), size()),
+ makeArrayRef(Other.data(), Other.size()),
+ AllowReplacements, MaxEditDistance);
+}
+
+//===----------------------------------------------------------------------===//
+// String Operations
+//===----------------------------------------------------------------------===//
+
+std::string StringRef::lower() const {
+ std::string Result(size(), char());
+ for (size_type i = 0, e = size(); i != e; ++i) {
+ Result[i] = ascii_tolower(Data[i]);
+ }
+ return Result;
+}
+
+std::string StringRef::upper() const {
+ std::string Result(size(), char());
+ for (size_type i = 0, e = size(); i != e; ++i) {
+ Result[i] = ascii_toupper(Data[i]);
+ }
+ return Result;
+}
+
+//===----------------------------------------------------------------------===//
+// String Searching
+//===----------------------------------------------------------------------===//
+
+
+/// find - Search for the first string \arg Str in the string.
+///
+/// \return - The index of the first occurrence of \arg Str, or npos if not
+/// found.
+size_t StringRef::find(StringRef Str, size_t From) const {
+ size_t N = Str.size();
+ if (N > Length)
+ return npos;
+
+ // For short haystacks or unsupported needles fall back to the naive algorithm
+ if (Length < 16 || N > 255 || N == 0) {
+ for (size_t e = Length - N + 1, i = std::min(From, e); i != e; ++i)
+ if (substr(i, N).equals(Str))
+ return i;
+ return npos;
+ }
+
+ if (From >= Length)
+ return npos;
+
+ // Build the bad char heuristic table, with uint8_t to reduce cache thrashing.
+ uint8_t BadCharSkip[256];
+ std::memset(BadCharSkip, N, 256);
+ for (unsigned i = 0; i != N-1; ++i)
+ BadCharSkip[(uint8_t)Str[i]] = N-1-i;
+
+ unsigned Len = Length-From, Pos = From;
+ while (Len >= N) {
+ if (substr(Pos, N).equals(Str)) // See if this is the correct substring.
+ return Pos;
+
+ // Otherwise skip the appropriate number of bytes.
+ uint8_t Skip = BadCharSkip[(uint8_t)(*this)[Pos+N-1]];
+ Len -= Skip;
+ Pos += Skip;
+ }
+
+ return npos;
+}
+
+/// rfind - Search for the last string \arg Str in the string.
+///
+/// \return - The index of the last occurrence of \arg Str, or npos if not
+/// found.
+size_t StringRef::rfind(StringRef Str) const {
+ size_t N = Str.size();
+ if (N > Length)
+ return npos;
+ for (size_t i = Length - N + 1, e = 0; i != e;) {
+ --i;
+ if (substr(i, N).equals(Str))
+ return i;
+ }
+ return npos;
+}
+
+/// find_first_of - Find the first character in the string that is in \arg
+/// Chars, or npos if not found.
+///
+/// Note: O(size() + Chars.size())
+StringRef::size_type StringRef::find_first_of(StringRef Chars,
+ size_t From) const {
+ std::bitset<1 << CHAR_BIT> CharBits;
+ for (size_type i = 0; i != Chars.size(); ++i)
+ CharBits.set((unsigned char)Chars[i]);
+
+ for (size_type i = std::min(From, Length), e = Length; i != e; ++i)
+ if (CharBits.test((unsigned char)Data[i]))
+ return i;
+ return npos;
+}
+
+/// find_first_not_of - Find the first character in the string that is not
+/// \arg C or npos if not found.
+StringRef::size_type StringRef::find_first_not_of(char C, size_t From) const {
+ for (size_type i = std::min(From, Length), e = Length; i != e; ++i)
+ if (Data[i] != C)
+ return i;
+ return npos;
+}
+
+/// find_first_not_of - Find the first character in the string that is not
+/// in the string \arg Chars, or npos if not found.
+///
+/// Note: O(size() + Chars.size())
+StringRef::size_type StringRef::find_first_not_of(StringRef Chars,
+ size_t From) const {
+ std::bitset<1 << CHAR_BIT> CharBits;
+ for (size_type i = 0; i != Chars.size(); ++i)
+ CharBits.set((unsigned char)Chars[i]);
+
+ for (size_type i = std::min(From, Length), e = Length; i != e; ++i)
+ if (!CharBits.test((unsigned char)Data[i]))
+ return i;
+ return npos;
+}
+
+/// find_last_of - Find the last character in the string that is in \arg C,
+/// or npos if not found.
+///
+/// Note: O(size() + Chars.size())
+StringRef::size_type StringRef::find_last_of(StringRef Chars,
+ size_t From) const {
+ std::bitset<1 << CHAR_BIT> CharBits;
+ for (size_type i = 0; i != Chars.size(); ++i)
+ CharBits.set((unsigned char)Chars[i]);
+
+ for (size_type i = std::min(From, Length) - 1, e = -1; i != e; --i)
+ if (CharBits.test((unsigned char)Data[i]))
+ return i;
+ return npos;
+}
+
+/// find_last_not_of - Find the last character in the string that is not
+/// \arg C, or npos if not found.
+StringRef::size_type StringRef::find_last_not_of(char C, size_t From) const {
+ for (size_type i = std::min(From, Length) - 1, e = -1; i != e; --i)
+ if (Data[i] != C)
+ return i;
+ return npos;
+}
+
+/// find_last_not_of - Find the last character in the string that is not in
+/// \arg Chars, or npos if not found.
+///
+/// Note: O(size() + Chars.size())
+StringRef::size_type StringRef::find_last_not_of(StringRef Chars,
+ size_t From) const {
+ std::bitset<1 << CHAR_BIT> CharBits;
+ for (size_type i = 0, e = Chars.size(); i != e; ++i)
+ CharBits.set((unsigned char)Chars[i]);
+
+ for (size_type i = std::min(From, Length) - 1, e = -1; i != e; --i)
+ if (!CharBits.test((unsigned char)Data[i]))
+ return i;
+ return npos;
+}
+
+void StringRef::split(SmallVectorImpl<StringRef> &A,
+ StringRef Separators, int MaxSplit,
+ bool KeepEmpty) const {
+ StringRef rest = *this;
+
+ // rest.data() is used to distinguish cases like "a," that splits into
+ // "a" + "" and "a" that splits into "a" + 0.
+ for (int splits = 0;
+ rest.data() != nullptr && (MaxSplit < 0 || splits < MaxSplit);
+ ++splits) {
+ std::pair<StringRef, StringRef> p = rest.split(Separators);
+
+ if (KeepEmpty || p.first.size() != 0)
+ A.push_back(p.first);
+ rest = p.second;
+ }
+ // If we have a tail left, add it.
+ if (rest.data() != nullptr && (rest.size() != 0 || KeepEmpty))
+ A.push_back(rest);
+}
+
+//===----------------------------------------------------------------------===//
+// Helpful Algorithms
+//===----------------------------------------------------------------------===//
+
+/// count - Return the number of non-overlapped occurrences of \arg Str in
+/// the string.
+size_t StringRef::count(StringRef Str) const {
+ size_t Count = 0;
+ size_t N = Str.size();
+ if (N > Length)
+ return 0;
+ for (size_t i = 0, e = Length - N + 1; i != e; ++i)
+ if (substr(i, N).equals(Str))
+ ++Count;
+ return Count;
+}
+
+static unsigned GetAutoSenseRadix(StringRef &Str) {
+ if (Str.startswith("0x")) {
+ Str = Str.substr(2);
+ return 16;
+ }
+
+ if (Str.startswith("0b")) {
+ Str = Str.substr(2);
+ return 2;
+ }
+
+ if (Str.startswith("0o")) {
+ Str = Str.substr(2);
+ return 8;
+ }
+
+ if (Str.startswith("0"))
+ return 8;
+
+ return 10;
+}
+
+
+/// GetAsUnsignedInteger - Workhorse method that converts a integer character
+/// sequence of radix up to 36 to an unsigned long long value.
+bool llvm::getAsUnsignedInteger(StringRef Str, unsigned Radix,
+ unsigned long long &Result) {
+ // Autosense radix if not specified.
+ if (Radix == 0)
+ Radix = GetAutoSenseRadix(Str);
+
+ // Empty strings (after the radix autosense) are invalid.
+ if (Str.empty()) return true;
+
+ // Parse all the bytes of the string given this radix. Watch for overflow.
+ Result = 0;
+ while (!Str.empty()) {
+ unsigned CharVal;
+ if (Str[0] >= '0' && Str[0] <= '9')
+ CharVal = Str[0]-'0';
+ else if (Str[0] >= 'a' && Str[0] <= 'z')
+ CharVal = Str[0]-'a'+10;
+ else if (Str[0] >= 'A' && Str[0] <= 'Z')
+ CharVal = Str[0]-'A'+10;
+ else
+ return true;
+
+ // If the parsed value is larger than the integer radix, the string is
+ // invalid.
+ if (CharVal >= Radix)
+ return true;
+
+ // Add in this character.
+ unsigned long long PrevResult = Result;
+ Result = Result*Radix+CharVal;
+
+ // Check for overflow by shifting back and seeing if bits were lost.
+ if (Result/Radix < PrevResult)
+ return true;
+
+ Str = Str.substr(1);
+ }
+
+ return false;
+}
+
+bool llvm::getAsSignedInteger(StringRef Str, unsigned Radix,
+ long long &Result) {
+ unsigned long long ULLVal;
+
+ // Handle positive strings first.
+ if (Str.empty() || Str.front() != '-') {
+ if (getAsUnsignedInteger(Str, Radix, ULLVal) ||
+ // Check for value so large it overflows a signed value.
+ (long long)ULLVal < 0)
+ return true;
+ Result = ULLVal;
+ return false;
+ }
+
+ // Get the positive part of the value.
+ if (getAsUnsignedInteger(Str.substr(1), Radix, ULLVal) ||
+ // Reject values so large they'd overflow as negative signed, but allow
+ // "-0". This negates the unsigned so that the negative isn't undefined
+ // on signed overflow.
+ (long long)-ULLVal > 0)
+ return true;
+
+ Result = -ULLVal;
+ return false;
+}
+
+bool StringRef::getAsInteger(unsigned Radix, APInt &Result) const {
+ StringRef Str = *this;
+
+ // Autosense radix if not specified.
+ if (Radix == 0)
+ Radix = GetAutoSenseRadix(Str);
+
+ assert(Radix > 1 && Radix <= 36);
+
+ // Empty strings (after the radix autosense) are invalid.
+ if (Str.empty()) return true;
+
+ // Skip leading zeroes. This can be a significant improvement if
+ // it means we don't need > 64 bits.
+ while (!Str.empty() && Str.front() == '0')
+ Str = Str.substr(1);
+
+ // If it was nothing but zeroes....
+ if (Str.empty()) {
+ Result = APInt(64, 0);
+ return false;
+ }
+
+ // (Over-)estimate the required number of bits.
+ unsigned Log2Radix = 0;
+ while ((1U << Log2Radix) < Radix) Log2Radix++;
+ bool IsPowerOf2Radix = ((1U << Log2Radix) == Radix);
+
+ unsigned BitWidth = Log2Radix * Str.size();
+ if (BitWidth < Result.getBitWidth())
+ BitWidth = Result.getBitWidth(); // don't shrink the result
+ else if (BitWidth > Result.getBitWidth())
+ Result = Result.zext(BitWidth);
+
+ APInt RadixAP, CharAP; // unused unless !IsPowerOf2Radix
+ if (!IsPowerOf2Radix) {
+ // These must have the same bit-width as Result.
+ RadixAP = APInt(BitWidth, Radix);
+ CharAP = APInt(BitWidth, 0);
+ }
+
+ // Parse all the bytes of the string given this radix.
+ Result = 0;
+ while (!Str.empty()) {
+ unsigned CharVal;
+ if (Str[0] >= '0' && Str[0] <= '9')
+ CharVal = Str[0]-'0';
+ else if (Str[0] >= 'a' && Str[0] <= 'z')
+ CharVal = Str[0]-'a'+10;
+ else if (Str[0] >= 'A' && Str[0] <= 'Z')
+ CharVal = Str[0]-'A'+10;
+ else
+ return true;
+
+ // If the parsed value is larger than the integer radix, the string is
+ // invalid.
+ if (CharVal >= Radix)
+ return true;
+
+ // Add in this character.
+ if (IsPowerOf2Radix) {
+ Result <<= Log2Radix;
+ Result |= CharVal;
+ } else {
+ Result *= RadixAP;
+ CharAP = CharVal;
+ Result += CharAP;
+ }
+
+ Str = Str.substr(1);
+ }
+
+ return false;
+}
+
+
+// Implementation of StringRef hashing.
+hash_code llvm::hash_value(StringRef S) {
+ return hash_combine_range(S.begin(), S.end());
+}
diff --git a/contrib/llvm/lib/Support/StringSaver.cpp b/contrib/llvm/lib/Support/StringSaver.cpp
new file mode 100644
index 000000000000..d6b84e53dccd
--- /dev/null
+++ b/contrib/llvm/lib/Support/StringSaver.cpp
@@ -0,0 +1,19 @@
+//===-- StringSaver.cpp ---------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/StringSaver.h"
+
+using namespace llvm;
+
+const char *StringSaver::saveImpl(StringRef S) {
+ char *P = Alloc.Allocate<char>(S.size() + 1);
+ memcpy(P, S.data(), S.size());
+ P[S.size()] = '\0';
+ return P;
+}
diff --git a/contrib/llvm/lib/Support/SystemUtils.cpp b/contrib/llvm/lib/Support/SystemUtils.cpp
new file mode 100644
index 000000000000..7fa6ae3f6199
--- /dev/null
+++ b/contrib/llvm/lib/Support/SystemUtils.cpp
@@ -0,0 +1,31 @@
+//===- SystemUtils.cpp - Utilities for low-level system tasks -------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/SystemUtils.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace llvm;
+
+bool llvm::CheckBitcodeOutputToConsole(raw_ostream &stream_to_check,
+ bool print_warning) {
+ if (stream_to_check.is_displayed()) {
+ if (print_warning) {
+ errs() << "WARNING: You're attempting to print out a bitcode file.\n"
+ "This is inadvisable as it may cause display problems. If\n"
+ "you REALLY want to taste LLVM bitcode first-hand, you\n"
+ "can force output with the `-f' option.\n\n";
+ }
+ return true;
+ }
+ return false;
+}
diff --git a/contrib/llvm/lib/Support/TargetParser.cpp b/contrib/llvm/lib/Support/TargetParser.cpp
new file mode 100644
index 000000000000..760cdc11f26a
--- /dev/null
+++ b/contrib/llvm/lib/Support/TargetParser.cpp
@@ -0,0 +1,591 @@
+//===-- TargetParser - Parser for target features ---------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a target parser to recognise hardware features such as
+// FPU/CPU/ARCH names as well as specific support such as HDIV, etc.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/ARMBuildAttributes.h"
+#include "llvm/Support/TargetParser.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringSwitch.h"
+#include <cctype>
+
+using namespace llvm;
+
+namespace {
+
+// List of canonical FPU names (use getFPUSynonym) and which architectural
+// features they correspond to (use getFPUFeatures).
+// FIXME: TableGen this.
+struct {
+ const char * Name;
+ ARM::FPUKind ID;
+ unsigned FPUVersion; ///< Corresponds directly to the FP arch version number.
+ ARM::NeonSupportLevel NeonSupport;
+ ARM::FPURestriction Restriction;
+} FPUNames[] = {
+ { "invalid", ARM::FK_INVALID, 0, ARM::NS_None, ARM::FR_None},
+ { "none", ARM::FK_NONE, 0, ARM::NS_None, ARM::FR_None},
+ { "vfp", ARM::FK_VFP, 2, ARM::NS_None, ARM::FR_None},
+ { "vfpv2", ARM::FK_VFPV2, 2, ARM::NS_None, ARM::FR_None},
+ { "vfpv3", ARM::FK_VFPV3, 3, ARM::NS_None, ARM::FR_None},
+ { "vfpv3-d16", ARM::FK_VFPV3_D16, 3, ARM::NS_None, ARM::FR_D16},
+ { "vfpv4", ARM::FK_VFPV4, 4, ARM::NS_None, ARM::FR_None},
+ { "vfpv4-d16", ARM::FK_VFPV4_D16, 4, ARM::NS_None, ARM::FR_D16},
+ { "fpv4-sp-d16", ARM::FK_FPV4_SP_D16, 4, ARM::NS_None, ARM::FR_SP_D16},
+ { "fpv5-d16", ARM::FK_FPV5_D16, 5, ARM::NS_None, ARM::FR_D16},
+ { "fpv5-sp-d16", ARM::FK_FPV5_SP_D16, 5, ARM::NS_None, ARM::FR_SP_D16},
+ { "fp-armv8", ARM::FK_FP_ARMV8, 5, ARM::NS_None, ARM::FR_None},
+ { "neon", ARM::FK_NEON, 3, ARM::NS_Neon, ARM::FR_None},
+ { "neon-vfpv4", ARM::FK_NEON_VFPV4, 4, ARM::NS_Neon, ARM::FR_None},
+ { "neon-fp-armv8", ARM::FK_NEON_FP_ARMV8, 5, ARM::NS_Neon, ARM::FR_None},
+ { "crypto-neon-fp-armv8",
+ ARM::FK_CRYPTO_NEON_FP_ARMV8, 5, ARM::NS_Crypto, ARM::FR_None},
+ { "softvfp", ARM::FK_SOFTVFP, 0, ARM::NS_None, ARM::FR_None},
+};
+
+// List of canonical arch names (use getArchSynonym).
+// This table also provides the build attribute fields for CPU arch
+// and Arch ID, according to the Addenda to the ARM ABI, chapters
+// 2.4 and 2.3.5.2 respectively.
+// FIXME: SubArch values were simplified to fit into the expectations
+// of the triples and are not conforming with their official names.
+// Check to see if the expectation should be changed.
+// FIXME: TableGen this.
+struct {
+ const char *Name;
+ ARM::ArchKind ID;
+ const char *CPUAttr; // CPU class in build attributes.
+ const char *SubArch; // Sub-Arch name.
+ ARMBuildAttrs::CPUArch ArchAttr; // Arch ID in build attributes.
+} ARCHNames[] = {
+ { "invalid", ARM::AK_INVALID, nullptr, nullptr, ARMBuildAttrs::CPUArch::Pre_v4 },
+ { "armv2", ARM::AK_ARMV2, "2", "v2", ARMBuildAttrs::CPUArch::Pre_v4 },
+ { "armv2a", ARM::AK_ARMV2A, "2A", "v2a", ARMBuildAttrs::CPUArch::Pre_v4 },
+ { "armv3", ARM::AK_ARMV3, "3", "v3", ARMBuildAttrs::CPUArch::Pre_v4 },
+ { "armv3m", ARM::AK_ARMV3M, "3M", "v3m", ARMBuildAttrs::CPUArch::Pre_v4 },
+ { "armv4", ARM::AK_ARMV4, "4", "v4", ARMBuildAttrs::CPUArch::v4 },
+ { "armv4t", ARM::AK_ARMV4T, "4T", "v4t", ARMBuildAttrs::CPUArch::v4T },
+ { "armv5t", ARM::AK_ARMV5T, "5T", "v5", ARMBuildAttrs::CPUArch::v5T },
+ { "armv5te", ARM::AK_ARMV5TE, "5TE", "v5e", ARMBuildAttrs::CPUArch::v5TE },
+ { "armv5tej", ARM::AK_ARMV5TEJ, "5TEJ", "v5e", ARMBuildAttrs::CPUArch::v5TEJ },
+ { "armv6", ARM::AK_ARMV6, "6", "v6", ARMBuildAttrs::CPUArch::v6 },
+ { "armv6k", ARM::AK_ARMV6K, "6K", "v6k", ARMBuildAttrs::CPUArch::v6K },
+ { "armv6t2", ARM::AK_ARMV6T2, "6T2", "v6t2", ARMBuildAttrs::CPUArch::v6T2 },
+ { "armv6z", ARM::AK_ARMV6Z, "6Z", "v6z", ARMBuildAttrs::CPUArch::v6KZ },
+ { "armv6zk", ARM::AK_ARMV6ZK, "6ZK", "v6zk", ARMBuildAttrs::CPUArch::v6KZ },
+ { "armv6-m", ARM::AK_ARMV6M, "6-M", "v6m", ARMBuildAttrs::CPUArch::v6_M },
+ { "armv6s-m", ARM::AK_ARMV6SM, "6S-M", "v6sm", ARMBuildAttrs::CPUArch::v6S_M },
+ { "armv7-a", ARM::AK_ARMV7A, "7-A", "v7", ARMBuildAttrs::CPUArch::v7 },
+ { "armv7-r", ARM::AK_ARMV7R, "7-R", "v7r", ARMBuildAttrs::CPUArch::v7 },
+ { "armv7-m", ARM::AK_ARMV7M, "7-M", "v7m", ARMBuildAttrs::CPUArch::v7 },
+ { "armv7e-m", ARM::AK_ARMV7EM, "7E-M", "v7em", ARMBuildAttrs::CPUArch::v7E_M },
+ { "armv8-a", ARM::AK_ARMV8A, "8-A", "v8", ARMBuildAttrs::CPUArch::v8 },
+ { "armv8.1-a", ARM::AK_ARMV8_1A, "8.1-A", "v8.1a", ARMBuildAttrs::CPUArch::v8 },
+ // Non-standard Arch names.
+ { "iwmmxt", ARM::AK_IWMMXT, "iwmmxt", "", ARMBuildAttrs::CPUArch::v5TE },
+ { "iwmmxt2", ARM::AK_IWMMXT2, "iwmmxt2", "", ARMBuildAttrs::CPUArch::v5TE },
+ { "xscale", ARM::AK_XSCALE, "xscale", "", ARMBuildAttrs::CPUArch::v5TE },
+ { "armv5", ARM::AK_ARMV5, "5T", "v5", ARMBuildAttrs::CPUArch::v5T },
+ { "armv5e", ARM::AK_ARMV5E, "5TE", "v5e", ARMBuildAttrs::CPUArch::v5TE },
+ { "armv6j", ARM::AK_ARMV6J, "6J", "v6", ARMBuildAttrs::CPUArch::v6 },
+ { "armv6hl", ARM::AK_ARMV6HL, "6-M", "v6hl", ARMBuildAttrs::CPUArch::v6_M },
+ { "armv7", ARM::AK_ARMV7, "7", "v7", ARMBuildAttrs::CPUArch::v7 },
+ { "armv7l", ARM::AK_ARMV7L, "7-L", "v7l", ARMBuildAttrs::CPUArch::v7 },
+ { "armv7hl", ARM::AK_ARMV7HL, "7-L", "v7hl", ARMBuildAttrs::CPUArch::v7 },
+ { "armv7s", ARM::AK_ARMV7S, "7-S", "v7s", ARMBuildAttrs::CPUArch::v7 }
+};
+// List of Arch Extension names.
+// FIXME: TableGen this.
+struct {
+ const char *Name;
+ ARM::ArchExtKind ID;
+} ARCHExtNames[] = {
+ { "invalid", ARM::AEK_INVALID },
+ { "crc", ARM::AEK_CRC },
+ { "crypto", ARM::AEK_CRYPTO },
+ { "fp", ARM::AEK_FP },
+ { "idiv", ARM::AEK_HWDIV },
+ { "mp", ARM::AEK_MP },
+ { "simd", ARM::AEK_SIMD },
+ { "sec", ARM::AEK_SEC },
+ { "virt", ARM::AEK_VIRT },
+ { "os", ARM::AEK_OS },
+ { "iwmmxt", ARM::AEK_IWMMXT },
+ { "iwmmxt2", ARM::AEK_IWMMXT2 },
+ { "maverick", ARM::AEK_MAVERICK },
+ { "xscale", ARM::AEK_XSCALE }
+};
+// List of CPU names and their arches.
+// The same CPU can have multiple arches and can be default on multiple arches.
+// When finding the Arch for a CPU, first-found prevails. Sort them accordingly.
+// When this becomes table-generated, we'd probably need two tables.
+// FIXME: TableGen this.
+struct {
+ const char *Name;
+ ARM::ArchKind ArchID;
+ bool Default;
+} CPUNames[] = {
+ { "arm2", ARM::AK_ARMV2, true },
+ { "arm3", ARM::AK_ARMV2A, true },
+ { "arm6", ARM::AK_ARMV3, true },
+ { "arm7m", ARM::AK_ARMV3M, true },
+ { "arm8", ARM::AK_ARMV4, false },
+ { "arm810", ARM::AK_ARMV4, false },
+ { "strongarm", ARM::AK_ARMV4, true },
+ { "strongarm110", ARM::AK_ARMV4, false },
+ { "strongarm1100", ARM::AK_ARMV4, false },
+ { "strongarm1110", ARM::AK_ARMV4, false },
+ { "arm7tdmi", ARM::AK_ARMV4T, true },
+ { "arm7tdmi-s", ARM::AK_ARMV4T, false },
+ { "arm710t", ARM::AK_ARMV4T, false },
+ { "arm720t", ARM::AK_ARMV4T, false },
+ { "arm9", ARM::AK_ARMV4T, false },
+ { "arm9tdmi", ARM::AK_ARMV4T, false },
+ { "arm920", ARM::AK_ARMV4T, false },
+ { "arm920t", ARM::AK_ARMV4T, false },
+ { "arm922t", ARM::AK_ARMV4T, false },
+ { "arm9312", ARM::AK_ARMV4T, false },
+ { "arm940t", ARM::AK_ARMV4T, false },
+ { "ep9312", ARM::AK_ARMV4T, false },
+ { "arm10tdmi", ARM::AK_ARMV5T, true },
+ { "arm1020t", ARM::AK_ARMV5T, false },
+ { "arm9e", ARM::AK_ARMV5TE, false },
+ { "arm946e-s", ARM::AK_ARMV5TE, false },
+ { "arm966e-s", ARM::AK_ARMV5TE, false },
+ { "arm968e-s", ARM::AK_ARMV5TE, false },
+ { "arm10e", ARM::AK_ARMV5TE, false },
+ { "arm1020e", ARM::AK_ARMV5TE, false },
+ { "arm1022e", ARM::AK_ARMV5TE, true },
+ { "iwmmxt", ARM::AK_ARMV5TE, false },
+ { "xscale", ARM::AK_ARMV5TE, false },
+ { "arm926ej-s", ARM::AK_ARMV5TEJ, true },
+ { "arm1136jf-s", ARM::AK_ARMV6, true },
+ { "arm1176j-s", ARM::AK_ARMV6K, false },
+ { "arm1176jz-s", ARM::AK_ARMV6K, false },
+ { "mpcore", ARM::AK_ARMV6K, false },
+ { "mpcorenovfp", ARM::AK_ARMV6K, false },
+ { "arm1176jzf-s", ARM::AK_ARMV6K, true },
+ { "arm1176jzf-s", ARM::AK_ARMV6Z, true },
+ { "arm1176jzf-s", ARM::AK_ARMV6ZK, true },
+ { "arm1156t2-s", ARM::AK_ARMV6T2, true },
+ { "arm1156t2f-s", ARM::AK_ARMV6T2, false },
+ { "cortex-m0", ARM::AK_ARMV6M, true },
+ { "cortex-m0plus", ARM::AK_ARMV6M, false },
+ { "cortex-m1", ARM::AK_ARMV6M, false },
+ { "sc000", ARM::AK_ARMV6M, false },
+ { "cortex-a5", ARM::AK_ARMV7A, false },
+ { "cortex-a7", ARM::AK_ARMV7A, false },
+ { "cortex-a8", ARM::AK_ARMV7A, true },
+ { "cortex-a9", ARM::AK_ARMV7A, false },
+ { "cortex-a12", ARM::AK_ARMV7A, false },
+ { "cortex-a15", ARM::AK_ARMV7A, false },
+ { "cortex-a17", ARM::AK_ARMV7A, false },
+ { "krait", ARM::AK_ARMV7A, false },
+ { "cortex-r4", ARM::AK_ARMV7R, true },
+ { "cortex-r4f", ARM::AK_ARMV7R, false },
+ { "cortex-r5", ARM::AK_ARMV7R, false },
+ { "cortex-r7", ARM::AK_ARMV7R, false },
+ { "sc300", ARM::AK_ARMV7M, false },
+ { "cortex-m3", ARM::AK_ARMV7M, true },
+ { "cortex-m4", ARM::AK_ARMV7EM, true },
+ { "cortex-m7", ARM::AK_ARMV7EM, false },
+ { "cortex-a53", ARM::AK_ARMV8A, true },
+ { "cortex-a57", ARM::AK_ARMV8A, false },
+ { "cortex-a72", ARM::AK_ARMV8A, false },
+ { "cyclone", ARM::AK_ARMV8A, false },
+ { "generic", ARM::AK_ARMV8_1A, true },
+ // Non-standard Arch names.
+ { "iwmmxt", ARM::AK_IWMMXT, true },
+ { "xscale", ARM::AK_XSCALE, true },
+ { "arm10tdmi", ARM::AK_ARMV5, true },
+ { "arm1022e", ARM::AK_ARMV5E, true },
+ { "arm1136j-s", ARM::AK_ARMV6J, true },
+ { "arm1136jz-s", ARM::AK_ARMV6J, false },
+ { "cortex-m0", ARM::AK_ARMV6SM, true },
+ { "arm1176jzf-s", ARM::AK_ARMV6HL, true },
+ { "cortex-a8", ARM::AK_ARMV7, true },
+ { "cortex-a8", ARM::AK_ARMV7L, true },
+ { "cortex-a8", ARM::AK_ARMV7HL, true },
+ { "cortex-m4", ARM::AK_ARMV7EM, true },
+ { "swift", ARM::AK_ARMV7S, true },
+ // Invalid CPU
+ { "invalid", ARM::AK_INVALID, true }
+};
+
+} // namespace
+
+// ======================================================= //
+// Information by ID
+// ======================================================= //
+
+const char *ARMTargetParser::getFPUName(unsigned FPUKind) {
+ if (FPUKind >= ARM::FK_LAST)
+ return nullptr;
+ return FPUNames[FPUKind].Name;
+}
+
+unsigned ARMTargetParser::getFPUVersion(unsigned FPUKind) {
+ if (FPUKind >= ARM::FK_LAST)
+ return 0;
+ return FPUNames[FPUKind].FPUVersion;
+}
+
+unsigned ARMTargetParser::getFPUNeonSupportLevel(unsigned FPUKind) {
+ if (FPUKind >= ARM::FK_LAST)
+ return 0;
+ return FPUNames[FPUKind].NeonSupport;
+}
+
+unsigned ARMTargetParser::getFPURestriction(unsigned FPUKind) {
+ if (FPUKind >= ARM::FK_LAST)
+ return 0;
+ return FPUNames[FPUKind].Restriction;
+}
+
+bool ARMTargetParser::getFPUFeatures(unsigned FPUKind,
+ std::vector<const char *> &Features) {
+
+ if (FPUKind >= ARM::FK_LAST || FPUKind == ARM::FK_INVALID)
+ return false;
+
+ // fp-only-sp and d16 subtarget features are independent of each other, so we
+ // must enable/disable both.
+ switch (FPUNames[FPUKind].Restriction) {
+ case ARM::FR_SP_D16:
+ Features.push_back("+fp-only-sp");
+ Features.push_back("+d16");
+ break;
+ case ARM::FR_D16:
+ Features.push_back("-fp-only-sp");
+ Features.push_back("+d16");
+ break;
+ case ARM::FR_None:
+ Features.push_back("-fp-only-sp");
+ Features.push_back("-d16");
+ break;
+ }
+
+ // FPU version subtarget features are inclusive of lower-numbered ones, so
+ // enable the one corresponding to this version and disable all that are
+ // higher. We also have to make sure to disable fp16 when vfp4 is disabled,
+ // as +vfp4 implies +fp16 but -vfp4 does not imply -fp16.
+ switch (FPUNames[FPUKind].FPUVersion) {
+ case 5:
+ Features.push_back("+fp-armv8");
+ break;
+ case 4:
+ Features.push_back("+vfp4");
+ Features.push_back("-fp-armv8");
+ break;
+ case 3:
+ Features.push_back("+vfp3");
+ Features.push_back("-fp16");
+ Features.push_back("-vfp4");
+ Features.push_back("-fp-armv8");
+ break;
+ case 2:
+ Features.push_back("+vfp2");
+ Features.push_back("-vfp3");
+ Features.push_back("-fp16");
+ Features.push_back("-vfp4");
+ Features.push_back("-fp-armv8");
+ break;
+ case 0:
+ Features.push_back("-vfp2");
+ Features.push_back("-vfp3");
+ Features.push_back("-fp16");
+ Features.push_back("-vfp4");
+ Features.push_back("-fp-armv8");
+ break;
+ }
+
+ // crypto includes neon, so we handle this similarly to FPU version.
+ switch (FPUNames[FPUKind].NeonSupport) {
+ case ARM::NS_Crypto:
+ Features.push_back("+crypto");
+ break;
+ case ARM::NS_Neon:
+ Features.push_back("+neon");
+ Features.push_back("-crypto");
+ break;
+ case ARM::NS_None:
+ Features.push_back("-neon");
+ Features.push_back("-crypto");
+ break;
+ }
+
+ return true;
+}
+
+const char *ARMTargetParser::getArchName(unsigned ArchKind) {
+ if (ArchKind >= ARM::AK_LAST)
+ return nullptr;
+ return ARCHNames[ArchKind].Name;
+}
+
+const char *ARMTargetParser::getCPUAttr(unsigned ArchKind) {
+ if (ArchKind >= ARM::AK_LAST)
+ return nullptr;
+ return ARCHNames[ArchKind].CPUAttr;
+}
+
+const char *ARMTargetParser::getSubArch(unsigned ArchKind) {
+ if (ArchKind >= ARM::AK_LAST)
+ return nullptr;
+ return ARCHNames[ArchKind].SubArch;
+}
+
+unsigned ARMTargetParser::getArchAttr(unsigned ArchKind) {
+ if (ArchKind >= ARM::AK_LAST)
+ return ARMBuildAttrs::CPUArch::Pre_v4;
+ return ARCHNames[ArchKind].ArchAttr;
+}
+
+const char *ARMTargetParser::getArchExtName(unsigned ArchExtKind) {
+ if (ArchExtKind >= ARM::AEK_LAST)
+ return nullptr;
+ return ARCHExtNames[ArchExtKind].Name;
+}
+
+const char *ARMTargetParser::getDefaultCPU(StringRef Arch) {
+ unsigned AK = parseArch(Arch);
+ if (AK == ARM::AK_INVALID)
+ return nullptr;
+
+ // Look for multiple AKs to find the default for pair AK+Name.
+ for (const auto CPU : CPUNames) {
+ if (CPU.ArchID == AK && CPU.Default)
+ return CPU.Name;
+ }
+ return nullptr;
+}
+
+// ======================================================= //
+// Parsers
+// ======================================================= //
+
+StringRef ARMTargetParser::getFPUSynonym(StringRef FPU) {
+ return StringSwitch<StringRef>(FPU)
+ .Cases("fpa", "fpe2", "fpe3", "maverick", "invalid") // Unsupported
+ .Case("vfp2", "vfpv2")
+ .Case("vfp3", "vfpv3")
+ .Case("vfp4", "vfpv4")
+ .Case("vfp3-d16", "vfpv3-d16")
+ .Case("vfp4-d16", "vfpv4-d16")
+ .Cases("fp4-sp-d16", "vfpv4-sp-d16", "fpv4-sp-d16")
+ .Cases("fp4-dp-d16", "fpv4-dp-d16", "vfpv4-d16")
+ .Case("fp5-sp-d16", "fpv5-sp-d16")
+ .Cases("fp5-dp-d16", "fpv5-dp-d16", "fpv5-d16")
+ // FIXME: Clang uses it, but it's bogus, since neon defaults to vfpv3.
+ .Case("neon-vfpv3", "neon")
+ .Default(FPU);
+}
+
+StringRef ARMTargetParser::getArchSynonym(StringRef Arch) {
+ return StringSwitch<StringRef>(Arch)
+ .Case("v6sm", "v6s-m")
+ .Case("v6m", "v6-m")
+ .Case("v7a", "v7-a")
+ .Case("v7r", "v7-r")
+ .Case("v7m", "v7-m")
+ .Case("v7em", "v7e-m")
+ .Cases("v8", "v8a", "aarch64", "arm64", "v8-a")
+ .Case("v8.1a", "v8.1-a")
+ .Default(Arch);
+}
+
+// MArch is expected to be of the form (arm|thumb)?(eb)?(v.+)?(eb)?, but
+// (iwmmxt|xscale)(eb)? is also permitted. If the former, return
+// "v.+", if the latter, return unmodified string, minus 'eb'.
+// If invalid, return empty string.
+StringRef ARMTargetParser::getCanonicalArchName(StringRef Arch) {
+ size_t offset = StringRef::npos;
+ StringRef A = Arch;
+ StringRef Error = "";
+
+ // Begins with "arm" / "thumb", move past it.
+ if (A.startswith("arm64"))
+ offset = 5;
+ else if (A.startswith("arm"))
+ offset = 3;
+ else if (A.startswith("thumb"))
+ offset = 5;
+ else if (A.startswith("aarch64")) {
+ offset = 7;
+ // AArch64 uses "_be", not "eb" suffix.
+ if (A.find("eb") != StringRef::npos)
+ return Error;
+ if (A.substr(offset,3) == "_be")
+ offset += 3;
+ }
+
+ // Ex. "armebv7", move past the "eb".
+ if (offset != StringRef::npos && A.substr(offset, 2) == "eb")
+ offset += 2;
+ // Or, if it ends with eb ("armv7eb"), chop it off.
+ else if (A.endswith("eb"))
+ A = A.substr(0, A.size() - 2);
+ // Trim the head
+ if (offset != StringRef::npos)
+ A = A.substr(offset);
+
+ // Empty string means offset reached the end, which means it's valid.
+ if (A.empty())
+ return Arch;
+
+ // Only match non-marketing names
+ if (offset != StringRef::npos) {
+ // Must start with 'vN'.
+ if (A[0] != 'v' || !std::isdigit(A[1]))
+ return Error;
+ // Can't have an extra 'eb'.
+ if (A.find("eb") != StringRef::npos)
+ return Error;
+ }
+
+ // Arch will either be a 'v' name (v7a) or a marketing name (xscale).
+ return A;
+}
+
+unsigned ARMTargetParser::parseFPU(StringRef FPU) {
+ StringRef Syn = getFPUSynonym(FPU);
+ for (const auto F : FPUNames) {
+ if (Syn == F.Name)
+ return F.ID;
+ }
+ return ARM::FK_INVALID;
+}
+
+// Allows partial match, ex. "v7a" matches "armv7a".
+unsigned ARMTargetParser::parseArch(StringRef Arch) {
+ Arch = getCanonicalArchName(Arch);
+ StringRef Syn = getArchSynonym(Arch);
+ for (const auto A : ARCHNames) {
+ if (StringRef(A.Name).endswith(Syn))
+ return A.ID;
+ }
+ return ARM::AK_INVALID;
+}
+
+unsigned ARMTargetParser::parseArchExt(StringRef ArchExt) {
+ for (const auto A : ARCHExtNames) {
+ if (ArchExt == A.Name)
+ return A.ID;
+ }
+ return ARM::AEK_INVALID;
+}
+
+unsigned ARMTargetParser::parseCPUArch(StringRef CPU) {
+ for (const auto C : CPUNames) {
+ if (CPU == C.Name)
+ return C.ArchID;
+ }
+ return ARM::AK_INVALID;
+}
+
+// ARM, Thumb, AArch64
+unsigned ARMTargetParser::parseArchISA(StringRef Arch) {
+ return StringSwitch<unsigned>(Arch)
+ .StartsWith("aarch64", ARM::IK_AARCH64)
+ .StartsWith("arm64", ARM::IK_AARCH64)
+ .StartsWith("thumb", ARM::IK_THUMB)
+ .StartsWith("arm", ARM::IK_ARM)
+ .Default(ARM::EK_INVALID);
+}
+
+// Little/Big endian
+unsigned ARMTargetParser::parseArchEndian(StringRef Arch) {
+ if (Arch.startswith("armeb") ||
+ Arch.startswith("thumbeb") ||
+ Arch.startswith("aarch64_be"))
+ return ARM::EK_BIG;
+
+ if (Arch.startswith("arm") || Arch.startswith("thumb")) {
+ if (Arch.endswith("eb"))
+ return ARM::EK_BIG;
+ else
+ return ARM::EK_LITTLE;
+ }
+
+ if (Arch.startswith("aarch64"))
+ return ARM::EK_LITTLE;
+
+ return ARM::EK_INVALID;
+}
+
+// Profile A/R/M
+unsigned ARMTargetParser::parseArchProfile(StringRef Arch) {
+ Arch = getCanonicalArchName(Arch);
+ switch(parseArch(Arch)) {
+ case ARM::AK_ARMV6M:
+ case ARM::AK_ARMV7M:
+ case ARM::AK_ARMV6SM:
+ case ARM::AK_ARMV7EM:
+ return ARM::PK_M;
+ case ARM::AK_ARMV7R:
+ return ARM::PK_R;
+ case ARM::AK_ARMV7:
+ case ARM::AK_ARMV7A:
+ case ARM::AK_ARMV8A:
+ case ARM::AK_ARMV8_1A:
+ return ARM::PK_A;
+ }
+ return ARM::PK_INVALID;
+}
+
+// Version number (ex. v7 = 7).
+unsigned ARMTargetParser::parseArchVersion(StringRef Arch) {
+ Arch = getCanonicalArchName(Arch);
+ switch(parseArch(Arch)) {
+ case ARM::AK_ARMV2:
+ case ARM::AK_ARMV2A:
+ return 2;
+ case ARM::AK_ARMV3:
+ case ARM::AK_ARMV3M:
+ return 3;
+ case ARM::AK_ARMV4:
+ case ARM::AK_ARMV4T:
+ return 4;
+ case ARM::AK_ARMV5:
+ case ARM::AK_ARMV5T:
+ case ARM::AK_ARMV5TE:
+ case ARM::AK_IWMMXT:
+ case ARM::AK_IWMMXT2:
+ case ARM::AK_XSCALE:
+ case ARM::AK_ARMV5E:
+ case ARM::AK_ARMV5TEJ:
+ return 5;
+ case ARM::AK_ARMV6:
+ case ARM::AK_ARMV6J:
+ case ARM::AK_ARMV6K:
+ case ARM::AK_ARMV6T2:
+ case ARM::AK_ARMV6Z:
+ case ARM::AK_ARMV6ZK:
+ case ARM::AK_ARMV6M:
+ case ARM::AK_ARMV6SM:
+ case ARM::AK_ARMV6HL:
+ return 6;
+ case ARM::AK_ARMV7:
+ case ARM::AK_ARMV7A:
+ case ARM::AK_ARMV7R:
+ case ARM::AK_ARMV7M:
+ case ARM::AK_ARMV7L:
+ case ARM::AK_ARMV7HL:
+ case ARM::AK_ARMV7S:
+ case ARM::AK_ARMV7EM:
+ return 7;
+ case ARM::AK_ARMV8A:
+ case ARM::AK_ARMV8_1A:
+ return 8;
+ }
+ return 0;
+}
diff --git a/contrib/llvm/lib/Support/TargetRegistry.cpp b/contrib/llvm/lib/Support/TargetRegistry.cpp
new file mode 100644
index 000000000000..eefef8ad8eaa
--- /dev/null
+++ b/contrib/llvm/lib/Support/TargetRegistry.cpp
@@ -0,0 +1,137 @@
+//===--- TargetRegistry.cpp - Target registration -------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/TargetRegistry.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cassert>
+#include <vector>
+using namespace llvm;
+
+// Clients are responsible for avoid race conditions in registration.
+static Target *FirstTarget = nullptr;
+
+iterator_range<TargetRegistry::iterator> TargetRegistry::targets() {
+ return make_range(iterator(FirstTarget), iterator());
+}
+
+const Target *TargetRegistry::lookupTarget(const std::string &ArchName,
+ Triple &TheTriple,
+ std::string &Error) {
+ // Allocate target machine. First, check whether the user has explicitly
+ // specified an architecture to compile for. If so we have to look it up by
+ // name, because it might be a backend that has no mapping to a target triple.
+ const Target *TheTarget = nullptr;
+ if (!ArchName.empty()) {
+ auto I =
+ std::find_if(targets().begin(), targets().end(),
+ [&](const Target &T) { return ArchName == T.getName(); });
+
+ if (I == targets().end()) {
+ Error = "error: invalid target '" + ArchName + "'.\n";
+ return nullptr;
+ }
+
+ TheTarget = &*I;
+
+ // Adjust the triple to match (if known), otherwise stick with the
+ // given triple.
+ Triple::ArchType Type = Triple::getArchTypeForLLVMName(ArchName);
+ if (Type != Triple::UnknownArch)
+ TheTriple.setArch(Type);
+ } else {
+ // Get the target specific parser.
+ std::string TempError;
+ TheTarget = TargetRegistry::lookupTarget(TheTriple.getTriple(), TempError);
+ if (!TheTarget) {
+ Error = ": error: unable to get target for '"
+ + TheTriple.getTriple()
+ + "', see --version and --triple.\n";
+ return nullptr;
+ }
+ }
+
+ return TheTarget;
+}
+
+const Target *TargetRegistry::lookupTarget(const std::string &TT,
+ std::string &Error) {
+ // Provide special warning when no targets are initialized.
+ if (targets().begin() == targets().end()) {
+ Error = "Unable to find target for this triple (no targets are registered)";
+ return nullptr;
+ }
+ Triple::ArchType Arch = Triple(TT).getArch();
+ auto ArchMatch = [&](const Target &T) { return T.ArchMatchFn(Arch); };
+ auto I = std::find_if(targets().begin(), targets().end(), ArchMatch);
+
+ if (I == targets().end()) {
+ Error = "No available targets are compatible with this triple, "
+ "see -version for the available targets.";
+ return nullptr;
+ }
+
+ auto J = std::find_if(std::next(I), targets().end(), ArchMatch);
+ if (J != targets().end()) {
+ Error = std::string("Cannot choose between targets \"") + I->Name +
+ "\" and \"" + J->Name + "\"";
+ return nullptr;
+ }
+
+ return &*I;
+}
+
+void TargetRegistry::RegisterTarget(Target &T,
+ const char *Name,
+ const char *ShortDesc,
+ Target::ArchMatchFnTy ArchMatchFn,
+ bool HasJIT) {
+ assert(Name && ShortDesc && ArchMatchFn &&
+ "Missing required target information!");
+
+ // Check if this target has already been initialized, we allow this as a
+ // convenience to some clients.
+ if (T.Name)
+ return;
+
+ // Add to the list of targets.
+ T.Next = FirstTarget;
+ FirstTarget = &T;
+
+ T.Name = Name;
+ T.ShortDesc = ShortDesc;
+ T.ArchMatchFn = ArchMatchFn;
+ T.HasJIT = HasJIT;
+}
+
+static int TargetArraySortFn(const std::pair<StringRef, const Target *> *LHS,
+ const std::pair<StringRef, const Target *> *RHS) {
+ return LHS->first.compare(RHS->first);
+}
+
+void TargetRegistry::printRegisteredTargetsForVersion() {
+ std::vector<std::pair<StringRef, const Target*> > Targets;
+ size_t Width = 0;
+ for (const auto &T : TargetRegistry::targets()) {
+ Targets.push_back(std::make_pair(T.getName(), &T));
+ Width = std::max(Width, Targets.back().first.size());
+ }
+ array_pod_sort(Targets.begin(), Targets.end(), TargetArraySortFn);
+
+ raw_ostream &OS = outs();
+ OS << " Registered Targets:\n";
+ for (unsigned i = 0, e = Targets.size(); i != e; ++i) {
+ OS << " " << Targets[i].first;
+ OS.indent(Width - Targets[i].first.size()) << " - "
+ << Targets[i].second->getShortDescription() << '\n';
+ }
+ if (Targets.empty())
+ OS << " (none)\n";
+}
diff --git a/contrib/llvm/lib/Support/ThreadLocal.cpp b/contrib/llvm/lib/Support/ThreadLocal.cpp
new file mode 100644
index 000000000000..9da1603080a2
--- /dev/null
+++ b/contrib/llvm/lib/Support/ThreadLocal.cpp
@@ -0,0 +1,48 @@
+//===- ThreadLocal.cpp - Thread Local Data ----------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the llvm::sys::ThreadLocal class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Config/config.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/ThreadLocal.h"
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only TRULY operating system
+//=== independent code.
+//===----------------------------------------------------------------------===//
+
+#if !defined(LLVM_ENABLE_THREADS) || LLVM_ENABLE_THREADS == 0
+// Define all methods as no-ops if threading is explicitly disabled
+namespace llvm {
+using namespace sys;
+ThreadLocalImpl::ThreadLocalImpl() : data() { }
+ThreadLocalImpl::~ThreadLocalImpl() { }
+void ThreadLocalImpl::setInstance(const void* d) {
+ static_assert(sizeof(d) <= sizeof(data), "size too big");
+ void **pd = reinterpret_cast<void**>(&data);
+ *pd = const_cast<void*>(d);
+}
+void *ThreadLocalImpl::getInstance() {
+ void **pd = reinterpret_cast<void**>(&data);
+ return *pd;
+}
+void ThreadLocalImpl::removeInstance() {
+ setInstance(nullptr);
+}
+}
+#elif defined(LLVM_ON_UNIX)
+#include "Unix/ThreadLocal.inc"
+#elif defined( LLVM_ON_WIN32)
+#include "Windows/ThreadLocal.inc"
+#else
+#warning Neither LLVM_ON_UNIX nor LLVM_ON_WIN32 set in Support/ThreadLocal.cpp
+#endif
diff --git a/contrib/llvm/lib/Support/Threading.cpp b/contrib/llvm/lib/Support/Threading.cpp
new file mode 100644
index 000000000000..ca7f3f64aa37
--- /dev/null
+++ b/contrib/llvm/lib/Support/Threading.cpp
@@ -0,0 +1,112 @@
+//===-- llvm/Support/Threading.cpp- Control multithreading mode --*- 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 helper functions for running LLVM in a multi-threaded
+// environment.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/Threading.h"
+#include "llvm/Config/config.h"
+#include "llvm/Support/Atomic.h"
+#include "llvm/Support/Mutex.h"
+#include <cassert>
+
+using namespace llvm;
+
+bool llvm::llvm_is_multithreaded() {
+#if LLVM_ENABLE_THREADS != 0
+ return true;
+#else
+ return false;
+#endif
+}
+
+#if LLVM_ENABLE_THREADS != 0 && defined(HAVE_PTHREAD_H)
+#include <pthread.h>
+
+struct ThreadInfo {
+ void (*UserFn)(void *);
+ void *UserData;
+};
+static void *ExecuteOnThread_Dispatch(void *Arg) {
+ ThreadInfo *TI = reinterpret_cast<ThreadInfo*>(Arg);
+ TI->UserFn(TI->UserData);
+ return nullptr;
+}
+
+void llvm::llvm_execute_on_thread(void (*Fn)(void*), void *UserData,
+ unsigned RequestedStackSize) {
+ ThreadInfo Info = { Fn, UserData };
+ pthread_attr_t Attr;
+ pthread_t Thread;
+
+ // Construct the attributes object.
+ if (::pthread_attr_init(&Attr) != 0)
+ return;
+
+ // Set the requested stack size, if given.
+ if (RequestedStackSize != 0) {
+ if (::pthread_attr_setstacksize(&Attr, RequestedStackSize) != 0)
+ goto error;
+ }
+
+ // Construct and execute the thread.
+ if (::pthread_create(&Thread, &Attr, ExecuteOnThread_Dispatch, &Info) != 0)
+ goto error;
+
+ // Wait for the thread and clean up.
+ ::pthread_join(Thread, nullptr);
+
+ error:
+ ::pthread_attr_destroy(&Attr);
+}
+#elif LLVM_ENABLE_THREADS!=0 && defined(LLVM_ON_WIN32)
+#include "Windows/WindowsSupport.h"
+#include <process.h>
+
+struct ThreadInfo {
+ void (*func)(void*);
+ void *param;
+};
+
+static unsigned __stdcall ThreadCallback(void *param) {
+ struct ThreadInfo *info = reinterpret_cast<struct ThreadInfo *>(param);
+ info->func(info->param);
+
+ return 0;
+}
+
+void llvm::llvm_execute_on_thread(void (*Fn)(void*), void *UserData,
+ unsigned RequestedStackSize) {
+ struct ThreadInfo param = { Fn, UserData };
+
+ HANDLE hThread = (HANDLE)::_beginthreadex(NULL,
+ RequestedStackSize, ThreadCallback,
+ &param, 0, NULL);
+
+ if (hThread) {
+ // We actually don't care whether the wait succeeds or fails, in
+ // the same way we don't care whether the pthread_join call succeeds
+ // or fails. There's not much we could do if this were to fail. But
+ // on success, this call will wait until the thread finishes executing
+ // before returning.
+ (void)::WaitForSingleObject(hThread, INFINITE);
+ ::CloseHandle(hThread);
+ }
+}
+#else
+// Support for non-Win32, non-pthread implementation.
+void llvm::llvm_execute_on_thread(void (*Fn)(void*), void *UserData,
+ unsigned RequestedStackSize) {
+ (void) RequestedStackSize;
+ Fn(UserData);
+}
+
+#endif
diff --git a/contrib/llvm/lib/Support/TimeValue.cpp b/contrib/llvm/lib/Support/TimeValue.cpp
new file mode 100644
index 000000000000..caa5b5aa7e53
--- /dev/null
+++ b/contrib/llvm/lib/Support/TimeValue.cpp
@@ -0,0 +1,56 @@
+//===-- TimeValue.cpp - Implement OS TimeValue Concept ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the operating system TimeValue concept.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/TimeValue.h"
+#include "llvm/Config/config.h"
+
+namespace llvm {
+using namespace sys;
+
+const TimeValue::SecondsType
+ TimeValue::PosixZeroTimeSeconds = -946684800;
+const TimeValue::SecondsType
+ TimeValue::Win32ZeroTimeSeconds = -12591158400ULL;
+
+void
+TimeValue::normalize( void ) {
+ if ( nanos_ >= NANOSECONDS_PER_SECOND ) {
+ do {
+ seconds_++;
+ nanos_ -= NANOSECONDS_PER_SECOND;
+ } while ( nanos_ >= NANOSECONDS_PER_SECOND );
+ } else if (nanos_ <= -NANOSECONDS_PER_SECOND ) {
+ do {
+ seconds_--;
+ nanos_ += NANOSECONDS_PER_SECOND;
+ } while (nanos_ <= -NANOSECONDS_PER_SECOND);
+ }
+
+ if (seconds_ >= 1 && nanos_ < 0) {
+ seconds_--;
+ nanos_ += NANOSECONDS_PER_SECOND;
+ } else if (seconds_ < 0 && nanos_ > 0) {
+ seconds_++;
+ nanos_ -= NANOSECONDS_PER_SECOND;
+ }
+}
+
+} // namespace llvm
+
+/// Include the platform-specific portion of TimeValue class
+#ifdef LLVM_ON_UNIX
+#include "Unix/TimeValue.inc"
+#endif
+#ifdef LLVM_ON_WIN32
+#include "Windows/TimeValue.inc"
+#endif
diff --git a/contrib/llvm/lib/Support/Timer.cpp b/contrib/llvm/lib/Support/Timer.cpp
new file mode 100644
index 000000000000..0ad253bec371
--- /dev/null
+++ b/contrib/llvm/lib/Support/Timer.cpp
@@ -0,0 +1,387 @@
+//===-- Timer.cpp - Interval Timing Support -------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Interval Timing implementation.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/Timer.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/Mutex.h"
+#include "llvm/Support/Process.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace llvm;
+
+// CreateInfoOutputFile - Return a file stream to print our output on.
+namespace llvm { extern raw_ostream *CreateInfoOutputFile(); }
+
+// getLibSupportInfoOutputFilename - This ugly hack is brought to you courtesy
+// of constructor/destructor ordering being unspecified by C++. Basically the
+// problem is that a Statistic object gets destroyed, which ends up calling
+// 'GetLibSupportInfoOutputFile()' (below), which calls this function.
+// LibSupportInfoOutputFilename used to be a global variable, but sometimes it
+// would get destroyed before the Statistic, causing havoc to ensue. We "fix"
+// this by creating the string the first time it is needed and never destroying
+// it.
+static ManagedStatic<std::string> LibSupportInfoOutputFilename;
+static std::string &getLibSupportInfoOutputFilename() {
+ return *LibSupportInfoOutputFilename;
+}
+
+static ManagedStatic<sys::SmartMutex<true> > TimerLock;
+
+namespace {
+ static cl::opt<bool>
+ TrackSpace("track-memory", cl::desc("Enable -time-passes memory "
+ "tracking (this may be slow)"),
+ cl::Hidden);
+
+ static cl::opt<std::string, true>
+ InfoOutputFilename("info-output-file", cl::value_desc("filename"),
+ cl::desc("File to append -stats and -timer output to"),
+ cl::Hidden, cl::location(getLibSupportInfoOutputFilename()));
+} // namespace
+
+// CreateInfoOutputFile - Return a file stream to print our output on.
+raw_ostream *llvm::CreateInfoOutputFile() {
+ const std::string &OutputFilename = getLibSupportInfoOutputFilename();
+ if (OutputFilename.empty())
+ return new raw_fd_ostream(2, false); // stderr.
+ if (OutputFilename == "-")
+ return new raw_fd_ostream(1, false); // stdout.
+
+ // Append mode is used because the info output file is opened and closed
+ // each time -stats or -time-passes wants to print output to it. To
+ // compensate for this, the test-suite Makefiles have code to delete the
+ // info output file before running commands which write to it.
+ std::error_code EC;
+ raw_ostream *Result = new raw_fd_ostream(OutputFilename, EC,
+ sys::fs::F_Append | sys::fs::F_Text);
+ if (!EC)
+ return Result;
+
+ errs() << "Error opening info-output-file '"
+ << OutputFilename << " for appending!\n";
+ delete Result;
+ return new raw_fd_ostream(2, false); // stderr.
+}
+
+
+static TimerGroup *DefaultTimerGroup = nullptr;
+static TimerGroup *getDefaultTimerGroup() {
+ TimerGroup *tmp = DefaultTimerGroup;
+ sys::MemoryFence();
+ if (tmp) return tmp;
+
+ sys::SmartScopedLock<true> Lock(*TimerLock);
+ tmp = DefaultTimerGroup;
+ if (!tmp) {
+ tmp = new TimerGroup("Miscellaneous Ungrouped Timers");
+ sys::MemoryFence();
+ DefaultTimerGroup = tmp;
+ }
+
+ return tmp;
+}
+
+//===----------------------------------------------------------------------===//
+// Timer Implementation
+//===----------------------------------------------------------------------===//
+
+void Timer::init(StringRef N) {
+ assert(!TG && "Timer already initialized");
+ Name.assign(N.begin(), N.end());
+ Started = false;
+ TG = getDefaultTimerGroup();
+ TG->addTimer(*this);
+}
+
+void Timer::init(StringRef N, TimerGroup &tg) {
+ assert(!TG && "Timer already initialized");
+ Name.assign(N.begin(), N.end());
+ Started = false;
+ TG = &tg;
+ TG->addTimer(*this);
+}
+
+Timer::~Timer() {
+ if (!TG) return; // Never initialized, or already cleared.
+ TG->removeTimer(*this);
+}
+
+static inline size_t getMemUsage() {
+ if (!TrackSpace) return 0;
+ return sys::Process::GetMallocUsage();
+}
+
+TimeRecord TimeRecord::getCurrentTime(bool Start) {
+ TimeRecord Result;
+ sys::TimeValue now(0,0), user(0,0), sys(0,0);
+
+ if (Start) {
+ Result.MemUsed = getMemUsage();
+ sys::Process::GetTimeUsage(now, user, sys);
+ } else {
+ sys::Process::GetTimeUsage(now, user, sys);
+ Result.MemUsed = getMemUsage();
+ }
+
+ Result.WallTime = now.seconds() + now.microseconds() / 1000000.0;
+ Result.UserTime = user.seconds() + user.microseconds() / 1000000.0;
+ Result.SystemTime = sys.seconds() + sys.microseconds() / 1000000.0;
+ return Result;
+}
+
+static ManagedStatic<std::vector<Timer*> > ActiveTimers;
+
+void Timer::startTimer() {
+ Started = true;
+ ActiveTimers->push_back(this);
+ Time -= TimeRecord::getCurrentTime(true);
+}
+
+void Timer::stopTimer() {
+ Time += TimeRecord::getCurrentTime(false);
+
+ if (ActiveTimers->back() == this) {
+ ActiveTimers->pop_back();
+ } else {
+ std::vector<Timer*>::iterator I =
+ std::find(ActiveTimers->begin(), ActiveTimers->end(), this);
+ assert(I != ActiveTimers->end() && "stop but no startTimer?");
+ ActiveTimers->erase(I);
+ }
+}
+
+static void printVal(double Val, double Total, raw_ostream &OS) {
+ if (Total < 1e-7) // Avoid dividing by zero.
+ OS << " ----- ";
+ else
+ OS << format(" %7.4f (%5.1f%%)", Val, Val*100/Total);
+}
+
+void TimeRecord::print(const TimeRecord &Total, raw_ostream &OS) const {
+ if (Total.getUserTime())
+ printVal(getUserTime(), Total.getUserTime(), OS);
+ if (Total.getSystemTime())
+ printVal(getSystemTime(), Total.getSystemTime(), OS);
+ if (Total.getProcessTime())
+ printVal(getProcessTime(), Total.getProcessTime(), OS);
+ printVal(getWallTime(), Total.getWallTime(), OS);
+
+ OS << " ";
+
+ if (Total.getMemUsed())
+ OS << format("%9" PRId64 " ", (int64_t)getMemUsed());
+}
+
+
+//===----------------------------------------------------------------------===//
+// NamedRegionTimer Implementation
+//===----------------------------------------------------------------------===//
+
+namespace {
+
+typedef StringMap<Timer> Name2TimerMap;
+
+class Name2PairMap {
+ StringMap<std::pair<TimerGroup*, Name2TimerMap> > Map;
+public:
+ ~Name2PairMap() {
+ for (StringMap<std::pair<TimerGroup*, Name2TimerMap> >::iterator
+ I = Map.begin(), E = Map.end(); I != E; ++I)
+ delete I->second.first;
+ }
+
+ Timer &get(StringRef Name, StringRef GroupName) {
+ sys::SmartScopedLock<true> L(*TimerLock);
+
+ std::pair<TimerGroup*, Name2TimerMap> &GroupEntry = Map[GroupName];
+
+ if (!GroupEntry.first)
+ GroupEntry.first = new TimerGroup(GroupName);
+
+ Timer &T = GroupEntry.second[Name];
+ if (!T.isInitialized())
+ T.init(Name, *GroupEntry.first);
+ return T;
+ }
+};
+
+} // namespace
+
+static ManagedStatic<Name2TimerMap> NamedTimers;
+static ManagedStatic<Name2PairMap> NamedGroupedTimers;
+
+static Timer &getNamedRegionTimer(StringRef Name) {
+ sys::SmartScopedLock<true> L(*TimerLock);
+
+ Timer &T = (*NamedTimers)[Name];
+ if (!T.isInitialized())
+ T.init(Name);
+ return T;
+}
+
+NamedRegionTimer::NamedRegionTimer(StringRef Name,
+ bool Enabled)
+ : TimeRegion(!Enabled ? nullptr : &getNamedRegionTimer(Name)) {}
+
+NamedRegionTimer::NamedRegionTimer(StringRef Name, StringRef GroupName,
+ bool Enabled)
+ : TimeRegion(!Enabled ? nullptr : &NamedGroupedTimers->get(Name, GroupName)){}
+
+//===----------------------------------------------------------------------===//
+// TimerGroup Implementation
+//===----------------------------------------------------------------------===//
+
+/// TimerGroupList - This is the global list of TimerGroups, maintained by the
+/// TimerGroup ctor/dtor and is protected by the TimerLock lock.
+static TimerGroup *TimerGroupList = nullptr;
+
+TimerGroup::TimerGroup(StringRef name)
+ : Name(name.begin(), name.end()), FirstTimer(nullptr) {
+
+ // Add the group to TimerGroupList.
+ sys::SmartScopedLock<true> L(*TimerLock);
+ if (TimerGroupList)
+ TimerGroupList->Prev = &Next;
+ Next = TimerGroupList;
+ Prev = &TimerGroupList;
+ TimerGroupList = this;
+}
+
+TimerGroup::~TimerGroup() {
+ // If the timer group is destroyed before the timers it owns, accumulate and
+ // print the timing data.
+ while (FirstTimer)
+ removeTimer(*FirstTimer);
+
+ // Remove the group from the TimerGroupList.
+ sys::SmartScopedLock<true> L(*TimerLock);
+ *Prev = Next;
+ if (Next)
+ Next->Prev = Prev;
+}
+
+
+void TimerGroup::removeTimer(Timer &T) {
+ sys::SmartScopedLock<true> L(*TimerLock);
+
+ // If the timer was started, move its data to TimersToPrint.
+ if (T.Started)
+ TimersToPrint.push_back(std::make_pair(T.Time, T.Name));
+
+ T.TG = nullptr;
+
+ // Unlink the timer from our list.
+ *T.Prev = T.Next;
+ if (T.Next)
+ T.Next->Prev = T.Prev;
+
+ // Print the report when all timers in this group are destroyed if some of
+ // them were started.
+ if (FirstTimer || TimersToPrint.empty())
+ return;
+
+ raw_ostream *OutStream = CreateInfoOutputFile();
+ PrintQueuedTimers(*OutStream);
+ delete OutStream; // Close the file.
+}
+
+void TimerGroup::addTimer(Timer &T) {
+ sys::SmartScopedLock<true> L(*TimerLock);
+
+ // Add the timer to our list.
+ if (FirstTimer)
+ FirstTimer->Prev = &T.Next;
+ T.Next = FirstTimer;
+ T.Prev = &FirstTimer;
+ FirstTimer = &T;
+}
+
+void TimerGroup::PrintQueuedTimers(raw_ostream &OS) {
+ // Sort the timers in descending order by amount of time taken.
+ std::sort(TimersToPrint.begin(), TimersToPrint.end());
+
+ TimeRecord Total;
+ for (unsigned i = 0, e = TimersToPrint.size(); i != e; ++i)
+ Total += TimersToPrint[i].first;
+
+ // Print out timing header.
+ OS << "===" << std::string(73, '-') << "===\n";
+ // Figure out how many spaces to indent TimerGroup name.
+ unsigned Padding = (80-Name.length())/2;
+ if (Padding > 80) Padding = 0; // Don't allow "negative" numbers
+ OS.indent(Padding) << Name << '\n';
+ OS << "===" << std::string(73, '-') << "===\n";
+
+ // If this is not an collection of ungrouped times, print the total time.
+ // Ungrouped timers don't really make sense to add up. We still print the
+ // TOTAL line to make the percentages make sense.
+ if (this != DefaultTimerGroup)
+ OS << format(" Total Execution Time: %5.4f seconds (%5.4f wall clock)\n",
+ Total.getProcessTime(), Total.getWallTime());
+ OS << '\n';
+
+ if (Total.getUserTime())
+ OS << " ---User Time---";
+ if (Total.getSystemTime())
+ OS << " --System Time--";
+ if (Total.getProcessTime())
+ OS << " --User+System--";
+ OS << " ---Wall Time---";
+ if (Total.getMemUsed())
+ OS << " ---Mem---";
+ OS << " --- Name ---\n";
+
+ // Loop through all of the timing data, printing it out.
+ for (unsigned i = 0, e = TimersToPrint.size(); i != e; ++i) {
+ const std::pair<TimeRecord, std::string> &Entry = TimersToPrint[e-i-1];
+ Entry.first.print(Total, OS);
+ OS << Entry.second << '\n';
+ }
+
+ Total.print(Total, OS);
+ OS << "Total\n\n";
+ OS.flush();
+
+ TimersToPrint.clear();
+}
+
+/// print - Print any started timers in this group and zero them.
+void TimerGroup::print(raw_ostream &OS) {
+ sys::SmartScopedLock<true> L(*TimerLock);
+
+ // See if any of our timers were started, if so add them to TimersToPrint and
+ // reset them.
+ for (Timer *T = FirstTimer; T; T = T->Next) {
+ if (!T->Started) continue;
+ TimersToPrint.push_back(std::make_pair(T->Time, T->Name));
+
+ // Clear out the time.
+ T->Started = 0;
+ T->Time = TimeRecord();
+ }
+
+ // If any timers were started, print the group.
+ if (!TimersToPrint.empty())
+ PrintQueuedTimers(OS);
+}
+
+/// printAll - This static method prints all timers and clears them all out.
+void TimerGroup::printAll(raw_ostream &OS) {
+ sys::SmartScopedLock<true> L(*TimerLock);
+
+ for (TimerGroup *TG = TimerGroupList; TG; TG = TG->Next)
+ TG->print(OS);
+}
diff --git a/contrib/llvm/lib/Support/ToolOutputFile.cpp b/contrib/llvm/lib/Support/ToolOutputFile.cpp
new file mode 100644
index 000000000000..8ae977db6a14
--- /dev/null
+++ b/contrib/llvm/lib/Support/ToolOutputFile.cpp
@@ -0,0 +1,46 @@
+//===--- ToolOutputFile.cpp - Implement the tool_output_file class --------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This implements the tool_output_file class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/ToolOutputFile.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Signals.h"
+using namespace llvm;
+
+tool_output_file::CleanupInstaller::CleanupInstaller(StringRef Filename)
+ : Filename(Filename), Keep(false) {
+ // Arrange for the file to be deleted if the process is killed.
+ if (Filename != "-")
+ sys::RemoveFileOnSignal(Filename);
+}
+
+tool_output_file::CleanupInstaller::~CleanupInstaller() {
+ // Delete the file if the client hasn't told us not to.
+ if (!Keep && Filename != "-")
+ sys::fs::remove(Filename);
+
+ // Ok, the file is successfully written and closed, or deleted. There's no
+ // further need to clean it up on signals.
+ if (Filename != "-")
+ sys::DontRemoveFileOnSignal(Filename);
+}
+
+tool_output_file::tool_output_file(StringRef Filename, std::error_code &EC,
+ sys::fs::OpenFlags Flags)
+ : Installer(Filename), OS(Filename, EC, Flags) {
+ // If open fails, no cleanup is needed.
+ if (EC)
+ Installer.Keep = true;
+}
+
+tool_output_file::tool_output_file(StringRef Filename, int FD)
+ : Installer(Filename), OS(FD, true) {}
diff --git a/contrib/llvm/lib/Support/Triple.cpp b/contrib/llvm/lib/Support/Triple.cpp
new file mode 100644
index 000000000000..072d4a0d79d8
--- /dev/null
+++ b/contrib/llvm/lib/Support/Triple.cpp
@@ -0,0 +1,1206 @@
+//===--- Triple.cpp - Target triple helper class --------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/Triple.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/TargetParser.h"
+#include "llvm/Support/Host.h"
+#include <cstring>
+using namespace llvm;
+
+const char *Triple::getArchTypeName(ArchType Kind) {
+ switch (Kind) {
+ case UnknownArch: return "unknown";
+
+ case aarch64: return "aarch64";
+ case aarch64_be: return "aarch64_be";
+ case arm: return "arm";
+ case armeb: return "armeb";
+ case bpfel: return "bpfel";
+ case bpfeb: return "bpfeb";
+ case hexagon: return "hexagon";
+ case mips: return "mips";
+ case mipsel: return "mipsel";
+ case mips64: return "mips64";
+ case mips64el: return "mips64el";
+ case msp430: return "msp430";
+ case ppc64: return "powerpc64";
+ case ppc64le: return "powerpc64le";
+ case ppc: return "powerpc";
+ case r600: return "r600";
+ case amdgcn: return "amdgcn";
+ case sparc: return "sparc";
+ case sparcv9: return "sparcv9";
+ case sparcel: return "sparcel";
+ case systemz: return "s390x";
+ case tce: return "tce";
+ case thumb: return "thumb";
+ case thumbeb: return "thumbeb";
+ case x86: return "i386";
+ case x86_64: return "x86_64";
+ case xcore: return "xcore";
+ case nvptx: return "nvptx";
+ case nvptx64: return "nvptx64";
+ case le32: return "le32";
+ case le64: return "le64";
+ case amdil: return "amdil";
+ case amdil64: return "amdil64";
+ case hsail: return "hsail";
+ case hsail64: return "hsail64";
+ case spir: return "spir";
+ case spir64: return "spir64";
+ case kalimba: return "kalimba";
+ case shave: return "shave";
+ }
+
+ llvm_unreachable("Invalid ArchType!");
+}
+
+const char *Triple::getArchTypePrefix(ArchType Kind) {
+ switch (Kind) {
+ default:
+ return nullptr;
+
+ case aarch64:
+ case aarch64_be: return "aarch64";
+
+ case arm:
+ case armeb:
+ case thumb:
+ case thumbeb: return "arm";
+
+ case ppc64:
+ case ppc64le:
+ case ppc: return "ppc";
+
+ case mips:
+ case mipsel:
+ case mips64:
+ case mips64el: return "mips";
+
+ case hexagon: return "hexagon";
+
+ case amdgcn:
+ case r600: return "amdgpu";
+
+ case bpfel:
+ case bpfeb: return "bpf";
+
+ case sparcv9:
+ case sparcel:
+ case sparc: return "sparc";
+
+ case systemz: return "s390";
+
+ case x86:
+ case x86_64: return "x86";
+
+ case xcore: return "xcore";
+
+ case nvptx: return "nvptx";
+ case nvptx64: return "nvptx";
+
+ case le32: return "le32";
+ case le64: return "le64";
+
+ case amdil:
+ case amdil64: return "amdil";
+
+ case hsail:
+ case hsail64: return "hsail";
+
+ case spir:
+ case spir64: return "spir";
+ case kalimba: return "kalimba";
+ case shave: return "shave";
+ }
+}
+
+const char *Triple::getVendorTypeName(VendorType Kind) {
+ switch (Kind) {
+ case UnknownVendor: return "unknown";
+
+ case Apple: return "apple";
+ case PC: return "pc";
+ case SCEI: return "scei";
+ case BGP: return "bgp";
+ case BGQ: return "bgq";
+ case Freescale: return "fsl";
+ case IBM: return "ibm";
+ case ImaginationTechnologies: return "img";
+ case MipsTechnologies: return "mti";
+ case NVIDIA: return "nvidia";
+ case CSR: return "csr";
+ }
+
+ llvm_unreachable("Invalid VendorType!");
+}
+
+const char *Triple::getOSTypeName(OSType Kind) {
+ switch (Kind) {
+ case UnknownOS: return "unknown";
+
+ case CloudABI: return "cloudabi";
+ case Darwin: return "darwin";
+ case DragonFly: return "dragonfly";
+ case FreeBSD: return "freebsd";
+ case IOS: return "ios";
+ case KFreeBSD: return "kfreebsd";
+ case Linux: return "linux";
+ case Lv2: return "lv2";
+ case MacOSX: return "macosx";
+ case NetBSD: return "netbsd";
+ case OpenBSD: return "openbsd";
+ case Solaris: return "solaris";
+ case Win32: return "windows";
+ case Haiku: return "haiku";
+ case Minix: return "minix";
+ case RTEMS: return "rtems";
+ case NaCl: return "nacl";
+ case CNK: return "cnk";
+ case Bitrig: return "bitrig";
+ case AIX: return "aix";
+ case CUDA: return "cuda";
+ case NVCL: return "nvcl";
+ case AMDHSA: return "amdhsa";
+ case PS4: return "ps4";
+ }
+
+ llvm_unreachable("Invalid OSType");
+}
+
+const char *Triple::getEnvironmentTypeName(EnvironmentType Kind) {
+ switch (Kind) {
+ case UnknownEnvironment: return "unknown";
+ case GNU: return "gnu";
+ case GNUEABIHF: return "gnueabihf";
+ case GNUEABI: return "gnueabi";
+ case GNUX32: return "gnux32";
+ case CODE16: return "code16";
+ case EABI: return "eabi";
+ case EABIHF: return "eabihf";
+ case Android: return "android";
+ case MSVC: return "msvc";
+ case Itanium: return "itanium";
+ case Cygnus: return "cygnus";
+ }
+
+ llvm_unreachable("Invalid EnvironmentType!");
+}
+
+static Triple::ArchType parseBPFArch(StringRef ArchName) {
+ if (ArchName.equals("bpf")) {
+ if (sys::IsLittleEndianHost)
+ return Triple::bpfel;
+ else
+ return Triple::bpfeb;
+ } else if (ArchName.equals("bpf_be") || ArchName.equals("bpfeb")) {
+ return Triple::bpfeb;
+ } else if (ArchName.equals("bpf_le") || ArchName.equals("bpfel")) {
+ return Triple::bpfel;
+ } else {
+ return Triple::UnknownArch;
+ }
+}
+
+Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
+ Triple::ArchType BPFArch(parseBPFArch(Name));
+ return StringSwitch<Triple::ArchType>(Name)
+ .Case("aarch64", aarch64)
+ .Case("aarch64_be", aarch64_be)
+ .Case("arm64", aarch64) // "arm64" is an alias for "aarch64"
+ .Case("arm", arm)
+ .Case("armeb", armeb)
+ .StartsWith("bpf", BPFArch)
+ .Case("mips", mips)
+ .Case("mipsel", mipsel)
+ .Case("mips64", mips64)
+ .Case("mips64el", mips64el)
+ .Case("msp430", msp430)
+ .Case("ppc64", ppc64)
+ .Case("ppc32", ppc)
+ .Case("ppc", ppc)
+ .Case("ppc64le", ppc64le)
+ .Case("r600", r600)
+ .Case("amdgcn", amdgcn)
+ .Case("hexagon", hexagon)
+ .Case("sparc", sparc)
+ .Case("sparcel", sparcel)
+ .Case("sparcv9", sparcv9)
+ .Case("systemz", systemz)
+ .Case("tce", tce)
+ .Case("thumb", thumb)
+ .Case("thumbeb", thumbeb)
+ .Case("x86", x86)
+ .Case("x86-64", x86_64)
+ .Case("xcore", xcore)
+ .Case("nvptx", nvptx)
+ .Case("nvptx64", nvptx64)
+ .Case("le32", le32)
+ .Case("le64", le64)
+ .Case("amdil", amdil)
+ .Case("amdil64", amdil64)
+ .Case("hsail", hsail)
+ .Case("hsail64", hsail64)
+ .Case("spir", spir)
+ .Case("spir64", spir64)
+ .Case("kalimba", kalimba)
+ .Case("shave", shave)
+ .Default(UnknownArch);
+}
+
+static Triple::ArchType parseARMArch(StringRef ArchName) {
+ unsigned ISA = ARMTargetParser::parseArchISA(ArchName);
+ unsigned ENDIAN = ARMTargetParser::parseArchEndian(ArchName);
+
+ Triple::ArchType arch = Triple::UnknownArch;
+ switch (ENDIAN) {
+ case ARM::EK_LITTLE: {
+ switch (ISA) {
+ case ARM::IK_ARM:
+ arch = Triple::arm;
+ break;
+ case ARM::IK_THUMB:
+ arch = Triple::thumb;
+ break;
+ case ARM::IK_AARCH64:
+ arch = Triple::aarch64;
+ break;
+ }
+ break;
+ }
+ case ARM::EK_BIG: {
+ switch (ISA) {
+ case ARM::IK_ARM:
+ arch = Triple::armeb;
+ break;
+ case ARM::IK_THUMB:
+ arch = Triple::thumbeb;
+ break;
+ case ARM::IK_AARCH64:
+ arch = Triple::aarch64_be;
+ break;
+ }
+ break;
+ }
+ }
+
+ ArchName = ARMTargetParser::getCanonicalArchName(ArchName);
+ if (ArchName.empty())
+ return Triple::UnknownArch;
+
+ // Thumb only exists in v4+
+ if (ISA == ARM::IK_THUMB &&
+ (ArchName.startswith("v2") || ArchName.startswith("v3")))
+ return Triple::UnknownArch;
+
+ // Thumb only for v6m
+ unsigned Profile = ARMTargetParser::parseArchProfile(ArchName);
+ unsigned Version = ARMTargetParser::parseArchVersion(ArchName);
+ if (Profile == ARM::PK_M && Version == 6) {
+ if (ENDIAN == ARM::EK_BIG)
+ return Triple::thumbeb;
+ else
+ return Triple::thumb;
+ }
+
+ return arch;
+}
+
+static Triple::ArchType parseArch(StringRef ArchName) {
+ Triple::ArchType ARMArch(parseARMArch(ArchName));
+ Triple::ArchType BPFArch(parseBPFArch(ArchName));
+
+ return StringSwitch<Triple::ArchType>(ArchName)
+ .Cases("i386", "i486", "i586", "i686", Triple::x86)
+ // FIXME: Do we need to support these?
+ .Cases("i786", "i886", "i986", Triple::x86)
+ .Cases("amd64", "x86_64", "x86_64h", Triple::x86_64)
+ .Case("powerpc", Triple::ppc)
+ .Cases("powerpc64", "ppu", Triple::ppc64)
+ .Case("powerpc64le", Triple::ppc64le)
+ .Case("xscale", Triple::arm)
+ .Case("xscaleeb", Triple::armeb)
+ .StartsWith("arm", ARMArch)
+ .StartsWith("thumb", ARMArch)
+ .StartsWith("aarch64", ARMArch)
+ .Case("msp430", Triple::msp430)
+ .Cases("mips", "mipseb", "mipsallegrex", Triple::mips)
+ .Cases("mipsel", "mipsallegrexel", Triple::mipsel)
+ .Cases("mips64", "mips64eb", Triple::mips64)
+ .Case("mips64el", Triple::mips64el)
+ .Case("r600", Triple::r600)
+ .Case("amdgcn", Triple::amdgcn)
+ .StartsWith("bpf", BPFArch)
+ .Case("hexagon", Triple::hexagon)
+ .Case("s390x", Triple::systemz)
+ .Case("sparc", Triple::sparc)
+ .Case("sparcel", Triple::sparcel)
+ .Cases("sparcv9", "sparc64", Triple::sparcv9)
+ .Case("tce", Triple::tce)
+ .Case("xcore", Triple::xcore)
+ .Case("nvptx", Triple::nvptx)
+ .Case("nvptx64", Triple::nvptx64)
+ .Case("le32", Triple::le32)
+ .Case("le64", Triple::le64)
+ .Case("amdil", Triple::amdil)
+ .Case("amdil64", Triple::amdil64)
+ .Case("hsail", Triple::hsail)
+ .Case("hsail64", Triple::hsail64)
+ .Case("spir", Triple::spir)
+ .Case("spir64", Triple::spir64)
+ .StartsWith("kalimba", Triple::kalimba)
+ .Case("shave", Triple::shave)
+ .Default(Triple::UnknownArch);
+}
+
+static Triple::VendorType parseVendor(StringRef VendorName) {
+ return StringSwitch<Triple::VendorType>(VendorName)
+ .Case("apple", Triple::Apple)
+ .Case("pc", Triple::PC)
+ .Case("scei", Triple::SCEI)
+ .Case("bgp", Triple::BGP)
+ .Case("bgq", Triple::BGQ)
+ .Case("fsl", Triple::Freescale)
+ .Case("ibm", Triple::IBM)
+ .Case("img", Triple::ImaginationTechnologies)
+ .Case("mti", Triple::MipsTechnologies)
+ .Case("nvidia", Triple::NVIDIA)
+ .Case("csr", Triple::CSR)
+ .Default(Triple::UnknownVendor);
+}
+
+static Triple::OSType parseOS(StringRef OSName) {
+ return StringSwitch<Triple::OSType>(OSName)
+ .StartsWith("cloudabi", Triple::CloudABI)
+ .StartsWith("darwin", Triple::Darwin)
+ .StartsWith("dragonfly", Triple::DragonFly)
+ .StartsWith("freebsd", Triple::FreeBSD)
+ .StartsWith("ios", Triple::IOS)
+ .StartsWith("kfreebsd", Triple::KFreeBSD)
+ .StartsWith("linux", Triple::Linux)
+ .StartsWith("lv2", Triple::Lv2)
+ .StartsWith("macosx", Triple::MacOSX)
+ .StartsWith("netbsd", Triple::NetBSD)
+ .StartsWith("openbsd", Triple::OpenBSD)
+ .StartsWith("solaris", Triple::Solaris)
+ .StartsWith("win32", Triple::Win32)
+ .StartsWith("windows", Triple::Win32)
+ .StartsWith("haiku", Triple::Haiku)
+ .StartsWith("minix", Triple::Minix)
+ .StartsWith("rtems", Triple::RTEMS)
+ .StartsWith("nacl", Triple::NaCl)
+ .StartsWith("cnk", Triple::CNK)
+ .StartsWith("bitrig", Triple::Bitrig)
+ .StartsWith("aix", Triple::AIX)
+ .StartsWith("cuda", Triple::CUDA)
+ .StartsWith("nvcl", Triple::NVCL)
+ .StartsWith("amdhsa", Triple::AMDHSA)
+ .StartsWith("ps4", Triple::PS4)
+ .Default(Triple::UnknownOS);
+}
+
+static Triple::EnvironmentType parseEnvironment(StringRef EnvironmentName) {
+ return StringSwitch<Triple::EnvironmentType>(EnvironmentName)
+ .StartsWith("eabihf", Triple::EABIHF)
+ .StartsWith("eabi", Triple::EABI)
+ .StartsWith("gnueabihf", Triple::GNUEABIHF)
+ .StartsWith("gnueabi", Triple::GNUEABI)
+ .StartsWith("gnux32", Triple::GNUX32)
+ .StartsWith("code16", Triple::CODE16)
+ .StartsWith("gnu", Triple::GNU)
+ .StartsWith("android", Triple::Android)
+ .StartsWith("msvc", Triple::MSVC)
+ .StartsWith("itanium", Triple::Itanium)
+ .StartsWith("cygnus", Triple::Cygnus)
+ .Default(Triple::UnknownEnvironment);
+}
+
+static Triple::ObjectFormatType parseFormat(StringRef EnvironmentName) {
+ return StringSwitch<Triple::ObjectFormatType>(EnvironmentName)
+ .EndsWith("coff", Triple::COFF)
+ .EndsWith("elf", Triple::ELF)
+ .EndsWith("macho", Triple::MachO)
+ .Default(Triple::UnknownObjectFormat);
+}
+
+static Triple::SubArchType parseSubArch(StringRef SubArchName) {
+ StringRef ARMSubArch = ARMTargetParser::getCanonicalArchName(SubArchName);
+
+ // For now, this is the small part. Early return.
+ if (ARMSubArch.empty())
+ return StringSwitch<Triple::SubArchType>(SubArchName)
+ .EndsWith("kalimba3", Triple::KalimbaSubArch_v3)
+ .EndsWith("kalimba4", Triple::KalimbaSubArch_v4)
+ .EndsWith("kalimba5", Triple::KalimbaSubArch_v5)
+ .Default(Triple::NoSubArch);
+
+ // ARM sub arch.
+ switch(ARMTargetParser::parseArch(ARMSubArch)) {
+ case ARM::AK_ARMV4:
+ return Triple::NoSubArch;
+ case ARM::AK_ARMV4T:
+ return Triple::ARMSubArch_v4t;
+ case ARM::AK_ARMV5:
+ case ARM::AK_ARMV5T:
+ case ARM::AK_ARMV5E:
+ return Triple::ARMSubArch_v5;
+ case ARM::AK_ARMV5TE:
+ case ARM::AK_IWMMXT:
+ case ARM::AK_IWMMXT2:
+ case ARM::AK_XSCALE:
+ case ARM::AK_ARMV5TEJ:
+ return Triple::ARMSubArch_v5te;
+ case ARM::AK_ARMV6:
+ case ARM::AK_ARMV6J:
+ case ARM::AK_ARMV6Z:
+ return Triple::ARMSubArch_v6;
+ case ARM::AK_ARMV6K:
+ case ARM::AK_ARMV6ZK:
+ case ARM::AK_ARMV6HL:
+ return Triple::ARMSubArch_v6k;
+ case ARM::AK_ARMV6T2:
+ return Triple::ARMSubArch_v6t2;
+ case ARM::AK_ARMV6M:
+ case ARM::AK_ARMV6SM:
+ return Triple::ARMSubArch_v6m;
+ case ARM::AK_ARMV7:
+ case ARM::AK_ARMV7A:
+ case ARM::AK_ARMV7R:
+ case ARM::AK_ARMV7L:
+ case ARM::AK_ARMV7HL:
+ return Triple::ARMSubArch_v7;
+ case ARM::AK_ARMV7M:
+ return Triple::ARMSubArch_v7m;
+ case ARM::AK_ARMV7S:
+ return Triple::ARMSubArch_v7s;
+ case ARM::AK_ARMV7EM:
+ return Triple::ARMSubArch_v7em;
+ case ARM::AK_ARMV8A:
+ return Triple::ARMSubArch_v8;
+ case ARM::AK_ARMV8_1A:
+ return Triple::ARMSubArch_v8_1a;
+ default:
+ return Triple::NoSubArch;
+ }
+}
+
+static const char *getObjectFormatTypeName(Triple::ObjectFormatType Kind) {
+ switch (Kind) {
+ case Triple::UnknownObjectFormat: return "";
+ case Triple::COFF: return "coff";
+ case Triple::ELF: return "elf";
+ case Triple::MachO: return "macho";
+ }
+ llvm_unreachable("unknown object format type");
+}
+
+static Triple::ObjectFormatType getDefaultFormat(const Triple &T) {
+ switch (T.getArch()) {
+ default:
+ break;
+ case Triple::hexagon:
+ case Triple::mips:
+ case Triple::mipsel:
+ case Triple::mips64:
+ case Triple::mips64el:
+ case Triple::r600:
+ case Triple::amdgcn:
+ case Triple::sparc:
+ case Triple::sparcv9:
+ case Triple::systemz:
+ case Triple::xcore:
+ case Triple::ppc64le:
+ return Triple::ELF;
+
+ case Triple::ppc:
+ case Triple::ppc64:
+ if (T.isOSDarwin())
+ return Triple::MachO;
+ return Triple::ELF;
+ }
+
+ if (T.isOSDarwin())
+ return Triple::MachO;
+ else if (T.isOSWindows())
+ return Triple::COFF;
+ return Triple::ELF;
+}
+
+/// \brief Construct a triple from the string representation provided.
+///
+/// This stores the string representation and parses the various pieces into
+/// enum members.
+Triple::Triple(const Twine &Str)
+ : Data(Str.str()),
+ Arch(parseArch(getArchName())),
+ SubArch(parseSubArch(getArchName())),
+ Vendor(parseVendor(getVendorName())),
+ OS(parseOS(getOSName())),
+ Environment(parseEnvironment(getEnvironmentName())),
+ ObjectFormat(parseFormat(getEnvironmentName())) {
+ if (ObjectFormat == Triple::UnknownObjectFormat)
+ ObjectFormat = getDefaultFormat(*this);
+}
+
+/// \brief Construct a triple from string representations of the architecture,
+/// vendor, and OS.
+///
+/// This joins each argument into a canonical string representation and parses
+/// them into enum members. It leaves the environment unknown and omits it from
+/// the string representation.
+Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr)
+ : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr).str()),
+ Arch(parseArch(ArchStr.str())),
+ SubArch(parseSubArch(ArchStr.str())),
+ Vendor(parseVendor(VendorStr.str())),
+ OS(parseOS(OSStr.str())),
+ Environment(), ObjectFormat(Triple::UnknownObjectFormat) {
+ ObjectFormat = getDefaultFormat(*this);
+}
+
+/// \brief Construct a triple from string representations of the architecture,
+/// vendor, OS, and environment.
+///
+/// This joins each argument into a canonical string representation and parses
+/// them into enum members.
+Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr,
+ const Twine &EnvironmentStr)
+ : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr + Twine('-') +
+ EnvironmentStr).str()),
+ Arch(parseArch(ArchStr.str())),
+ SubArch(parseSubArch(ArchStr.str())),
+ Vendor(parseVendor(VendorStr.str())),
+ OS(parseOS(OSStr.str())),
+ Environment(parseEnvironment(EnvironmentStr.str())),
+ ObjectFormat(parseFormat(EnvironmentStr.str())) {
+ if (ObjectFormat == Triple::UnknownObjectFormat)
+ ObjectFormat = getDefaultFormat(*this);
+}
+
+std::string Triple::normalize(StringRef Str) {
+ bool IsMinGW32 = false;
+ bool IsCygwin = false;
+
+ // Parse into components.
+ SmallVector<StringRef, 4> Components;
+ Str.split(Components, "-");
+
+ // If the first component corresponds to a known architecture, preferentially
+ // use it for the architecture. If the second component corresponds to a
+ // known vendor, preferentially use it for the vendor, etc. This avoids silly
+ // component movement when a component parses as (eg) both a valid arch and a
+ // valid os.
+ ArchType Arch = UnknownArch;
+ if (Components.size() > 0)
+ Arch = parseArch(Components[0]);
+ VendorType Vendor = UnknownVendor;
+ if (Components.size() > 1)
+ Vendor = parseVendor(Components[1]);
+ OSType OS = UnknownOS;
+ if (Components.size() > 2) {
+ OS = parseOS(Components[2]);
+ IsCygwin = Components[2].startswith("cygwin");
+ IsMinGW32 = Components[2].startswith("mingw");
+ }
+ EnvironmentType Environment = UnknownEnvironment;
+ if (Components.size() > 3)
+ Environment = parseEnvironment(Components[3]);
+ ObjectFormatType ObjectFormat = UnknownObjectFormat;
+ if (Components.size() > 4)
+ ObjectFormat = parseFormat(Components[4]);
+
+ // Note which components are already in their final position. These will not
+ // be moved.
+ bool Found[4];
+ Found[0] = Arch != UnknownArch;
+ Found[1] = Vendor != UnknownVendor;
+ Found[2] = OS != UnknownOS;
+ Found[3] = Environment != UnknownEnvironment;
+
+ // If they are not there already, permute the components into their canonical
+ // positions by seeing if they parse as a valid architecture, and if so moving
+ // the component to the architecture position etc.
+ for (unsigned Pos = 0; Pos != array_lengthof(Found); ++Pos) {
+ if (Found[Pos])
+ continue; // Already in the canonical position.
+
+ for (unsigned Idx = 0; Idx != Components.size(); ++Idx) {
+ // Do not reparse any components that already matched.
+ if (Idx < array_lengthof(Found) && Found[Idx])
+ continue;
+
+ // Does this component parse as valid for the target position?
+ bool Valid = false;
+ StringRef Comp = Components[Idx];
+ switch (Pos) {
+ default: llvm_unreachable("unexpected component type!");
+ case 0:
+ Arch = parseArch(Comp);
+ Valid = Arch != UnknownArch;
+ break;
+ case 1:
+ Vendor = parseVendor(Comp);
+ Valid = Vendor != UnknownVendor;
+ break;
+ case 2:
+ OS = parseOS(Comp);
+ IsCygwin = Comp.startswith("cygwin");
+ IsMinGW32 = Comp.startswith("mingw");
+ Valid = OS != UnknownOS || IsCygwin || IsMinGW32;
+ break;
+ case 3:
+ Environment = parseEnvironment(Comp);
+ Valid = Environment != UnknownEnvironment;
+ if (!Valid) {
+ ObjectFormat = parseFormat(Comp);
+ Valid = ObjectFormat != UnknownObjectFormat;
+ }
+ break;
+ }
+ if (!Valid)
+ continue; // Nope, try the next component.
+
+ // Move the component to the target position, pushing any non-fixed
+ // components that are in the way to the right. This tends to give
+ // good results in the common cases of a forgotten vendor component
+ // or a wrongly positioned environment.
+ if (Pos < Idx) {
+ // Insert left, pushing the existing components to the right. For
+ // example, a-b-i386 -> i386-a-b when moving i386 to the front.
+ StringRef CurrentComponent(""); // The empty component.
+ // Replace the component we are moving with an empty component.
+ std::swap(CurrentComponent, Components[Idx]);
+ // Insert the component being moved at Pos, displacing any existing
+ // components to the right.
+ for (unsigned i = Pos; !CurrentComponent.empty(); ++i) {
+ // Skip over any fixed components.
+ while (i < array_lengthof(Found) && Found[i])
+ ++i;
+ // Place the component at the new position, getting the component
+ // that was at this position - it will be moved right.
+ std::swap(CurrentComponent, Components[i]);
+ }
+ } else if (Pos > Idx) {
+ // Push right by inserting empty components until the component at Idx
+ // reaches the target position Pos. For example, pc-a -> -pc-a when
+ // moving pc to the second position.
+ do {
+ // Insert one empty component at Idx.
+ StringRef CurrentComponent(""); // The empty component.
+ for (unsigned i = Idx; i < Components.size();) {
+ // Place the component at the new position, getting the component
+ // that was at this position - it will be moved right.
+ std::swap(CurrentComponent, Components[i]);
+ // If it was placed on top of an empty component then we are done.
+ if (CurrentComponent.empty())
+ break;
+ // Advance to the next component, skipping any fixed components.
+ while (++i < array_lengthof(Found) && Found[i])
+ ;
+ }
+ // The last component was pushed off the end - append it.
+ if (!CurrentComponent.empty())
+ Components.push_back(CurrentComponent);
+
+ // Advance Idx to the component's new position.
+ while (++Idx < array_lengthof(Found) && Found[Idx])
+ ;
+ } while (Idx < Pos); // Add more until the final position is reached.
+ }
+ assert(Pos < Components.size() && Components[Pos] == Comp &&
+ "Component moved wrong!");
+ Found[Pos] = true;
+ break;
+ }
+ }
+
+ // Special case logic goes here. At this point Arch, Vendor and OS have the
+ // correct values for the computed components.
+ std::string NormalizedEnvironment;
+ if (Environment == Triple::Android && Components[3].startswith("androideabi")) {
+ StringRef AndroidVersion = Components[3].drop_front(strlen("androideabi"));
+ if (AndroidVersion.empty()) {
+ Components[3] = "android";
+ } else {
+ NormalizedEnvironment = Twine("android", AndroidVersion).str();
+ Components[3] = NormalizedEnvironment;
+ }
+ }
+
+ if (OS == Triple::Win32) {
+ Components.resize(4);
+ Components[2] = "windows";
+ if (Environment == UnknownEnvironment) {
+ if (ObjectFormat == UnknownObjectFormat || ObjectFormat == Triple::COFF)
+ Components[3] = "msvc";
+ else
+ Components[3] = getObjectFormatTypeName(ObjectFormat);
+ }
+ } else if (IsMinGW32) {
+ Components.resize(4);
+ Components[2] = "windows";
+ Components[3] = "gnu";
+ } else if (IsCygwin) {
+ Components.resize(4);
+ Components[2] = "windows";
+ Components[3] = "cygnus";
+ }
+ if (IsMinGW32 || IsCygwin ||
+ (OS == Triple::Win32 && Environment != UnknownEnvironment)) {
+ if (ObjectFormat != UnknownObjectFormat && ObjectFormat != Triple::COFF) {
+ Components.resize(5);
+ Components[4] = getObjectFormatTypeName(ObjectFormat);
+ }
+ }
+
+ // Stick the corrected components back together to form the normalized string.
+ std::string Normalized;
+ for (unsigned i = 0, e = Components.size(); i != e; ++i) {
+ if (i) Normalized += '-';
+ Normalized += Components[i];
+ }
+ return Normalized;
+}
+
+StringRef Triple::getArchName() const {
+ return StringRef(Data).split('-').first; // Isolate first component
+}
+
+StringRef Triple::getVendorName() const {
+ StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
+ return Tmp.split('-').first; // Isolate second component
+}
+
+StringRef Triple::getOSName() const {
+ StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
+ Tmp = Tmp.split('-').second; // Strip second component
+ return Tmp.split('-').first; // Isolate third component
+}
+
+StringRef Triple::getEnvironmentName() const {
+ StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
+ Tmp = Tmp.split('-').second; // Strip second component
+ return Tmp.split('-').second; // Strip third component
+}
+
+StringRef Triple::getOSAndEnvironmentName() const {
+ StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
+ return Tmp.split('-').second; // Strip second component
+}
+
+static unsigned EatNumber(StringRef &Str) {
+ assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number");
+ unsigned Result = 0;
+
+ do {
+ // Consume the leading digit.
+ Result = Result*10 + (Str[0] - '0');
+
+ // Eat the digit.
+ Str = Str.substr(1);
+ } while (!Str.empty() && Str[0] >= '0' && Str[0] <= '9');
+
+ return Result;
+}
+
+static void parseVersionFromName(StringRef Name, unsigned &Major,
+ unsigned &Minor, unsigned &Micro) {
+ // Any unset version defaults to 0.
+ Major = Minor = Micro = 0;
+
+ // Parse up to three components.
+ unsigned *Components[3] = {&Major, &Minor, &Micro};
+ for (unsigned i = 0; i != 3; ++i) {
+ if (Name.empty() || Name[0] < '0' || Name[0] > '9')
+ break;
+
+ // Consume the leading number.
+ *Components[i] = EatNumber(Name);
+
+ // Consume the separator, if present.
+ if (Name.startswith("."))
+ Name = Name.substr(1);
+ }
+}
+
+void Triple::getEnvironmentVersion(unsigned &Major, unsigned &Minor,
+ unsigned &Micro) const {
+ StringRef EnvironmentName = getEnvironmentName();
+ StringRef EnvironmentTypeName = getEnvironmentTypeName(getEnvironment());
+ if (EnvironmentName.startswith(EnvironmentTypeName))
+ EnvironmentName = EnvironmentName.substr(EnvironmentTypeName.size());
+
+ parseVersionFromName(EnvironmentName, Major, Minor, Micro);
+}
+
+void Triple::getOSVersion(unsigned &Major, unsigned &Minor,
+ unsigned &Micro) const {
+ StringRef OSName = getOSName();
+ // Assume that the OS portion of the triple starts with the canonical name.
+ StringRef OSTypeName = getOSTypeName(getOS());
+ if (OSName.startswith(OSTypeName))
+ OSName = OSName.substr(OSTypeName.size());
+
+ parseVersionFromName(OSName, Major, Minor, Micro);
+}
+
+bool Triple::getMacOSXVersion(unsigned &Major, unsigned &Minor,
+ unsigned &Micro) const {
+ getOSVersion(Major, Minor, Micro);
+
+ switch (getOS()) {
+ default: llvm_unreachable("unexpected OS for Darwin triple");
+ case Darwin:
+ // Default to darwin8, i.e., MacOSX 10.4.
+ if (Major == 0)
+ Major = 8;
+ // Darwin version numbers are skewed from OS X versions.
+ if (Major < 4)
+ return false;
+ Micro = 0;
+ Minor = Major - 4;
+ Major = 10;
+ break;
+ case MacOSX:
+ // Default to 10.4.
+ if (Major == 0) {
+ Major = 10;
+ Minor = 4;
+ }
+ if (Major != 10)
+ return false;
+ break;
+ case IOS:
+ // Ignore the version from the triple. This is only handled because the
+ // the clang driver combines OS X and IOS support into a common Darwin
+ // toolchain that wants to know the OS X version number even when targeting
+ // IOS.
+ Major = 10;
+ Minor = 4;
+ Micro = 0;
+ break;
+ }
+ return true;
+}
+
+void Triple::getiOSVersion(unsigned &Major, unsigned &Minor,
+ unsigned &Micro) const {
+ switch (getOS()) {
+ default: llvm_unreachable("unexpected OS for Darwin triple");
+ case Darwin:
+ case MacOSX:
+ // Ignore the version from the triple. This is only handled because the
+ // the clang driver combines OS X and IOS support into a common Darwin
+ // toolchain that wants to know the iOS version number even when targeting
+ // OS X.
+ Major = 5;
+ Minor = 0;
+ Micro = 0;
+ break;
+ case IOS:
+ getOSVersion(Major, Minor, Micro);
+ // Default to 5.0 (or 7.0 for arm64).
+ if (Major == 0)
+ Major = (getArch() == aarch64) ? 7 : 5;
+ break;
+ }
+}
+
+void Triple::setTriple(const Twine &Str) {
+ *this = Triple(Str);
+}
+
+void Triple::setArch(ArchType Kind) {
+ setArchName(getArchTypeName(Kind));
+}
+
+void Triple::setVendor(VendorType Kind) {
+ setVendorName(getVendorTypeName(Kind));
+}
+
+void Triple::setOS(OSType Kind) {
+ setOSName(getOSTypeName(Kind));
+}
+
+void Triple::setEnvironment(EnvironmentType Kind) {
+ if (ObjectFormat == getDefaultFormat(*this))
+ return setEnvironmentName(getEnvironmentTypeName(Kind));
+
+ setEnvironmentName((getEnvironmentTypeName(Kind) + Twine("-") +
+ getObjectFormatTypeName(ObjectFormat)).str());
+}
+
+void Triple::setObjectFormat(ObjectFormatType Kind) {
+ if (Environment == UnknownEnvironment)
+ return setEnvironmentName(getObjectFormatTypeName(Kind));
+
+ setEnvironmentName((getEnvironmentTypeName(Environment) + Twine("-") +
+ getObjectFormatTypeName(Kind)).str());
+}
+
+void Triple::setArchName(StringRef Str) {
+ // Work around a miscompilation bug for Twines in gcc 4.0.3.
+ SmallString<64> Triple;
+ Triple += Str;
+ Triple += "-";
+ Triple += getVendorName();
+ Triple += "-";
+ Triple += getOSAndEnvironmentName();
+ setTriple(Triple);
+}
+
+void Triple::setVendorName(StringRef Str) {
+ setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName());
+}
+
+void Triple::setOSName(StringRef Str) {
+ if (hasEnvironment())
+ setTriple(getArchName() + "-" + getVendorName() + "-" + Str +
+ "-" + getEnvironmentName());
+ else
+ setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
+}
+
+void Triple::setEnvironmentName(StringRef Str) {
+ setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() +
+ "-" + Str);
+}
+
+void Triple::setOSAndEnvironmentName(StringRef Str) {
+ setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
+}
+
+static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
+ switch (Arch) {
+ case llvm::Triple::UnknownArch:
+ return 0;
+
+ case llvm::Triple::msp430:
+ return 16;
+
+ case llvm::Triple::arm:
+ case llvm::Triple::armeb:
+ case llvm::Triple::hexagon:
+ case llvm::Triple::le32:
+ case llvm::Triple::mips:
+ case llvm::Triple::mipsel:
+ case llvm::Triple::nvptx:
+ case llvm::Triple::ppc:
+ case llvm::Triple::r600:
+ case llvm::Triple::sparc:
+ case llvm::Triple::sparcel:
+ case llvm::Triple::tce:
+ case llvm::Triple::thumb:
+ case llvm::Triple::thumbeb:
+ case llvm::Triple::x86:
+ case llvm::Triple::xcore:
+ case llvm::Triple::amdil:
+ case llvm::Triple::hsail:
+ case llvm::Triple::spir:
+ case llvm::Triple::kalimba:
+ case llvm::Triple::shave:
+ return 32;
+
+ case llvm::Triple::aarch64:
+ case llvm::Triple::aarch64_be:
+ case llvm::Triple::amdgcn:
+ case llvm::Triple::bpfel:
+ case llvm::Triple::bpfeb:
+ case llvm::Triple::le64:
+ case llvm::Triple::mips64:
+ case llvm::Triple::mips64el:
+ case llvm::Triple::nvptx64:
+ case llvm::Triple::ppc64:
+ case llvm::Triple::ppc64le:
+ case llvm::Triple::sparcv9:
+ case llvm::Triple::systemz:
+ case llvm::Triple::x86_64:
+ case llvm::Triple::amdil64:
+ case llvm::Triple::hsail64:
+ case llvm::Triple::spir64:
+ return 64;
+ }
+ llvm_unreachable("Invalid architecture value");
+}
+
+bool Triple::isArch64Bit() const {
+ return getArchPointerBitWidth(getArch()) == 64;
+}
+
+bool Triple::isArch32Bit() const {
+ return getArchPointerBitWidth(getArch()) == 32;
+}
+
+bool Triple::isArch16Bit() const {
+ return getArchPointerBitWidth(getArch()) == 16;
+}
+
+Triple Triple::get32BitArchVariant() const {
+ Triple T(*this);
+ switch (getArch()) {
+ case Triple::UnknownArch:
+ case Triple::aarch64:
+ case Triple::aarch64_be:
+ case Triple::amdgcn:
+ case Triple::bpfel:
+ case Triple::bpfeb:
+ case Triple::msp430:
+ case Triple::systemz:
+ case Triple::ppc64le:
+ T.setArch(UnknownArch);
+ break;
+
+ case Triple::amdil:
+ case Triple::hsail:
+ case Triple::spir:
+ case Triple::arm:
+ case Triple::armeb:
+ case Triple::hexagon:
+ case Triple::kalimba:
+ case Triple::le32:
+ case Triple::mips:
+ case Triple::mipsel:
+ case Triple::nvptx:
+ case Triple::ppc:
+ case Triple::r600:
+ case Triple::sparc:
+ case Triple::sparcel:
+ case Triple::tce:
+ case Triple::thumb:
+ case Triple::thumbeb:
+ case Triple::x86:
+ case Triple::xcore:
+ case Triple::shave:
+ // Already 32-bit.
+ break;
+
+ case Triple::le64: T.setArch(Triple::le32); break;
+ case Triple::mips64: T.setArch(Triple::mips); break;
+ case Triple::mips64el: T.setArch(Triple::mipsel); break;
+ case Triple::nvptx64: T.setArch(Triple::nvptx); break;
+ case Triple::ppc64: T.setArch(Triple::ppc); break;
+ case Triple::sparcv9: T.setArch(Triple::sparc); break;
+ case Triple::x86_64: T.setArch(Triple::x86); break;
+ case Triple::amdil64: T.setArch(Triple::amdil); break;
+ case Triple::hsail64: T.setArch(Triple::hsail); break;
+ case Triple::spir64: T.setArch(Triple::spir); break;
+ }
+ return T;
+}
+
+Triple Triple::get64BitArchVariant() const {
+ Triple T(*this);
+ switch (getArch()) {
+ case Triple::UnknownArch:
+ case Triple::arm:
+ case Triple::armeb:
+ case Triple::hexagon:
+ case Triple::kalimba:
+ case Triple::msp430:
+ case Triple::r600:
+ case Triple::tce:
+ case Triple::thumb:
+ case Triple::thumbeb:
+ case Triple::xcore:
+ case Triple::sparcel:
+ case Triple::shave:
+ T.setArch(UnknownArch);
+ break;
+
+ case Triple::aarch64:
+ case Triple::aarch64_be:
+ case Triple::bpfel:
+ case Triple::bpfeb:
+ case Triple::le64:
+ case Triple::amdil64:
+ case Triple::amdgcn:
+ case Triple::hsail64:
+ case Triple::spir64:
+ case Triple::mips64:
+ case Triple::mips64el:
+ case Triple::nvptx64:
+ case Triple::ppc64:
+ case Triple::ppc64le:
+ case Triple::sparcv9:
+ case Triple::systemz:
+ case Triple::x86_64:
+ // Already 64-bit.
+ break;
+
+ case Triple::le32: T.setArch(Triple::le64); break;
+ case Triple::mips: T.setArch(Triple::mips64); break;
+ case Triple::mipsel: T.setArch(Triple::mips64el); break;
+ case Triple::nvptx: T.setArch(Triple::nvptx64); break;
+ case Triple::ppc: T.setArch(Triple::ppc64); break;
+ case Triple::sparc: T.setArch(Triple::sparcv9); break;
+ case Triple::x86: T.setArch(Triple::x86_64); break;
+ case Triple::amdil: T.setArch(Triple::amdil64); break;
+ case Triple::hsail: T.setArch(Triple::hsail64); break;
+ case Triple::spir: T.setArch(Triple::spir64); break;
+ }
+ return T;
+}
+
+const char *Triple::getARMCPUForArch(StringRef MArch) const {
+ if (MArch.empty())
+ MArch = getArchName();
+ MArch = ARMTargetParser::getCanonicalArchName(MArch);
+
+ // Some defaults are forced.
+ switch (getOS()) {
+ case llvm::Triple::FreeBSD:
+ case llvm::Triple::NetBSD:
+ if (!MArch.empty() && MArch == "v6")
+ return "arm1176jzf-s";
+ break;
+ case llvm::Triple::Win32:
+ // FIXME: this is invalid for WindowsCE
+ return "cortex-a9";
+ default:
+ break;
+ }
+
+ if (MArch.empty())
+ return nullptr;
+
+ const char *CPU = ARMTargetParser::getDefaultCPU(MArch);
+ if (CPU)
+ return CPU;
+
+ // If no specific architecture version is requested, return the minimum CPU
+ // required by the OS and environment.
+ switch (getOS()) {
+ case llvm::Triple::NetBSD:
+ switch (getEnvironment()) {
+ case llvm::Triple::GNUEABIHF:
+ case llvm::Triple::GNUEABI:
+ case llvm::Triple::EABIHF:
+ case llvm::Triple::EABI:
+ return "arm926ej-s";
+ default:
+ return "strongarm";
+ }
+ case llvm::Triple::NaCl:
+ return "cortex-a8";
+ default:
+ switch (getEnvironment()) {
+ case llvm::Triple::EABIHF:
+ case llvm::Triple::GNUEABIHF:
+ return "arm1176jzf-s";
+ default:
+ return "arm7tdmi";
+ }
+ }
+
+ llvm_unreachable("invalid arch name");
+}
diff --git a/contrib/llvm/lib/Support/Twine.cpp b/contrib/llvm/lib/Support/Twine.cpp
new file mode 100644
index 000000000000..020dd9596d9c
--- /dev/null
+++ b/contrib/llvm/lib/Support/Twine.cpp
@@ -0,0 +1,170 @@
+//===-- Twine.cpp - Fast Temporary String Concatenation -------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/Twine.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace llvm;
+
+std::string Twine::str() const {
+ // If we're storing only a std::string, just return it.
+ if (LHSKind == StdStringKind && RHSKind == EmptyKind)
+ return *LHS.stdString;
+
+ // Otherwise, flatten and copy the contents first.
+ SmallString<256> Vec;
+ return toStringRef(Vec).str();
+}
+
+void Twine::toVector(SmallVectorImpl<char> &Out) const {
+ raw_svector_ostream OS(Out);
+ print(OS);
+}
+
+StringRef Twine::toNullTerminatedStringRef(SmallVectorImpl<char> &Out) const {
+ if (isUnary()) {
+ switch (getLHSKind()) {
+ case CStringKind:
+ // Already null terminated, yay!
+ return StringRef(LHS.cString);
+ case StdStringKind: {
+ const std::string *str = LHS.stdString;
+ return StringRef(str->c_str(), str->size());
+ }
+ default:
+ break;
+ }
+ }
+ toVector(Out);
+ Out.push_back(0);
+ Out.pop_back();
+ return StringRef(Out.data(), Out.size());
+}
+
+void Twine::printOneChild(raw_ostream &OS, Child Ptr,
+ NodeKind Kind) const {
+ switch (Kind) {
+ case Twine::NullKind: break;
+ case Twine::EmptyKind: break;
+ case Twine::TwineKind:
+ Ptr.twine->print(OS);
+ break;
+ case Twine::CStringKind:
+ OS << Ptr.cString;
+ break;
+ case Twine::StdStringKind:
+ OS << *Ptr.stdString;
+ break;
+ case Twine::StringRefKind:
+ OS << *Ptr.stringRef;
+ break;
+ case Twine::SmallStringKind:
+ OS << *Ptr.smallString;
+ break;
+ case Twine::CharKind:
+ OS << Ptr.character;
+ break;
+ case Twine::DecUIKind:
+ OS << Ptr.decUI;
+ break;
+ case Twine::DecIKind:
+ OS << Ptr.decI;
+ break;
+ case Twine::DecULKind:
+ OS << *Ptr.decUL;
+ break;
+ case Twine::DecLKind:
+ OS << *Ptr.decL;
+ break;
+ case Twine::DecULLKind:
+ OS << *Ptr.decULL;
+ break;
+ case Twine::DecLLKind:
+ OS << *Ptr.decLL;
+ break;
+ case Twine::UHexKind:
+ OS.write_hex(*Ptr.uHex);
+ break;
+ }
+}
+
+void Twine::printOneChildRepr(raw_ostream &OS, Child Ptr,
+ NodeKind Kind) const {
+ switch (Kind) {
+ case Twine::NullKind:
+ OS << "null"; break;
+ case Twine::EmptyKind:
+ OS << "empty"; break;
+ case Twine::TwineKind:
+ OS << "rope:";
+ Ptr.twine->printRepr(OS);
+ break;
+ case Twine::CStringKind:
+ OS << "cstring:\""
+ << Ptr.cString << "\"";
+ break;
+ case Twine::StdStringKind:
+ OS << "std::string:\""
+ << Ptr.stdString << "\"";
+ break;
+ case Twine::StringRefKind:
+ OS << "stringref:\""
+ << Ptr.stringRef << "\"";
+ break;
+ case Twine::SmallStringKind:
+ OS << "smallstring:\"" << *Ptr.smallString << "\"";
+ break;
+ case Twine::CharKind:
+ OS << "char:\"" << Ptr.character << "\"";
+ break;
+ case Twine::DecUIKind:
+ OS << "decUI:\"" << Ptr.decUI << "\"";
+ break;
+ case Twine::DecIKind:
+ OS << "decI:\"" << Ptr.decI << "\"";
+ break;
+ case Twine::DecULKind:
+ OS << "decUL:\"" << *Ptr.decUL << "\"";
+ break;
+ case Twine::DecLKind:
+ OS << "decL:\"" << *Ptr.decL << "\"";
+ break;
+ case Twine::DecULLKind:
+ OS << "decULL:\"" << *Ptr.decULL << "\"";
+ break;
+ case Twine::DecLLKind:
+ OS << "decLL:\"" << *Ptr.decLL << "\"";
+ break;
+ case Twine::UHexKind:
+ OS << "uhex:\"" << Ptr.uHex << "\"";
+ break;
+ }
+}
+
+void Twine::print(raw_ostream &OS) const {
+ printOneChild(OS, LHS, getLHSKind());
+ printOneChild(OS, RHS, getRHSKind());
+}
+
+void Twine::printRepr(raw_ostream &OS) const {
+ OS << "(Twine ";
+ printOneChildRepr(OS, LHS, getLHSKind());
+ OS << " ";
+ printOneChildRepr(OS, RHS, getRHSKind());
+ OS << ")";
+}
+
+void Twine::dump() const {
+ print(dbgs());
+}
+
+void Twine::dumpRepr() const {
+ printRepr(dbgs());
+}
diff --git a/contrib/llvm/lib/Support/Unicode.cpp b/contrib/llvm/lib/Support/Unicode.cpp
new file mode 100644
index 000000000000..b719bd826dc1
--- /dev/null
+++ b/contrib/llvm/lib/Support/Unicode.cpp
@@ -0,0 +1,367 @@
+//===- llvm/Support/Unicode.cpp - Unicode character properties -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements functions that allow querying certain properties of
+// Unicode characters.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/Unicode.h"
+#include "llvm/Support/ConvertUTF.h"
+#include "llvm/Support/UnicodeCharRanges.h"
+
+namespace llvm {
+namespace sys {
+namespace unicode {
+
+bool isPrintable(int UCS) {
+ // Sorted list of non-overlapping intervals of code points that are not
+ // supposed to be printable.
+ static const UnicodeCharRange NonPrintableRanges[] = {
+ { 0x0000, 0x001F }, { 0x007F, 0x009F }, { 0x034F, 0x034F },
+ { 0x0378, 0x0379 }, { 0x037F, 0x0383 }, { 0x038B, 0x038B },
+ { 0x038D, 0x038D }, { 0x03A2, 0x03A2 }, { 0x0528, 0x0530 },
+ { 0x0557, 0x0558 }, { 0x0560, 0x0560 }, { 0x0588, 0x0588 },
+ { 0x058B, 0x058E }, { 0x0590, 0x0590 }, { 0x05C8, 0x05CF },
+ { 0x05EB, 0x05EF }, { 0x05F5, 0x0605 }, { 0x061C, 0x061D },
+ { 0x06DD, 0x06DD }, { 0x070E, 0x070F }, { 0x074B, 0x074C },
+ { 0x07B2, 0x07BF }, { 0x07FB, 0x07FF }, { 0x082E, 0x082F },
+ { 0x083F, 0x083F }, { 0x085C, 0x085D }, { 0x085F, 0x089F },
+ { 0x08A1, 0x08A1 }, { 0x08AD, 0x08E3 }, { 0x08FF, 0x08FF },
+ { 0x0978, 0x0978 }, { 0x0980, 0x0980 }, { 0x0984, 0x0984 },
+ { 0x098D, 0x098E }, { 0x0991, 0x0992 }, { 0x09A9, 0x09A9 },
+ { 0x09B1, 0x09B1 }, { 0x09B3, 0x09B5 }, { 0x09BA, 0x09BB },
+ { 0x09C5, 0x09C6 }, { 0x09C9, 0x09CA }, { 0x09CF, 0x09D6 },
+ { 0x09D8, 0x09DB }, { 0x09DE, 0x09DE }, { 0x09E4, 0x09E5 },
+ { 0x09FC, 0x0A00 }, { 0x0A04, 0x0A04 }, { 0x0A0B, 0x0A0E },
+ { 0x0A11, 0x0A12 }, { 0x0A29, 0x0A29 }, { 0x0A31, 0x0A31 },
+ { 0x0A34, 0x0A34 }, { 0x0A37, 0x0A37 }, { 0x0A3A, 0x0A3B },
+ { 0x0A3D, 0x0A3D }, { 0x0A43, 0x0A46 }, { 0x0A49, 0x0A4A },
+ { 0x0A4E, 0x0A50 }, { 0x0A52, 0x0A58 }, { 0x0A5D, 0x0A5D },
+ { 0x0A5F, 0x0A65 }, { 0x0A76, 0x0A80 }, { 0x0A84, 0x0A84 },
+ { 0x0A8E, 0x0A8E }, { 0x0A92, 0x0A92 }, { 0x0AA9, 0x0AA9 },
+ { 0x0AB1, 0x0AB1 }, { 0x0AB4, 0x0AB4 }, { 0x0ABA, 0x0ABB },
+ { 0x0AC6, 0x0AC6 }, { 0x0ACA, 0x0ACA }, { 0x0ACE, 0x0ACF },
+ { 0x0AD1, 0x0ADF }, { 0x0AE4, 0x0AE5 }, { 0x0AF2, 0x0B00 },
+ { 0x0B04, 0x0B04 }, { 0x0B0D, 0x0B0E }, { 0x0B11, 0x0B12 },
+ { 0x0B29, 0x0B29 }, { 0x0B31, 0x0B31 }, { 0x0B34, 0x0B34 },
+ { 0x0B3A, 0x0B3B }, { 0x0B45, 0x0B46 }, { 0x0B49, 0x0B4A },
+ { 0x0B4E, 0x0B55 }, { 0x0B58, 0x0B5B }, { 0x0B5E, 0x0B5E },
+ { 0x0B64, 0x0B65 }, { 0x0B78, 0x0B81 }, { 0x0B84, 0x0B84 },
+ { 0x0B8B, 0x0B8D }, { 0x0B91, 0x0B91 }, { 0x0B96, 0x0B98 },
+ { 0x0B9B, 0x0B9B }, { 0x0B9D, 0x0B9D }, { 0x0BA0, 0x0BA2 },
+ { 0x0BA5, 0x0BA7 }, { 0x0BAB, 0x0BAD }, { 0x0BBA, 0x0BBD },
+ { 0x0BC3, 0x0BC5 }, { 0x0BC9, 0x0BC9 }, { 0x0BCE, 0x0BCF },
+ { 0x0BD1, 0x0BD6 }, { 0x0BD8, 0x0BE5 }, { 0x0BFB, 0x0C00 },
+ { 0x0C04, 0x0C04 }, { 0x0C0D, 0x0C0D }, { 0x0C11, 0x0C11 },
+ { 0x0C29, 0x0C29 }, { 0x0C34, 0x0C34 }, { 0x0C3A, 0x0C3C },
+ { 0x0C45, 0x0C45 }, { 0x0C49, 0x0C49 }, { 0x0C4E, 0x0C54 },
+ { 0x0C57, 0x0C57 }, { 0x0C5A, 0x0C5F }, { 0x0C64, 0x0C65 },
+ { 0x0C70, 0x0C77 }, { 0x0C80, 0x0C81 }, { 0x0C84, 0x0C84 },
+ { 0x0C8D, 0x0C8D }, { 0x0C91, 0x0C91 }, { 0x0CA9, 0x0CA9 },
+ { 0x0CB4, 0x0CB4 }, { 0x0CBA, 0x0CBB }, { 0x0CC5, 0x0CC5 },
+ { 0x0CC9, 0x0CC9 }, { 0x0CCE, 0x0CD4 }, { 0x0CD7, 0x0CDD },
+ { 0x0CDF, 0x0CDF }, { 0x0CE4, 0x0CE5 }, { 0x0CF0, 0x0CF0 },
+ { 0x0CF3, 0x0D01 }, { 0x0D04, 0x0D04 }, { 0x0D0D, 0x0D0D },
+ { 0x0D11, 0x0D11 }, { 0x0D3B, 0x0D3C }, { 0x0D45, 0x0D45 },
+ { 0x0D49, 0x0D49 }, { 0x0D4F, 0x0D56 }, { 0x0D58, 0x0D5F },
+ { 0x0D64, 0x0D65 }, { 0x0D76, 0x0D78 }, { 0x0D80, 0x0D81 },
+ { 0x0D84, 0x0D84 }, { 0x0D97, 0x0D99 }, { 0x0DB2, 0x0DB2 },
+ { 0x0DBC, 0x0DBC }, { 0x0DBE, 0x0DBF }, { 0x0DC7, 0x0DC9 },
+ { 0x0DCB, 0x0DCE }, { 0x0DD5, 0x0DD5 }, { 0x0DD7, 0x0DD7 },
+ { 0x0DE0, 0x0DF1 }, { 0x0DF5, 0x0E00 }, { 0x0E3B, 0x0E3E },
+ { 0x0E5C, 0x0E80 }, { 0x0E83, 0x0E83 }, { 0x0E85, 0x0E86 },
+ { 0x0E89, 0x0E89 }, { 0x0E8B, 0x0E8C }, { 0x0E8E, 0x0E93 },
+ { 0x0E98, 0x0E98 }, { 0x0EA0, 0x0EA0 }, { 0x0EA4, 0x0EA4 },
+ { 0x0EA6, 0x0EA6 }, { 0x0EA8, 0x0EA9 }, { 0x0EAC, 0x0EAC },
+ { 0x0EBA, 0x0EBA }, { 0x0EBE, 0x0EBF }, { 0x0EC5, 0x0EC5 },
+ { 0x0EC7, 0x0EC7 }, { 0x0ECE, 0x0ECF }, { 0x0EDA, 0x0EDB },
+ { 0x0EE0, 0x0EFF }, { 0x0F48, 0x0F48 }, { 0x0F6D, 0x0F70 },
+ { 0x0F98, 0x0F98 }, { 0x0FBD, 0x0FBD }, { 0x0FCD, 0x0FCD },
+ { 0x0FDB, 0x0FFF }, { 0x10C6, 0x10C6 }, { 0x10C8, 0x10CC },
+ { 0x10CE, 0x10CF }, { 0x115F, 0x1160 }, { 0x1249, 0x1249 },
+ { 0x124E, 0x124F }, { 0x1257, 0x1257 }, { 0x1259, 0x1259 },
+ { 0x125E, 0x125F }, { 0x1289, 0x1289 }, { 0x128E, 0x128F },
+ { 0x12B1, 0x12B1 }, { 0x12B6, 0x12B7 }, { 0x12BF, 0x12BF },
+ { 0x12C1, 0x12C1 }, { 0x12C6, 0x12C7 }, { 0x12D7, 0x12D7 },
+ { 0x1311, 0x1311 }, { 0x1316, 0x1317 }, { 0x135B, 0x135C },
+ { 0x137D, 0x137F }, { 0x139A, 0x139F }, { 0x13F5, 0x13FF },
+ { 0x169D, 0x169F }, { 0x16F1, 0x16FF }, { 0x170D, 0x170D },
+ { 0x1715, 0x171F }, { 0x1737, 0x173F }, { 0x1754, 0x175F },
+ { 0x176D, 0x176D }, { 0x1771, 0x1771 }, { 0x1774, 0x177F },
+ { 0x17B4, 0x17B5 }, { 0x17DE, 0x17DF }, { 0x17EA, 0x17EF },
+ { 0x17FA, 0x17FF }, { 0x180B, 0x180D }, { 0x180F, 0x180F },
+ { 0x181A, 0x181F }, { 0x1878, 0x187F }, { 0x18AB, 0x18AF },
+ { 0x18F6, 0x18FF }, { 0x191D, 0x191F }, { 0x192C, 0x192F },
+ { 0x193C, 0x193F }, { 0x1941, 0x1943 }, { 0x196E, 0x196F },
+ { 0x1975, 0x197F }, { 0x19AC, 0x19AF }, { 0x19CA, 0x19CF },
+ { 0x19DB, 0x19DD }, { 0x1A1C, 0x1A1D }, { 0x1A5F, 0x1A5F },
+ { 0x1A7D, 0x1A7E }, { 0x1A8A, 0x1A8F }, { 0x1A9A, 0x1A9F },
+ { 0x1AAE, 0x1AFF }, { 0x1B4C, 0x1B4F }, { 0x1B7D, 0x1B7F },
+ { 0x1BF4, 0x1BFB }, { 0x1C38, 0x1C3A }, { 0x1C4A, 0x1C4C },
+ { 0x1C80, 0x1CBF }, { 0x1CC8, 0x1CCF }, { 0x1CF7, 0x1CFF },
+ { 0x1DE7, 0x1DFB }, { 0x1F16, 0x1F17 }, { 0x1F1E, 0x1F1F },
+ { 0x1F46, 0x1F47 }, { 0x1F4E, 0x1F4F }, { 0x1F58, 0x1F58 },
+ { 0x1F5A, 0x1F5A }, { 0x1F5C, 0x1F5C }, { 0x1F5E, 0x1F5E },
+ { 0x1F7E, 0x1F7F }, { 0x1FB5, 0x1FB5 }, { 0x1FC5, 0x1FC5 },
+ { 0x1FD4, 0x1FD5 }, { 0x1FDC, 0x1FDC }, { 0x1FF0, 0x1FF1 },
+ { 0x1FF5, 0x1FF5 }, { 0x1FFF, 0x1FFF }, { 0x200B, 0x200F },
+ { 0x202A, 0x202E }, { 0x2060, 0x206F }, { 0x2072, 0x2073 },
+ { 0x208F, 0x208F }, { 0x209D, 0x209F }, { 0x20BB, 0x20CF },
+ { 0x20F1, 0x20FF }, { 0x218A, 0x218F }, { 0x23F4, 0x23FF },
+ { 0x2427, 0x243F }, { 0x244B, 0x245F }, { 0x2700, 0x2700 },
+ { 0x2B4D, 0x2B4F }, { 0x2B5A, 0x2BFF }, { 0x2C2F, 0x2C2F },
+ { 0x2C5F, 0x2C5F }, { 0x2CF4, 0x2CF8 }, { 0x2D26, 0x2D26 },
+ { 0x2D28, 0x2D2C }, { 0x2D2E, 0x2D2F }, { 0x2D68, 0x2D6E },
+ { 0x2D71, 0x2D7E }, { 0x2D97, 0x2D9F }, { 0x2DA7, 0x2DA7 },
+ { 0x2DAF, 0x2DAF }, { 0x2DB7, 0x2DB7 }, { 0x2DBF, 0x2DBF },
+ { 0x2DC7, 0x2DC7 }, { 0x2DCF, 0x2DCF }, { 0x2DD7, 0x2DD7 },
+ { 0x2DDF, 0x2DDF }, { 0x2E3C, 0x2E7F }, { 0x2E9A, 0x2E9A },
+ { 0x2EF4, 0x2EFF }, { 0x2FD6, 0x2FEF }, { 0x2FFC, 0x2FFF },
+ { 0x3040, 0x3040 }, { 0x3097, 0x3098 }, { 0x3100, 0x3104 },
+ { 0x312E, 0x3130 }, { 0x3164, 0x3164 }, { 0x318F, 0x318F },
+ { 0x31BB, 0x31BF }, { 0x31E4, 0x31EF }, { 0x321F, 0x321F },
+ { 0x32FF, 0x32FF }, { 0x4DB6, 0x4DBF }, { 0x9FCD, 0x9FFF },
+ { 0xA48D, 0xA48F }, { 0xA4C7, 0xA4CF }, { 0xA62C, 0xA63F },
+ { 0xA698, 0xA69E }, { 0xA6F8, 0xA6FF }, { 0xA78F, 0xA78F },
+ { 0xA794, 0xA79F }, { 0xA7AB, 0xA7F7 }, { 0xA82C, 0xA82F },
+ { 0xA83A, 0xA83F }, { 0xA878, 0xA87F }, { 0xA8C5, 0xA8CD },
+ { 0xA8DA, 0xA8DF }, { 0xA8FC, 0xA8FF }, { 0xA954, 0xA95E },
+ { 0xA97D, 0xA97F }, { 0xA9CE, 0xA9CE }, { 0xA9DA, 0xA9DD },
+ { 0xA9E0, 0xA9FF }, { 0xAA37, 0xAA3F }, { 0xAA4E, 0xAA4F },
+ { 0xAA5A, 0xAA5B }, { 0xAA7C, 0xAA7F }, { 0xAAC3, 0xAADA },
+ { 0xAAF7, 0xAB00 }, { 0xAB07, 0xAB08 }, { 0xAB0F, 0xAB10 },
+ { 0xAB17, 0xAB1F }, { 0xAB27, 0xAB27 }, { 0xAB2F, 0xABBF },
+ { 0xABEE, 0xABEF }, { 0xABFA, 0xABFF }, { 0xD7A4, 0xD7AF },
+ { 0xD7C7, 0xD7CA }, { 0xD7FC, 0xDFFF }, { 0xFA6E, 0xFA6F },
+ { 0xFADA, 0xFAFF }, { 0xFB07, 0xFB12 }, { 0xFB18, 0xFB1C },
+ { 0xFB37, 0xFB37 }, { 0xFB3D, 0xFB3D }, { 0xFB3F, 0xFB3F },
+ { 0xFB42, 0xFB42 }, { 0xFB45, 0xFB45 }, { 0xFBC2, 0xFBD2 },
+ { 0xFD40, 0xFD4F }, { 0xFD90, 0xFD91 }, { 0xFDC8, 0xFDEF },
+ { 0xFDFE, 0xFE0F }, { 0xFE1A, 0xFE1F }, { 0xFE27, 0xFE2F },
+ { 0xFE53, 0xFE53 }, { 0xFE67, 0xFE67 }, { 0xFE6C, 0xFE6F },
+ { 0xFE75, 0xFE75 }, { 0xFEFD, 0xFEFF }, { 0xFF00, 0xFF00 },
+ { 0xFFA0, 0xFFA0 }, { 0xFFBF, 0xFFC1 }, { 0xFFC8, 0xFFC9 },
+ { 0xFFD0, 0xFFD1 }, { 0xFFD8, 0xFFD9 }, { 0xFFDD, 0xFFDF },
+ { 0xFFE7, 0xFFE7 }, { 0xFFEF, 0xFFFB }, { 0xFFFE, 0xFFFF },
+ { 0x1000C, 0x1000C }, { 0x10027, 0x10027 }, { 0x1003B, 0x1003B },
+ { 0x1003E, 0x1003E }, { 0x1004E, 0x1004F }, { 0x1005E, 0x1007F },
+ { 0x100FB, 0x100FF }, { 0x10103, 0x10106 }, { 0x10134, 0x10136 },
+ { 0x1018B, 0x1018F }, { 0x1019C, 0x101CF }, { 0x101FE, 0x1027F },
+ { 0x1029D, 0x1029F }, { 0x102D1, 0x102FF }, { 0x1031F, 0x1031F },
+ { 0x10324, 0x1032F }, { 0x1034B, 0x1037F }, { 0x1039E, 0x1039E },
+ { 0x103C4, 0x103C7 }, { 0x103D6, 0x103FF }, { 0x1049E, 0x1049F },
+ { 0x104AA, 0x107FF }, { 0x10806, 0x10807 }, { 0x10809, 0x10809 },
+ { 0x10836, 0x10836 }, { 0x10839, 0x1083B }, { 0x1083D, 0x1083E },
+ { 0x10856, 0x10856 }, { 0x10860, 0x108FF }, { 0x1091C, 0x1091E },
+ { 0x1093A, 0x1093E }, { 0x10940, 0x1097F }, { 0x109B8, 0x109BD },
+ { 0x109C0, 0x109FF }, { 0x10A04, 0x10A04 }, { 0x10A07, 0x10A0B },
+ { 0x10A14, 0x10A14 }, { 0x10A18, 0x10A18 }, { 0x10A34, 0x10A37 },
+ { 0x10A3B, 0x10A3E }, { 0x10A48, 0x10A4F }, { 0x10A59, 0x10A5F },
+ { 0x10A80, 0x10AFF }, { 0x10B36, 0x10B38 }, { 0x10B56, 0x10B57 },
+ { 0x10B73, 0x10B77 }, { 0x10B80, 0x10BFF }, { 0x10C49, 0x10E5F },
+ { 0x10E7F, 0x10FFF }, { 0x1104E, 0x11051 }, { 0x11070, 0x1107F },
+ { 0x110BD, 0x110BD }, { 0x110C2, 0x110CF }, { 0x110E9, 0x110EF },
+ { 0x110FA, 0x110FF }, { 0x11135, 0x11135 }, { 0x11144, 0x1117F },
+ { 0x111C9, 0x111CF }, { 0x111DA, 0x1167F }, { 0x116B8, 0x116BF },
+ { 0x116CA, 0x11FFF }, { 0x1236F, 0x123FF }, { 0x12463, 0x1246F },
+ { 0x12474, 0x12FFF }, { 0x1342F, 0x167FF }, { 0x16A39, 0x16EFF },
+ { 0x16F45, 0x16F4F }, { 0x16F7F, 0x16F8E }, { 0x16FA0, 0x1AFFF },
+ { 0x1B002, 0x1CFFF }, { 0x1D0F6, 0x1D0FF }, { 0x1D127, 0x1D128 },
+ { 0x1D173, 0x1D17A }, { 0x1D1DE, 0x1D1FF }, { 0x1D246, 0x1D2FF },
+ { 0x1D357, 0x1D35F }, { 0x1D372, 0x1D3FF }, { 0x1D455, 0x1D455 },
+ { 0x1D49D, 0x1D49D }, { 0x1D4A0, 0x1D4A1 }, { 0x1D4A3, 0x1D4A4 },
+ { 0x1D4A7, 0x1D4A8 }, { 0x1D4AD, 0x1D4AD }, { 0x1D4BA, 0x1D4BA },
+ { 0x1D4BC, 0x1D4BC }, { 0x1D4C4, 0x1D4C4 }, { 0x1D506, 0x1D506 },
+ { 0x1D50B, 0x1D50C }, { 0x1D515, 0x1D515 }, { 0x1D51D, 0x1D51D },
+ { 0x1D53A, 0x1D53A }, { 0x1D53F, 0x1D53F }, { 0x1D545, 0x1D545 },
+ { 0x1D547, 0x1D549 }, { 0x1D551, 0x1D551 }, { 0x1D6A6, 0x1D6A7 },
+ { 0x1D7CC, 0x1D7CD }, { 0x1D800, 0x1EDFF }, { 0x1EE04, 0x1EE04 },
+ { 0x1EE20, 0x1EE20 }, { 0x1EE23, 0x1EE23 }, { 0x1EE25, 0x1EE26 },
+ { 0x1EE28, 0x1EE28 }, { 0x1EE33, 0x1EE33 }, { 0x1EE38, 0x1EE38 },
+ { 0x1EE3A, 0x1EE3A }, { 0x1EE3C, 0x1EE41 }, { 0x1EE43, 0x1EE46 },
+ { 0x1EE48, 0x1EE48 }, { 0x1EE4A, 0x1EE4A }, { 0x1EE4C, 0x1EE4C },
+ { 0x1EE50, 0x1EE50 }, { 0x1EE53, 0x1EE53 }, { 0x1EE55, 0x1EE56 },
+ { 0x1EE58, 0x1EE58 }, { 0x1EE5A, 0x1EE5A }, { 0x1EE5C, 0x1EE5C },
+ { 0x1EE5E, 0x1EE5E }, { 0x1EE60, 0x1EE60 }, { 0x1EE63, 0x1EE63 },
+ { 0x1EE65, 0x1EE66 }, { 0x1EE6B, 0x1EE6B }, { 0x1EE73, 0x1EE73 },
+ { 0x1EE78, 0x1EE78 }, { 0x1EE7D, 0x1EE7D }, { 0x1EE7F, 0x1EE7F },
+ { 0x1EE8A, 0x1EE8A }, { 0x1EE9C, 0x1EEA0 }, { 0x1EEA4, 0x1EEA4 },
+ { 0x1EEAA, 0x1EEAA }, { 0x1EEBC, 0x1EEEF }, { 0x1EEF2, 0x1EFFF },
+ { 0x1F02C, 0x1F02F }, { 0x1F094, 0x1F09F }, { 0x1F0AF, 0x1F0B0 },
+ { 0x1F0BF, 0x1F0C0 }, { 0x1F0D0, 0x1F0D0 }, { 0x1F0E0, 0x1F0FF },
+ { 0x1F10B, 0x1F10F }, { 0x1F12F, 0x1F12F }, { 0x1F16C, 0x1F16F },
+ { 0x1F19B, 0x1F1E5 }, { 0x1F203, 0x1F20F }, { 0x1F23B, 0x1F23F },
+ { 0x1F249, 0x1F24F }, { 0x1F252, 0x1F2FF }, { 0x1F321, 0x1F32F },
+ { 0x1F336, 0x1F336 }, { 0x1F37D, 0x1F37F }, { 0x1F394, 0x1F39F },
+ { 0x1F3C5, 0x1F3C5 }, { 0x1F3CB, 0x1F3DF }, { 0x1F3F1, 0x1F3FF },
+ { 0x1F43F, 0x1F43F }, { 0x1F441, 0x1F441 }, { 0x1F4F8, 0x1F4F8 },
+ { 0x1F4FD, 0x1F4FF }, { 0x1F53E, 0x1F53F }, { 0x1F544, 0x1F54F },
+ { 0x1F568, 0x1F5FA }, { 0x1F641, 0x1F644 }, { 0x1F650, 0x1F67F },
+ { 0x1F6C6, 0x1F6FF }, { 0x1F774, 0x1FFFF }, { 0x2A6D7, 0x2A6FF },
+ { 0x2B735, 0x2B73F }, { 0x2B81E, 0x2F7FF }, { 0x2FA1E, 0xF0000 },
+ { 0xFFFFE, 0xFFFFF }, { 0x10FFFE, 0x10FFFF }
+ };
+ static const UnicodeCharSet NonPrintables(NonPrintableRanges);
+
+ return UCS >= 0 && UCS <= 0x10FFFF && !NonPrintables.contains(UCS);
+}
+
+/// Gets the number of positions a character is likely to occupy when output
+/// on a terminal ("character width"). This depends on the implementation of the
+/// terminal, and there's no standard definition of character width.
+/// The implementation defines it in a way that is expected to be compatible
+/// with a generic Unicode-capable terminal.
+/// \return Character width:
+/// * ErrorNonPrintableCharacter (-1) for non-printable characters (as
+/// identified by isPrintable);
+/// * 0 for non-spacing and enclosing combining marks;
+/// * 2 for CJK characters excluding halfwidth forms;
+/// * 1 for all remaining characters.
+static inline int charWidth(int UCS)
+{
+ if (!isPrintable(UCS))
+ return ErrorNonPrintableCharacter;
+
+ // Sorted list of non-spacing and enclosing combining mark intervals as
+ // defined in "3.6 Combination" of
+ // http://www.unicode.org/versions/Unicode6.2.0/UnicodeStandard-6.2.pdf
+ static const UnicodeCharRange CombiningCharacterRanges[] = {
+ { 0x0300, 0x036F }, { 0x0483, 0x0489 }, { 0x0591, 0x05BD },
+ { 0x05BF, 0x05BF }, { 0x05C1, 0x05C2 }, { 0x05C4, 0x05C5 },
+ { 0x05C7, 0x05C7 }, { 0x0610, 0x061A }, { 0x064B, 0x065F },
+ { 0x0670, 0x0670 }, { 0x06D6, 0x06DC }, { 0x06DF, 0x06E4 },
+ { 0x06E7, 0x06E8 }, { 0x06EA, 0x06ED }, { 0x0711, 0x0711 },
+ { 0x0730, 0x074A }, { 0x07A6, 0x07B0 }, { 0x07EB, 0x07F3 },
+ { 0x0816, 0x0819 }, { 0x081B, 0x0823 }, { 0x0825, 0x0827 },
+ { 0x0829, 0x082D }, { 0x0859, 0x085B }, { 0x08E4, 0x08FE },
+ { 0x0900, 0x0902 }, { 0x093A, 0x093A }, { 0x093C, 0x093C },
+ { 0x0941, 0x0948 }, { 0x094D, 0x094D }, { 0x0951, 0x0957 },
+ { 0x0962, 0x0963 }, { 0x0981, 0x0981 }, { 0x09BC, 0x09BC },
+ { 0x09C1, 0x09C4 }, { 0x09CD, 0x09CD }, { 0x09E2, 0x09E3 },
+ { 0x0A01, 0x0A02 }, { 0x0A3C, 0x0A3C }, { 0x0A41, 0x0A42 },
+ { 0x0A47, 0x0A48 }, { 0x0A4B, 0x0A4D }, { 0x0A51, 0x0A51 },
+ { 0x0A70, 0x0A71 }, { 0x0A75, 0x0A75 }, { 0x0A81, 0x0A82 },
+ { 0x0ABC, 0x0ABC }, { 0x0AC1, 0x0AC5 }, { 0x0AC7, 0x0AC8 },
+ { 0x0ACD, 0x0ACD }, { 0x0AE2, 0x0AE3 }, { 0x0B01, 0x0B01 },
+ { 0x0B3C, 0x0B3C }, { 0x0B3F, 0x0B3F }, { 0x0B41, 0x0B44 },
+ { 0x0B4D, 0x0B4D }, { 0x0B56, 0x0B56 }, { 0x0B62, 0x0B63 },
+ { 0x0B82, 0x0B82 }, { 0x0BC0, 0x0BC0 }, { 0x0BCD, 0x0BCD },
+ { 0x0C3E, 0x0C40 }, { 0x0C46, 0x0C48 }, { 0x0C4A, 0x0C4D },
+ { 0x0C55, 0x0C56 }, { 0x0C62, 0x0C63 }, { 0x0CBC, 0x0CBC },
+ { 0x0CBF, 0x0CBF }, { 0x0CC6, 0x0CC6 }, { 0x0CCC, 0x0CCD },
+ { 0x0CE2, 0x0CE3 }, { 0x0D41, 0x0D44 }, { 0x0D4D, 0x0D4D },
+ { 0x0D62, 0x0D63 }, { 0x0DCA, 0x0DCA }, { 0x0DD2, 0x0DD4 },
+ { 0x0DD6, 0x0DD6 }, { 0x0E31, 0x0E31 }, { 0x0E34, 0x0E3A },
+ { 0x0E47, 0x0E4E }, { 0x0EB1, 0x0EB1 }, { 0x0EB4, 0x0EB9 },
+ { 0x0EBB, 0x0EBC }, { 0x0EC8, 0x0ECD }, { 0x0F18, 0x0F19 },
+ { 0x0F35, 0x0F35 }, { 0x0F37, 0x0F37 }, { 0x0F39, 0x0F39 },
+ { 0x0F71, 0x0F7E }, { 0x0F80, 0x0F84 }, { 0x0F86, 0x0F87 },
+ { 0x0F8D, 0x0F97 }, { 0x0F99, 0x0FBC }, { 0x0FC6, 0x0FC6 },
+ { 0x102D, 0x1030 }, { 0x1032, 0x1037 }, { 0x1039, 0x103A },
+ { 0x103D, 0x103E }, { 0x1058, 0x1059 }, { 0x105E, 0x1060 },
+ { 0x1071, 0x1074 }, { 0x1082, 0x1082 }, { 0x1085, 0x1086 },
+ { 0x108D, 0x108D }, { 0x109D, 0x109D }, { 0x135D, 0x135F },
+ { 0x1712, 0x1714 }, { 0x1732, 0x1734 }, { 0x1752, 0x1753 },
+ { 0x1772, 0x1773 }, { 0x17B4, 0x17B5 }, { 0x17B7, 0x17BD },
+ { 0x17C6, 0x17C6 }, { 0x17C9, 0x17D3 }, { 0x17DD, 0x17DD },
+ { 0x180B, 0x180D }, { 0x18A9, 0x18A9 }, { 0x1920, 0x1922 },
+ { 0x1927, 0x1928 }, { 0x1932, 0x1932 }, { 0x1939, 0x193B },
+ { 0x1A17, 0x1A18 }, { 0x1A56, 0x1A56 }, { 0x1A58, 0x1A5E },
+ { 0x1A60, 0x1A60 }, { 0x1A62, 0x1A62 }, { 0x1A65, 0x1A6C },
+ { 0x1A73, 0x1A7C }, { 0x1A7F, 0x1A7F }, { 0x1B00, 0x1B03 },
+ { 0x1B34, 0x1B34 }, { 0x1B36, 0x1B3A }, { 0x1B3C, 0x1B3C },
+ { 0x1B42, 0x1B42 }, { 0x1B6B, 0x1B73 }, { 0x1B80, 0x1B81 },
+ { 0x1BA2, 0x1BA5 }, { 0x1BA8, 0x1BA9 }, { 0x1BAB, 0x1BAB },
+ { 0x1BE6, 0x1BE6 }, { 0x1BE8, 0x1BE9 }, { 0x1BED, 0x1BED },
+ { 0x1BEF, 0x1BF1 }, { 0x1C2C, 0x1C33 }, { 0x1C36, 0x1C37 },
+ { 0x1CD0, 0x1CD2 }, { 0x1CD4, 0x1CE0 }, { 0x1CE2, 0x1CE8 },
+ { 0x1CED, 0x1CED }, { 0x1CF4, 0x1CF4 }, { 0x1DC0, 0x1DE6 },
+ { 0x1DFC, 0x1DFF }, { 0x20D0, 0x20F0 }, { 0x2CEF, 0x2CF1 },
+ { 0x2D7F, 0x2D7F }, { 0x2DE0, 0x2DFF }, { 0x302A, 0x302D },
+ { 0x3099, 0x309A }, { 0xA66F, 0xA672 }, { 0xA674, 0xA67D },
+ { 0xA69F, 0xA69F }, { 0xA6F0, 0xA6F1 }, { 0xA802, 0xA802 },
+ { 0xA806, 0xA806 }, { 0xA80B, 0xA80B }, { 0xA825, 0xA826 },
+ { 0xA8C4, 0xA8C4 }, { 0xA8E0, 0xA8F1 }, { 0xA926, 0xA92D },
+ { 0xA947, 0xA951 }, { 0xA980, 0xA982 }, { 0xA9B3, 0xA9B3 },
+ { 0xA9B6, 0xA9B9 }, { 0xA9BC, 0xA9BC }, { 0xAA29, 0xAA2E },
+ { 0xAA31, 0xAA32 }, { 0xAA35, 0xAA36 }, { 0xAA43, 0xAA43 },
+ { 0xAA4C, 0xAA4C }, { 0xAAB0, 0xAAB0 }, { 0xAAB2, 0xAAB4 },
+ { 0xAAB7, 0xAAB8 }, { 0xAABE, 0xAABF }, { 0xAAC1, 0xAAC1 },
+ { 0xAAEC, 0xAAED }, { 0xAAF6, 0xAAF6 }, { 0xABE5, 0xABE5 },
+ { 0xABE8, 0xABE8 }, { 0xABED, 0xABED }, { 0xFB1E, 0xFB1E },
+ { 0xFE00, 0xFE0F }, { 0xFE20, 0xFE26 }, { 0x101FD, 0x101FD },
+ { 0x10A01, 0x10A03 }, { 0x10A05, 0x10A06 }, { 0x10A0C, 0x10A0F },
+ { 0x10A38, 0x10A3A }, { 0x10A3F, 0x10A3F }, { 0x11001, 0x11001 },
+ { 0x11038, 0x11046 }, { 0x11080, 0x11081 }, { 0x110B3, 0x110B6 },
+ { 0x110B9, 0x110BA }, { 0x11100, 0x11102 }, { 0x11127, 0x1112B },
+ { 0x1112D, 0x11134 }, { 0x11180, 0x11181 }, { 0x111B6, 0x111BE },
+ { 0x116AB, 0x116AB }, { 0x116AD, 0x116AD }, { 0x116B0, 0x116B5 },
+ { 0x116B7, 0x116B7 }, { 0x16F8F, 0x16F92 }, { 0x1D167, 0x1D169 },
+ { 0x1D17B, 0x1D182 }, { 0x1D185, 0x1D18B }, { 0x1D1AA, 0x1D1AD },
+ { 0x1D242, 0x1D244 }, { 0xE0100, 0xE01EF },
+ };
+ static const UnicodeCharSet CombiningCharacters(CombiningCharacterRanges);
+
+ if (CombiningCharacters.contains(UCS))
+ return 0;
+
+ static const UnicodeCharRange DoubleWidthCharacterRanges[] = {
+ // Hangul Jamo
+ { 0x1100, 0x11FF },
+ // Deprecated fullwidth angle brackets
+ { 0x2329, 0x232A },
+ // CJK Misc, CJK Unified Ideographs, Yijing Hexagrams, Yi
+ // excluding U+303F (IDEOGRAPHIC HALF FILL SPACE)
+ { 0x2E80, 0x303E }, { 0x3040, 0xA4CF },
+ // Hangul
+ { 0xAC00, 0xD7A3 }, { 0xD7B0, 0xD7C6 }, { 0xD7CB, 0xD7FB },
+ // CJK Unified Ideographs
+ { 0xF900, 0xFAFF },
+ // Vertical forms
+ { 0xFE10, 0xFE19 },
+ // CJK Compatibility Forms + Small Form Variants
+ { 0xFE30, 0xFE6F },
+ // Fullwidth forms
+ { 0xFF01, 0xFF60 }, { 0xFFE0, 0xFFE6 },
+ // CJK Unified Ideographs
+ { 0x20000, 0x2A6DF }, { 0x2A700, 0x2B81F }, { 0x2F800, 0x2FA1F }
+ };
+ static const UnicodeCharSet DoubleWidthCharacters(DoubleWidthCharacterRanges);
+
+ if (DoubleWidthCharacters.contains(UCS))
+ return 2;
+ return 1;
+}
+
+int columnWidthUTF8(StringRef Text) {
+ unsigned ColumnWidth = 0;
+ unsigned Length;
+ for (size_t i = 0, e = Text.size(); i < e; i += Length) {
+ Length = getNumBytesForUTF8(Text[i]);
+ if (Length <= 0 || i + Length > Text.size())
+ return ErrorInvalidUTF8;
+ UTF32 buf[1];
+ const UTF8 *Start = reinterpret_cast<const UTF8 *>(Text.data() + i);
+ UTF32 *Target = &buf[0];
+ if (conversionOK != ConvertUTF8toUTF32(&Start, Start + Length, &Target,
+ Target + 1, strictConversion))
+ return ErrorInvalidUTF8;
+ int Width = charWidth(buf[0]);
+ if (Width < 0)
+ return ErrorNonPrintableCharacter;
+ ColumnWidth += Width;
+ }
+ return ColumnWidth;
+}
+
+} // namespace unicode
+} // namespace sys
+} // namespace llvm
+
diff --git a/contrib/llvm/lib/Support/Unix/COM.inc b/contrib/llvm/lib/Support/Unix/COM.inc
new file mode 100644
index 000000000000..5b71de74ebf3
--- /dev/null
+++ b/contrib/llvm/lib/Support/Unix/COM.inc
@@ -0,0 +1,27 @@
+//===- llvm/Support/Unix/COM.inc - Unix COM Implementation -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the Unix portion of COM support.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only generic UNIX code that
+//=== is guaranteed to work on *all* UNIX variants.
+//===----------------------------------------------------------------------===//
+
+namespace llvm {
+namespace sys {
+
+InitializeCOMRAII::InitializeCOMRAII(COMThreadingMode Threading,
+ bool SpeedOverMemory) {}
+
+InitializeCOMRAII::~InitializeCOMRAII() {}
+}
+}
diff --git a/contrib/llvm/lib/Support/Unix/Host.inc b/contrib/llvm/lib/Support/Unix/Host.inc
new file mode 100644
index 000000000000..457217125a22
--- /dev/null
+++ b/contrib/llvm/lib/Support/Unix/Host.inc
@@ -0,0 +1,49 @@
+//===- llvm/Support/Unix/Host.inc -------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the UNIX Host support.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only generic UNIX code that
+//=== is guaranteed to work on *all* UNIX variants.
+//===----------------------------------------------------------------------===//
+
+#include "Unix.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Config/config.h"
+#include <cctype>
+#include <string>
+#include <sys/utsname.h>
+
+using namespace llvm;
+
+static std::string getOSVersion() {
+ struct utsname info;
+
+ if (uname(&info))
+ return "";
+
+ return info.release;
+}
+
+std::string sys::getDefaultTargetTriple() {
+ std::string TargetTripleString(LLVM_DEFAULT_TARGET_TRIPLE);
+
+ // On darwin, we want to update the version to match that of the
+ // target.
+ std::string::size_type DarwinDashIdx = TargetTripleString.find("-darwin");
+ if (DarwinDashIdx != std::string::npos) {
+ TargetTripleString.resize(DarwinDashIdx + strlen("-darwin"));
+ TargetTripleString += getOSVersion();
+ }
+
+ return Triple::normalize(TargetTripleString);
+}
diff --git a/contrib/llvm/lib/Support/Unix/Memory.inc b/contrib/llvm/lib/Support/Unix/Memory.inc
new file mode 100644
index 000000000000..c421ee84c2b7
--- /dev/null
+++ b/contrib/llvm/lib/Support/Unix/Memory.inc
@@ -0,0 +1,350 @@
+//===- Unix/Memory.cpp - Generic UNIX System Configuration ------*- 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 some functions for various memory management utilities.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Unix.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/Process.h"
+
+#ifdef HAVE_SYS_MMAN_H
+#include <sys/mman.h>
+#endif
+
+#ifdef __APPLE__
+#include <mach/mach.h>
+#endif
+
+#if defined(__mips__)
+# if defined(__OpenBSD__)
+# include <mips64/sysarch.h>
+# else
+# include <sys/cachectl.h>
+# endif
+#endif
+
+#ifdef __APPLE__
+extern "C" void sys_icache_invalidate(const void *Addr, size_t len);
+#else
+extern "C" void __clear_cache(void *, void*);
+#endif
+
+namespace {
+
+int getPosixProtectionFlags(unsigned Flags) {
+ switch (Flags) {
+ case llvm::sys::Memory::MF_READ:
+ return PROT_READ;
+ case llvm::sys::Memory::MF_WRITE:
+ return PROT_WRITE;
+ case llvm::sys::Memory::MF_READ|llvm::sys::Memory::MF_WRITE:
+ return PROT_READ | PROT_WRITE;
+ case llvm::sys::Memory::MF_READ|llvm::sys::Memory::MF_EXEC:
+ return PROT_READ | PROT_EXEC;
+ case llvm::sys::Memory::MF_READ |
+ llvm::sys::Memory::MF_WRITE |
+ llvm::sys::Memory::MF_EXEC:
+ return PROT_READ | PROT_WRITE | PROT_EXEC;
+ case llvm::sys::Memory::MF_EXEC:
+#if defined(__FreeBSD__)
+ // On PowerPC, having an executable page that has no read permission
+ // can have unintended consequences. The function InvalidateInstruction-
+ // Cache uses instructions dcbf and icbi, both of which are treated by
+ // the processor as loads. If the page has no read permissions,
+ // executing these instructions will result in a segmentation fault.
+ // Somehow, this problem is not present on Linux, but it does happen
+ // on FreeBSD.
+ return PROT_READ | PROT_EXEC;
+#else
+ return PROT_EXEC;
+#endif
+ default:
+ llvm_unreachable("Illegal memory protection flag specified!");
+ }
+ // Provide a default return value as required by some compilers.
+ return PROT_NONE;
+}
+
+} // namespace
+
+namespace llvm {
+namespace sys {
+
+MemoryBlock
+Memory::allocateMappedMemory(size_t NumBytes,
+ const MemoryBlock *const NearBlock,
+ unsigned PFlags,
+ std::error_code &EC) {
+ EC = std::error_code();
+ if (NumBytes == 0)
+ return MemoryBlock();
+
+ static const size_t PageSize = Process::getPageSize();
+ const size_t NumPages = (NumBytes+PageSize-1)/PageSize;
+
+ int fd = -1;
+#ifdef NEED_DEV_ZERO_FOR_MMAP
+ static int zero_fd = open("/dev/zero", O_RDWR);
+ if (zero_fd == -1) {
+ EC = std::error_code(errno, std::generic_category());
+ return MemoryBlock();
+ }
+ fd = zero_fd;
+#endif
+
+ int MMFlags = MAP_PRIVATE |
+#ifdef HAVE_MMAP_ANONYMOUS
+ MAP_ANONYMOUS
+#else
+ MAP_ANON
+#endif
+ ; // Ends statement above
+
+ int Protect = getPosixProtectionFlags(PFlags);
+
+ // Use any near hint and the page size to set a page-aligned starting address
+ uintptr_t Start = NearBlock ? reinterpret_cast<uintptr_t>(NearBlock->base()) +
+ NearBlock->size() : 0;
+ if (Start && Start % PageSize)
+ Start += PageSize - Start % PageSize;
+
+ void *Addr = ::mmap(reinterpret_cast<void*>(Start), PageSize*NumPages,
+ Protect, MMFlags, fd, 0);
+ if (Addr == MAP_FAILED) {
+ if (NearBlock) //Try again without a near hint
+ return allocateMappedMemory(NumBytes, nullptr, PFlags, EC);
+
+ EC = std::error_code(errno, std::generic_category());
+ return MemoryBlock();
+ }
+
+ MemoryBlock Result;
+ Result.Address = Addr;
+ Result.Size = NumPages*PageSize;
+
+ if (PFlags & MF_EXEC)
+ Memory::InvalidateInstructionCache(Result.Address, Result.Size);
+
+ return Result;
+}
+
+std::error_code
+Memory::releaseMappedMemory(MemoryBlock &M) {
+ if (M.Address == nullptr || M.Size == 0)
+ return std::error_code();
+
+ if (0 != ::munmap(M.Address, M.Size))
+ return std::error_code(errno, std::generic_category());
+
+ M.Address = nullptr;
+ M.Size = 0;
+
+ return std::error_code();
+}
+
+std::error_code
+Memory::protectMappedMemory(const MemoryBlock &M, unsigned Flags) {
+ if (M.Address == nullptr || M.Size == 0)
+ return std::error_code();
+
+ if (!Flags)
+ return std::error_code(EINVAL, std::generic_category());
+
+ int Protect = getPosixProtectionFlags(Flags);
+
+ int Result = ::mprotect(M.Address, M.Size, Protect);
+ if (Result != 0)
+ return std::error_code(errno, std::generic_category());
+
+ if (Flags & MF_EXEC)
+ Memory::InvalidateInstructionCache(M.Address, M.Size);
+
+ return std::error_code();
+}
+
+/// AllocateRWX - Allocate a slab of memory with read/write/execute
+/// permissions. This is typically used for JIT applications where we want
+/// to emit code to the memory then jump to it. Getting this type of memory
+/// is very OS specific.
+///
+MemoryBlock
+Memory::AllocateRWX(size_t NumBytes, const MemoryBlock* NearBlock,
+ std::string *ErrMsg) {
+ if (NumBytes == 0) return MemoryBlock();
+
+ size_t PageSize = Process::getPageSize();
+ size_t NumPages = (NumBytes+PageSize-1)/PageSize;
+
+ int fd = -1;
+#ifdef NEED_DEV_ZERO_FOR_MMAP
+ static int zero_fd = open("/dev/zero", O_RDWR);
+ if (zero_fd == -1) {
+ MakeErrMsg(ErrMsg, "Can't open /dev/zero device");
+ return MemoryBlock();
+ }
+ fd = zero_fd;
+#endif
+
+ int flags = MAP_PRIVATE |
+#ifdef HAVE_MMAP_ANONYMOUS
+ MAP_ANONYMOUS
+#else
+ MAP_ANON
+#endif
+ ;
+
+ void* start = NearBlock ? (unsigned char*)NearBlock->base() +
+ NearBlock->size() : nullptr;
+
+#if defined(__APPLE__) && (defined(__arm__) || defined(__arm64__))
+ void *pa = ::mmap(start, PageSize*NumPages, PROT_READ|PROT_EXEC,
+ flags, fd, 0);
+#else
+ void *pa = ::mmap(start, PageSize*NumPages, PROT_READ|PROT_WRITE|PROT_EXEC,
+ flags, fd, 0);
+#endif
+ if (pa == MAP_FAILED) {
+ if (NearBlock) //Try again without a near hint
+ return AllocateRWX(NumBytes, nullptr);
+
+ MakeErrMsg(ErrMsg, "Can't allocate RWX Memory");
+ return MemoryBlock();
+ }
+
+#if defined(__APPLE__) && (defined(__arm__) || defined(__arm64__))
+ kern_return_t kr = vm_protect(mach_task_self(), (vm_address_t)pa,
+ (vm_size_t)(PageSize*NumPages), 0,
+ VM_PROT_READ | VM_PROT_EXECUTE | VM_PROT_COPY);
+ if (KERN_SUCCESS != kr) {
+ MakeErrMsg(ErrMsg, "vm_protect max RX failed");
+ return MemoryBlock();
+ }
+
+ kr = vm_protect(mach_task_self(), (vm_address_t)pa,
+ (vm_size_t)(PageSize*NumPages), 0,
+ VM_PROT_READ | VM_PROT_WRITE);
+ if (KERN_SUCCESS != kr) {
+ MakeErrMsg(ErrMsg, "vm_protect RW failed");
+ return MemoryBlock();
+ }
+#endif
+
+ MemoryBlock result;
+ result.Address = pa;
+ result.Size = NumPages*PageSize;
+
+ return result;
+}
+
+bool Memory::ReleaseRWX(MemoryBlock &M, std::string *ErrMsg) {
+ if (M.Address == nullptr || M.Size == 0) return false;
+ if (0 != ::munmap(M.Address, M.Size))
+ return MakeErrMsg(ErrMsg, "Can't release RWX Memory");
+ return false;
+}
+
+bool Memory::setWritable (MemoryBlock &M, std::string *ErrMsg) {
+#if defined(__APPLE__) && (defined(__arm__) || defined(__arm64__))
+ if (M.Address == 0 || M.Size == 0) return false;
+ Memory::InvalidateInstructionCache(M.Address, M.Size);
+ kern_return_t kr = vm_protect(mach_task_self(), (vm_address_t)M.Address,
+ (vm_size_t)M.Size, 0, VM_PROT_READ | VM_PROT_WRITE);
+ return KERN_SUCCESS == kr;
+#else
+ return true;
+#endif
+}
+
+bool Memory::setExecutable (MemoryBlock &M, std::string *ErrMsg) {
+#if defined(__APPLE__) && (defined(__arm__) || defined(__arm64__))
+ if (M.Address == 0 || M.Size == 0) return false;
+ Memory::InvalidateInstructionCache(M.Address, M.Size);
+ kern_return_t kr = vm_protect(mach_task_self(), (vm_address_t)M.Address,
+ (vm_size_t)M.Size, 0, VM_PROT_READ | VM_PROT_EXECUTE | VM_PROT_COPY);
+ return KERN_SUCCESS == kr;
+#elif defined(__arm__) || defined(__aarch64__)
+ Memory::InvalidateInstructionCache(M.Address, M.Size);
+ return true;
+#else
+ return true;
+#endif
+}
+
+bool Memory::setRangeWritable(const void *Addr, size_t Size) {
+#if defined(__APPLE__) && (defined(__arm__) || defined(__arm64__))
+ kern_return_t kr = vm_protect(mach_task_self(), (vm_address_t)Addr,
+ (vm_size_t)Size, 0,
+ VM_PROT_READ | VM_PROT_WRITE);
+ return KERN_SUCCESS == kr;
+#else
+ return true;
+#endif
+}
+
+bool Memory::setRangeExecutable(const void *Addr, size_t Size) {
+#if defined(__APPLE__) && (defined(__arm__) || defined(__arm64__))
+ kern_return_t kr = vm_protect(mach_task_self(), (vm_address_t)Addr,
+ (vm_size_t)Size, 0,
+ VM_PROT_READ | VM_PROT_EXECUTE | VM_PROT_COPY);
+ return KERN_SUCCESS == kr;
+#else
+ return true;
+#endif
+}
+
+/// InvalidateInstructionCache - Before the JIT can run a block of code
+/// that has been emitted it must invalidate the instruction cache on some
+/// platforms.
+void Memory::InvalidateInstructionCache(const void *Addr,
+ size_t Len) {
+
+// icache invalidation for PPC and ARM.
+#if defined(__APPLE__)
+
+# if (defined(__POWERPC__) || defined (__ppc__) || \
+ defined(_POWER) || defined(_ARCH_PPC) || defined(__arm__) || \
+ defined(__arm64__))
+ sys_icache_invalidate(const_cast<void *>(Addr), Len);
+# endif
+
+#else
+
+# if (defined(__POWERPC__) || defined (__ppc__) || \
+ defined(_POWER) || defined(_ARCH_PPC)) && defined(__GNUC__)
+ const size_t LineSize = 32;
+
+ const intptr_t Mask = ~(LineSize - 1);
+ const intptr_t StartLine = ((intptr_t) Addr) & Mask;
+ const intptr_t EndLine = ((intptr_t) Addr + Len + LineSize - 1) & Mask;
+
+ for (intptr_t Line = StartLine; Line < EndLine; Line += LineSize)
+ asm volatile("dcbf 0, %0" : : "r"(Line));
+ asm volatile("sync");
+
+ for (intptr_t Line = StartLine; Line < EndLine; Line += LineSize)
+ asm volatile("icbi 0, %0" : : "r"(Line));
+ asm volatile("isync");
+# elif (defined(__arm__) || defined(__aarch64__) || defined(__mips__)) && \
+ defined(__GNUC__)
+ // FIXME: Can we safely always call this for __GNUC__ everywhere?
+ const char *Start = static_cast<const char *>(Addr);
+ const char *End = Start + Len;
+ __clear_cache(const_cast<char *>(Start), const_cast<char *>(End));
+# endif
+
+#endif // end apple
+
+ ValgrindDiscardTranslations(Addr, Len);
+}
+
+} // namespace sys
+} // namespace llvm
diff --git a/contrib/llvm/lib/Support/Unix/Mutex.inc b/contrib/llvm/lib/Support/Unix/Mutex.inc
new file mode 100644
index 000000000000..fe6b17041457
--- /dev/null
+++ b/contrib/llvm/lib/Support/Unix/Mutex.inc
@@ -0,0 +1,43 @@
+//===- llvm/Support/Unix/Mutex.inc - Unix Mutex Implementation ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the Unix specific (non-pthread) Mutex class.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only generic UNIX code that
+//=== is guaranteed to work on *all* UNIX variants.
+//===----------------------------------------------------------------------===//
+
+namespace llvm
+{
+using namespace sys;
+
+MutexImpl::MutexImpl( bool recursive)
+{
+}
+
+MutexImpl::~MutexImpl()
+{
+}
+
+bool
+MutexImpl::release()
+{
+ return true;
+}
+
+bool
+MutexImpl::tryacquire( void )
+{
+ return true;
+}
+
+}
diff --git a/contrib/llvm/lib/Support/Unix/Path.inc b/contrib/llvm/lib/Support/Unix/Path.inc
new file mode 100644
index 000000000000..973d010dcac1
--- /dev/null
+++ b/contrib/llvm/lib/Support/Unix/Path.inc
@@ -0,0 +1,621 @@
+//===- llvm/Support/Unix/Path.inc - Unix Path Implementation ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the Unix specific implementation of the Path API.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only generic UNIX code that
+//=== is guaranteed to work on *all* UNIX variants.
+//===----------------------------------------------------------------------===//
+
+#include "Unix.h"
+#include <limits.h>
+#include <stdio.h>
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_SYS_MMAN_H
+#include <sys/mman.h>
+#endif
+#if HAVE_DIRENT_H
+# include <dirent.h>
+# define NAMLEN(dirent) strlen((dirent)->d_name)
+#else
+# define dirent direct
+# define NAMLEN(dirent) (dirent)->d_namlen
+# if HAVE_SYS_NDIR_H
+# include <sys/ndir.h>
+# endif
+# if HAVE_SYS_DIR_H
+# include <sys/dir.h>
+# endif
+# if HAVE_NDIR_H
+# include <ndir.h>
+# endif
+#endif
+
+#ifdef __APPLE__
+#include <mach-o/dyld.h>
+#endif
+
+// Both stdio.h and cstdio are included via different pathes and
+// stdcxx's cstdio doesn't include stdio.h, so it doesn't #undef the macros
+// either.
+#undef ferror
+#undef feof
+
+// For GNU Hurd
+#if defined(__GNU__) && !defined(PATH_MAX)
+# define PATH_MAX 4096
+#endif
+
+using namespace llvm;
+
+namespace llvm {
+namespace sys {
+namespace fs {
+#if defined(__FreeBSD__) || defined (__NetBSD__) || defined(__Bitrig__) || \
+ defined(__OpenBSD__) || defined(__minix) || defined(__FreeBSD_kernel__) || \
+ defined(__linux__) || defined(__CYGWIN__) || defined(__DragonFly__)
+static int
+test_dir(char ret[PATH_MAX], const char *dir, const char *bin)
+{
+ struct stat sb;
+ char fullpath[PATH_MAX];
+
+ snprintf(fullpath, PATH_MAX, "%s/%s", dir, bin);
+ if (realpath(fullpath, ret) == NULL)
+ return (1);
+ if (stat(fullpath, &sb) != 0)
+ return (1);
+
+ return (0);
+}
+
+static char *
+getprogpath(char ret[PATH_MAX], const char *bin)
+{
+ char *pv, *s, *t;
+
+ /* First approach: absolute path. */
+ if (bin[0] == '/') {
+ if (test_dir(ret, "/", bin) == 0)
+ return (ret);
+ return (NULL);
+ }
+
+ /* Second approach: relative path. */
+ if (strchr(bin, '/') != NULL) {
+ char cwd[PATH_MAX];
+ if (getcwd(cwd, PATH_MAX) == NULL)
+ return (NULL);
+ if (test_dir(ret, cwd, bin) == 0)
+ return (ret);
+ return (NULL);
+ }
+
+ /* Third approach: $PATH */
+ if ((pv = getenv("PATH")) == NULL)
+ return (NULL);
+ s = pv = strdup(pv);
+ if (pv == NULL)
+ return (NULL);
+ while ((t = strsep(&s, ":")) != NULL) {
+ if (test_dir(ret, t, bin) == 0) {
+ free(pv);
+ return (ret);
+ }
+ }
+ free(pv);
+ return (NULL);
+}
+#endif // __FreeBSD__ || __NetBSD__ || __FreeBSD_kernel__
+
+/// GetMainExecutable - Return the path to the main executable, given the
+/// value of argv[0] from program startup.
+std::string getMainExecutable(const char *argv0, void *MainAddr) {
+#if defined(__APPLE__)
+ // On OS X the executable path is saved to the stack by dyld. Reading it
+ // from there is much faster than calling dladdr, especially for large
+ // binaries with symbols.
+ char exe_path[MAXPATHLEN];
+ uint32_t size = sizeof(exe_path);
+ if (_NSGetExecutablePath(exe_path, &size) == 0) {
+ char link_path[MAXPATHLEN];
+ if (realpath(exe_path, link_path))
+ return link_path;
+ }
+#elif defined(__FreeBSD__) || defined (__NetBSD__) || defined(__Bitrig__) || \
+ defined(__OpenBSD__) || defined(__minix) || defined(__DragonFly__) || \
+ defined(__FreeBSD_kernel__)
+ char exe_path[PATH_MAX];
+
+ if (getprogpath(exe_path, argv0) != NULL)
+ return exe_path;
+#elif defined(__linux__) || defined(__CYGWIN__)
+ char exe_path[MAXPATHLEN];
+ StringRef aPath("/proc/self/exe");
+ if (sys::fs::exists(aPath)) {
+ // /proc is not always mounted under Linux (chroot for example).
+ ssize_t len = readlink(aPath.str().c_str(), exe_path, sizeof(exe_path));
+ if (len >= 0)
+ return std::string(exe_path, len);
+ } else {
+ // Fall back to the classical detection.
+ if (getprogpath(exe_path, argv0) != NULL)
+ return exe_path;
+ }
+#elif defined(HAVE_DLFCN_H)
+ // Use dladdr to get executable path if available.
+ Dl_info DLInfo;
+ int err = dladdr(MainAddr, &DLInfo);
+ if (err == 0)
+ return "";
+
+ // If the filename is a symlink, we need to resolve and return the location of
+ // the actual executable.
+ char link_path[MAXPATHLEN];
+ if (realpath(DLInfo.dli_fname, link_path))
+ return link_path;
+#else
+#error GetMainExecutable is not implemented on this host yet.
+#endif
+ return "";
+}
+
+TimeValue file_status::getLastModificationTime() const {
+ TimeValue Ret;
+ Ret.fromEpochTime(fs_st_mtime);
+ return Ret;
+}
+
+UniqueID file_status::getUniqueID() const {
+ return UniqueID(fs_st_dev, fs_st_ino);
+}
+
+std::error_code current_path(SmallVectorImpl<char> &result) {
+ result.clear();
+
+ const char *pwd = ::getenv("PWD");
+ llvm::sys::fs::file_status PWDStatus, DotStatus;
+ if (pwd && llvm::sys::path::is_absolute(pwd) &&
+ !llvm::sys::fs::status(pwd, PWDStatus) &&
+ !llvm::sys::fs::status(".", DotStatus) &&
+ PWDStatus.getUniqueID() == DotStatus.getUniqueID()) {
+ result.append(pwd, pwd + strlen(pwd));
+ return std::error_code();
+ }
+
+#ifdef MAXPATHLEN
+ result.reserve(MAXPATHLEN);
+#else
+// For GNU Hurd
+ result.reserve(1024);
+#endif
+
+ while (true) {
+ if (::getcwd(result.data(), result.capacity()) == nullptr) {
+ // See if there was a real error.
+ if (errno != ENOMEM)
+ return std::error_code(errno, std::generic_category());
+ // Otherwise there just wasn't enough space.
+ result.reserve(result.capacity() * 2);
+ } else
+ break;
+ }
+
+ result.set_size(strlen(result.data()));
+ return std::error_code();
+}
+
+std::error_code create_directory(const Twine &path, bool IgnoreExisting) {
+ SmallString<128> path_storage;
+ StringRef p = path.toNullTerminatedStringRef(path_storage);
+
+ if (::mkdir(p.begin(), S_IRWXU | S_IRWXG) == -1) {
+ if (errno != EEXIST || !IgnoreExisting)
+ return std::error_code(errno, std::generic_category());
+ }
+
+ return std::error_code();
+}
+
+// Note that we are using symbolic link because hard links are not supported by
+// all filesystems (SMB doesn't).
+std::error_code create_link(const Twine &to, const Twine &from) {
+ // Get arguments.
+ SmallString<128> from_storage;
+ SmallString<128> to_storage;
+ StringRef f = from.toNullTerminatedStringRef(from_storage);
+ StringRef t = to.toNullTerminatedStringRef(to_storage);
+
+ if (::symlink(t.begin(), f.begin()) == -1)
+ return std::error_code(errno, std::generic_category());
+
+ return std::error_code();
+}
+
+std::error_code remove(const Twine &path, bool IgnoreNonExisting) {
+ SmallString<128> path_storage;
+ StringRef p = path.toNullTerminatedStringRef(path_storage);
+
+ struct stat buf;
+ if (lstat(p.begin(), &buf) != 0) {
+ if (errno != ENOENT || !IgnoreNonExisting)
+ return std::error_code(errno, std::generic_category());
+ return std::error_code();
+ }
+
+ // Note: this check catches strange situations. In all cases, LLVM should
+ // only be involved in the creation and deletion of regular files. This
+ // check ensures that what we're trying to erase is a regular file. It
+ // effectively prevents LLVM from erasing things like /dev/null, any block
+ // special file, or other things that aren't "regular" files.
+ if (!S_ISREG(buf.st_mode) && !S_ISDIR(buf.st_mode) && !S_ISLNK(buf.st_mode))
+ return make_error_code(errc::operation_not_permitted);
+
+ if (::remove(p.begin()) == -1) {
+ if (errno != ENOENT || !IgnoreNonExisting)
+ return std::error_code(errno, std::generic_category());
+ }
+
+ return std::error_code();
+}
+
+std::error_code rename(const Twine &from, const Twine &to) {
+ // Get arguments.
+ SmallString<128> from_storage;
+ SmallString<128> to_storage;
+ StringRef f = from.toNullTerminatedStringRef(from_storage);
+ StringRef t = to.toNullTerminatedStringRef(to_storage);
+
+ if (::rename(f.begin(), t.begin()) == -1)
+ return std::error_code(errno, std::generic_category());
+
+ return std::error_code();
+}
+
+std::error_code resize_file(int FD, uint64_t Size) {
+ if (::ftruncate(FD, Size) == -1)
+ return std::error_code(errno, std::generic_category());
+
+ return std::error_code();
+}
+
+static int convertAccessMode(AccessMode Mode) {
+ switch (Mode) {
+ case AccessMode::Exist:
+ return F_OK;
+ case AccessMode::Write:
+ return W_OK;
+ case AccessMode::Execute:
+ return R_OK | X_OK; // scripts also need R_OK.
+ }
+ llvm_unreachable("invalid enum");
+}
+
+std::error_code access(const Twine &Path, AccessMode Mode) {
+ SmallString<128> PathStorage;
+ StringRef P = Path.toNullTerminatedStringRef(PathStorage);
+
+ if (::access(P.begin(), convertAccessMode(Mode)) == -1)
+ return std::error_code(errno, std::generic_category());
+
+ if (Mode == AccessMode::Execute) {
+ // Don't say that directories are executable.
+ struct stat buf;
+ if (0 != stat(P.begin(), &buf))
+ return errc::permission_denied;
+ if (!S_ISREG(buf.st_mode))
+ return errc::permission_denied;
+ }
+
+ return std::error_code();
+}
+
+bool equivalent(file_status A, file_status B) {
+ assert(status_known(A) && status_known(B));
+ return A.fs_st_dev == B.fs_st_dev &&
+ A.fs_st_ino == B.fs_st_ino;
+}
+
+std::error_code equivalent(const Twine &A, const Twine &B, bool &result) {
+ file_status fsA, fsB;
+ if (std::error_code ec = status(A, fsA))
+ return ec;
+ if (std::error_code ec = status(B, fsB))
+ return ec;
+ result = equivalent(fsA, fsB);
+ return std::error_code();
+}
+
+static std::error_code fillStatus(int StatRet, const struct stat &Status,
+ file_status &Result) {
+ if (StatRet != 0) {
+ std::error_code ec(errno, std::generic_category());
+ if (ec == errc::no_such_file_or_directory)
+ Result = file_status(file_type::file_not_found);
+ else
+ Result = file_status(file_type::status_error);
+ return ec;
+ }
+
+ file_type Type = file_type::type_unknown;
+
+ if (S_ISDIR(Status.st_mode))
+ Type = file_type::directory_file;
+ else if (S_ISREG(Status.st_mode))
+ Type = file_type::regular_file;
+ else if (S_ISBLK(Status.st_mode))
+ Type = file_type::block_file;
+ else if (S_ISCHR(Status.st_mode))
+ Type = file_type::character_file;
+ else if (S_ISFIFO(Status.st_mode))
+ Type = file_type::fifo_file;
+ else if (S_ISSOCK(Status.st_mode))
+ Type = file_type::socket_file;
+
+ perms Perms = static_cast<perms>(Status.st_mode);
+ Result =
+ file_status(Type, Perms, Status.st_dev, Status.st_ino, Status.st_mtime,
+ Status.st_uid, Status.st_gid, Status.st_size);
+
+ return std::error_code();
+}
+
+std::error_code status(const Twine &Path, file_status &Result) {
+ SmallString<128> PathStorage;
+ StringRef P = Path.toNullTerminatedStringRef(PathStorage);
+
+ struct stat Status;
+ int StatRet = ::stat(P.begin(), &Status);
+ return fillStatus(StatRet, Status, Result);
+}
+
+std::error_code status(int FD, file_status &Result) {
+ struct stat Status;
+ int StatRet = ::fstat(FD, &Status);
+ return fillStatus(StatRet, Status, Result);
+}
+
+std::error_code setLastModificationAndAccessTime(int FD, TimeValue Time) {
+#if defined(HAVE_FUTIMENS)
+ timespec Times[2];
+ Times[0].tv_sec = Time.toEpochTime();
+ Times[0].tv_nsec = 0;
+ Times[1] = Times[0];
+ if (::futimens(FD, Times))
+ return std::error_code(errno, std::generic_category());
+ return std::error_code();
+#elif defined(HAVE_FUTIMES)
+ timeval Times[2];
+ Times[0].tv_sec = Time.toEpochTime();
+ Times[0].tv_usec = 0;
+ Times[1] = Times[0];
+ if (::futimes(FD, Times))
+ return std::error_code(errno, std::generic_category());
+ return std::error_code();
+#else
+#warning Missing futimes() and futimens()
+ return make_error_code(errc::function_not_supported);
+#endif
+}
+
+std::error_code mapped_file_region::init(int FD, uint64_t Offset,
+ mapmode Mode) {
+ assert(Size != 0);
+
+ int flags = (Mode == readwrite) ? MAP_SHARED : MAP_PRIVATE;
+ int prot = (Mode == readonly) ? PROT_READ : (PROT_READ | PROT_WRITE);
+ Mapping = ::mmap(nullptr, Size, prot, flags, FD, Offset);
+ if (Mapping == MAP_FAILED)
+ return std::error_code(errno, std::generic_category());
+ return std::error_code();
+}
+
+mapped_file_region::mapped_file_region(int fd, mapmode mode, uint64_t length,
+ uint64_t offset, std::error_code &ec)
+ : Size(length), Mapping() {
+ // Make sure that the requested size fits within SIZE_T.
+ if (length > std::numeric_limits<size_t>::max()) {
+ ec = make_error_code(errc::invalid_argument);
+ return;
+ }
+
+ ec = init(fd, offset, mode);
+ if (ec)
+ Mapping = nullptr;
+}
+
+mapped_file_region::~mapped_file_region() {
+ if (Mapping)
+ ::munmap(Mapping, Size);
+}
+
+uint64_t mapped_file_region::size() const {
+ assert(Mapping && "Mapping failed but used anyway!");
+ return Size;
+}
+
+char *mapped_file_region::data() const {
+ assert(Mapping && "Mapping failed but used anyway!");
+ return reinterpret_cast<char*>(Mapping);
+}
+
+const char *mapped_file_region::const_data() const {
+ assert(Mapping && "Mapping failed but used anyway!");
+ return reinterpret_cast<const char*>(Mapping);
+}
+
+int mapped_file_region::alignment() {
+ return Process::getPageSize();
+}
+
+std::error_code detail::directory_iterator_construct(detail::DirIterState &it,
+ StringRef path){
+ SmallString<128> path_null(path);
+ DIR *directory = ::opendir(path_null.c_str());
+ if (!directory)
+ return std::error_code(errno, std::generic_category());
+
+ it.IterationHandle = reinterpret_cast<intptr_t>(directory);
+ // Add something for replace_filename to replace.
+ path::append(path_null, ".");
+ it.CurrentEntry = directory_entry(path_null.str());
+ return directory_iterator_increment(it);
+}
+
+std::error_code detail::directory_iterator_destruct(detail::DirIterState &it) {
+ if (it.IterationHandle)
+ ::closedir(reinterpret_cast<DIR *>(it.IterationHandle));
+ it.IterationHandle = 0;
+ it.CurrentEntry = directory_entry();
+ return std::error_code();
+}
+
+std::error_code detail::directory_iterator_increment(detail::DirIterState &it) {
+ errno = 0;
+ dirent *cur_dir = ::readdir(reinterpret_cast<DIR *>(it.IterationHandle));
+ if (cur_dir == nullptr && errno != 0) {
+ return std::error_code(errno, std::generic_category());
+ } else if (cur_dir != nullptr) {
+ StringRef name(cur_dir->d_name, NAMLEN(cur_dir));
+ if ((name.size() == 1 && name[0] == '.') ||
+ (name.size() == 2 && name[0] == '.' && name[1] == '.'))
+ return directory_iterator_increment(it);
+ it.CurrentEntry.replace_filename(name);
+ } else
+ return directory_iterator_destruct(it);
+
+ return std::error_code();
+}
+
+std::error_code openFileForRead(const Twine &Name, int &ResultFD) {
+ SmallString<128> Storage;
+ StringRef P = Name.toNullTerminatedStringRef(Storage);
+ while ((ResultFD = open(P.begin(), O_RDONLY)) < 0) {
+ if (errno != EINTR)
+ return std::error_code(errno, std::generic_category());
+ }
+ return std::error_code();
+}
+
+std::error_code openFileForWrite(const Twine &Name, int &ResultFD,
+ sys::fs::OpenFlags Flags, unsigned Mode) {
+ // Verify that we don't have both "append" and "excl".
+ assert((!(Flags & sys::fs::F_Excl) || !(Flags & sys::fs::F_Append)) &&
+ "Cannot specify both 'excl' and 'append' file creation flags!");
+
+ int OpenFlags = O_CREAT;
+
+ if (Flags & F_RW)
+ OpenFlags |= O_RDWR;
+ else
+ OpenFlags |= O_WRONLY;
+
+ if (Flags & F_Append)
+ OpenFlags |= O_APPEND;
+ else
+ OpenFlags |= O_TRUNC;
+
+ if (Flags & F_Excl)
+ OpenFlags |= O_EXCL;
+
+ SmallString<128> Storage;
+ StringRef P = Name.toNullTerminatedStringRef(Storage);
+ while ((ResultFD = open(P.begin(), OpenFlags, Mode)) < 0) {
+ if (errno != EINTR)
+ return std::error_code(errno, std::generic_category());
+ }
+ return std::error_code();
+}
+
+} // end namespace fs
+
+namespace path {
+
+bool home_directory(SmallVectorImpl<char> &result) {
+ if (char *RequestedDir = getenv("HOME")) {
+ result.clear();
+ result.append(RequestedDir, RequestedDir + strlen(RequestedDir));
+ return true;
+ }
+
+ return false;
+}
+
+static const char *getEnvTempDir() {
+ // Check whether the temporary directory is specified by an environment
+ // variable.
+ const char *EnvironmentVariables[] = {"TMPDIR", "TMP", "TEMP", "TEMPDIR"};
+ for (const char *Env : EnvironmentVariables) {
+ if (const char *Dir = std::getenv(Env))
+ return Dir;
+ }
+
+ return nullptr;
+}
+
+static const char *getDefaultTempDir(bool ErasedOnReboot) {
+#ifdef P_tmpdir
+ if ((bool)P_tmpdir)
+ return P_tmpdir;
+#endif
+
+ if (ErasedOnReboot)
+ return "/tmp";
+ return "/var/tmp";
+}
+
+void system_temp_directory(bool ErasedOnReboot, SmallVectorImpl<char> &Result) {
+ Result.clear();
+
+ if (ErasedOnReboot) {
+ // There is no env variable for the cache directory.
+ if (const char *RequestedDir = getEnvTempDir()) {
+ Result.append(RequestedDir, RequestedDir + strlen(RequestedDir));
+ return;
+ }
+ }
+
+#if defined(_CS_DARWIN_USER_TEMP_DIR) && defined(_CS_DARWIN_USER_CACHE_DIR)
+ // On Darwin, use DARWIN_USER_TEMP_DIR or DARWIN_USER_CACHE_DIR.
+ // macros defined in <unistd.h> on darwin >= 9
+ int ConfName = ErasedOnReboot? _CS_DARWIN_USER_TEMP_DIR
+ : _CS_DARWIN_USER_CACHE_DIR;
+ size_t ConfLen = confstr(ConfName, nullptr, 0);
+ if (ConfLen > 0) {
+ do {
+ Result.resize(ConfLen);
+ ConfLen = confstr(ConfName, Result.data(), Result.size());
+ } while (ConfLen > 0 && ConfLen != Result.size());
+
+ if (ConfLen > 0) {
+ assert(Result.back() == 0);
+ Result.pop_back();
+ return;
+ }
+
+ Result.clear();
+ }
+#endif
+
+ const char *RequestedDir = getDefaultTempDir(ErasedOnReboot);
+ Result.append(RequestedDir, RequestedDir + strlen(RequestedDir));
+}
+
+} // end namespace path
+
+} // end namespace sys
+} // end namespace llvm
diff --git a/contrib/llvm/lib/Support/Unix/Process.inc b/contrib/llvm/lib/Support/Unix/Process.inc
new file mode 100644
index 000000000000..b15cedd7f6dc
--- /dev/null
+++ b/contrib/llvm/lib/Support/Unix/Process.inc
@@ -0,0 +1,458 @@
+//===- Unix/Process.cpp - Unix Process Implementation --------- -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides the generic Unix implementation of the Process class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Unix.h"
+#include "llvm/ADT/Hashing.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/Mutex.h"
+#include "llvm/Support/MutexGuard.h"
+#include "llvm/Support/TimeValue.h"
+#if HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+// DragonFlyBSD, OpenBSD, and Bitrig have deprecated <malloc.h> for
+// <stdlib.h> instead. Unix.h includes this for us already.
+#if defined(HAVE_MALLOC_H) && !defined(__DragonFly__) && \
+ !defined(__OpenBSD__) && !defined(__Bitrig__)
+#include <malloc.h>
+#endif
+#if defined(HAVE_MALLCTL)
+#include <malloc_np.h>
+#endif
+#ifdef HAVE_MALLOC_MALLOC_H
+#include <malloc/malloc.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+# include <sys/ioctl.h>
+#endif
+#ifdef HAVE_TERMIOS_H
+# include <termios.h>
+#endif
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only generic UNIX code that
+//=== is guaranteed to work on *all* UNIX variants.
+//===----------------------------------------------------------------------===//
+
+using namespace llvm;
+using namespace sys;
+
+static std::pair<TimeValue, TimeValue> getRUsageTimes() {
+#if defined(HAVE_GETRUSAGE)
+ struct rusage RU;
+ ::getrusage(RUSAGE_SELF, &RU);
+ return std::make_pair(
+ TimeValue(
+ static_cast<TimeValue::SecondsType>(RU.ru_utime.tv_sec),
+ static_cast<TimeValue::NanoSecondsType>(
+ RU.ru_utime.tv_usec * TimeValue::NANOSECONDS_PER_MICROSECOND)),
+ TimeValue(
+ static_cast<TimeValue::SecondsType>(RU.ru_stime.tv_sec),
+ static_cast<TimeValue::NanoSecondsType>(
+ RU.ru_stime.tv_usec * TimeValue::NANOSECONDS_PER_MICROSECOND)));
+#else
+#warning Cannot get usage times on this platform
+ return std::make_pair(TimeValue(), TimeValue());
+#endif
+}
+
+// On Cygwin, getpagesize() returns 64k(AllocationGranularity) and
+// offset in mmap(3) should be aligned to the AllocationGranularity.
+unsigned Process::getPageSize() {
+#if defined(HAVE_GETPAGESIZE)
+ static const int page_size = ::getpagesize();
+#elif defined(HAVE_SYSCONF)
+ static long page_size = ::sysconf(_SC_PAGE_SIZE);
+#else
+#warning Cannot get the page size on this machine
+#endif
+ return static_cast<unsigned>(page_size);
+}
+
+size_t Process::GetMallocUsage() {
+#if defined(HAVE_MALLINFO)
+ struct mallinfo mi;
+ mi = ::mallinfo();
+ return mi.uordblks;
+#elif defined(HAVE_MALLOC_ZONE_STATISTICS) && defined(HAVE_MALLOC_MALLOC_H)
+ malloc_statistics_t Stats;
+ malloc_zone_statistics(malloc_default_zone(), &Stats);
+ return Stats.size_in_use; // darwin
+#elif defined(HAVE_MALLCTL)
+ size_t alloc, sz;
+ sz = sizeof(size_t);
+ if (mallctl("stats.allocated", &alloc, &sz, NULL, 0) == 0)
+ return alloc;
+ return 0;
+#elif defined(HAVE_SBRK)
+ // Note this is only an approximation and more closely resembles
+ // the value returned by mallinfo in the arena field.
+ static char *StartOfMemory = reinterpret_cast<char*>(::sbrk(0));
+ char *EndOfMemory = (char*)sbrk(0);
+ if (EndOfMemory != ((char*)-1) && StartOfMemory != ((char*)-1))
+ return EndOfMemory - StartOfMemory;
+ return 0;
+#else
+#warning Cannot get malloc info on this platform
+ return 0;
+#endif
+}
+
+void Process::GetTimeUsage(TimeValue &elapsed, TimeValue &user_time,
+ TimeValue &sys_time) {
+ elapsed = TimeValue::now();
+ std::tie(user_time, sys_time) = getRUsageTimes();
+}
+
+#if defined(HAVE_MACH_MACH_H) && !defined(__GNU__)
+#include <mach/mach.h>
+#endif
+
+// Some LLVM programs such as bugpoint produce core files as a normal part of
+// their operation. To prevent the disk from filling up, this function
+// does what's necessary to prevent their generation.
+void Process::PreventCoreFiles() {
+#if HAVE_SETRLIMIT
+ struct rlimit rlim;
+ rlim.rlim_cur = rlim.rlim_max = 0;
+ setrlimit(RLIMIT_CORE, &rlim);
+#endif
+
+#if defined(HAVE_MACH_MACH_H) && !defined(__GNU__)
+ // Disable crash reporting on Mac OS X 10.0-10.4
+
+ // get information about the original set of exception ports for the task
+ mach_msg_type_number_t Count = 0;
+ exception_mask_t OriginalMasks[EXC_TYPES_COUNT];
+ exception_port_t OriginalPorts[EXC_TYPES_COUNT];
+ exception_behavior_t OriginalBehaviors[EXC_TYPES_COUNT];
+ thread_state_flavor_t OriginalFlavors[EXC_TYPES_COUNT];
+ kern_return_t err =
+ task_get_exception_ports(mach_task_self(), EXC_MASK_ALL, OriginalMasks,
+ &Count, OriginalPorts, OriginalBehaviors,
+ OriginalFlavors);
+ if (err == KERN_SUCCESS) {
+ // replace each with MACH_PORT_NULL.
+ for (unsigned i = 0; i != Count; ++i)
+ task_set_exception_ports(mach_task_self(), OriginalMasks[i],
+ MACH_PORT_NULL, OriginalBehaviors[i],
+ OriginalFlavors[i]);
+ }
+
+ // Disable crash reporting on Mac OS X 10.5
+ signal(SIGABRT, _exit);
+ signal(SIGILL, _exit);
+ signal(SIGFPE, _exit);
+ signal(SIGSEGV, _exit);
+ signal(SIGBUS, _exit);
+#endif
+}
+
+Optional<std::string> Process::GetEnv(StringRef Name) {
+ std::string NameStr = Name.str();
+ const char *Val = ::getenv(NameStr.c_str());
+ if (!Val)
+ return None;
+ return std::string(Val);
+}
+
+std::error_code
+Process::GetArgumentVector(SmallVectorImpl<const char *> &ArgsOut,
+ ArrayRef<const char *> ArgsIn,
+ SpecificBumpPtrAllocator<char> &) {
+ ArgsOut.append(ArgsIn.begin(), ArgsIn.end());
+
+ return std::error_code();
+}
+
+namespace {
+class FDCloser {
+public:
+ FDCloser(int &FD) : FD(FD), KeepOpen(false) {}
+ void keepOpen() { KeepOpen = true; }
+ ~FDCloser() {
+ if (!KeepOpen && FD >= 0)
+ ::close(FD);
+ }
+
+private:
+ FDCloser(const FDCloser &) = delete;
+ void operator=(const FDCloser &) = delete;
+
+ int &FD;
+ bool KeepOpen;
+};
+} // namespace
+
+std::error_code Process::FixupStandardFileDescriptors() {
+ int NullFD = -1;
+ FDCloser FDC(NullFD);
+ const int StandardFDs[] = {STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO};
+ for (int StandardFD : StandardFDs) {
+ struct stat st;
+ errno = 0;
+ while (fstat(StandardFD, &st) < 0) {
+ assert(errno && "expected errno to be set if fstat failed!");
+ // fstat should return EBADF if the file descriptor is closed.
+ if (errno == EBADF)
+ break;
+ // retry fstat if we got EINTR, otherwise bubble up the failure.
+ if (errno != EINTR)
+ return std::error_code(errno, std::generic_category());
+ }
+ // if fstat succeeds, move on to the next FD.
+ if (!errno)
+ continue;
+ assert(errno == EBADF && "expected errno to have EBADF at this point!");
+
+ if (NullFD < 0) {
+ while ((NullFD = open("/dev/null", O_RDWR)) < 0) {
+ if (errno == EINTR)
+ continue;
+ return std::error_code(errno, std::generic_category());
+ }
+ }
+
+ if (NullFD == StandardFD)
+ FDC.keepOpen();
+ else if (dup2(NullFD, StandardFD) < 0)
+ return std::error_code(errno, std::generic_category());
+ }
+ return std::error_code();
+}
+
+std::error_code Process::SafelyCloseFileDescriptor(int FD) {
+ // Create a signal set filled with *all* signals.
+ sigset_t FullSet;
+ if (sigfillset(&FullSet) < 0)
+ return std::error_code(errno, std::generic_category());
+ // Atomically swap our current signal mask with a full mask.
+ sigset_t SavedSet;
+#if LLVM_ENABLE_THREADS
+ if (int EC = pthread_sigmask(SIG_SETMASK, &FullSet, &SavedSet))
+ return std::error_code(EC, std::generic_category());
+#else
+ if (sigprocmask(SIG_SETMASK, &FullSet, &SavedSet) < 0)
+ return std::error_code(errno, std::generic_category());
+#endif
+ // Attempt to close the file descriptor.
+ // We need to save the error, if one occurs, because our subsequent call to
+ // pthread_sigmask might tamper with errno.
+ int ErrnoFromClose = 0;
+ if (::close(FD) < 0)
+ ErrnoFromClose = errno;
+ // Restore the signal mask back to what we saved earlier.
+ int EC = 0;
+#if LLVM_ENABLE_THREADS
+ EC = pthread_sigmask(SIG_SETMASK, &SavedSet, nullptr);
+#else
+ if (sigprocmask(SIG_SETMASK, &SavedSet, nullptr) < 0)
+ EC = errno;
+#endif
+ // The error code from close takes precedence over the one from
+ // pthread_sigmask.
+ if (ErrnoFromClose)
+ return std::error_code(ErrnoFromClose, std::generic_category());
+ return std::error_code(EC, std::generic_category());
+}
+
+bool Process::StandardInIsUserInput() {
+ return FileDescriptorIsDisplayed(STDIN_FILENO);
+}
+
+bool Process::StandardOutIsDisplayed() {
+ return FileDescriptorIsDisplayed(STDOUT_FILENO);
+}
+
+bool Process::StandardErrIsDisplayed() {
+ return FileDescriptorIsDisplayed(STDERR_FILENO);
+}
+
+bool Process::FileDescriptorIsDisplayed(int fd) {
+#if HAVE_ISATTY
+ return isatty(fd);
+#else
+ // If we don't have isatty, just return false.
+ return false;
+#endif
+}
+
+static unsigned getColumns(int FileID) {
+ // If COLUMNS is defined in the environment, wrap to that many columns.
+ if (const char *ColumnsStr = std::getenv("COLUMNS")) {
+ int Columns = std::atoi(ColumnsStr);
+ if (Columns > 0)
+ return Columns;
+ }
+
+ unsigned Columns = 0;
+
+#if defined(HAVE_SYS_IOCTL_H) && defined(HAVE_TERMIOS_H)
+ // Try to determine the width of the terminal.
+ struct winsize ws;
+ if (ioctl(FileID, TIOCGWINSZ, &ws) == 0)
+ Columns = ws.ws_col;
+#endif
+
+ return Columns;
+}
+
+unsigned Process::StandardOutColumns() {
+ if (!StandardOutIsDisplayed())
+ return 0;
+
+ return getColumns(1);
+}
+
+unsigned Process::StandardErrColumns() {
+ if (!StandardErrIsDisplayed())
+ return 0;
+
+ return getColumns(2);
+}
+
+#ifdef HAVE_TERMINFO
+// We manually declare these extern functions because finding the correct
+// headers from various terminfo, curses, or other sources is harder than
+// writing their specs down.
+extern "C" int setupterm(char *term, int filedes, int *errret);
+extern "C" struct term *set_curterm(struct term *termp);
+extern "C" int del_curterm(struct term *termp);
+extern "C" int tigetnum(char *capname);
+#endif
+
+#ifdef HAVE_TERMINFO
+static ManagedStatic<sys::Mutex> TermColorMutex;
+#endif
+
+static bool terminalHasColors(int fd) {
+#ifdef HAVE_TERMINFO
+ // First, acquire a global lock because these C routines are thread hostile.
+ MutexGuard G(*TermColorMutex);
+
+ int errret = 0;
+ if (setupterm((char *)nullptr, fd, &errret) != 0)
+ // Regardless of why, if we can't get terminfo, we shouldn't try to print
+ // colors.
+ return false;
+
+ // Test whether the terminal as set up supports color output. How to do this
+ // isn't entirely obvious. We can use the curses routine 'has_colors' but it
+ // would be nice to avoid a dependency on curses proper when we can make do
+ // with a minimal terminfo parsing library. Also, we don't really care whether
+ // the terminal supports the curses-specific color changing routines, merely
+ // if it will interpret ANSI color escape codes in a reasonable way. Thus, the
+ // strategy here is just to query the baseline colors capability and if it
+ // supports colors at all to assume it will translate the escape codes into
+ // whatever range of colors it does support. We can add more detailed tests
+ // here if users report them as necessary.
+ //
+ // The 'tigetnum' routine returns -2 or -1 on errors, and might return 0 if
+ // the terminfo says that no colors are supported.
+ bool HasColors = tigetnum(const_cast<char *>("colors")) > 0;
+
+ // Now extract the structure allocated by setupterm and free its memory
+ // through a really silly dance.
+ struct term *termp = set_curterm((struct term *)nullptr);
+ (void)del_curterm(termp); // Drop any errors here.
+
+ // Return true if we found a color capabilities for the current terminal.
+ if (HasColors)
+ return true;
+#endif
+
+ // Otherwise, be conservative.
+ return false;
+}
+
+bool Process::FileDescriptorHasColors(int fd) {
+ // A file descriptor has colors if it is displayed and the terminal has
+ // colors.
+ return FileDescriptorIsDisplayed(fd) && terminalHasColors(fd);
+}
+
+bool Process::StandardOutHasColors() {
+ return FileDescriptorHasColors(STDOUT_FILENO);
+}
+
+bool Process::StandardErrHasColors() {
+ return FileDescriptorHasColors(STDERR_FILENO);
+}
+
+void Process::UseANSIEscapeCodes(bool /*enable*/) {
+ // No effect.
+}
+
+bool Process::ColorNeedsFlush() {
+ // No, we use ANSI escape sequences.
+ return false;
+}
+
+const char *Process::OutputColor(char code, bool bold, bool bg) {
+ return colorcodes[bg?1:0][bold?1:0][code&7];
+}
+
+const char *Process::OutputBold(bool bg) {
+ return "\033[1m";
+}
+
+const char *Process::OutputReverse() {
+ return "\033[7m";
+}
+
+const char *Process::ResetColor() {
+ return "\033[0m";
+}
+
+#if !defined(HAVE_DECL_ARC4RANDOM) || !HAVE_DECL_ARC4RANDOM
+static unsigned GetRandomNumberSeed() {
+ // Attempt to get the initial seed from /dev/urandom, if possible.
+ if (FILE *RandomSource = ::fopen("/dev/urandom", "r")) {
+ unsigned seed;
+ int count = ::fread((void *)&seed, sizeof(seed), 1, RandomSource);
+ ::fclose(RandomSource);
+
+ // Return the seed if the read was successful.
+ if (count == 1)
+ return seed;
+ }
+
+ // Otherwise, swizzle the current time and the process ID to form a reasonable
+ // seed.
+ TimeValue Now = TimeValue::now();
+ return hash_combine(Now.seconds(), Now.nanoseconds(), ::getpid());
+}
+#endif
+
+unsigned llvm::sys::Process::GetRandomNumber() {
+#if defined(HAVE_DECL_ARC4RANDOM) && HAVE_DECL_ARC4RANDOM
+ return arc4random();
+#else
+ static int x = (::srand(GetRandomNumberSeed()), 0);
+ (void)x;
+ return ::rand();
+#endif
+}
diff --git a/contrib/llvm/lib/Support/Unix/Program.inc b/contrib/llvm/lib/Support/Unix/Program.inc
new file mode 100644
index 000000000000..dc633ab313e9
--- /dev/null
+++ b/contrib/llvm/lib/Support/Unix/Program.inc
@@ -0,0 +1,476 @@
+//===- llvm/Support/Unix/Program.cpp -----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the Unix specific portion of the Program class.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only generic UNIX code that
+//=== is guaranteed to work on *all* UNIX variants.
+//===----------------------------------------------------------------------===//
+
+#include "Unix.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Config/config.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Errc.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/raw_ostream.h"
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
+#if HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+#if HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_POSIX_SPAWN
+#ifdef __sun__
+#define _RESTRICT_KYWD
+#endif
+#include <spawn.h>
+
+#if defined(__APPLE__)
+#include <TargetConditionals.h>
+#endif
+
+#if defined(__APPLE__) && !(defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE)
+#define USE_NSGETENVIRON 1
+#else
+#define USE_NSGETENVIRON 0
+#endif
+
+#if !USE_NSGETENVIRON
+ extern char **environ;
+#else
+#include <crt_externs.h> // _NSGetEnviron
+#endif
+#endif
+
+namespace llvm {
+
+using namespace sys;
+
+ProcessInfo::ProcessInfo() : Pid(0), ReturnCode(0) {}
+
+ErrorOr<std::string> sys::findProgramByName(StringRef Name,
+ ArrayRef<StringRef> Paths) {
+ assert(!Name.empty() && "Must have a name!");
+ // Use the given path verbatim if it contains any slashes; this matches
+ // the behavior of sh(1) and friends.
+ if (Name.find('/') != StringRef::npos)
+ return std::string(Name);
+
+ SmallVector<StringRef, 16> EnvironmentPaths;
+ if (Paths.empty())
+ if (const char *PathEnv = std::getenv("PATH")) {
+ SplitString(PathEnv, EnvironmentPaths, ":");
+ Paths = EnvironmentPaths;
+ }
+
+ for (auto Path : Paths) {
+ if (Path.empty())
+ continue;
+
+ // Check to see if this first directory contains the executable...
+ SmallString<128> FilePath(Path);
+ sys::path::append(FilePath, Name);
+ if (sys::fs::can_execute(FilePath.c_str()))
+ return std::string(FilePath.str()); // Found the executable!
+ }
+ return errc::no_such_file_or_directory;
+}
+
+static bool RedirectIO(const StringRef *Path, int FD, std::string* ErrMsg) {
+ if (!Path) // Noop
+ return false;
+ std::string File;
+ if (Path->empty())
+ // Redirect empty paths to /dev/null
+ File = "/dev/null";
+ else
+ File = *Path;
+
+ // Open the file
+ int InFD = open(File.c_str(), FD == 0 ? O_RDONLY : O_WRONLY|O_CREAT, 0666);
+ if (InFD == -1) {
+ MakeErrMsg(ErrMsg, "Cannot open file '" + File + "' for "
+ + (FD == 0 ? "input" : "output"));
+ return true;
+ }
+
+ // Install it as the requested FD
+ if (dup2(InFD, FD) == -1) {
+ MakeErrMsg(ErrMsg, "Cannot dup2");
+ close(InFD);
+ return true;
+ }
+ close(InFD); // Close the original FD
+ return false;
+}
+
+#ifdef HAVE_POSIX_SPAWN
+static bool RedirectIO_PS(const std::string *Path, int FD, std::string *ErrMsg,
+ posix_spawn_file_actions_t *FileActions) {
+ if (!Path) // Noop
+ return false;
+ const char *File;
+ if (Path->empty())
+ // Redirect empty paths to /dev/null
+ File = "/dev/null";
+ else
+ File = Path->c_str();
+
+ if (int Err = posix_spawn_file_actions_addopen(
+ FileActions, FD, File,
+ FD == 0 ? O_RDONLY : O_WRONLY | O_CREAT, 0666))
+ return MakeErrMsg(ErrMsg, "Cannot dup2", Err);
+ return false;
+}
+#endif
+
+static void TimeOutHandler(int Sig) {
+}
+
+static void SetMemoryLimits (unsigned size)
+{
+#if HAVE_SYS_RESOURCE_H && HAVE_GETRLIMIT && HAVE_SETRLIMIT
+ struct rlimit r;
+ __typeof__ (r.rlim_cur) limit = (__typeof__ (r.rlim_cur)) (size) * 1048576;
+
+ // Heap size
+ getrlimit (RLIMIT_DATA, &r);
+ r.rlim_cur = limit;
+ setrlimit (RLIMIT_DATA, &r);
+#ifdef RLIMIT_RSS
+ // Resident set size.
+ getrlimit (RLIMIT_RSS, &r);
+ r.rlim_cur = limit;
+ setrlimit (RLIMIT_RSS, &r);
+#endif
+#ifdef RLIMIT_AS // e.g. NetBSD doesn't have it.
+ // Don't set virtual memory limit if built with any Sanitizer. They need 80Tb
+ // of virtual memory for shadow memory mapping.
+#if !LLVM_MEMORY_SANITIZER_BUILD && !LLVM_ADDRESS_SANITIZER_BUILD
+ // Virtual memory.
+ getrlimit (RLIMIT_AS, &r);
+ r.rlim_cur = limit;
+ setrlimit (RLIMIT_AS, &r);
+#endif
+#endif
+#endif
+}
+
+} // namespace llvm
+
+static bool Execute(ProcessInfo &PI, StringRef Program, const char **args,
+ const char **envp, const StringRef **redirects,
+ unsigned memoryLimit, std::string *ErrMsg) {
+ if (!llvm::sys::fs::exists(Program)) {
+ if (ErrMsg)
+ *ErrMsg = std::string("Executable \"") + Program.str() +
+ std::string("\" doesn't exist!");
+ return false;
+ }
+
+ // If this OS has posix_spawn and there is no memory limit being implied, use
+ // posix_spawn. It is more efficient than fork/exec.
+#ifdef HAVE_POSIX_SPAWN
+ if (memoryLimit == 0) {
+ posix_spawn_file_actions_t FileActionsStore;
+ posix_spawn_file_actions_t *FileActions = nullptr;
+
+ // If we call posix_spawn_file_actions_addopen we have to make sure the
+ // c strings we pass to it stay alive until the call to posix_spawn,
+ // so we copy any StringRefs into this variable.
+ std::string RedirectsStorage[3];
+
+ if (redirects) {
+ std::string *RedirectsStr[3] = {nullptr, nullptr, nullptr};
+ for (int I = 0; I < 3; ++I) {
+ if (redirects[I]) {
+ RedirectsStorage[I] = *redirects[I];
+ RedirectsStr[I] = &RedirectsStorage[I];
+ }
+ }
+
+ FileActions = &FileActionsStore;
+ posix_spawn_file_actions_init(FileActions);
+
+ // Redirect stdin/stdout.
+ if (RedirectIO_PS(RedirectsStr[0], 0, ErrMsg, FileActions) ||
+ RedirectIO_PS(RedirectsStr[1], 1, ErrMsg, FileActions))
+ return false;
+ if (redirects[1] == nullptr || redirects[2] == nullptr ||
+ *redirects[1] != *redirects[2]) {
+ // Just redirect stderr
+ if (RedirectIO_PS(RedirectsStr[2], 2, ErrMsg, FileActions))
+ return false;
+ } else {
+ // If stdout and stderr should go to the same place, redirect stderr
+ // to the FD already open for stdout.
+ if (int Err = posix_spawn_file_actions_adddup2(FileActions, 1, 2))
+ return !MakeErrMsg(ErrMsg, "Can't redirect stderr to stdout", Err);
+ }
+ }
+
+ if (!envp)
+#if !USE_NSGETENVIRON
+ envp = const_cast<const char **>(environ);
+#else
+ // environ is missing in dylibs.
+ envp = const_cast<const char **>(*_NSGetEnviron());
+#endif
+
+ // Explicitly initialized to prevent what appears to be a valgrind false
+ // positive.
+ pid_t PID = 0;
+ int Err = posix_spawn(&PID, Program.str().c_str(), FileActions,
+ /*attrp*/nullptr, const_cast<char **>(args),
+ const_cast<char **>(envp));
+
+ if (FileActions)
+ posix_spawn_file_actions_destroy(FileActions);
+
+ if (Err)
+ return !MakeErrMsg(ErrMsg, "posix_spawn failed", Err);
+
+ PI.Pid = PID;
+
+ return true;
+ }
+#endif
+
+ // Create a child process.
+ int child = fork();
+ switch (child) {
+ // An error occurred: Return to the caller.
+ case -1:
+ MakeErrMsg(ErrMsg, "Couldn't fork");
+ return false;
+
+ // Child process: Execute the program.
+ case 0: {
+ // Redirect file descriptors...
+ if (redirects) {
+ // Redirect stdin
+ if (RedirectIO(redirects[0], 0, ErrMsg)) { return false; }
+ // Redirect stdout
+ if (RedirectIO(redirects[1], 1, ErrMsg)) { return false; }
+ if (redirects[1] && redirects[2] &&
+ *(redirects[1]) == *(redirects[2])) {
+ // If stdout and stderr should go to the same place, redirect stderr
+ // to the FD already open for stdout.
+ if (-1 == dup2(1,2)) {
+ MakeErrMsg(ErrMsg, "Can't redirect stderr to stdout");
+ return false;
+ }
+ } else {
+ // Just redirect stderr
+ if (RedirectIO(redirects[2], 2, ErrMsg)) { return false; }
+ }
+ }
+
+ // Set memory limits
+ if (memoryLimit!=0) {
+ SetMemoryLimits(memoryLimit);
+ }
+
+ // Execute!
+ std::string PathStr = Program;
+ if (envp != nullptr)
+ execve(PathStr.c_str(),
+ const_cast<char **>(args),
+ const_cast<char **>(envp));
+ else
+ execv(PathStr.c_str(),
+ const_cast<char **>(args));
+ // If the execve() failed, we should exit. Follow Unix protocol and
+ // return 127 if the executable was not found, and 126 otherwise.
+ // Use _exit rather than exit so that atexit functions and static
+ // object destructors cloned from the parent process aren't
+ // redundantly run, and so that any data buffered in stdio buffers
+ // cloned from the parent aren't redundantly written out.
+ _exit(errno == ENOENT ? 127 : 126);
+ }
+
+ // Parent process: Break out of the switch to do our processing.
+ default:
+ break;
+ }
+
+ PI.Pid = child;
+
+ return true;
+}
+
+namespace llvm {
+
+ProcessInfo sys::Wait(const ProcessInfo &PI, unsigned SecondsToWait,
+ bool WaitUntilTerminates, std::string *ErrMsg) {
+#ifdef HAVE_SYS_WAIT_H
+ struct sigaction Act, Old;
+ assert(PI.Pid && "invalid pid to wait on, process not started?");
+
+ int WaitPidOptions = 0;
+ pid_t ChildPid = PI.Pid;
+ if (WaitUntilTerminates) {
+ SecondsToWait = 0;
+ } else if (SecondsToWait) {
+ // Install a timeout handler. The handler itself does nothing, but the
+ // simple fact of having a handler at all causes the wait below to return
+ // with EINTR, unlike if we used SIG_IGN.
+ memset(&Act, 0, sizeof(Act));
+ Act.sa_handler = TimeOutHandler;
+ sigemptyset(&Act.sa_mask);
+ sigaction(SIGALRM, &Act, &Old);
+ alarm(SecondsToWait);
+ } else if (SecondsToWait == 0)
+ WaitPidOptions = WNOHANG;
+
+ // Parent process: Wait for the child process to terminate.
+ int status;
+ ProcessInfo WaitResult;
+
+ do {
+ WaitResult.Pid = waitpid(ChildPid, &status, WaitPidOptions);
+ } while (WaitUntilTerminates && WaitResult.Pid == -1 && errno == EINTR);
+
+ if (WaitResult.Pid != PI.Pid) {
+ if (WaitResult.Pid == 0) {
+ // Non-blocking wait.
+ return WaitResult;
+ } else {
+ if (SecondsToWait && errno == EINTR) {
+ // Kill the child.
+ kill(PI.Pid, SIGKILL);
+
+ // Turn off the alarm and restore the signal handler
+ alarm(0);
+ sigaction(SIGALRM, &Old, nullptr);
+
+ // Wait for child to die
+ if (wait(&status) != ChildPid)
+ MakeErrMsg(ErrMsg, "Child timed out but wouldn't die");
+ else
+ MakeErrMsg(ErrMsg, "Child timed out", 0);
+
+ WaitResult.ReturnCode = -2; // Timeout detected
+ return WaitResult;
+ } else if (errno != EINTR) {
+ MakeErrMsg(ErrMsg, "Error waiting for child process");
+ WaitResult.ReturnCode = -1;
+ return WaitResult;
+ }
+ }
+ }
+
+ // We exited normally without timeout, so turn off the timer.
+ if (SecondsToWait && !WaitUntilTerminates) {
+ alarm(0);
+ sigaction(SIGALRM, &Old, nullptr);
+ }
+
+ // Return the proper exit status. Detect error conditions
+ // so we can return -1 for them and set ErrMsg informatively.
+ int result = 0;
+ if (WIFEXITED(status)) {
+ result = WEXITSTATUS(status);
+ WaitResult.ReturnCode = result;
+
+ if (result == 127) {
+ if (ErrMsg)
+ *ErrMsg = llvm::sys::StrError(ENOENT);
+ WaitResult.ReturnCode = -1;
+ return WaitResult;
+ }
+ if (result == 126) {
+ if (ErrMsg)
+ *ErrMsg = "Program could not be executed";
+ WaitResult.ReturnCode = -1;
+ return WaitResult;
+ }
+ } else if (WIFSIGNALED(status)) {
+ if (ErrMsg) {
+ *ErrMsg = strsignal(WTERMSIG(status));
+#ifdef WCOREDUMP
+ if (WCOREDUMP(status))
+ *ErrMsg += " (core dumped)";
+#endif
+ }
+ // Return a special value to indicate that the process received an unhandled
+ // signal during execution as opposed to failing to execute.
+ WaitResult.ReturnCode = -2;
+ }
+#else
+ if (ErrMsg)
+ *ErrMsg = "Program::Wait is not implemented on this platform yet!";
+ ProcessInfo WaitResult;
+ WaitResult.ReturnCode = -2;
+#endif
+ return WaitResult;
+}
+
+ std::error_code sys::ChangeStdinToBinary(){
+ // Do nothing, as Unix doesn't differentiate between text and binary.
+ return std::error_code();
+}
+
+ std::error_code sys::ChangeStdoutToBinary(){
+ // Do nothing, as Unix doesn't differentiate between text and binary.
+ return std::error_code();
+}
+
+std::error_code
+llvm::sys::writeFileWithEncoding(StringRef FileName, StringRef Contents,
+ WindowsEncodingMethod Encoding /*unused*/) {
+ std::error_code EC;
+ llvm::raw_fd_ostream OS(FileName, EC, llvm::sys::fs::OpenFlags::F_Text);
+
+ if (EC)
+ return EC;
+
+ OS << Contents;
+
+ if (OS.has_error())
+ return make_error_code(errc::io_error);
+
+ return EC;
+}
+
+bool llvm::sys::argumentsFitWithinSystemLimits(ArrayRef<const char*> Args) {
+ static long ArgMax = sysconf(_SC_ARG_MAX);
+
+ // System says no practical limit.
+ if (ArgMax == -1)
+ return true;
+
+ // Conservatively account for space required by environment variables.
+ long HalfArgMax = ArgMax / 2;
+
+ size_t ArgLength = 0;
+ for (ArrayRef<const char*>::iterator I = Args.begin(), E = Args.end();
+ I != E; ++I) {
+ ArgLength += strlen(*I) + 1;
+ if (ArgLength > size_t(HalfArgMax)) {
+ return false;
+ }
+ }
+ return true;
+}
+} // namespace llvm
diff --git a/contrib/llvm/lib/Support/Unix/README.txt b/contrib/llvm/lib/Support/Unix/README.txt
new file mode 100644
index 000000000000..3d547c2990d5
--- /dev/null
+++ b/contrib/llvm/lib/Support/Unix/README.txt
@@ -0,0 +1,16 @@
+llvm/lib/Support/Unix README
+===========================
+
+This directory provides implementations of the lib/System classes that
+are common to two or more variants of UNIX. For example, the directory
+structure underneath this directory could look like this:
+
+Unix - only code that is truly generic to all UNIX platforms
+ Posix - code that is specific to Posix variants of UNIX
+ SUS - code that is specific to the Single Unix Specification
+ SysV - code that is specific to System V variants of UNIX
+
+As a rule, only those directories actually needing to be created should be
+created. Also, further subdirectories could be created to reflect versions of
+the various standards. For example, under SUS there could be v1, v2, and v3
+subdirectories to reflect the three major versions of SUS.
diff --git a/contrib/llvm/lib/Support/Unix/RWMutex.inc b/contrib/llvm/lib/Support/Unix/RWMutex.inc
new file mode 100644
index 000000000000..85a104334a27
--- /dev/null
+++ b/contrib/llvm/lib/Support/Unix/RWMutex.inc
@@ -0,0 +1,51 @@
+//= llvm/Support/Unix/RWMutex.inc - Unix Reader/Writer Mutual Exclusion Lock =//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the Unix specific (non-pthread) RWMutex class.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only generic UNIX code that
+//=== is guaranteed to work on *all* UNIX variants.
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/Mutex.h"
+
+namespace llvm {
+
+using namespace sys;
+
+// This naive implementation treats readers the same as writers. This
+// will therefore deadlock if a thread tries to acquire a read lock
+// multiple times.
+
+RWMutexImpl::RWMutexImpl() : data_(new MutexImpl(false)) { }
+
+RWMutexImpl::~RWMutexImpl() {
+ delete static_cast<MutexImpl *>(data_);
+}
+
+bool RWMutexImpl::reader_acquire() {
+ return static_cast<MutexImpl *>(data_)->acquire();
+}
+
+bool RWMutexImpl::reader_release() {
+ return static_cast<MutexImpl *>(data_)->release();
+}
+
+bool RWMutexImpl::writer_acquire() {
+ return static_cast<MutexImpl *>(data_)->acquire();
+}
+
+bool RWMutexImpl::writer_release() {
+ return static_cast<MutexImpl *>(data_)->release();
+}
+
+}
diff --git a/contrib/llvm/lib/Support/Unix/Signals.inc b/contrib/llvm/lib/Support/Unix/Signals.inc
new file mode 100644
index 000000000000..bfe2a3a380ed
--- /dev/null
+++ b/contrib/llvm/lib/Support/Unix/Signals.inc
@@ -0,0 +1,558 @@
+//===- Signals.cpp - Generic Unix Signals Implementation -----*- 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 some helpful functions for dealing with the possibility of
+// Unix signals occurring while your program is running.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Unix.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/FileUtilities.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Mutex.h"
+#include "llvm/Support/Program.h"
+#include "llvm/Support/UniqueLock.h"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <string>
+#include <vector>
+#if HAVE_EXECINFO_H
+# include <execinfo.h> // For backtrace().
+#endif
+#if HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_CXXABI_H
+#include <cxxabi.h>
+#endif
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+#if HAVE_MACH_MACH_H
+#include <mach/mach.h>
+#endif
+#if HAVE_LINK_H
+#include <link.h>
+#endif
+
+using namespace llvm;
+
+static RETSIGTYPE SignalHandler(int Sig); // defined below.
+
+static ManagedStatic<SmartMutex<true> > SignalsMutex;
+
+/// InterruptFunction - The function to call if ctrl-c is pressed.
+static void (*InterruptFunction)() = nullptr;
+
+static ManagedStatic<std::vector<std::string>> FilesToRemove;
+static ManagedStatic<std::vector<std::pair<void (*)(void *), void *>>>
+ CallBacksToRun;
+
+// IntSigs - Signals that represent requested termination. There's no bug
+// or failure, or if there is, it's not our direct responsibility. For whatever
+// reason, our continued execution is no longer desirable.
+static const int IntSigs[] = {
+ SIGHUP, SIGINT, SIGPIPE, SIGTERM, SIGUSR1, SIGUSR2
+};
+
+// KillSigs - Signals that represent that we have a bug, and our prompt
+// termination has been ordered.
+static const int KillSigs[] = {
+ SIGILL, SIGTRAP, SIGABRT, SIGFPE, SIGBUS, SIGSEGV, SIGQUIT
+#ifdef SIGSYS
+ , SIGSYS
+#endif
+#ifdef SIGXCPU
+ , SIGXCPU
+#endif
+#ifdef SIGXFSZ
+ , SIGXFSZ
+#endif
+#ifdef SIGEMT
+ , SIGEMT
+#endif
+};
+
+static unsigned NumRegisteredSignals = 0;
+static struct {
+ struct sigaction SA;
+ int SigNo;
+} RegisteredSignalInfo[(sizeof(IntSigs)+sizeof(KillSigs))/sizeof(KillSigs[0])];
+
+
+static void RegisterHandler(int Signal) {
+ assert(NumRegisteredSignals <
+ sizeof(RegisteredSignalInfo)/sizeof(RegisteredSignalInfo[0]) &&
+ "Out of space for signal handlers!");
+
+ struct sigaction NewHandler;
+
+ NewHandler.sa_handler = SignalHandler;
+ NewHandler.sa_flags = SA_NODEFER|SA_RESETHAND;
+ sigemptyset(&NewHandler.sa_mask);
+
+ // Install the new handler, save the old one in RegisteredSignalInfo.
+ sigaction(Signal, &NewHandler,
+ &RegisteredSignalInfo[NumRegisteredSignals].SA);
+ RegisteredSignalInfo[NumRegisteredSignals].SigNo = Signal;
+ ++NumRegisteredSignals;
+}
+
+static void RegisterHandlers() {
+ // We need to dereference the signals mutex during handler registration so
+ // that we force its construction. This is to prevent the first use being
+ // during handling an actual signal because you can't safely call new in a
+ // signal handler.
+ *SignalsMutex;
+
+ // If the handlers are already registered, we're done.
+ if (NumRegisteredSignals != 0) return;
+
+ for (auto S : IntSigs) RegisterHandler(S);
+ for (auto S : KillSigs) RegisterHandler(S);
+}
+
+static void UnregisterHandlers() {
+ // Restore all of the signal handlers to how they were before we showed up.
+ for (unsigned i = 0, e = NumRegisteredSignals; i != e; ++i)
+ sigaction(RegisteredSignalInfo[i].SigNo,
+ &RegisteredSignalInfo[i].SA, nullptr);
+ NumRegisteredSignals = 0;
+}
+
+
+/// RemoveFilesToRemove - Process the FilesToRemove list. This function
+/// should be called with the SignalsMutex lock held.
+/// NB: This must be an async signal safe function. It cannot allocate or free
+/// memory, even in debug builds.
+static void RemoveFilesToRemove() {
+ // Avoid constructing ManagedStatic in the signal handler.
+ // If FilesToRemove is not constructed, there are no files to remove.
+ if (!FilesToRemove.isConstructed())
+ return;
+
+ // We avoid iterators in case of debug iterators that allocate or release
+ // memory.
+ std::vector<std::string>& FilesToRemoveRef = *FilesToRemove;
+ for (unsigned i = 0, e = FilesToRemoveRef.size(); i != e; ++i) {
+ // We rely on a std::string implementation for which repeated calls to
+ // 'c_str()' don't allocate memory. We pre-call 'c_str()' on all of these
+ // strings to try to ensure this is safe.
+ const char *path = FilesToRemoveRef[i].c_str();
+
+ // Get the status so we can determine if it's a file or directory. If we
+ // can't stat the file, ignore it.
+ struct stat buf;
+ if (stat(path, &buf) != 0)
+ continue;
+
+ // If this is not a regular file, ignore it. We want to prevent removal of
+ // special files like /dev/null, even if the compiler is being run with the
+ // super-user permissions.
+ if (!S_ISREG(buf.st_mode))
+ continue;
+
+ // Otherwise, remove the file. We ignore any errors here as there is nothing
+ // else we can do.
+ unlink(path);
+ }
+}
+
+// SignalHandler - The signal handler that runs.
+static RETSIGTYPE SignalHandler(int Sig) {
+ // Restore the signal behavior to default, so that the program actually
+ // crashes when we return and the signal reissues. This also ensures that if
+ // we crash in our signal handler that the program will terminate immediately
+ // instead of recursing in the signal handler.
+ UnregisterHandlers();
+
+ // Unmask all potentially blocked kill signals.
+ sigset_t SigMask;
+ sigfillset(&SigMask);
+ sigprocmask(SIG_UNBLOCK, &SigMask, nullptr);
+
+ {
+ unique_lock<SmartMutex<true>> Guard(*SignalsMutex);
+ RemoveFilesToRemove();
+
+ if (std::find(std::begin(IntSigs), std::end(IntSigs), Sig)
+ != std::end(IntSigs)) {
+ if (InterruptFunction) {
+ void (*IF)() = InterruptFunction;
+ Guard.unlock();
+ InterruptFunction = nullptr;
+ IF(); // run the interrupt function.
+ return;
+ }
+
+ Guard.unlock();
+ raise(Sig); // Execute the default handler.
+ return;
+ }
+ }
+
+ // Otherwise if it is a fault (like SEGV) run any handler.
+ if (CallBacksToRun.isConstructed()) {
+ auto &CallBacksToRunRef = *CallBacksToRun;
+ for (unsigned i = 0, e = CallBacksToRun->size(); i != e; ++i)
+ CallBacksToRunRef[i].first(CallBacksToRunRef[i].second);
+ }
+
+#ifdef __s390__
+ // On S/390, certain signals are delivered with PSW Address pointing to
+ // *after* the faulting instruction. Simply returning from the signal
+ // handler would continue execution after that point, instead of
+ // re-raising the signal. Raise the signal manually in those cases.
+ if (Sig == SIGILL || Sig == SIGFPE || Sig == SIGTRAP)
+ raise(Sig);
+#endif
+}
+
+void llvm::sys::RunInterruptHandlers() {
+ sys::SmartScopedLock<true> Guard(*SignalsMutex);
+ RemoveFilesToRemove();
+}
+
+void llvm::sys::SetInterruptFunction(void (*IF)()) {
+ {
+ sys::SmartScopedLock<true> Guard(*SignalsMutex);
+ InterruptFunction = IF;
+ }
+ RegisterHandlers();
+}
+
+// RemoveFileOnSignal - The public API
+bool llvm::sys::RemoveFileOnSignal(StringRef Filename,
+ std::string* ErrMsg) {
+ {
+ sys::SmartScopedLock<true> Guard(*SignalsMutex);
+ std::vector<std::string>& FilesToRemoveRef = *FilesToRemove;
+ std::string *OldPtr =
+ FilesToRemoveRef.empty() ? nullptr : &FilesToRemoveRef[0];
+ FilesToRemoveRef.push_back(Filename);
+
+ // We want to call 'c_str()' on every std::string in this vector so that if
+ // the underlying implementation requires a re-allocation, it happens here
+ // rather than inside of the signal handler. If we see the vector grow, we
+ // have to call it on every entry. If it remains in place, we only need to
+ // call it on the latest one.
+ if (OldPtr == &FilesToRemoveRef[0])
+ FilesToRemoveRef.back().c_str();
+ else
+ for (unsigned i = 0, e = FilesToRemoveRef.size(); i != e; ++i)
+ FilesToRemoveRef[i].c_str();
+ }
+
+ RegisterHandlers();
+ return false;
+}
+
+// DontRemoveFileOnSignal - The public API
+void llvm::sys::DontRemoveFileOnSignal(StringRef Filename) {
+ sys::SmartScopedLock<true> Guard(*SignalsMutex);
+ std::vector<std::string>::reverse_iterator RI =
+ std::find(FilesToRemove->rbegin(), FilesToRemove->rend(), Filename);
+ std::vector<std::string>::iterator I = FilesToRemove->end();
+ if (RI != FilesToRemove->rend())
+ I = FilesToRemove->erase(RI.base()-1);
+
+ // We need to call c_str() on every element which would have been moved by
+ // the erase. These elements, in a C++98 implementation where c_str()
+ // requires a reallocation on the first call may have had the call to c_str()
+ // made on insertion become invalid by being copied down an element.
+ for (std::vector<std::string>::iterator E = FilesToRemove->end(); I != E; ++I)
+ I->c_str();
+}
+
+/// AddSignalHandler - Add a function to be called when a signal is delivered
+/// to the process. The handler can have a cookie passed to it to identify
+/// what instance of the handler it is.
+void llvm::sys::AddSignalHandler(void (*FnPtr)(void *), void *Cookie) {
+ CallBacksToRun->push_back(std::make_pair(FnPtr, Cookie));
+ RegisterHandlers();
+}
+
+#if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
+
+#if HAVE_LINK_H && (defined(__linux__) || defined(__FreeBSD__) || \
+ defined(__FreeBSD_kernel__) || defined(__NetBSD__))
+struct DlIteratePhdrData {
+ void **StackTrace;
+ int depth;
+ bool first;
+ const char **modules;
+ intptr_t *offsets;
+ const char *main_exec_name;
+};
+
+static int dl_iterate_phdr_cb(dl_phdr_info *info, size_t size, void *arg) {
+ DlIteratePhdrData *data = (DlIteratePhdrData*)arg;
+ const char *name = data->first ? data->main_exec_name : info->dlpi_name;
+ data->first = false;
+ for (int i = 0; i < info->dlpi_phnum; i++) {
+ const auto *phdr = &info->dlpi_phdr[i];
+ if (phdr->p_type != PT_LOAD)
+ continue;
+ intptr_t beg = info->dlpi_addr + phdr->p_vaddr;
+ intptr_t end = beg + phdr->p_memsz;
+ for (int j = 0; j < data->depth; j++) {
+ if (data->modules[j])
+ continue;
+ intptr_t addr = (intptr_t)data->StackTrace[j];
+ if (beg <= addr && addr < end) {
+ data->modules[j] = name;
+ data->offsets[j] = addr - info->dlpi_addr;
+ }
+ }
+ }
+ return 0;
+}
+
+static bool findModulesAndOffsets(void **StackTrace, int Depth,
+ const char **Modules, intptr_t *Offsets,
+ const char *MainExecutableName) {
+ DlIteratePhdrData data = {StackTrace, Depth, true,
+ Modules, Offsets, MainExecutableName};
+ dl_iterate_phdr(dl_iterate_phdr_cb, &data);
+ return true;
+}
+#else
+static bool findModulesAndOffsets(void **StackTrace, int Depth,
+ const char **Modules, intptr_t *Offsets,
+ const char *MainExecutableName) {
+ return false;
+}
+#endif
+
+static bool printSymbolizedStackTrace(void **StackTrace, int Depth,
+ llvm::raw_ostream &OS) {
+ // FIXME: Subtract necessary number from StackTrace entries to turn return addresses
+ // into actual instruction addresses.
+ // Use llvm-symbolizer tool to symbolize the stack traces.
+ ErrorOr<std::string> LLVMSymbolizerPathOrErr =
+ sys::findProgramByName("llvm-symbolizer");
+ if (!LLVMSymbolizerPathOrErr)
+ return false;
+ const std::string &LLVMSymbolizerPath = *LLVMSymbolizerPathOrErr;
+ // We don't know argv0 or the address of main() at this point, but try
+ // to guess it anyway (it's possible on some platforms).
+ std::string MainExecutableName = sys::fs::getMainExecutable(nullptr, nullptr);
+ if (MainExecutableName.empty() ||
+ MainExecutableName.find("llvm-symbolizer") != std::string::npos)
+ return false;
+
+ std::vector<const char *> Modules(Depth, nullptr);
+ std::vector<intptr_t> Offsets(Depth, 0);
+ if (!findModulesAndOffsets(StackTrace, Depth, Modules.data(), Offsets.data(),
+ MainExecutableName.c_str()))
+ return false;
+ int InputFD;
+ SmallString<32> InputFile, OutputFile;
+ sys::fs::createTemporaryFile("symbolizer-input", "", InputFD, InputFile);
+ sys::fs::createTemporaryFile("symbolizer-output", "", OutputFile);
+ FileRemover InputRemover(InputFile.c_str());
+ FileRemover OutputRemover(OutputFile.c_str());
+
+ {
+ raw_fd_ostream Input(InputFD, true);
+ for (int i = 0; i < Depth; i++) {
+ if (Modules[i])
+ Input << Modules[i] << " " << (void*)Offsets[i] << "\n";
+ }
+ }
+
+ StringRef InputFileStr(InputFile);
+ StringRef OutputFileStr(OutputFile);
+ StringRef StderrFileStr;
+ const StringRef *Redirects[] = {&InputFileStr, &OutputFileStr,
+ &StderrFileStr};
+ const char *Args[] = {"llvm-symbolizer", "--functions=linkage", "--inlining",
+ "--demangle", nullptr};
+ int RunResult =
+ sys::ExecuteAndWait(LLVMSymbolizerPath, Args, nullptr, Redirects);
+ if (RunResult != 0)
+ return false;
+
+ auto OutputBuf = MemoryBuffer::getFile(OutputFile.c_str());
+ if (!OutputBuf)
+ return false;
+ StringRef Output = OutputBuf.get()->getBuffer();
+ SmallVector<StringRef, 32> Lines;
+ Output.split(Lines, "\n");
+ auto CurLine = Lines.begin();
+ int frame_no = 0;
+ for (int i = 0; i < Depth; i++) {
+ if (!Modules[i]) {
+ OS << format("#%d %p\n", frame_no++, StackTrace[i]);
+ continue;
+ }
+ // Read pairs of lines (function name and file/line info) until we
+ // encounter empty line.
+ for (;;) {
+ if (CurLine == Lines.end())
+ return false;
+ StringRef FunctionName = *CurLine++;
+ if (FunctionName.empty())
+ break;
+ OS << format("#%d %p ", frame_no++, StackTrace[i]);
+ if (!FunctionName.startswith("??"))
+ OS << format("%s ", FunctionName.str().c_str());
+ if (CurLine == Lines.end())
+ return false;
+ StringRef FileLineInfo = *CurLine++;
+ if (!FileLineInfo.startswith("??"))
+ OS << format("%s", FileLineInfo.str().c_str());
+ else
+ OS << format("(%s+%p)", Modules[i], (void *)Offsets[i]);
+ OS << "\n";
+ }
+ }
+ return true;
+}
+#endif // defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
+
+// PrintStackTrace - In the case of a program crash or fault, print out a stack
+// trace so that the user has an indication of why and where we died.
+//
+// On glibc systems we have the 'backtrace' function, which works nicely, but
+// doesn't demangle symbols.
+void llvm::sys::PrintStackTrace(raw_ostream &OS) {
+#if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
+ static void* StackTrace[256];
+ // Use backtrace() to output a backtrace on Linux systems with glibc.
+ int depth = backtrace(StackTrace,
+ static_cast<int>(array_lengthof(StackTrace)));
+ if (printSymbolizedStackTrace(StackTrace, depth, OS))
+ return;
+#if HAVE_DLFCN_H && __GNUG__
+ int width = 0;
+ for (int i = 0; i < depth; ++i) {
+ Dl_info dlinfo;
+ dladdr(StackTrace[i], &dlinfo);
+ const char* name = strrchr(dlinfo.dli_fname, '/');
+
+ int nwidth;
+ if (!name) nwidth = strlen(dlinfo.dli_fname);
+ else nwidth = strlen(name) - 1;
+
+ if (nwidth > width) width = nwidth;
+ }
+
+ for (int i = 0; i < depth; ++i) {
+ Dl_info dlinfo;
+ dladdr(StackTrace[i], &dlinfo);
+
+ OS << format("%-2d", i);
+
+ const char* name = strrchr(dlinfo.dli_fname, '/');
+ if (!name) OS << format(" %-*s", width, dlinfo.dli_fname);
+ else OS << format(" %-*s", width, name+1);
+
+ OS << format(" %#0*lx", (int)(sizeof(void*) * 2) + 2,
+ (unsigned long)StackTrace[i]);
+
+ if (dlinfo.dli_sname != nullptr) {
+ OS << ' ';
+# if HAVE_CXXABI_H
+ int res;
+ char* d = abi::__cxa_demangle(dlinfo.dli_sname, nullptr, nullptr, &res);
+# else
+ char* d = NULL;
+# endif
+ if (!d) OS << dlinfo.dli_sname;
+ else OS << d;
+ free(d);
+
+ // FIXME: When we move to C++11, use %t length modifier. It's not in
+ // C++03 and causes gcc to issue warnings. Losing the upper 32 bits of
+ // the stack offset for a stack dump isn't likely to cause any problems.
+ OS << format(" + %u",(unsigned)((char*)StackTrace[i]-
+ (char*)dlinfo.dli_saddr));
+ }
+ OS << '\n';
+ }
+#else
+ backtrace_symbols_fd(StackTrace, depth, STDERR_FILENO);
+#endif
+#endif
+}
+
+static void PrintStackTraceSignalHandler(void *) {
+ PrintStackTrace(llvm::errs());
+}
+
+void llvm::sys::DisableSystemDialogsOnCrash() {}
+
+/// PrintStackTraceOnErrorSignal - When an error signal (such as SIGABRT or
+/// SIGSEGV) is delivered to the process, print a stack trace and then exit.
+void llvm::sys::PrintStackTraceOnErrorSignal(bool DisableCrashReporting) {
+ AddSignalHandler(PrintStackTraceSignalHandler, nullptr);
+
+#if defined(__APPLE__) && defined(ENABLE_CRASH_OVERRIDES)
+ // Environment variable to disable any kind of crash dialog.
+ if (DisableCrashReporting || getenv("LLVM_DISABLE_CRASH_REPORT")) {
+ mach_port_t self = mach_task_self();
+
+ exception_mask_t mask = EXC_MASK_CRASH;
+
+ kern_return_t ret = task_set_exception_ports(self,
+ mask,
+ MACH_PORT_NULL,
+ EXCEPTION_STATE_IDENTITY | MACH_EXCEPTION_CODES,
+ THREAD_STATE_NONE);
+ (void)ret;
+ }
+#endif
+}
+
+
+/***/
+
+// On Darwin, raise sends a signal to the main thread instead of the current
+// thread. This has the unfortunate effect that assert() and abort() will end up
+// bypassing our crash recovery attempts. We work around this for anything in
+// the same linkage unit by just defining our own versions of the assert handler
+// and abort.
+
+#if defined(__APPLE__) && defined(ENABLE_CRASH_OVERRIDES)
+
+#include <signal.h>
+#include <pthread.h>
+
+int raise(int sig) {
+ return pthread_kill(pthread_self(), sig);
+}
+
+void __assert_rtn(const char *func,
+ const char *file,
+ int line,
+ const char *expr) {
+ if (func)
+ fprintf(stderr, "Assertion failed: (%s), function %s, file %s, line %d.\n",
+ expr, func, file, line);
+ else
+ fprintf(stderr, "Assertion failed: (%s), file %s, line %d.\n",
+ expr, file, line);
+ abort();
+}
+
+void abort() {
+ raise(SIGABRT);
+ usleep(1000);
+ __builtin_trap();
+}
+
+#endif
diff --git a/contrib/llvm/lib/Support/Unix/ThreadLocal.inc b/contrib/llvm/lib/Support/Unix/ThreadLocal.inc
new file mode 100644
index 000000000000..a04dd3ee402b
--- /dev/null
+++ b/contrib/llvm/lib/Support/Unix/ThreadLocal.inc
@@ -0,0 +1,69 @@
+//=== llvm/Support/Unix/ThreadLocal.inc - Unix Thread Local Data -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the Unix specific (non-pthread) ThreadLocal class.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only generic UNIX code that
+//=== is guaranteed to work on *all* UNIX variants.
+//===----------------------------------------------------------------------===//
+
+#if defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_GETSPECIFIC)
+
+#include <cassert>
+#include <pthread.h>
+#include <stdlib.h>
+
+namespace llvm {
+using namespace sys;
+
+ThreadLocalImpl::ThreadLocalImpl() : data() {
+ static_assert(sizeof(pthread_key_t) <= sizeof(data), "size too big");
+ pthread_key_t* key = reinterpret_cast<pthread_key_t*>(&data);
+ int errorcode = pthread_key_create(key, nullptr);
+ assert(errorcode == 0);
+ (void) errorcode;
+}
+
+ThreadLocalImpl::~ThreadLocalImpl() {
+ pthread_key_t* key = reinterpret_cast<pthread_key_t*>(&data);
+ int errorcode = pthread_key_delete(*key);
+ assert(errorcode == 0);
+ (void) errorcode;
+}
+
+void ThreadLocalImpl::setInstance(const void* d) {
+ pthread_key_t* key = reinterpret_cast<pthread_key_t*>(&data);
+ int errorcode = pthread_setspecific(*key, d);
+ assert(errorcode == 0);
+ (void) errorcode;
+}
+
+void *ThreadLocalImpl::getInstance() {
+ pthread_key_t* key = reinterpret_cast<pthread_key_t*>(&data);
+ return pthread_getspecific(*key);
+}
+
+void ThreadLocalImpl::removeInstance() {
+ setInstance(nullptr);
+}
+
+} // namespace llvm
+#else
+namespace llvm {
+using namespace sys;
+ThreadLocalImpl::ThreadLocalImpl() : data() { }
+ThreadLocalImpl::~ThreadLocalImpl() { }
+void ThreadLocalImpl::setInstance(const void* d) { data = const_cast<void*>(d);}
+void *ThreadLocalImpl::getInstance() { return data; }
+void ThreadLocalImpl::removeInstance() { setInstance(0); }
+}
+#endif
diff --git a/contrib/llvm/lib/Support/Unix/TimeValue.inc b/contrib/llvm/lib/Support/Unix/TimeValue.inc
new file mode 100644
index 000000000000..2c4f04c04f12
--- /dev/null
+++ b/contrib/llvm/lib/Support/Unix/TimeValue.inc
@@ -0,0 +1,54 @@
+//===- Unix/TimeValue.cpp - Unix TimeValue Implementation -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the Unix specific portion of the TimeValue class.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only generic UNIX code that
+//=== is guaranteed to work on *all* UNIX variants.
+//===----------------------------------------------------------------------===//
+
+#include "Unix.h"
+
+namespace llvm {
+ using namespace sys;
+
+std::string TimeValue::str() const {
+ time_t OurTime = time_t(this->toEpochTime());
+ struct tm Storage;
+ struct tm *LT = ::localtime_r(&OurTime, &Storage);
+ assert(LT);
+ char Buffer1[sizeof("YYYY-MM-DD HH:MM:SS")];
+ strftime(Buffer1, sizeof(Buffer1), "%Y-%m-%d %H:%M:%S", LT);
+ char Buffer2[sizeof("YYYY-MM-DD HH:MM:SS.MMMUUUNNN")];
+ snprintf(Buffer2, sizeof(Buffer2), "%s.%.9u", Buffer1, this->nanoseconds());
+ return std::string(Buffer2);
+}
+
+TimeValue TimeValue::now() {
+ struct timeval the_time;
+ timerclear(&the_time);
+ if (0 != ::gettimeofday(&the_time,nullptr)) {
+ // This is *really* unlikely to occur because the only gettimeofday
+ // errors concern the timezone parameter which we're passing in as 0.
+ // In the unlikely case it does happen, just return MinTime, no error
+ // message needed.
+ return MinTime();
+ }
+
+ return TimeValue(
+ static_cast<TimeValue::SecondsType>( the_time.tv_sec +
+ PosixZeroTimeSeconds ),
+ static_cast<TimeValue::NanoSecondsType>( the_time.tv_usec *
+ NANOSECONDS_PER_MICROSECOND ) );
+}
+
+} // namespace llvm
diff --git a/contrib/llvm/lib/Support/Unix/Unix.h b/contrib/llvm/lib/Support/Unix/Unix.h
new file mode 100644
index 000000000000..e16a226a8eaf
--- /dev/null
+++ b/contrib/llvm/lib/Support/Unix/Unix.h
@@ -0,0 +1,79 @@
+//===- llvm/Support/Unix/Unix.h - Common Unix Include File -------*- 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 things specific to Unix implementations.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_SUPPORT_UNIX_UNIX_H
+#define LLVM_LIB_SUPPORT_UNIX_UNIX_H
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only generic UNIX code that
+//=== is guaranteed to work on all UNIX variants.
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Config/config.h" // Get autoconf configuration settings
+#include "llvm/Support/Errno.h"
+#include <algorithm>
+#include <assert.h>
+#include <cerrno>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <string>
+#include <sys/types.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+
+#ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+#endif
+#include <time.h>
+
+#ifdef HAVE_SYS_WAIT_H
+# include <sys/wait.h>
+#endif
+
+#ifdef HAVE_DLFCN_H
+# include <dlfcn.h>
+#endif
+
+#ifndef WEXITSTATUS
+# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
+#endif
+
+#ifndef WIFEXITED
+# define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
+#endif
+
+/// This function builds an error message into \p ErrMsg using the \p prefix
+/// string and the Unix error number given by \p errnum. If errnum is -1, the
+/// default then the value of errno is used.
+/// @brief Make an error message
+///
+/// If the error number can be converted to a string, it will be
+/// separated from prefix by ": ".
+static inline bool MakeErrMsg(
+ std::string* ErrMsg, const std::string& prefix, int errnum = -1) {
+ if (!ErrMsg)
+ return true;
+ if (errnum == -1)
+ errnum = errno;
+ *ErrMsg = prefix + ": " + llvm::sys::StrError(errnum);
+ return true;
+}
+
+#endif
diff --git a/contrib/llvm/lib/Support/Unix/Watchdog.inc b/contrib/llvm/lib/Support/Unix/Watchdog.inc
new file mode 100644
index 000000000000..9e335aaa8ca7
--- /dev/null
+++ b/contrib/llvm/lib/Support/Unix/Watchdog.inc
@@ -0,0 +1,32 @@
+//===--- Unix/Watchdog.inc - Unix Watchdog Implementation -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides the generic Unix implementation of the Watchdog class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+namespace llvm {
+ namespace sys {
+ Watchdog::Watchdog(unsigned int seconds) {
+#ifdef HAVE_UNISTD_H
+ alarm(seconds);
+#endif
+ }
+
+ Watchdog::~Watchdog() {
+#ifdef HAVE_UNISTD_H
+ alarm(0);
+#endif
+ }
+ } // namespace sys
+} // namespace llvm
diff --git a/contrib/llvm/lib/Support/Valgrind.cpp b/contrib/llvm/lib/Support/Valgrind.cpp
new file mode 100644
index 000000000000..facf8d927ecd
--- /dev/null
+++ b/contrib/llvm/lib/Support/Valgrind.cpp
@@ -0,0 +1,74 @@
+//===-- Valgrind.cpp - Implement Valgrind communication ---------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Defines Valgrind communication methods, if HAVE_VALGRIND_VALGRIND_H is
+// defined. If we have valgrind.h but valgrind isn't running, its macros are
+// no-ops.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/Valgrind.h"
+#include "llvm/Config/config.h"
+
+#if HAVE_VALGRIND_VALGRIND_H
+#include <valgrind/valgrind.h>
+
+static bool InitNotUnderValgrind() {
+ return !RUNNING_ON_VALGRIND;
+}
+
+// This bool is negated from what we'd expect because code may run before it
+// gets initialized. If that happens, it will appear to be 0 (false), and we
+// want that to cause the rest of the code in this file to run the
+// Valgrind-provided macros.
+static const bool NotUnderValgrind = InitNotUnderValgrind();
+
+bool llvm::sys::RunningOnValgrind() {
+ if (NotUnderValgrind)
+ return false;
+ return RUNNING_ON_VALGRIND;
+}
+
+void llvm::sys::ValgrindDiscardTranslations(const void *Addr, size_t Len) {
+ if (NotUnderValgrind)
+ return;
+
+ VALGRIND_DISCARD_TRANSLATIONS(Addr, Len);
+}
+
+#else // !HAVE_VALGRIND_VALGRIND_H
+
+bool llvm::sys::RunningOnValgrind() {
+ return false;
+}
+
+void llvm::sys::ValgrindDiscardTranslations(const void *Addr, size_t Len) {
+}
+
+#endif // !HAVE_VALGRIND_VALGRIND_H
+
+// These functions require no implementation, tsan just looks at the arguments
+// they're called with. However, they are required to be weak as some other
+// application or library may already be providing these definitions for the
+// same reason we are.
+extern "C" {
+LLVM_ATTRIBUTE_WEAK void AnnotateHappensAfter(const char *file, int line,
+ const volatile void *cv);
+void AnnotateHappensAfter(const char *file, int line, const volatile void *cv) {
+}
+LLVM_ATTRIBUTE_WEAK void AnnotateHappensBefore(const char *file, int line,
+ const volatile void *cv);
+void AnnotateHappensBefore(const char *file, int line,
+ const volatile void *cv) {}
+LLVM_ATTRIBUTE_WEAK void AnnotateIgnoreWritesBegin(const char *file, int line);
+void AnnotateIgnoreWritesBegin(const char *file, int line) {}
+LLVM_ATTRIBUTE_WEAK void AnnotateIgnoreWritesEnd(const char *file, int line);
+void AnnotateIgnoreWritesEnd(const char *file, int line) {}
+}
+
diff --git a/contrib/llvm/lib/Support/Watchdog.cpp b/contrib/llvm/lib/Support/Watchdog.cpp
new file mode 100644
index 000000000000..724aa001f16e
--- /dev/null
+++ b/contrib/llvm/lib/Support/Watchdog.cpp
@@ -0,0 +1,23 @@
+//===---- Watchdog.cpp - Implement Watchdog ---------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the Watchdog class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/Watchdog.h"
+#include "llvm/Config/config.h"
+
+// Include the platform-specific parts of this class.
+#ifdef LLVM_ON_UNIX
+#include "Unix/Watchdog.inc"
+#endif
+#ifdef LLVM_ON_WIN32
+#include "Windows/Watchdog.inc"
+#endif
diff --git a/contrib/llvm/lib/Support/Windows/COM.inc b/contrib/llvm/lib/Support/Windows/COM.inc
new file mode 100644
index 000000000000..0c50d6f74ea3
--- /dev/null
+++ b/contrib/llvm/lib/Support/Windows/COM.inc
@@ -0,0 +1,37 @@
+//===- llvm/Support/Windows/COM.inc - Windows COM Implementation *- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the Windows portion of COM support.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only Windows code.
+//===----------------------------------------------------------------------===//
+
+#include <objbase.h>
+
+namespace llvm {
+namespace sys {
+
+InitializeCOMRAII::InitializeCOMRAII(COMThreadingMode Threading,
+ bool SpeedOverMemory) {
+ DWORD Coinit = 0;
+ if (Threading == COMThreadingMode::SingleThreaded)
+ Coinit |= COINIT_APARTMENTTHREADED;
+ else
+ Coinit |= COINIT_MULTITHREADED;
+ if (SpeedOverMemory)
+ Coinit |= COINIT_SPEED_OVER_MEMORY;
+ ::CoInitializeEx(nullptr, Coinit);
+}
+
+InitializeCOMRAII::~InitializeCOMRAII() { ::CoUninitialize(); }
+}
+}
diff --git a/contrib/llvm/lib/Support/Windows/DynamicLibrary.inc b/contrib/llvm/lib/Support/Windows/DynamicLibrary.inc
new file mode 100644
index 000000000000..79d5f79afa97
--- /dev/null
+++ b/contrib/llvm/lib/Support/Windows/DynamicLibrary.inc
@@ -0,0 +1,172 @@
+//===- Win32/DynamicLibrary.cpp - Win32 DL Implementation -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides the Win32 specific implementation of DynamicLibrary.
+//
+//===----------------------------------------------------------------------===//
+
+#include "WindowsSupport.h"
+
+#ifdef __MINGW32__
+ #include <imagehlp.h>
+#else
+ #include <dbghelp.h>
+#endif
+
+#ifdef _MSC_VER
+ #include <ntverp.h>
+#endif
+
+#ifdef __MINGW32__
+ #if (HAVE_LIBIMAGEHLP != 1)
+ #error "libimagehlp.a should be present"
+ #endif
+#else
+ #pragma comment(lib, "dbghelp.lib")
+#endif
+
+namespace llvm {
+using namespace sys;
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only Win32 specific code
+//=== and must not be UNIX code.
+//===----------------------------------------------------------------------===//
+
+static DenseSet<HMODULE> *OpenedHandles;
+
+static BOOL CALLBACK
+ELM_Callback(WIN32_ELMCB_PCSTR ModuleName, ULONG_PTR ModuleBase,
+ ULONG ModuleSize, PVOID UserContext) {
+ OpenedHandles->insert((HMODULE)ModuleBase);
+ return TRUE;
+}
+
+DynamicLibrary DynamicLibrary::getPermanentLibrary(const char *filename,
+ std::string *errMsg) {
+ SmartScopedLock<true> lock(*SymbolsMutex);
+
+ if (!filename) {
+ // When no file is specified, enumerate all DLLs and EXEs in the process.
+ if (OpenedHandles == 0)
+ OpenedHandles = new DenseSet<HMODULE>();
+
+ EnumerateLoadedModules(GetCurrentProcess(), ELM_Callback, 0);
+ // Dummy library that represents "search all handles".
+ // This is mostly to ensure that the return value still shows up as "valid".
+ return DynamicLibrary(&OpenedHandles);
+ }
+
+ SmallVector<wchar_t, MAX_PATH> filenameUnicode;
+ if (std::error_code ec = windows::UTF8ToUTF16(filename, filenameUnicode)) {
+ SetLastError(ec.value());
+ MakeErrMsg(errMsg, std::string(filename) + ": Can't convert to UTF-16: ");
+ return DynamicLibrary();
+ }
+
+ HMODULE a_handle = LoadLibraryW(filenameUnicode.data());
+
+ if (a_handle == 0) {
+ MakeErrMsg(errMsg, std::string(filename) + ": Can't open : ");
+ return DynamicLibrary();
+ }
+
+ if (OpenedHandles == 0)
+ OpenedHandles = new DenseSet<HMODULE>();
+
+ // If we've already loaded this library, FreeLibrary() the handle in order to
+ // keep the internal refcount at +1.
+ if (!OpenedHandles->insert(a_handle).second)
+ FreeLibrary(a_handle);
+
+ return DynamicLibrary(a_handle);
+}
+
+// Stack probing routines are in the support library (e.g. libgcc), but we don't
+// have dynamic linking on windows. Provide a hook.
+#define EXPLICIT_SYMBOL(SYM) \
+ extern "C" { extern void *SYM; }
+#define EXPLICIT_SYMBOL2(SYMFROM, SYMTO) EXPLICIT_SYMBOL(SYMTO)
+
+#ifdef _M_IX86
+// Win32 on x86 implements certain single-precision math functions as macros.
+// These functions are not exported by the DLL, but will still be needed
+// for symbol-resolution by the JIT loader. Therefore, this Support libray
+// provides helper functions with the same implementation.
+
+#define INLINE_DEF_SYMBOL1(TYP, SYM) \
+ extern "C" TYP inline_##SYM(TYP _X) { return SYM(_X); }
+#define INLINE_DEF_SYMBOL2(TYP, SYM) \
+ extern "C" TYP inline_##SYM(TYP _X, TYP _Y) { return SYM(_X, _Y); }
+#endif
+
+#include "explicit_symbols.inc"
+
+#undef EXPLICIT_SYMBOL
+#undef EXPLICIT_SYMBOL2
+#undef INLINE_DEF_SYMBOL1
+#undef INLINE_DEF_SYMBOL2
+
+void* DynamicLibrary::SearchForAddressOfSymbol(const char* symbolName) {
+ SmartScopedLock<true> Lock(*SymbolsMutex);
+
+ // First check symbols added via AddSymbol().
+ if (ExplicitSymbols.isConstructed()) {
+ StringMap<void *>::iterator i = ExplicitSymbols->find(symbolName);
+
+ if (i != ExplicitSymbols->end())
+ return i->second;
+ }
+
+ // Now search the libraries.
+ if (OpenedHandles) {
+ for (DenseSet<HMODULE>::iterator I = OpenedHandles->begin(),
+ E = OpenedHandles->end(); I != E; ++I) {
+ FARPROC ptr = GetProcAddress((HMODULE)*I, symbolName);
+ if (ptr) {
+ return (void *)(intptr_t)ptr;
+ }
+ }
+ }
+
+#define EXPLICIT_SYMBOL(SYM) \
+ if (!strcmp(symbolName, #SYM)) \
+ return (void *)&SYM;
+#define EXPLICIT_SYMBOL2(SYMFROM, SYMTO) \
+ if (!strcmp(symbolName, #SYMFROM)) \
+ return (void *)&SYMTO;
+
+#ifdef _M_IX86
+#define INLINE_DEF_SYMBOL1(TYP, SYM) \
+ if (!strcmp(symbolName, #SYM)) \
+ return (void *)&inline_##SYM;
+#define INLINE_DEF_SYMBOL2(TYP, SYM) INLINE_DEF_SYMBOL1(TYP, SYM)
+#endif
+
+ {
+#include "explicit_symbols.inc"
+ }
+
+#undef EXPLICIT_SYMBOL
+#undef EXPLICIT_SYMBOL2
+#undef INLINE_DEF_SYMBOL1
+#undef INLINE_DEF_SYMBOL2
+
+ return 0;
+}
+
+void *DynamicLibrary::getAddressOfSymbol(const char *symbolName) {
+ if (!isValid())
+ return NULL;
+ if (Data == &OpenedHandles)
+ return SearchForAddressOfSymbol(symbolName);
+ return (void *)(intptr_t)GetProcAddress((HMODULE)Data, symbolName);
+}
+
+}
diff --git a/contrib/llvm/lib/Support/Windows/Host.inc b/contrib/llvm/lib/Support/Windows/Host.inc
new file mode 100644
index 000000000000..fe89fe0aad8c
--- /dev/null
+++ b/contrib/llvm/lib/Support/Windows/Host.inc
@@ -0,0 +1,22 @@
+//===- llvm/Support/Win32/Host.inc ------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the Win32 Host support.
+//
+//===----------------------------------------------------------------------===//
+
+#include "WindowsSupport.h"
+#include <cstdio>
+#include <string>
+
+using namespace llvm;
+
+std::string sys::getDefaultTargetTriple() {
+ return Triple::normalize(LLVM_DEFAULT_TARGET_TRIPLE);
+}
diff --git a/contrib/llvm/lib/Support/Windows/Memory.inc b/contrib/llvm/lib/Support/Windows/Memory.inc
new file mode 100644
index 000000000000..4b2ff2e2d324
--- /dev/null
+++ b/contrib/llvm/lib/Support/Windows/Memory.inc
@@ -0,0 +1,244 @@
+//===- Win32/Memory.cpp - Win32 Memory Implementation -----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides the Win32 specific implementation of various Memory
+// management utilities
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/Process.h"
+#include "llvm/Support/WindowsError.h"
+
+// The Windows.h header must be the last one included.
+#include "WindowsSupport.h"
+
+namespace {
+
+DWORD getWindowsProtectionFlags(unsigned Flags) {
+ switch (Flags) {
+ // Contrary to what you might expect, the Windows page protection flags
+ // are not a bitwise combination of RWX values
+ case llvm::sys::Memory::MF_READ:
+ return PAGE_READONLY;
+ case llvm::sys::Memory::MF_WRITE:
+ // Note: PAGE_WRITE is not supported by VirtualProtect
+ return PAGE_READWRITE;
+ case llvm::sys::Memory::MF_READ|llvm::sys::Memory::MF_WRITE:
+ return PAGE_READWRITE;
+ case llvm::sys::Memory::MF_READ|llvm::sys::Memory::MF_EXEC:
+ return PAGE_EXECUTE_READ;
+ case llvm::sys::Memory::MF_READ |
+ llvm::sys::Memory::MF_WRITE |
+ llvm::sys::Memory::MF_EXEC:
+ return PAGE_EXECUTE_READWRITE;
+ case llvm::sys::Memory::MF_EXEC:
+ return PAGE_EXECUTE;
+ default:
+ llvm_unreachable("Illegal memory protection flag specified!");
+ }
+ // Provide a default return value as required by some compilers.
+ return PAGE_NOACCESS;
+}
+
+size_t getAllocationGranularity() {
+ SYSTEM_INFO Info;
+ ::GetSystemInfo(&Info);
+ if (Info.dwPageSize > Info.dwAllocationGranularity)
+ return Info.dwPageSize;
+ else
+ return Info.dwAllocationGranularity;
+}
+
+} // namespace
+
+namespace llvm {
+namespace sys {
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only Win32 specific code
+//=== and must not be UNIX code
+//===----------------------------------------------------------------------===//
+
+MemoryBlock Memory::allocateMappedMemory(size_t NumBytes,
+ const MemoryBlock *const NearBlock,
+ unsigned Flags,
+ std::error_code &EC) {
+ EC = std::error_code();
+ if (NumBytes == 0)
+ return MemoryBlock();
+
+ // While we'd be happy to allocate single pages, the Windows allocation
+ // granularity may be larger than a single page (in practice, it is 64K)
+ // so mapping less than that will create an unreachable fragment of memory.
+ // Avoid using one-time initialization of static locals here, since they
+ // aren't thread safe with MSVC.
+ static volatile size_t GranularityCached;
+ size_t Granularity = GranularityCached;
+ if (Granularity == 0) {
+ Granularity = getAllocationGranularity();
+ GranularityCached = Granularity;
+ }
+
+ const size_t NumBlocks = (NumBytes+Granularity-1)/Granularity;
+
+ uintptr_t Start = NearBlock ? reinterpret_cast<uintptr_t>(NearBlock->base()) +
+ NearBlock->size()
+ : 0;
+
+ // If the requested address is not aligned to the allocation granularity,
+ // round up to get beyond NearBlock. VirtualAlloc would have rounded down.
+ if (Start && Start % Granularity != 0)
+ Start += Granularity - Start % Granularity;
+
+ DWORD Protect = getWindowsProtectionFlags(Flags);
+
+ void *PA = ::VirtualAlloc(reinterpret_cast<void*>(Start),
+ NumBlocks*Granularity,
+ MEM_RESERVE | MEM_COMMIT, Protect);
+ if (PA == NULL) {
+ if (NearBlock) {
+ // Try again without the NearBlock hint
+ return allocateMappedMemory(NumBytes, NULL, Flags, EC);
+ }
+ EC = mapWindowsError(::GetLastError());
+ return MemoryBlock();
+ }
+
+ MemoryBlock Result;
+ Result.Address = PA;
+ Result.Size = NumBlocks*Granularity;
+
+ if (Flags & MF_EXEC)
+ Memory::InvalidateInstructionCache(Result.Address, Result.Size);
+
+ return Result;
+}
+
+ std::error_code Memory::releaseMappedMemory(MemoryBlock &M) {
+ if (M.Address == 0 || M.Size == 0)
+ return std::error_code();
+
+ if (!VirtualFree(M.Address, 0, MEM_RELEASE))
+ return mapWindowsError(::GetLastError());
+
+ M.Address = 0;
+ M.Size = 0;
+
+ return std::error_code();
+}
+
+ std::error_code Memory::protectMappedMemory(const MemoryBlock &M,
+ unsigned Flags) {
+ if (M.Address == 0 || M.Size == 0)
+ return std::error_code();
+
+ DWORD Protect = getWindowsProtectionFlags(Flags);
+
+ DWORD OldFlags;
+ if (!VirtualProtect(M.Address, M.Size, Protect, &OldFlags))
+ return mapWindowsError(::GetLastError());
+
+ if (Flags & MF_EXEC)
+ Memory::InvalidateInstructionCache(M.Address, M.Size);
+
+ return std::error_code();
+}
+
+/// InvalidateInstructionCache - Before the JIT can run a block of code
+/// that has been emitted it must invalidate the instruction cache on some
+/// platforms.
+void Memory::InvalidateInstructionCache(
+ const void *Addr, size_t Len) {
+ FlushInstructionCache(GetCurrentProcess(), Addr, Len);
+}
+
+
+MemoryBlock Memory::AllocateRWX(size_t NumBytes,
+ const MemoryBlock *NearBlock,
+ std::string *ErrMsg) {
+ MemoryBlock MB;
+ std::error_code EC;
+ MB = allocateMappedMemory(NumBytes, NearBlock,
+ MF_READ|MF_WRITE|MF_EXEC, EC);
+ if (EC != std::error_code() && ErrMsg) {
+ MakeErrMsg(ErrMsg, EC.message());
+ }
+ return MB;
+}
+
+bool Memory::ReleaseRWX(MemoryBlock &M, std::string *ErrMsg) {
+ std::error_code EC = releaseMappedMemory(M);
+ if (EC == std::error_code())
+ return false;
+ MakeErrMsg(ErrMsg, EC.message());
+ return true;
+}
+
+static DWORD getProtection(const void *addr) {
+ MEMORY_BASIC_INFORMATION info;
+ if (sizeof(info) == ::VirtualQuery(addr, &info, sizeof(info))) {
+ return info.Protect;
+ }
+ return 0;
+}
+
+bool Memory::setWritable(MemoryBlock &M, std::string *ErrMsg) {
+ if (!setRangeWritable(M.Address, M.Size)) {
+ return MakeErrMsg(ErrMsg, "Cannot set memory to writeable: ");
+ }
+ return true;
+}
+
+bool Memory::setExecutable(MemoryBlock &M, std::string *ErrMsg) {
+ if (!setRangeExecutable(M.Address, M.Size)) {
+ return MakeErrMsg(ErrMsg, "Cannot set memory to executable: ");
+ }
+ return true;
+}
+
+bool Memory::setRangeWritable(const void *Addr, size_t Size) {
+ DWORD prot = getProtection(Addr);
+ if (!prot)
+ return false;
+
+ if (prot == PAGE_EXECUTE || prot == PAGE_EXECUTE_READ) {
+ prot = PAGE_EXECUTE_READWRITE;
+ } else if (prot == PAGE_NOACCESS || prot == PAGE_READONLY) {
+ prot = PAGE_READWRITE;
+ }
+
+ DWORD oldProt;
+ Memory::InvalidateInstructionCache(Addr, Size);
+ return ::VirtualProtect(const_cast<LPVOID>(Addr), Size, prot, &oldProt)
+ == TRUE;
+}
+
+bool Memory::setRangeExecutable(const void *Addr, size_t Size) {
+ DWORD prot = getProtection(Addr);
+ if (!prot)
+ return false;
+
+ if (prot == PAGE_NOACCESS) {
+ prot = PAGE_EXECUTE;
+ } else if (prot == PAGE_READONLY) {
+ prot = PAGE_EXECUTE_READ;
+ } else if (prot == PAGE_READWRITE) {
+ prot = PAGE_EXECUTE_READWRITE;
+ }
+
+ DWORD oldProt;
+ Memory::InvalidateInstructionCache(Addr, Size);
+ return ::VirtualProtect(const_cast<LPVOID>(Addr), Size, prot, &oldProt)
+ == TRUE;
+}
+
+} // namespace sys
+} // namespace llvm
diff --git a/contrib/llvm/lib/Support/Windows/Mutex.inc b/contrib/llvm/lib/Support/Windows/Mutex.inc
new file mode 100644
index 000000000000..ab79d079122f
--- /dev/null
+++ b/contrib/llvm/lib/Support/Windows/Mutex.inc
@@ -0,0 +1,58 @@
+//===- llvm/Support/Win32/Mutex.inc - Win32 Mutex Implementation -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the Win32 specific (non-pthread) Mutex class.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only generic Win32 code that
+//=== is guaranteed to work on *all* Win32 variants.
+//===----------------------------------------------------------------------===//
+
+#include "WindowsSupport.h"
+#include "llvm/Support/Mutex.h"
+
+namespace llvm {
+using namespace sys;
+
+MutexImpl::MutexImpl(bool /*recursive*/)
+{
+ data_ = new CRITICAL_SECTION;
+ InitializeCriticalSection((LPCRITICAL_SECTION)data_);
+}
+
+MutexImpl::~MutexImpl()
+{
+ DeleteCriticalSection((LPCRITICAL_SECTION)data_);
+ delete (LPCRITICAL_SECTION)data_;
+ data_ = 0;
+}
+
+bool
+MutexImpl::acquire()
+{
+ EnterCriticalSection((LPCRITICAL_SECTION)data_);
+ return true;
+}
+
+bool
+MutexImpl::release()
+{
+ LeaveCriticalSection((LPCRITICAL_SECTION)data_);
+ return true;
+}
+
+bool
+MutexImpl::tryacquire()
+{
+ return TryEnterCriticalSection((LPCRITICAL_SECTION)data_);
+}
+
+}
diff --git a/contrib/llvm/lib/Support/Windows/Path.inc b/contrib/llvm/lib/Support/Windows/Path.inc
new file mode 100644
index 000000000000..72da7c5fec32
--- /dev/null
+++ b/contrib/llvm/lib/Support/Windows/Path.inc
@@ -0,0 +1,859 @@
+//===- llvm/Support/Windows/Path.inc - Windows Path Impl --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the Windows specific implementation of the Path API.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only generic Windows code that
+//=== is guaranteed to work on *all* Windows variants.
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/WindowsError.h"
+#include <fcntl.h>
+#include <io.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+// These two headers must be included last, and make sure shlobj is required
+// after Windows.h to make sure it picks up our definition of _WIN32_WINNT
+#include "WindowsSupport.h"
+#include <shlobj.h>
+
+#undef max
+
+// MinGW doesn't define this.
+#ifndef _ERRNO_T_DEFINED
+#define _ERRNO_T_DEFINED
+typedef int errno_t;
+#endif
+
+#ifdef _MSC_VER
+# pragma comment(lib, "advapi32.lib") // This provides CryptAcquireContextW.
+#endif
+
+using namespace llvm;
+
+using llvm::sys::windows::UTF8ToUTF16;
+using llvm::sys::windows::UTF16ToUTF8;
+using llvm::sys::path::widenPath;
+
+static bool is_separator(const wchar_t value) {
+ switch (value) {
+ case L'\\':
+ case L'/':
+ return true;
+ default:
+ return false;
+ }
+}
+
+namespace llvm {
+namespace sys {
+namespace path {
+
+// Convert a UTF-8 path to UTF-16. Also, if the absolute equivalent of the
+// path is longer than CreateDirectory can tolerate, make it absolute and
+// prefixed by '\\?\'.
+std::error_code widenPath(const Twine &Path8,
+ SmallVectorImpl<wchar_t> &Path16) {
+ const size_t MaxDirLen = MAX_PATH - 12; // Must leave room for 8.3 filename.
+
+ // Several operations would convert Path8 to SmallString; more efficient to
+ // do it once up front.
+ SmallString<128> Path8Str;
+ Path8.toVector(Path8Str);
+
+ // If we made this path absolute, how much longer would it get?
+ size_t CurPathLen;
+ if (llvm::sys::path::is_absolute(Twine(Path8Str)))
+ CurPathLen = 0; // No contribution from current_path needed.
+ else {
+ CurPathLen = ::GetCurrentDirectoryW(0, NULL);
+ if (CurPathLen == 0)
+ return mapWindowsError(::GetLastError());
+ }
+
+ // Would the absolute path be longer than our limit?
+ if ((Path8Str.size() + CurPathLen) >= MaxDirLen &&
+ !Path8Str.startswith("\\\\?\\")) {
+ SmallString<2*MAX_PATH> FullPath("\\\\?\\");
+ if (CurPathLen) {
+ SmallString<80> CurPath;
+ if (std::error_code EC = llvm::sys::fs::current_path(CurPath))
+ return EC;
+ FullPath.append(CurPath);
+ }
+ // Traverse the requested path, canonicalizing . and .. as we go (because
+ // the \\?\ prefix is documented to treat them as real components).
+ // The iterators don't report separators and append() always attaches
+ // preferred_separator so we don't need to call native() on the result.
+ for (llvm::sys::path::const_iterator I = llvm::sys::path::begin(Path8Str),
+ E = llvm::sys::path::end(Path8Str);
+ I != E; ++I) {
+ if (I->size() == 1 && *I == ".")
+ continue;
+ if (I->size() == 2 && *I == "..")
+ llvm::sys::path::remove_filename(FullPath);
+ else
+ llvm::sys::path::append(FullPath, *I);
+ }
+ return UTF8ToUTF16(FullPath, Path16);
+ }
+
+ // Just use the caller's original path.
+ return UTF8ToUTF16(Path8Str, Path16);
+}
+} // end namespace path
+
+namespace fs {
+
+std::string getMainExecutable(const char *argv0, void *MainExecAddr) {
+ SmallVector<wchar_t, MAX_PATH> PathName;
+ DWORD Size = ::GetModuleFileNameW(NULL, PathName.data(), PathName.capacity());
+
+ // A zero return value indicates a failure other than insufficient space.
+ if (Size == 0)
+ return "";
+
+ // Insufficient space is determined by a return value equal to the size of
+ // the buffer passed in.
+ if (Size == PathName.capacity())
+ return "";
+
+ // On success, GetModuleFileNameW returns the number of characters written to
+ // the buffer not including the NULL terminator.
+ PathName.set_size(Size);
+
+ // Convert the result from UTF-16 to UTF-8.
+ SmallVector<char, MAX_PATH> PathNameUTF8;
+ if (UTF16ToUTF8(PathName.data(), PathName.size(), PathNameUTF8))
+ return "";
+
+ return std::string(PathNameUTF8.data());
+}
+
+UniqueID file_status::getUniqueID() const {
+ // The file is uniquely identified by the volume serial number along
+ // with the 64-bit file identifier.
+ uint64_t FileID = (static_cast<uint64_t>(FileIndexHigh) << 32ULL) |
+ static_cast<uint64_t>(FileIndexLow);
+
+ return UniqueID(VolumeSerialNumber, FileID);
+}
+
+TimeValue file_status::getLastModificationTime() const {
+ ULARGE_INTEGER UI;
+ UI.LowPart = LastWriteTimeLow;
+ UI.HighPart = LastWriteTimeHigh;
+
+ TimeValue Ret;
+ Ret.fromWin32Time(UI.QuadPart);
+ return Ret;
+}
+
+std::error_code current_path(SmallVectorImpl<char> &result) {
+ SmallVector<wchar_t, MAX_PATH> cur_path;
+ DWORD len = MAX_PATH;
+
+ do {
+ cur_path.reserve(len);
+ len = ::GetCurrentDirectoryW(cur_path.capacity(), cur_path.data());
+
+ // A zero return value indicates a failure other than insufficient space.
+ if (len == 0)
+ return mapWindowsError(::GetLastError());
+
+ // If there's insufficient space, the len returned is larger than the len
+ // given.
+ } while (len > cur_path.capacity());
+
+ // On success, GetCurrentDirectoryW returns the number of characters not
+ // including the null-terminator.
+ cur_path.set_size(len);
+ return UTF16ToUTF8(cur_path.begin(), cur_path.size(), result);
+}
+
+std::error_code create_directory(const Twine &path, bool IgnoreExisting) {
+ SmallVector<wchar_t, 128> path_utf16;
+
+ if (std::error_code ec = widenPath(path, path_utf16))
+ return ec;
+
+ if (!::CreateDirectoryW(path_utf16.begin(), NULL)) {
+ DWORD LastError = ::GetLastError();
+ if (LastError != ERROR_ALREADY_EXISTS || !IgnoreExisting)
+ return mapWindowsError(LastError);
+ }
+
+ return std::error_code();
+}
+
+// We can't use symbolic links for windows.
+std::error_code create_link(const Twine &to, const Twine &from) {
+ // Convert to utf-16.
+ SmallVector<wchar_t, 128> wide_from;
+ SmallVector<wchar_t, 128> wide_to;
+ if (std::error_code ec = widenPath(from, wide_from))
+ return ec;
+ if (std::error_code ec = widenPath(to, wide_to))
+ return ec;
+
+ if (!::CreateHardLinkW(wide_from.begin(), wide_to.begin(), NULL))
+ return mapWindowsError(::GetLastError());
+
+ return std::error_code();
+}
+
+std::error_code remove(const Twine &path, bool IgnoreNonExisting) {
+ SmallVector<wchar_t, 128> path_utf16;
+
+ file_status ST;
+ if (std::error_code EC = status(path, ST)) {
+ if (EC != errc::no_such_file_or_directory || !IgnoreNonExisting)
+ return EC;
+ return std::error_code();
+ }
+
+ if (std::error_code ec = widenPath(path, path_utf16))
+ return ec;
+
+ if (ST.type() == file_type::directory_file) {
+ if (!::RemoveDirectoryW(c_str(path_utf16))) {
+ std::error_code EC = mapWindowsError(::GetLastError());
+ if (EC != errc::no_such_file_or_directory || !IgnoreNonExisting)
+ return EC;
+ }
+ return std::error_code();
+ }
+ if (!::DeleteFileW(c_str(path_utf16))) {
+ std::error_code EC = mapWindowsError(::GetLastError());
+ if (EC != errc::no_such_file_or_directory || !IgnoreNonExisting)
+ return EC;
+ }
+ return std::error_code();
+}
+
+std::error_code rename(const Twine &from, const Twine &to) {
+ // Convert to utf-16.
+ SmallVector<wchar_t, 128> wide_from;
+ SmallVector<wchar_t, 128> wide_to;
+ if (std::error_code ec = widenPath(from, wide_from))
+ return ec;
+ if (std::error_code ec = widenPath(to, wide_to))
+ return ec;
+
+ std::error_code ec = std::error_code();
+ for (int i = 0; i < 2000; i++) {
+ if (::MoveFileExW(wide_from.begin(), wide_to.begin(),
+ MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING))
+ return std::error_code();
+ DWORD LastError = ::GetLastError();
+ ec = mapWindowsError(LastError);
+ if (LastError != ERROR_ACCESS_DENIED)
+ break;
+ // Retry MoveFile() at ACCESS_DENIED.
+ // System scanners (eg. indexer) might open the source file when
+ // It is written and closed.
+ ::Sleep(1);
+ }
+
+ return ec;
+}
+
+std::error_code resize_file(int FD, uint64_t Size) {
+#ifdef HAVE__CHSIZE_S
+ errno_t error = ::_chsize_s(FD, Size);
+#else
+ errno_t error = ::_chsize(FD, Size);
+#endif
+ return std::error_code(error, std::generic_category());
+}
+
+std::error_code access(const Twine &Path, AccessMode Mode) {
+ SmallVector<wchar_t, 128> PathUtf16;
+
+ if (std::error_code EC = widenPath(Path, PathUtf16))
+ return EC;
+
+ DWORD Attributes = ::GetFileAttributesW(PathUtf16.begin());
+
+ if (Attributes == INVALID_FILE_ATTRIBUTES) {
+ // See if the file didn't actually exist.
+ DWORD LastError = ::GetLastError();
+ if (LastError != ERROR_FILE_NOT_FOUND &&
+ LastError != ERROR_PATH_NOT_FOUND)
+ return mapWindowsError(LastError);
+ return errc::no_such_file_or_directory;
+ }
+
+ if (Mode == AccessMode::Write && (Attributes & FILE_ATTRIBUTE_READONLY))
+ return errc::permission_denied;
+
+ return std::error_code();
+}
+
+bool equivalent(file_status A, file_status B) {
+ assert(status_known(A) && status_known(B));
+ return A.FileIndexHigh == B.FileIndexHigh &&
+ A.FileIndexLow == B.FileIndexLow &&
+ A.FileSizeHigh == B.FileSizeHigh &&
+ A.FileSizeLow == B.FileSizeLow &&
+ A.LastWriteTimeHigh == B.LastWriteTimeHigh &&
+ A.LastWriteTimeLow == B.LastWriteTimeLow &&
+ A.VolumeSerialNumber == B.VolumeSerialNumber;
+}
+
+std::error_code equivalent(const Twine &A, const Twine &B, bool &result) {
+ file_status fsA, fsB;
+ if (std::error_code ec = status(A, fsA))
+ return ec;
+ if (std::error_code ec = status(B, fsB))
+ return ec;
+ result = equivalent(fsA, fsB);
+ return std::error_code();
+}
+
+static bool isReservedName(StringRef path) {
+ // This list of reserved names comes from MSDN, at:
+ // http://msdn.microsoft.com/en-us/library/aa365247%28v=vs.85%29.aspx
+ static const char *sReservedNames[] = { "nul", "con", "prn", "aux",
+ "com1", "com2", "com3", "com4", "com5", "com6",
+ "com7", "com8", "com9", "lpt1", "lpt2", "lpt3",
+ "lpt4", "lpt5", "lpt6", "lpt7", "lpt8", "lpt9" };
+
+ // First, check to see if this is a device namespace, which always
+ // starts with \\.\, since device namespaces are not legal file paths.
+ if (path.startswith("\\\\.\\"))
+ return true;
+
+ // Then compare against the list of ancient reserved names
+ for (size_t i = 0; i < array_lengthof(sReservedNames); ++i) {
+ if (path.equals_lower(sReservedNames[i]))
+ return true;
+ }
+
+ // The path isn't what we consider reserved.
+ return false;
+}
+
+static std::error_code getStatus(HANDLE FileHandle, file_status &Result) {
+ if (FileHandle == INVALID_HANDLE_VALUE)
+ goto handle_status_error;
+
+ switch (::GetFileType(FileHandle)) {
+ default:
+ llvm_unreachable("Don't know anything about this file type");
+ case FILE_TYPE_UNKNOWN: {
+ DWORD Err = ::GetLastError();
+ if (Err != NO_ERROR)
+ return mapWindowsError(Err);
+ Result = file_status(file_type::type_unknown);
+ return std::error_code();
+ }
+ case FILE_TYPE_DISK:
+ break;
+ case FILE_TYPE_CHAR:
+ Result = file_status(file_type::character_file);
+ return std::error_code();
+ case FILE_TYPE_PIPE:
+ Result = file_status(file_type::fifo_file);
+ return std::error_code();
+ }
+
+ BY_HANDLE_FILE_INFORMATION Info;
+ if (!::GetFileInformationByHandle(FileHandle, &Info))
+ goto handle_status_error;
+
+ {
+ file_type Type = (Info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ ? file_type::directory_file
+ : file_type::regular_file;
+ Result =
+ file_status(Type, Info.ftLastWriteTime.dwHighDateTime,
+ Info.ftLastWriteTime.dwLowDateTime,
+ Info.dwVolumeSerialNumber, Info.nFileSizeHigh,
+ Info.nFileSizeLow, Info.nFileIndexHigh, Info.nFileIndexLow);
+ return std::error_code();
+ }
+
+handle_status_error:
+ DWORD LastError = ::GetLastError();
+ if (LastError == ERROR_FILE_NOT_FOUND ||
+ LastError == ERROR_PATH_NOT_FOUND)
+ Result = file_status(file_type::file_not_found);
+ else if (LastError == ERROR_SHARING_VIOLATION)
+ Result = file_status(file_type::type_unknown);
+ else
+ Result = file_status(file_type::status_error);
+ return mapWindowsError(LastError);
+}
+
+std::error_code status(const Twine &path, file_status &result) {
+ SmallString<128> path_storage;
+ SmallVector<wchar_t, 128> path_utf16;
+
+ StringRef path8 = path.toStringRef(path_storage);
+ if (isReservedName(path8)) {
+ result = file_status(file_type::character_file);
+ return std::error_code();
+ }
+
+ if (std::error_code ec = widenPath(path8, path_utf16))
+ return ec;
+
+ DWORD attr = ::GetFileAttributesW(path_utf16.begin());
+ if (attr == INVALID_FILE_ATTRIBUTES)
+ return getStatus(INVALID_HANDLE_VALUE, result);
+
+ // Handle reparse points.
+ if (attr & FILE_ATTRIBUTE_REPARSE_POINT) {
+ ScopedFileHandle h(
+ ::CreateFileW(path_utf16.begin(),
+ 0, // Attributes only.
+ FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS,
+ 0));
+ if (!h)
+ return getStatus(INVALID_HANDLE_VALUE, result);
+ }
+
+ ScopedFileHandle h(
+ ::CreateFileW(path_utf16.begin(), 0, // Attributes only.
+ FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0));
+ if (!h)
+ return getStatus(INVALID_HANDLE_VALUE, result);
+
+ return getStatus(h, result);
+}
+
+std::error_code status(int FD, file_status &Result) {
+ HANDLE FileHandle = reinterpret_cast<HANDLE>(_get_osfhandle(FD));
+ return getStatus(FileHandle, Result);
+}
+
+std::error_code setLastModificationAndAccessTime(int FD, TimeValue Time) {
+ ULARGE_INTEGER UI;
+ UI.QuadPart = Time.toWin32Time();
+ FILETIME FT;
+ FT.dwLowDateTime = UI.LowPart;
+ FT.dwHighDateTime = UI.HighPart;
+ HANDLE FileHandle = reinterpret_cast<HANDLE>(_get_osfhandle(FD));
+ if (!SetFileTime(FileHandle, NULL, &FT, &FT))
+ return mapWindowsError(::GetLastError());
+ return std::error_code();
+}
+
+std::error_code mapped_file_region::init(int FD, uint64_t Offset,
+ mapmode Mode) {
+ // Make sure that the requested size fits within SIZE_T.
+ if (Size > std::numeric_limits<SIZE_T>::max())
+ return make_error_code(errc::invalid_argument);
+
+ HANDLE FileHandle = reinterpret_cast<HANDLE>(_get_osfhandle(FD));
+ if (FileHandle == INVALID_HANDLE_VALUE)
+ return make_error_code(errc::bad_file_descriptor);
+
+ DWORD flprotect;
+ switch (Mode) {
+ case readonly: flprotect = PAGE_READONLY; break;
+ case readwrite: flprotect = PAGE_READWRITE; break;
+ case priv: flprotect = PAGE_WRITECOPY; break;
+ }
+
+ HANDLE FileMappingHandle =
+ ::CreateFileMappingW(FileHandle, 0, flprotect,
+ (Offset + Size) >> 32,
+ (Offset + Size) & 0xffffffff,
+ 0);
+ if (FileMappingHandle == NULL) {
+ std::error_code ec = mapWindowsError(GetLastError());
+ return ec;
+ }
+
+ DWORD dwDesiredAccess;
+ switch (Mode) {
+ case readonly: dwDesiredAccess = FILE_MAP_READ; break;
+ case readwrite: dwDesiredAccess = FILE_MAP_WRITE; break;
+ case priv: dwDesiredAccess = FILE_MAP_COPY; break;
+ }
+ Mapping = ::MapViewOfFile(FileMappingHandle,
+ dwDesiredAccess,
+ Offset >> 32,
+ Offset & 0xffffffff,
+ Size);
+ if (Mapping == NULL) {
+ std::error_code ec = mapWindowsError(GetLastError());
+ ::CloseHandle(FileMappingHandle);
+ return ec;
+ }
+
+ if (Size == 0) {
+ MEMORY_BASIC_INFORMATION mbi;
+ SIZE_T Result = VirtualQuery(Mapping, &mbi, sizeof(mbi));
+ if (Result == 0) {
+ std::error_code ec = mapWindowsError(GetLastError());
+ ::UnmapViewOfFile(Mapping);
+ ::CloseHandle(FileMappingHandle);
+ return ec;
+ }
+ Size = mbi.RegionSize;
+ }
+
+ // Close all the handles except for the view. It will keep the other handles
+ // alive.
+ ::CloseHandle(FileMappingHandle);
+ return std::error_code();
+}
+
+mapped_file_region::mapped_file_region(int fd, mapmode mode, uint64_t length,
+ uint64_t offset, std::error_code &ec)
+ : Size(length), Mapping() {
+ ec = init(fd, offset, mode);
+ if (ec)
+ Mapping = 0;
+}
+
+mapped_file_region::~mapped_file_region() {
+ if (Mapping)
+ ::UnmapViewOfFile(Mapping);
+}
+
+uint64_t mapped_file_region::size() const {
+ assert(Mapping && "Mapping failed but used anyway!");
+ return Size;
+}
+
+char *mapped_file_region::data() const {
+ assert(Mapping && "Mapping failed but used anyway!");
+ return reinterpret_cast<char*>(Mapping);
+}
+
+const char *mapped_file_region::const_data() const {
+ assert(Mapping && "Mapping failed but used anyway!");
+ return reinterpret_cast<const char*>(Mapping);
+}
+
+int mapped_file_region::alignment() {
+ SYSTEM_INFO SysInfo;
+ ::GetSystemInfo(&SysInfo);
+ return SysInfo.dwAllocationGranularity;
+}
+
+std::error_code detail::directory_iterator_construct(detail::DirIterState &it,
+ StringRef path){
+ SmallVector<wchar_t, 128> path_utf16;
+
+ if (std::error_code ec = widenPath(path, path_utf16))
+ return ec;
+
+ // Convert path to the format that Windows is happy with.
+ if (path_utf16.size() > 0 &&
+ !is_separator(path_utf16[path.size() - 1]) &&
+ path_utf16[path.size() - 1] != L':') {
+ path_utf16.push_back(L'\\');
+ path_utf16.push_back(L'*');
+ } else {
+ path_utf16.push_back(L'*');
+ }
+
+ // Get the first directory entry.
+ WIN32_FIND_DATAW FirstFind;
+ ScopedFindHandle FindHandle(::FindFirstFileW(c_str(path_utf16), &FirstFind));
+ if (!FindHandle)
+ return mapWindowsError(::GetLastError());
+
+ size_t FilenameLen = ::wcslen(FirstFind.cFileName);
+ while ((FilenameLen == 1 && FirstFind.cFileName[0] == L'.') ||
+ (FilenameLen == 2 && FirstFind.cFileName[0] == L'.' &&
+ FirstFind.cFileName[1] == L'.'))
+ if (!::FindNextFileW(FindHandle, &FirstFind)) {
+ DWORD LastError = ::GetLastError();
+ // Check for end.
+ if (LastError == ERROR_NO_MORE_FILES)
+ return detail::directory_iterator_destruct(it);
+ return mapWindowsError(LastError);
+ } else
+ FilenameLen = ::wcslen(FirstFind.cFileName);
+
+ // Construct the current directory entry.
+ SmallString<128> directory_entry_name_utf8;
+ if (std::error_code ec =
+ UTF16ToUTF8(FirstFind.cFileName, ::wcslen(FirstFind.cFileName),
+ directory_entry_name_utf8))
+ return ec;
+
+ it.IterationHandle = intptr_t(FindHandle.take());
+ SmallString<128> directory_entry_path(path);
+ path::append(directory_entry_path, directory_entry_name_utf8);
+ it.CurrentEntry = directory_entry(directory_entry_path);
+
+ return std::error_code();
+}
+
+std::error_code detail::directory_iterator_destruct(detail::DirIterState &it) {
+ if (it.IterationHandle != 0)
+ // Closes the handle if it's valid.
+ ScopedFindHandle close(HANDLE(it.IterationHandle));
+ it.IterationHandle = 0;
+ it.CurrentEntry = directory_entry();
+ return std::error_code();
+}
+
+std::error_code detail::directory_iterator_increment(detail::DirIterState &it) {
+ WIN32_FIND_DATAW FindData;
+ if (!::FindNextFileW(HANDLE(it.IterationHandle), &FindData)) {
+ DWORD LastError = ::GetLastError();
+ // Check for end.
+ if (LastError == ERROR_NO_MORE_FILES)
+ return detail::directory_iterator_destruct(it);
+ return mapWindowsError(LastError);
+ }
+
+ size_t FilenameLen = ::wcslen(FindData.cFileName);
+ if ((FilenameLen == 1 && FindData.cFileName[0] == L'.') ||
+ (FilenameLen == 2 && FindData.cFileName[0] == L'.' &&
+ FindData.cFileName[1] == L'.'))
+ return directory_iterator_increment(it);
+
+ SmallString<128> directory_entry_path_utf8;
+ if (std::error_code ec =
+ UTF16ToUTF8(FindData.cFileName, ::wcslen(FindData.cFileName),
+ directory_entry_path_utf8))
+ return ec;
+
+ it.CurrentEntry.replace_filename(Twine(directory_entry_path_utf8));
+ return std::error_code();
+}
+
+std::error_code openFileForRead(const Twine &Name, int &ResultFD) {
+ SmallVector<wchar_t, 128> PathUTF16;
+
+ if (std::error_code EC = widenPath(Name, PathUTF16))
+ return EC;
+
+ HANDLE H = ::CreateFileW(PathUTF16.begin(), GENERIC_READ,
+ FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
+ OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (H == INVALID_HANDLE_VALUE) {
+ DWORD LastError = ::GetLastError();
+ std::error_code EC = mapWindowsError(LastError);
+ // Provide a better error message when trying to open directories.
+ // This only runs if we failed to open the file, so there is probably
+ // no performances issues.
+ if (LastError != ERROR_ACCESS_DENIED)
+ return EC;
+ if (is_directory(Name))
+ return make_error_code(errc::is_a_directory);
+ return EC;
+ }
+
+ int FD = ::_open_osfhandle(intptr_t(H), 0);
+ if (FD == -1) {
+ ::CloseHandle(H);
+ return mapWindowsError(ERROR_INVALID_HANDLE);
+ }
+
+ ResultFD = FD;
+ return std::error_code();
+}
+
+std::error_code openFileForWrite(const Twine &Name, int &ResultFD,
+ sys::fs::OpenFlags Flags, unsigned Mode) {
+ // Verify that we don't have both "append" and "excl".
+ assert((!(Flags & sys::fs::F_Excl) || !(Flags & sys::fs::F_Append)) &&
+ "Cannot specify both 'excl' and 'append' file creation flags!");
+
+ SmallVector<wchar_t, 128> PathUTF16;
+
+ if (std::error_code EC = widenPath(Name, PathUTF16))
+ return EC;
+
+ DWORD CreationDisposition;
+ if (Flags & F_Excl)
+ CreationDisposition = CREATE_NEW;
+ else if (Flags & F_Append)
+ CreationDisposition = OPEN_ALWAYS;
+ else
+ CreationDisposition = CREATE_ALWAYS;
+
+ DWORD Access = GENERIC_WRITE;
+ if (Flags & F_RW)
+ Access |= GENERIC_READ;
+
+ HANDLE H = ::CreateFileW(PathUTF16.begin(), Access,
+ FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
+ CreationDisposition, FILE_ATTRIBUTE_NORMAL, NULL);
+
+ if (H == INVALID_HANDLE_VALUE) {
+ DWORD LastError = ::GetLastError();
+ std::error_code EC = mapWindowsError(LastError);
+ // Provide a better error message when trying to open directories.
+ // This only runs if we failed to open the file, so there is probably
+ // no performances issues.
+ if (LastError != ERROR_ACCESS_DENIED)
+ return EC;
+ if (is_directory(Name))
+ return make_error_code(errc::is_a_directory);
+ return EC;
+ }
+
+ int OpenFlags = 0;
+ if (Flags & F_Append)
+ OpenFlags |= _O_APPEND;
+
+ if (Flags & F_Text)
+ OpenFlags |= _O_TEXT;
+
+ int FD = ::_open_osfhandle(intptr_t(H), OpenFlags);
+ if (FD == -1) {
+ ::CloseHandle(H);
+ return mapWindowsError(ERROR_INVALID_HANDLE);
+ }
+
+ ResultFD = FD;
+ return std::error_code();
+}
+} // end namespace fs
+
+namespace path {
+
+bool home_directory(SmallVectorImpl<char> &result) {
+ wchar_t Path[MAX_PATH];
+ if (::SHGetFolderPathW(0, CSIDL_APPDATA | CSIDL_FLAG_CREATE, 0,
+ /*SHGFP_TYPE_CURRENT*/0, Path) != S_OK)
+ return false;
+
+ if (UTF16ToUTF8(Path, ::wcslen(Path), result))
+ return false;
+
+ return true;
+}
+
+static bool getTempDirEnvVar(const char *Var, SmallVectorImpl<char> &Res) {
+ SmallVector<wchar_t, 128> NameUTF16;
+ if (windows::UTF8ToUTF16(Var, NameUTF16))
+ return false;
+
+ SmallVector<wchar_t, 1024> Buf;
+ size_t Size = 1024;
+ do {
+ Buf.reserve(Size);
+ Size =
+ GetEnvironmentVariableW(NameUTF16.data(), Buf.data(), Buf.capacity());
+ if (Size == 0)
+ return false;
+
+ // Try again with larger buffer.
+ } while (Size > Buf.capacity());
+ Buf.set_size(Size);
+
+ if (windows::UTF16ToUTF8(Buf.data(), Size, Res))
+ return false;
+ return true;
+}
+
+static bool getTempDirEnvVar(SmallVectorImpl<char> &Res) {
+ const char *EnvironmentVariables[] = {"TMP", "TEMP", "USERPROFILE"};
+ for (const char *Env : EnvironmentVariables) {
+ if (getTempDirEnvVar(Env, Res))
+ return true;
+ }
+ return false;
+}
+
+void system_temp_directory(bool ErasedOnReboot, SmallVectorImpl<char> &Result) {
+ (void)ErasedOnReboot;
+ Result.clear();
+
+ // Check whether the temporary directory is specified by an environment
+ // variable.
+ if (getTempDirEnvVar(Result))
+ return;
+
+ // Fall back to a system default.
+ const char *DefaultResult = "C:\\TEMP";
+ Result.append(DefaultResult, DefaultResult + strlen(DefaultResult));
+}
+} // end namespace path
+
+namespace windows {
+std::error_code UTF8ToUTF16(llvm::StringRef utf8,
+ llvm::SmallVectorImpl<wchar_t> &utf16) {
+ if (!utf8.empty()) {
+ int len = ::MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, utf8.begin(),
+ utf8.size(), utf16.begin(), 0);
+
+ if (len == 0)
+ return mapWindowsError(::GetLastError());
+
+ utf16.reserve(len + 1);
+ utf16.set_size(len);
+
+ len = ::MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, utf8.begin(),
+ utf8.size(), utf16.begin(), utf16.size());
+
+ if (len == 0)
+ return mapWindowsError(::GetLastError());
+ }
+
+ // Make utf16 null terminated.
+ utf16.push_back(0);
+ utf16.pop_back();
+
+ return std::error_code();
+}
+
+static
+std::error_code UTF16ToCodePage(unsigned codepage, const wchar_t *utf16,
+ size_t utf16_len,
+ llvm::SmallVectorImpl<char> &utf8) {
+ if (utf16_len) {
+ // Get length.
+ int len = ::WideCharToMultiByte(codepage, 0, utf16, utf16_len, utf8.begin(),
+ 0, NULL, NULL);
+
+ if (len == 0)
+ return mapWindowsError(::GetLastError());
+
+ utf8.reserve(len);
+ utf8.set_size(len);
+
+ // Now do the actual conversion.
+ len = ::WideCharToMultiByte(codepage, 0, utf16, utf16_len, utf8.data(),
+ utf8.size(), NULL, NULL);
+
+ if (len == 0)
+ return mapWindowsError(::GetLastError());
+ }
+
+ // Make utf8 null terminated.
+ utf8.push_back(0);
+ utf8.pop_back();
+
+ return std::error_code();
+}
+
+std::error_code UTF16ToUTF8(const wchar_t *utf16, size_t utf16_len,
+ llvm::SmallVectorImpl<char> &utf8) {
+ return UTF16ToCodePage(CP_UTF8, utf16, utf16_len, utf8);
+}
+
+std::error_code UTF16ToCurCP(const wchar_t *utf16, size_t utf16_len,
+ llvm::SmallVectorImpl<char> &utf8) {
+ return UTF16ToCodePage(CP_ACP, utf16, utf16_len, utf8);
+}
+} // end namespace windows
+} // end namespace sys
+} // end namespace llvm
diff --git a/contrib/llvm/lib/Support/Windows/Process.inc b/contrib/llvm/lib/Support/Windows/Process.inc
new file mode 100644
index 000000000000..8164956d1511
--- /dev/null
+++ b/contrib/llvm/lib/Support/Windows/Process.inc
@@ -0,0 +1,432 @@
+//===- Win32/Process.cpp - Win32 Process Implementation ------- -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides the Win32 specific implementation of the Process class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/WindowsError.h"
+#include <malloc.h>
+
+// The Windows.h header must be after LLVM and standard headers.
+#include "WindowsSupport.h"
+
+#include <direct.h>
+#include <io.h>
+#include <psapi.h>
+#include <shellapi.h>
+
+#ifdef __MINGW32__
+ #if (HAVE_LIBPSAPI != 1)
+ #error "libpsapi.a should be present"
+ #endif
+ #if (HAVE_LIBSHELL32 != 1)
+ #error "libshell32.a should be present"
+ #endif
+#else
+ #pragma comment(lib, "psapi.lib")
+ #pragma comment(lib, "shell32.lib")
+#endif
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only Win32 specific code
+//=== and must not be UNIX code
+//===----------------------------------------------------------------------===//
+
+#ifdef __MINGW32__
+// This ban should be lifted when MinGW 1.0+ has defined this value.
+# define _HEAPOK (-2)
+#endif
+
+using namespace llvm;
+using namespace sys;
+
+static TimeValue getTimeValueFromFILETIME(FILETIME Time) {
+ ULARGE_INTEGER TimeInteger;
+ TimeInteger.LowPart = Time.dwLowDateTime;
+ TimeInteger.HighPart = Time.dwHighDateTime;
+
+ // FILETIME's are # of 100 nanosecond ticks (1/10th of a microsecond)
+ return TimeValue(
+ static_cast<TimeValue::SecondsType>(TimeInteger.QuadPart / 10000000),
+ static_cast<TimeValue::NanoSecondsType>(
+ (TimeInteger.QuadPart % 10000000) * 100));
+}
+
+// This function retrieves the page size using GetNativeSystemInfo() and is
+// present solely so it can be called once to initialize the self_process member
+// below.
+static unsigned computePageSize() {
+ // GetNativeSystemInfo() provides the physical page size which may differ
+ // from GetSystemInfo() in 32-bit applications running under WOW64.
+ SYSTEM_INFO info;
+ GetNativeSystemInfo(&info);
+ // FIXME: FileOffset in MapViewOfFile() should be aligned to not dwPageSize,
+ // but dwAllocationGranularity.
+ return static_cast<unsigned>(info.dwPageSize);
+}
+
+unsigned Process::getPageSize() {
+ static unsigned Ret = computePageSize();
+ return Ret;
+}
+
+size_t
+Process::GetMallocUsage()
+{
+ _HEAPINFO hinfo;
+ hinfo._pentry = NULL;
+
+ size_t size = 0;
+
+ while (_heapwalk(&hinfo) == _HEAPOK)
+ size += hinfo._size;
+
+ return size;
+}
+
+void Process::GetTimeUsage(TimeValue &elapsed, TimeValue &user_time,
+ TimeValue &sys_time) {
+ elapsed = TimeValue::now();
+
+ FILETIME ProcCreate, ProcExit, KernelTime, UserTime;
+ if (GetProcessTimes(GetCurrentProcess(), &ProcCreate, &ProcExit, &KernelTime,
+ &UserTime) == 0)
+ return;
+
+ user_time = getTimeValueFromFILETIME(UserTime);
+ sys_time = getTimeValueFromFILETIME(KernelTime);
+}
+
+// Some LLVM programs such as bugpoint produce core files as a normal part of
+// their operation. To prevent the disk from filling up, this configuration
+// item does what's necessary to prevent their generation.
+void Process::PreventCoreFiles() {
+ // Windows does have the concept of core files, called minidumps. However,
+ // disabling minidumps for a particular application extends past the lifetime
+ // of that application, which is the incorrect behavior for this API.
+ // Additionally, the APIs require elevated privileges to disable and re-
+ // enable minidumps, which makes this untenable. For more information, see
+ // WerAddExcludedApplication and WerRemoveExcludedApplication (Vista and
+ // later).
+ //
+ // Windows also has modal pop-up message boxes. As this method is used by
+ // bugpoint, preventing these pop-ups is additionally important.
+ SetErrorMode(SEM_FAILCRITICALERRORS |
+ SEM_NOGPFAULTERRORBOX |
+ SEM_NOOPENFILEERRORBOX);
+}
+
+/// Returns the environment variable \arg Name's value as a string encoded in
+/// UTF-8. \arg Name is assumed to be in UTF-8 encoding.
+Optional<std::string> Process::GetEnv(StringRef Name) {
+ // Convert the argument to UTF-16 to pass it to _wgetenv().
+ SmallVector<wchar_t, 128> NameUTF16;
+ if (windows::UTF8ToUTF16(Name, NameUTF16))
+ return None;
+
+ // Environment variable can be encoded in non-UTF8 encoding, and there's no
+ // way to know what the encoding is. The only reliable way to look up
+ // multibyte environment variable is to use GetEnvironmentVariableW().
+ SmallVector<wchar_t, MAX_PATH> Buf;
+ size_t Size = MAX_PATH;
+ do {
+ Buf.reserve(Size);
+ Size =
+ GetEnvironmentVariableW(NameUTF16.data(), Buf.data(), Buf.capacity());
+ if (Size == 0)
+ return None;
+
+ // Try again with larger buffer.
+ } while (Size > Buf.capacity());
+ Buf.set_size(Size);
+
+ // Convert the result from UTF-16 to UTF-8.
+ SmallVector<char, MAX_PATH> Res;
+ if (windows::UTF16ToUTF8(Buf.data(), Size, Res))
+ return None;
+ return std::string(Res.data());
+}
+
+static void AllocateAndPush(const SmallVectorImpl<char> &S,
+ SmallVectorImpl<const char *> &Vector,
+ SpecificBumpPtrAllocator<char> &Allocator) {
+ char *Buffer = Allocator.Allocate(S.size() + 1);
+ ::memcpy(Buffer, S.data(), S.size());
+ Buffer[S.size()] = '\0';
+ Vector.push_back(Buffer);
+}
+
+/// Convert Arg from UTF-16 to UTF-8 and push it onto Args.
+static std::error_code
+ConvertAndPushArg(const wchar_t *Arg, SmallVectorImpl<const char *> &Args,
+ SpecificBumpPtrAllocator<char> &Allocator) {
+ SmallVector<char, MAX_PATH> ArgString;
+ if (std::error_code ec = windows::UTF16ToUTF8(Arg, wcslen(Arg), ArgString))
+ return ec;
+ AllocateAndPush(ArgString, Args, Allocator);
+ return std::error_code();
+}
+
+/// \brief Perform wildcard expansion of Arg, or just push it into Args if it
+/// doesn't have wildcards or doesn't match any files.
+static std::error_code
+WildcardExpand(const wchar_t *Arg, SmallVectorImpl<const char *> &Args,
+ SpecificBumpPtrAllocator<char> &Allocator) {
+ if (!wcspbrk(Arg, L"*?")) {
+ // Arg does not contain any wildcard characters. This is the common case.
+ return ConvertAndPushArg(Arg, Args, Allocator);
+ }
+
+ if (wcscmp(Arg, L"/?") == 0 || wcscmp(Arg, L"-?") == 0) {
+ // Don't wildcard expand /?. Always treat it as an option.
+ return ConvertAndPushArg(Arg, Args, Allocator);
+ }
+
+ // Extract any directory part of the argument.
+ SmallVector<char, MAX_PATH> Dir;
+ if (std::error_code ec = windows::UTF16ToUTF8(Arg, wcslen(Arg), Dir))
+ return ec;
+ sys::path::remove_filename(Dir);
+ const int DirSize = Dir.size();
+
+ // Search for matching files.
+ WIN32_FIND_DATAW FileData;
+ HANDLE FindHandle = FindFirstFileW(Arg, &FileData);
+ if (FindHandle == INVALID_HANDLE_VALUE) {
+ return ConvertAndPushArg(Arg, Args, Allocator);
+ }
+
+ std::error_code ec;
+ do {
+ SmallVector<char, MAX_PATH> FileName;
+ ec = windows::UTF16ToUTF8(FileData.cFileName, wcslen(FileData.cFileName),
+ FileName);
+ if (ec)
+ break;
+
+ // Push the filename onto Dir, and remove it afterwards.
+ llvm::sys::path::append(Dir, StringRef(FileName.data(), FileName.size()));
+ AllocateAndPush(Dir, Args, Allocator);
+ Dir.resize(DirSize);
+ } while (FindNextFileW(FindHandle, &FileData));
+
+ FindClose(FindHandle);
+ return ec;
+}
+
+std::error_code
+Process::GetArgumentVector(SmallVectorImpl<const char *> &Args,
+ ArrayRef<const char *>,
+ SpecificBumpPtrAllocator<char> &ArgAllocator) {
+ int ArgCount;
+ wchar_t **UnicodeCommandLine =
+ CommandLineToArgvW(GetCommandLineW(), &ArgCount);
+ if (!UnicodeCommandLine)
+ return mapWindowsError(::GetLastError());
+
+ Args.reserve(ArgCount);
+ std::error_code ec;
+
+ for (int i = 0; i < ArgCount; ++i) {
+ ec = WildcardExpand(UnicodeCommandLine[i], Args, ArgAllocator);
+ if (ec)
+ break;
+ }
+
+ LocalFree(UnicodeCommandLine);
+ return ec;
+}
+
+std::error_code Process::FixupStandardFileDescriptors() {
+ return std::error_code();
+}
+
+std::error_code Process::SafelyCloseFileDescriptor(int FD) {
+ if (::close(FD) < 0)
+ return std::error_code(errno, std::generic_category());
+ return std::error_code();
+}
+
+bool Process::StandardInIsUserInput() {
+ return FileDescriptorIsDisplayed(0);
+}
+
+bool Process::StandardOutIsDisplayed() {
+ return FileDescriptorIsDisplayed(1);
+}
+
+bool Process::StandardErrIsDisplayed() {
+ return FileDescriptorIsDisplayed(2);
+}
+
+bool Process::FileDescriptorIsDisplayed(int fd) {
+ DWORD Mode; // Unused
+ return (GetConsoleMode((HANDLE)_get_osfhandle(fd), &Mode) != 0);
+}
+
+unsigned Process::StandardOutColumns() {
+ unsigned Columns = 0;
+ CONSOLE_SCREEN_BUFFER_INFO csbi;
+ if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi))
+ Columns = csbi.dwSize.X;
+ return Columns;
+}
+
+unsigned Process::StandardErrColumns() {
+ unsigned Columns = 0;
+ CONSOLE_SCREEN_BUFFER_INFO csbi;
+ if (GetConsoleScreenBufferInfo(GetStdHandle(STD_ERROR_HANDLE), &csbi))
+ Columns = csbi.dwSize.X;
+ return Columns;
+}
+
+// The terminal always has colors.
+bool Process::FileDescriptorHasColors(int fd) {
+ return FileDescriptorIsDisplayed(fd);
+}
+
+bool Process::StandardOutHasColors() {
+ return FileDescriptorHasColors(1);
+}
+
+bool Process::StandardErrHasColors() {
+ return FileDescriptorHasColors(2);
+}
+
+static bool UseANSI = false;
+void Process::UseANSIEscapeCodes(bool enable) {
+ UseANSI = enable;
+}
+
+namespace {
+class DefaultColors
+{
+ private:
+ WORD defaultColor;
+ public:
+ DefaultColors()
+ :defaultColor(GetCurrentColor()) {}
+ static unsigned GetCurrentColor() {
+ CONSOLE_SCREEN_BUFFER_INFO csbi;
+ if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi))
+ return csbi.wAttributes;
+ return 0;
+ }
+ WORD operator()() const { return defaultColor; }
+};
+
+DefaultColors defaultColors;
+
+WORD fg_color(WORD color) {
+ return color & (FOREGROUND_BLUE | FOREGROUND_GREEN |
+ FOREGROUND_INTENSITY | FOREGROUND_RED);
+}
+
+WORD bg_color(WORD color) {
+ return color & (BACKGROUND_BLUE | BACKGROUND_GREEN |
+ BACKGROUND_INTENSITY | BACKGROUND_RED);
+}
+}
+
+bool Process::ColorNeedsFlush() {
+ return !UseANSI;
+}
+
+const char *Process::OutputBold(bool bg) {
+ if (UseANSI) return "\033[1m";
+
+ WORD colors = DefaultColors::GetCurrentColor();
+ if (bg)
+ colors |= BACKGROUND_INTENSITY;
+ else
+ colors |= FOREGROUND_INTENSITY;
+ SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), colors);
+ return 0;
+}
+
+const char *Process::OutputColor(char code, bool bold, bool bg) {
+ if (UseANSI) return colorcodes[bg?1:0][bold?1:0][code&7];
+
+ WORD current = DefaultColors::GetCurrentColor();
+ WORD colors;
+ if (bg) {
+ colors = ((code&1) ? BACKGROUND_RED : 0) |
+ ((code&2) ? BACKGROUND_GREEN : 0 ) |
+ ((code&4) ? BACKGROUND_BLUE : 0);
+ if (bold)
+ colors |= BACKGROUND_INTENSITY;
+ colors |= fg_color(current);
+ } else {
+ colors = ((code&1) ? FOREGROUND_RED : 0) |
+ ((code&2) ? FOREGROUND_GREEN : 0 ) |
+ ((code&4) ? FOREGROUND_BLUE : 0);
+ if (bold)
+ colors |= FOREGROUND_INTENSITY;
+ colors |= bg_color(current);
+ }
+ SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), colors);
+ return 0;
+}
+
+static WORD GetConsoleTextAttribute(HANDLE hConsoleOutput) {
+ CONSOLE_SCREEN_BUFFER_INFO info;
+ GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &info);
+ return info.wAttributes;
+}
+
+const char *Process::OutputReverse() {
+ if (UseANSI) return "\033[7m";
+
+ const WORD attributes
+ = GetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE));
+
+ const WORD foreground_mask = FOREGROUND_BLUE | FOREGROUND_GREEN |
+ FOREGROUND_RED | FOREGROUND_INTENSITY;
+ const WORD background_mask = BACKGROUND_BLUE | BACKGROUND_GREEN |
+ BACKGROUND_RED | BACKGROUND_INTENSITY;
+ const WORD color_mask = foreground_mask | background_mask;
+
+ WORD new_attributes =
+ ((attributes & FOREGROUND_BLUE )?BACKGROUND_BLUE :0) |
+ ((attributes & FOREGROUND_GREEN )?BACKGROUND_GREEN :0) |
+ ((attributes & FOREGROUND_RED )?BACKGROUND_RED :0) |
+ ((attributes & FOREGROUND_INTENSITY)?BACKGROUND_INTENSITY:0) |
+ ((attributes & BACKGROUND_BLUE )?FOREGROUND_BLUE :0) |
+ ((attributes & BACKGROUND_GREEN )?FOREGROUND_GREEN :0) |
+ ((attributes & BACKGROUND_RED )?FOREGROUND_RED :0) |
+ ((attributes & BACKGROUND_INTENSITY)?FOREGROUND_INTENSITY:0) |
+ 0;
+ new_attributes = (attributes & ~color_mask) | (new_attributes & color_mask);
+
+ SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), new_attributes);
+ return 0;
+}
+
+const char *Process::ResetColor() {
+ if (UseANSI) return "\033[0m";
+ SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), defaultColors());
+ return 0;
+}
+
+unsigned Process::GetRandomNumber() {
+ HCRYPTPROV HCPC;
+ if (!::CryptAcquireContextW(&HCPC, NULL, NULL, PROV_RSA_FULL,
+ CRYPT_VERIFYCONTEXT))
+ report_fatal_error("Could not acquire a cryptographic context");
+
+ ScopedCryptContext CryptoProvider(HCPC);
+ unsigned Ret;
+ if (!::CryptGenRandom(CryptoProvider, sizeof(Ret),
+ reinterpret_cast<BYTE *>(&Ret)))
+ report_fatal_error("Could not generate a random number");
+ return Ret;
+}
diff --git a/contrib/llvm/lib/Support/Windows/Program.inc b/contrib/llvm/lib/Support/Windows/Program.inc
new file mode 100644
index 000000000000..c29d8729b1de
--- /dev/null
+++ b/contrib/llvm/lib/Support/Windows/Program.inc
@@ -0,0 +1,538 @@
+//===- Win32/Program.cpp - Win32 Program Implementation ------- -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides the Win32 specific implementation of the Program class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "WindowsSupport.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/ConvertUTF.h"
+#include "llvm/Support/Errc.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/WindowsError.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cstdio>
+#include <fcntl.h>
+#include <io.h>
+#include <malloc.h>
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only Win32 specific code
+//=== and must not be UNIX code
+//===----------------------------------------------------------------------===//
+
+namespace llvm {
+using namespace sys;
+
+ProcessInfo::ProcessInfo() : ProcessHandle(0), Pid(0), ReturnCode(0) {}
+
+ErrorOr<std::string> sys::findProgramByName(StringRef Name,
+ ArrayRef<StringRef> Paths) {
+ assert(!Name.empty() && "Must have a name!");
+
+ if (Name.find_first_of("/\\") != StringRef::npos)
+ return std::string(Name);
+
+ const wchar_t *Path = nullptr;
+ std::wstring PathStorage;
+ if (!Paths.empty()) {
+ PathStorage.reserve(Paths.size() * MAX_PATH);
+ for (unsigned i = 0; i < Paths.size(); ++i) {
+ if (i)
+ PathStorage.push_back(L';');
+ StringRef P = Paths[i];
+ SmallVector<wchar_t, MAX_PATH> TmpPath;
+ if (std::error_code EC = windows::UTF8ToUTF16(P, TmpPath))
+ return EC;
+ PathStorage.append(TmpPath.begin(), TmpPath.end());
+ }
+ Path = PathStorage.c_str();
+ }
+
+ SmallVector<wchar_t, MAX_PATH> U16Name;
+ if (std::error_code EC = windows::UTF8ToUTF16(Name, U16Name))
+ return EC;
+
+ SmallVector<StringRef, 12> PathExts;
+ PathExts.push_back("");
+ PathExts.push_back(".exe"); // FIXME: This must be in %PATHEXT%.
+ if (const char *PathExtEnv = std::getenv("PATHEXT"))
+ SplitString(PathExtEnv, PathExts, ";");
+
+ SmallVector<wchar_t, MAX_PATH> U16Result;
+ DWORD Len = MAX_PATH;
+ for (StringRef Ext : PathExts) {
+ SmallVector<wchar_t, MAX_PATH> U16Ext;
+ if (std::error_code EC = windows::UTF8ToUTF16(Ext, U16Ext))
+ return EC;
+
+ do {
+ U16Result.reserve(Len);
+ Len = ::SearchPathW(Path, c_str(U16Name),
+ U16Ext.empty() ? nullptr : c_str(U16Ext),
+ U16Result.capacity(), U16Result.data(), nullptr);
+ } while (Len > U16Result.capacity());
+
+ if (Len != 0)
+ break; // Found it.
+ }
+
+ if (Len == 0)
+ return mapWindowsError(::GetLastError());
+
+ U16Result.set_size(Len);
+
+ SmallVector<char, MAX_PATH> U8Result;
+ if (std::error_code EC =
+ windows::UTF16ToUTF8(U16Result.data(), U16Result.size(), U8Result))
+ return EC;
+
+ return std::string(U8Result.begin(), U8Result.end());
+}
+
+static HANDLE RedirectIO(const StringRef *path, int fd, std::string* ErrMsg) {
+ HANDLE h;
+ if (path == 0) {
+ if (!DuplicateHandle(GetCurrentProcess(), (HANDLE)_get_osfhandle(fd),
+ GetCurrentProcess(), &h,
+ 0, TRUE, DUPLICATE_SAME_ACCESS))
+ return INVALID_HANDLE_VALUE;
+ return h;
+ }
+
+ std::string fname;
+ if (path->empty())
+ fname = "NUL";
+ else
+ fname = *path;
+
+ SECURITY_ATTRIBUTES sa;
+ sa.nLength = sizeof(sa);
+ sa.lpSecurityDescriptor = 0;
+ sa.bInheritHandle = TRUE;
+
+ SmallVector<wchar_t, 128> fnameUnicode;
+ if (path->empty()) {
+ // Don't play long-path tricks on "NUL".
+ if (windows::UTF8ToUTF16(fname, fnameUnicode))
+ return INVALID_HANDLE_VALUE;
+ } else {
+ if (path::widenPath(fname, fnameUnicode))
+ return INVALID_HANDLE_VALUE;
+ }
+ h = CreateFileW(fnameUnicode.data(), fd ? GENERIC_WRITE : GENERIC_READ,
+ FILE_SHARE_READ, &sa, fd == 0 ? OPEN_EXISTING : CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL, NULL);
+ if (h == INVALID_HANDLE_VALUE) {
+ MakeErrMsg(ErrMsg, fname + ": Can't open file for " +
+ (fd ? "input: " : "output: "));
+ }
+
+ return h;
+}
+
+/// ArgNeedsQuotes - Check whether argument needs to be quoted when calling
+/// CreateProcess.
+static bool ArgNeedsQuotes(const char *Str) {
+ return Str[0] == '\0' || strpbrk(Str, "\t \"&\'()*<>\\`^|") != 0;
+}
+
+/// CountPrecedingBackslashes - Returns the number of backslashes preceding Cur
+/// in the C string Start.
+static unsigned int CountPrecedingBackslashes(const char *Start,
+ const char *Cur) {
+ unsigned int Count = 0;
+ --Cur;
+ while (Cur >= Start && *Cur == '\\') {
+ ++Count;
+ --Cur;
+ }
+ return Count;
+}
+
+/// EscapePrecedingEscapes - Append a backslash to Dst for every backslash
+/// preceding Cur in the Start string. Assumes Dst has enough space.
+static char *EscapePrecedingEscapes(char *Dst, const char *Start,
+ const char *Cur) {
+ unsigned PrecedingEscapes = CountPrecedingBackslashes(Start, Cur);
+ while (PrecedingEscapes > 0) {
+ *Dst++ = '\\';
+ --PrecedingEscapes;
+ }
+ return Dst;
+}
+
+/// ArgLenWithQuotes - Check whether argument needs to be quoted when calling
+/// CreateProcess and returns length of quoted arg with escaped quotes
+static unsigned int ArgLenWithQuotes(const char *Str) {
+ const char *Start = Str;
+ bool Quoted = ArgNeedsQuotes(Str);
+ unsigned int len = Quoted ? 2 : 0;
+
+ while (*Str != '\0') {
+ if (*Str == '\"') {
+ // We need to add a backslash, but ensure that it isn't escaped.
+ unsigned PrecedingEscapes = CountPrecedingBackslashes(Start, Str);
+ len += PrecedingEscapes + 1;
+ }
+ // Note that we *don't* need to escape runs of backslashes that don't
+ // precede a double quote! See MSDN:
+ // http://msdn.microsoft.com/en-us/library/17w5ykft%28v=vs.85%29.aspx
+
+ ++len;
+ ++Str;
+ }
+
+ if (Quoted) {
+ // Make sure the closing quote doesn't get escaped by a trailing backslash.
+ unsigned PrecedingEscapes = CountPrecedingBackslashes(Start, Str);
+ len += PrecedingEscapes + 1;
+ }
+
+ return len;
+}
+
+}
+
+static std::unique_ptr<char[]> flattenArgs(const char **args) {
+ // First, determine the length of the command line.
+ unsigned len = 0;
+ for (unsigned i = 0; args[i]; i++) {
+ len += ArgLenWithQuotes(args[i]) + 1;
+ }
+
+ // Now build the command line.
+ std::unique_ptr<char[]> command(new char[len+1]);
+ char *p = command.get();
+
+ for (unsigned i = 0; args[i]; i++) {
+ const char *arg = args[i];
+ const char *start = arg;
+
+ bool needsQuoting = ArgNeedsQuotes(arg);
+ if (needsQuoting)
+ *p++ = '"';
+
+ while (*arg != '\0') {
+ if (*arg == '\"') {
+ // Escape all preceding escapes (if any), and then escape the quote.
+ p = EscapePrecedingEscapes(p, start, arg);
+ *p++ = '\\';
+ }
+
+ *p++ = *arg++;
+ }
+
+ if (needsQuoting) {
+ // Make sure our quote doesn't get escaped by a trailing backslash.
+ p = EscapePrecedingEscapes(p, start, arg);
+ *p++ = '"';
+ }
+ *p++ = ' ';
+ }
+
+ *p = 0;
+ return command;
+}
+
+static bool Execute(ProcessInfo &PI, StringRef Program, const char **args,
+ const char **envp, const StringRef **redirects,
+ unsigned memoryLimit, std::string *ErrMsg) {
+ if (!sys::fs::can_execute(Program)) {
+ if (ErrMsg)
+ *ErrMsg = "program not executable";
+ return false;
+ }
+
+ // Windows wants a command line, not an array of args, to pass to the new
+ // process. We have to concatenate them all, while quoting the args that
+ // have embedded spaces (or are empty).
+ std::unique_ptr<char[]> command = flattenArgs(args);
+
+ // The pointer to the environment block for the new process.
+ std::vector<wchar_t> EnvBlock;
+
+ if (envp) {
+ // An environment block consists of a null-terminated block of
+ // null-terminated strings. Convert the array of environment variables to
+ // an environment block by concatenating them.
+ for (unsigned i = 0; envp[i]; ++i) {
+ SmallVector<wchar_t, MAX_PATH> EnvString;
+ if (std::error_code ec = windows::UTF8ToUTF16(envp[i], EnvString)) {
+ SetLastError(ec.value());
+ MakeErrMsg(ErrMsg, "Unable to convert environment variable to UTF-16");
+ return false;
+ }
+
+ EnvBlock.insert(EnvBlock.end(), EnvString.begin(), EnvString.end());
+ EnvBlock.push_back(0);
+ }
+ EnvBlock.push_back(0);
+ }
+
+ // Create a child process.
+ STARTUPINFOW si;
+ memset(&si, 0, sizeof(si));
+ si.cb = sizeof(si);
+ si.hStdInput = INVALID_HANDLE_VALUE;
+ si.hStdOutput = INVALID_HANDLE_VALUE;
+ si.hStdError = INVALID_HANDLE_VALUE;
+
+ if (redirects) {
+ si.dwFlags = STARTF_USESTDHANDLES;
+
+ si.hStdInput = RedirectIO(redirects[0], 0, ErrMsg);
+ if (si.hStdInput == INVALID_HANDLE_VALUE) {
+ MakeErrMsg(ErrMsg, "can't redirect stdin");
+ return false;
+ }
+ si.hStdOutput = RedirectIO(redirects[1], 1, ErrMsg);
+ if (si.hStdOutput == INVALID_HANDLE_VALUE) {
+ CloseHandle(si.hStdInput);
+ MakeErrMsg(ErrMsg, "can't redirect stdout");
+ return false;
+ }
+ if (redirects[1] && redirects[2] && *(redirects[1]) == *(redirects[2])) {
+ // If stdout and stderr should go to the same place, redirect stderr
+ // to the handle already open for stdout.
+ if (!DuplicateHandle(GetCurrentProcess(), si.hStdOutput,
+ GetCurrentProcess(), &si.hStdError,
+ 0, TRUE, DUPLICATE_SAME_ACCESS)) {
+ CloseHandle(si.hStdInput);
+ CloseHandle(si.hStdOutput);
+ MakeErrMsg(ErrMsg, "can't dup stderr to stdout");
+ return false;
+ }
+ } else {
+ // Just redirect stderr
+ si.hStdError = RedirectIO(redirects[2], 2, ErrMsg);
+ if (si.hStdError == INVALID_HANDLE_VALUE) {
+ CloseHandle(si.hStdInput);
+ CloseHandle(si.hStdOutput);
+ MakeErrMsg(ErrMsg, "can't redirect stderr");
+ return false;
+ }
+ }
+ }
+
+ PROCESS_INFORMATION pi;
+ memset(&pi, 0, sizeof(pi));
+
+ fflush(stdout);
+ fflush(stderr);
+
+ SmallVector<wchar_t, MAX_PATH> ProgramUtf16;
+ if (std::error_code ec = path::widenPath(Program, ProgramUtf16)) {
+ SetLastError(ec.value());
+ MakeErrMsg(ErrMsg,
+ std::string("Unable to convert application name to UTF-16"));
+ return false;
+ }
+
+ SmallVector<wchar_t, MAX_PATH> CommandUtf16;
+ if (std::error_code ec = windows::UTF8ToUTF16(command.get(), CommandUtf16)) {
+ SetLastError(ec.value());
+ MakeErrMsg(ErrMsg,
+ std::string("Unable to convert command-line to UTF-16"));
+ return false;
+ }
+
+ BOOL rc = CreateProcessW(ProgramUtf16.data(), CommandUtf16.data(), 0, 0,
+ TRUE, CREATE_UNICODE_ENVIRONMENT,
+ EnvBlock.empty() ? 0 : EnvBlock.data(), 0, &si,
+ &pi);
+ DWORD err = GetLastError();
+
+ // Regardless of whether the process got created or not, we are done with
+ // the handles we created for it to inherit.
+ CloseHandle(si.hStdInput);
+ CloseHandle(si.hStdOutput);
+ CloseHandle(si.hStdError);
+
+ // Now return an error if the process didn't get created.
+ if (!rc) {
+ SetLastError(err);
+ MakeErrMsg(ErrMsg, std::string("Couldn't execute program '") +
+ Program.str() + "'");
+ return false;
+ }
+
+ PI.Pid = pi.dwProcessId;
+ PI.ProcessHandle = pi.hProcess;
+
+ // Make sure these get closed no matter what.
+ ScopedCommonHandle hThread(pi.hThread);
+
+ // Assign the process to a job if a memory limit is defined.
+ ScopedJobHandle hJob;
+ if (memoryLimit != 0) {
+ hJob = CreateJobObjectW(0, 0);
+ bool success = false;
+ if (hJob) {
+ JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli;
+ memset(&jeli, 0, sizeof(jeli));
+ jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_PROCESS_MEMORY;
+ jeli.ProcessMemoryLimit = uintptr_t(memoryLimit) * 1048576;
+ if (SetInformationJobObject(hJob, JobObjectExtendedLimitInformation,
+ &jeli, sizeof(jeli))) {
+ if (AssignProcessToJobObject(hJob, pi.hProcess))
+ success = true;
+ }
+ }
+ if (!success) {
+ SetLastError(GetLastError());
+ MakeErrMsg(ErrMsg, std::string("Unable to set memory limit"));
+ TerminateProcess(pi.hProcess, 1);
+ WaitForSingleObject(pi.hProcess, INFINITE);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+namespace llvm {
+ProcessInfo sys::Wait(const ProcessInfo &PI, unsigned SecondsToWait,
+ bool WaitUntilChildTerminates, std::string *ErrMsg) {
+ assert(PI.Pid && "invalid pid to wait on, process not started?");
+ assert(PI.ProcessHandle &&
+ "invalid process handle to wait on, process not started?");
+ DWORD milliSecondsToWait = 0;
+ if (WaitUntilChildTerminates)
+ milliSecondsToWait = INFINITE;
+ else if (SecondsToWait > 0)
+ milliSecondsToWait = SecondsToWait * 1000;
+
+ ProcessInfo WaitResult = PI;
+ DWORD WaitStatus = WaitForSingleObject(PI.ProcessHandle, milliSecondsToWait);
+ if (WaitStatus == WAIT_TIMEOUT) {
+ if (SecondsToWait) {
+ if (!TerminateProcess(PI.ProcessHandle, 1)) {
+ if (ErrMsg)
+ MakeErrMsg(ErrMsg, "Failed to terminate timed-out program.");
+
+ // -2 indicates a crash or timeout as opposed to failure to execute.
+ WaitResult.ReturnCode = -2;
+ CloseHandle(PI.ProcessHandle);
+ return WaitResult;
+ }
+ WaitForSingleObject(PI.ProcessHandle, INFINITE);
+ CloseHandle(PI.ProcessHandle);
+ } else {
+ // Non-blocking wait.
+ return ProcessInfo();
+ }
+ }
+
+ // Get its exit status.
+ DWORD status;
+ BOOL rc = GetExitCodeProcess(PI.ProcessHandle, &status);
+ DWORD err = GetLastError();
+ if (err != ERROR_INVALID_HANDLE)
+ CloseHandle(PI.ProcessHandle);
+
+ if (!rc) {
+ SetLastError(err);
+ if (ErrMsg)
+ MakeErrMsg(ErrMsg, "Failed getting status for program.");
+
+ // -2 indicates a crash or timeout as opposed to failure to execute.
+ WaitResult.ReturnCode = -2;
+ return WaitResult;
+ }
+
+ if (!status)
+ return WaitResult;
+
+ // Pass 10(Warning) and 11(Error) to the callee as negative value.
+ if ((status & 0xBFFF0000U) == 0x80000000U)
+ WaitResult.ReturnCode = static_cast<int>(status);
+ else if (status & 0xFF)
+ WaitResult.ReturnCode = status & 0x7FFFFFFF;
+ else
+ WaitResult.ReturnCode = 1;
+
+ return WaitResult;
+}
+
+std::error_code sys::ChangeStdinToBinary() {
+ int result = _setmode(_fileno(stdin), _O_BINARY);
+ if (result == -1)
+ return std::error_code(errno, std::generic_category());
+ return std::error_code();
+}
+
+std::error_code sys::ChangeStdoutToBinary() {
+ int result = _setmode(_fileno(stdout), _O_BINARY);
+ if (result == -1)
+ return std::error_code(errno, std::generic_category());
+ return std::error_code();
+}
+
+std::error_code
+llvm::sys::writeFileWithEncoding(StringRef FileName, StringRef Contents,
+ WindowsEncodingMethod Encoding) {
+ std::error_code EC;
+ llvm::raw_fd_ostream OS(FileName, EC, llvm::sys::fs::OpenFlags::F_Text);
+ if (EC)
+ return EC;
+
+ if (Encoding == WEM_UTF8) {
+ OS << Contents;
+ } else if (Encoding == WEM_CurrentCodePage) {
+ SmallVector<wchar_t, 1> ArgsUTF16;
+ SmallVector<char, 1> ArgsCurCP;
+
+ if ((EC = windows::UTF8ToUTF16(Contents, ArgsUTF16)))
+ return EC;
+
+ if ((EC = windows::UTF16ToCurCP(
+ ArgsUTF16.data(), ArgsUTF16.size(), ArgsCurCP)))
+ return EC;
+
+ OS.write(ArgsCurCP.data(), ArgsCurCP.size());
+ } else if (Encoding == WEM_UTF16) {
+ SmallVector<wchar_t, 1> ArgsUTF16;
+
+ if ((EC = windows::UTF8ToUTF16(Contents, ArgsUTF16)))
+ return EC;
+
+ // Endianness guessing
+ char BOM[2];
+ uint16_t src = UNI_UTF16_BYTE_ORDER_MARK_NATIVE;
+ memcpy(BOM, &src, 2);
+ OS.write(BOM, 2);
+ OS.write((char *)ArgsUTF16.data(), ArgsUTF16.size() << 1);
+ } else {
+ llvm_unreachable("Unknown encoding");
+ }
+
+ if (OS.has_error())
+ return make_error_code(errc::io_error);
+
+ return EC;
+}
+
+bool llvm::sys::argumentsFitWithinSystemLimits(ArrayRef<const char*> Args) {
+ // The documented max length of the command line passed to CreateProcess.
+ static const size_t MaxCommandStringLength = 32768;
+ size_t ArgLength = 0;
+ for (ArrayRef<const char*>::iterator I = Args.begin(), E = Args.end();
+ I != E; ++I) {
+ // Account for the trailing space for every arg but the last one and the
+ // trailing NULL of the last argument.
+ ArgLength += ArgLenWithQuotes(*I) + 1;
+ if (ArgLength > MaxCommandStringLength) {
+ return false;
+ }
+ }
+ return true;
+}
+}
diff --git a/contrib/llvm/lib/Support/Windows/RWMutex.inc b/contrib/llvm/lib/Support/Windows/RWMutex.inc
new file mode 100644
index 000000000000..2d1d25f67b8a
--- /dev/null
+++ b/contrib/llvm/lib/Support/Windows/RWMutex.inc
@@ -0,0 +1,130 @@
+//= llvm/Support/Win32/Mutex.inc - Win32 Reader/Writer Mutual Exclusion Lock =//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the Win32 specific (non-pthread) RWMutex class.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only generic Win32 code that
+//=== is guaranteed to work on *all* Win32 variants.
+//===----------------------------------------------------------------------===//
+
+#include "WindowsSupport.h"
+
+namespace llvm {
+using namespace sys;
+
+// Windows has slim read-writer lock support on Vista and higher, so we
+// will attempt to load the APIs. If they exist, we will use them, and
+// if not, we will fall back on critical sections. When we drop support
+// for XP, we can stop lazy-loading these APIs and just use them directly.
+#if defined(__MINGW32__)
+ // Taken from WinNT.h
+ typedef struct _RTL_SRWLOCK {
+ PVOID Ptr;
+ } RTL_SRWLOCK, *PRTL_SRWLOCK;
+
+ // Taken from WinBase.h
+ typedef RTL_SRWLOCK SRWLOCK, *PSRWLOCK;
+#endif
+
+static VOID (WINAPI *fpInitializeSRWLock)(PSRWLOCK lock) = NULL;
+static VOID (WINAPI *fpAcquireSRWLockExclusive)(PSRWLOCK lock) = NULL;
+static VOID (WINAPI *fpAcquireSRWLockShared)(PSRWLOCK lock) = NULL;
+static VOID (WINAPI *fpReleaseSRWLockExclusive)(PSRWLOCK lock) = NULL;
+static VOID (WINAPI *fpReleaseSRWLockShared)(PSRWLOCK lock) = NULL;
+
+static bool sHasSRW = false;
+
+static bool loadSRW() {
+ static bool sChecked = false;
+ if (!sChecked) {
+ sChecked = true;
+
+ if (HMODULE hLib = ::GetModuleHandleW(L"Kernel32.dll")) {
+ fpInitializeSRWLock =
+ (VOID (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib,
+ "InitializeSRWLock");
+ fpAcquireSRWLockExclusive =
+ (VOID (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib,
+ "AcquireSRWLockExclusive");
+ fpAcquireSRWLockShared =
+ (VOID (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib,
+ "AcquireSRWLockShared");
+ fpReleaseSRWLockExclusive =
+ (VOID (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib,
+ "ReleaseSRWLockExclusive");
+ fpReleaseSRWLockShared =
+ (VOID (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib,
+ "ReleaseSRWLockShared");
+
+ if (fpInitializeSRWLock != NULL) {
+ sHasSRW = true;
+ }
+ }
+ }
+ return sHasSRW;
+}
+
+RWMutexImpl::RWMutexImpl() {
+ if (loadSRW()) {
+ data_ = calloc(1, sizeof(SRWLOCK));
+ fpInitializeSRWLock(static_cast<PSRWLOCK>(data_));
+ } else {
+ data_ = calloc(1, sizeof(CRITICAL_SECTION));
+ InitializeCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
+ }
+}
+
+RWMutexImpl::~RWMutexImpl() {
+ if (!sHasSRW)
+ DeleteCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
+ // Nothing to do in the case of slim reader/writers except free the memory.
+ free(data_);
+}
+
+bool RWMutexImpl::reader_acquire() {
+ if (sHasSRW) {
+ fpAcquireSRWLockShared(static_cast<PSRWLOCK>(data_));
+ } else {
+ EnterCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
+ }
+ return true;
+}
+
+bool RWMutexImpl::reader_release() {
+ if (sHasSRW) {
+ fpReleaseSRWLockShared(static_cast<PSRWLOCK>(data_));
+ } else {
+ LeaveCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
+ }
+ return true;
+}
+
+bool RWMutexImpl::writer_acquire() {
+ if (sHasSRW) {
+ fpAcquireSRWLockExclusive(static_cast<PSRWLOCK>(data_));
+ } else {
+ EnterCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
+ }
+ return true;
+}
+
+bool RWMutexImpl::writer_release() {
+ if (sHasSRW) {
+ fpReleaseSRWLockExclusive(static_cast<PSRWLOCK>(data_));
+ } else {
+ LeaveCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
+ }
+ return true;
+}
+
+
+}
diff --git a/contrib/llvm/lib/Support/Windows/Signals.inc b/contrib/llvm/lib/Support/Windows/Signals.inc
new file mode 100644
index 000000000000..6006499f4da2
--- /dev/null
+++ b/contrib/llvm/lib/Support/Windows/Signals.inc
@@ -0,0 +1,537 @@
+//===- Win32/Signals.cpp - Win32 Signals Implementation ---------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides the Win32 specific implementation of the Signals class.
+//
+//===----------------------------------------------------------------------===//
+#include "llvm/Support/FileSystem.h"
+#include <algorithm>
+#include <signal.h>
+#include <stdio.h>
+#include <vector>
+
+#include "llvm/Support/Format.h"
+#include "llvm/Support/raw_ostream.h"
+
+// The Windows.h header must be after LLVM and standard headers.
+#include "WindowsSupport.h"
+
+#ifdef __MINGW32__
+ #include <imagehlp.h>
+#else
+ #include <dbghelp.h>
+#endif
+#include <psapi.h>
+
+#ifdef _MSC_VER
+ #pragma comment(lib, "psapi.lib")
+ #pragma comment(lib, "dbghelp.lib")
+#elif __MINGW32__
+ #if ((HAVE_LIBIMAGEHLP != 1) || (HAVE_LIBPSAPI != 1))
+ #error "libimagehlp.a & libpsapi.a should be present"
+ #endif
+ // The version of g++ that comes with MinGW does *not* properly understand
+ // the ll format specifier for printf. However, MinGW passes the format
+ // specifiers on to the MSVCRT entirely, and the CRT understands the ll
+ // specifier. So these warnings are spurious in this case. Since we compile
+ // with -Wall, this will generate these warnings which should be ignored. So
+ // we will turn off the warnings for this just file. However, MinGW also does
+ // not support push and pop for diagnostics, so we have to manually turn it
+ // back on at the end of the file.
+ #pragma GCC diagnostic ignored "-Wformat"
+ #pragma GCC diagnostic ignored "-Wformat-extra-args"
+
+ #if !defined(__MINGW64_VERSION_MAJOR)
+ // MinGW.org does not have updated support for the 64-bit versions of the
+ // DebugHlp APIs. So we will have to load them manually. The structures and
+ // method signatures were pulled from DbgHelp.h in the Windows Platform SDK,
+ // and adjusted for brevity.
+ typedef struct _IMAGEHLP_LINE64 {
+ DWORD SizeOfStruct;
+ PVOID Key;
+ DWORD LineNumber;
+ PCHAR FileName;
+ DWORD64 Address;
+ } IMAGEHLP_LINE64, *PIMAGEHLP_LINE64;
+
+ typedef struct _IMAGEHLP_SYMBOL64 {
+ DWORD SizeOfStruct;
+ DWORD64 Address;
+ DWORD Size;
+ DWORD Flags;
+ DWORD MaxNameLength;
+ CHAR Name[1];
+ } IMAGEHLP_SYMBOL64, *PIMAGEHLP_SYMBOL64;
+
+ typedef struct _tagADDRESS64 {
+ DWORD64 Offset;
+ WORD Segment;
+ ADDRESS_MODE Mode;
+ } ADDRESS64, *LPADDRESS64;
+
+ typedef struct _KDHELP64 {
+ DWORD64 Thread;
+ DWORD ThCallbackStack;
+ DWORD ThCallbackBStore;
+ DWORD NextCallback;
+ DWORD FramePointer;
+ DWORD64 KiCallUserMode;
+ DWORD64 KeUserCallbackDispatcher;
+ DWORD64 SystemRangeStart;
+ DWORD64 KiUserExceptionDispatcher;
+ DWORD64 StackBase;
+ DWORD64 StackLimit;
+ DWORD64 Reserved[5];
+ } KDHELP64, *PKDHELP64;
+
+ typedef struct _tagSTACKFRAME64 {
+ ADDRESS64 AddrPC;
+ ADDRESS64 AddrReturn;
+ ADDRESS64 AddrFrame;
+ ADDRESS64 AddrStack;
+ ADDRESS64 AddrBStore;
+ PVOID FuncTableEntry;
+ DWORD64 Params[4];
+ BOOL Far;
+ BOOL Virtual;
+ DWORD64 Reserved[3];
+ KDHELP64 KdHelp;
+ } STACKFRAME64, *LPSTACKFRAME64;
+
+typedef BOOL (__stdcall *PREAD_PROCESS_MEMORY_ROUTINE64)(HANDLE hProcess,
+ DWORD64 qwBaseAddress, PVOID lpBuffer, DWORD nSize,
+ LPDWORD lpNumberOfBytesRead);
+
+typedef PVOID (__stdcall *PFUNCTION_TABLE_ACCESS_ROUTINE64)( HANDLE ahProcess,
+ DWORD64 AddrBase);
+
+typedef DWORD64 (__stdcall *PGET_MODULE_BASE_ROUTINE64)(HANDLE hProcess,
+ DWORD64 Address);
+
+typedef DWORD64 (__stdcall *PTRANSLATE_ADDRESS_ROUTINE64)(HANDLE hProcess,
+ HANDLE hThread, LPADDRESS64 lpaddr);
+
+typedef BOOL (WINAPI *fpStackWalk64)(DWORD, HANDLE, HANDLE, LPSTACKFRAME64,
+ PVOID, PREAD_PROCESS_MEMORY_ROUTINE64,
+ PFUNCTION_TABLE_ACCESS_ROUTINE64,
+ PGET_MODULE_BASE_ROUTINE64,
+ PTRANSLATE_ADDRESS_ROUTINE64);
+static fpStackWalk64 StackWalk64;
+
+typedef DWORD64 (WINAPI *fpSymGetModuleBase64)(HANDLE, DWORD64);
+static fpSymGetModuleBase64 SymGetModuleBase64;
+
+typedef BOOL (WINAPI *fpSymGetSymFromAddr64)(HANDLE, DWORD64,
+ PDWORD64, PIMAGEHLP_SYMBOL64);
+static fpSymGetSymFromAddr64 SymGetSymFromAddr64;
+
+typedef BOOL (WINAPI *fpSymGetLineFromAddr64)(HANDLE, DWORD64,
+ PDWORD, PIMAGEHLP_LINE64);
+static fpSymGetLineFromAddr64 SymGetLineFromAddr64;
+
+typedef PVOID (WINAPI *fpSymFunctionTableAccess64)(HANDLE, DWORD64);
+static fpSymFunctionTableAccess64 SymFunctionTableAccess64;
+
+static bool load64BitDebugHelp(void) {
+ HMODULE hLib = ::LoadLibraryW(L"Dbghelp.dll");
+ if (hLib) {
+ StackWalk64 = (fpStackWalk64)
+ ::GetProcAddress(hLib, "StackWalk64");
+ SymGetModuleBase64 = (fpSymGetModuleBase64)
+ ::GetProcAddress(hLib, "SymGetModuleBase64");
+ SymGetSymFromAddr64 = (fpSymGetSymFromAddr64)
+ ::GetProcAddress(hLib, "SymGetSymFromAddr64");
+ SymGetLineFromAddr64 = (fpSymGetLineFromAddr64)
+ ::GetProcAddress(hLib, "SymGetLineFromAddr64");
+ SymFunctionTableAccess64 = (fpSymFunctionTableAccess64)
+ ::GetProcAddress(hLib, "SymFunctionTableAccess64");
+ }
+ return StackWalk64 != NULL;
+}
+ #endif // !defined(__MINGW64_VERSION_MAJOR)
+#endif // __MINGW32__
+
+// Forward declare.
+static LONG WINAPI LLVMUnhandledExceptionFilter(LPEXCEPTION_POINTERS ep);
+static BOOL WINAPI LLVMConsoleCtrlHandler(DWORD dwCtrlType);
+
+// InterruptFunction - The function to call if ctrl-c is pressed.
+static void (*InterruptFunction)() = 0;
+
+static std::vector<std::string> *FilesToRemove = NULL;
+static std::vector<std::pair<void(*)(void*), void*> > *CallBacksToRun = 0;
+static bool RegisteredUnhandledExceptionFilter = false;
+static bool CleanupExecuted = false;
+static PTOP_LEVEL_EXCEPTION_FILTER OldFilter = NULL;
+
+// Windows creates a new thread to execute the console handler when an event
+// (such as CTRL/C) occurs. This causes concurrency issues with the above
+// globals which this critical section addresses.
+static CRITICAL_SECTION CriticalSection;
+static bool CriticalSectionInitialized = false;
+
+static void PrintStackTraceForThread(llvm::raw_ostream &OS, HANDLE hProcess,
+ HANDLE hThread, STACKFRAME64 &StackFrame,
+ CONTEXT *Context) {
+ DWORD machineType;
+#if defined(_M_X64)
+ machineType = IMAGE_FILE_MACHINE_AMD64;
+#else
+ machineType = IMAGE_FILE_MACHINE_I386;
+#endif
+
+ // Initialize the symbol handler.
+ SymSetOptions(SYMOPT_DEFERRED_LOADS | SYMOPT_LOAD_LINES);
+ SymInitialize(hProcess, NULL, TRUE);
+
+ while (true) {
+ if (!StackWalk64(machineType, hProcess, hThread, &StackFrame, Context, NULL,
+ SymFunctionTableAccess64, SymGetModuleBase64, NULL)) {
+ break;
+ }
+
+ if (StackFrame.AddrFrame.Offset == 0)
+ break;
+
+ using namespace llvm;
+ // Print the PC in hexadecimal.
+ DWORD64 PC = StackFrame.AddrPC.Offset;
+#if defined(_M_X64)
+ OS << format("0x%016llX", PC);
+#elif defined(_M_IX86)
+ OS << format("0x%08lX", static_cast<DWORD>(PC));
+#endif
+
+// Print the parameters. Assume there are four.
+#if defined(_M_X64)
+ OS << format(" (0x%016llX 0x%016llX 0x%016llX 0x%016llX)",
+ StackFrame.Params[0], StackFrame.Params[1], StackFrame.Params[2],
+ StackFrame.Params[3]);
+#elif defined(_M_IX86)
+ OS << format(" (0x%08lX 0x%08lX 0x%08lX 0x%08lX)",
+ static_cast<DWORD>(StackFrame.Params[0]),
+ static_cast<DWORD>(StackFrame.Params[1]),
+ static_cast<DWORD>(StackFrame.Params[2]),
+ static_cast<DWORD>(StackFrame.Params[3]));
+#endif
+ // Verify the PC belongs to a module in this process.
+ if (!SymGetModuleBase64(hProcess, PC)) {
+ OS << " <unknown module>\n";
+ continue;
+ }
+
+ // Print the symbol name.
+ char buffer[512];
+ IMAGEHLP_SYMBOL64 *symbol = reinterpret_cast<IMAGEHLP_SYMBOL64 *>(buffer);
+ memset(symbol, 0, sizeof(IMAGEHLP_SYMBOL64));
+ symbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64);
+ symbol->MaxNameLength = 512 - sizeof(IMAGEHLP_SYMBOL64);
+
+ DWORD64 dwDisp;
+ if (!SymGetSymFromAddr64(hProcess, PC, &dwDisp, symbol)) {
+ OS << '\n';
+ continue;
+ }
+
+ buffer[511] = 0;
+ if (dwDisp > 0)
+ OS << format(", %s() + 0x%llX bytes(s)", (const char*)symbol->Name,
+ dwDisp);
+ else
+ OS << format(", %s", (const char*)symbol->Name);
+
+ // Print the source file and line number information.
+ IMAGEHLP_LINE64 line = {};
+ DWORD dwLineDisp;
+ line.SizeOfStruct = sizeof(line);
+ if (SymGetLineFromAddr64(hProcess, PC, &dwLineDisp, &line)) {
+ OS << format(", %s, line %lu", line.FileName, line.LineNumber);
+ if (dwLineDisp > 0)
+ OS << format(" + 0x%lX byte(s)", dwLineDisp);
+ }
+
+ OS << '\n';
+ }
+}
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only Win32 specific code
+//=== and must not be UNIX code
+//===----------------------------------------------------------------------===//
+
+#ifdef _MSC_VER
+/// AvoidMessageBoxHook - Emulates hitting "retry" from an "abort, retry,
+/// ignore" CRT debug report dialog. "retry" raises an exception which
+/// ultimately triggers our stack dumper.
+static LLVM_ATTRIBUTE_UNUSED int
+AvoidMessageBoxHook(int ReportType, char *Message, int *Return) {
+ // Set *Return to the retry code for the return value of _CrtDbgReport:
+ // http://msdn.microsoft.com/en-us/library/8hyw4sy7(v=vs.71).aspx
+ // This may also trigger just-in-time debugging via DebugBreak().
+ if (Return)
+ *Return = 1;
+ // Don't call _CrtDbgReport.
+ return TRUE;
+}
+
+#endif
+
+extern "C" void HandleAbort(int Sig) {
+ if (Sig == SIGABRT) {
+ LLVM_BUILTIN_TRAP;
+ }
+}
+
+static void InitializeThreading() {
+ if (CriticalSectionInitialized)
+ return;
+
+ // Now's the time to create the critical section. This is the first time
+ // through here, and there's only one thread.
+ InitializeCriticalSection(&CriticalSection);
+ CriticalSectionInitialized = true;
+}
+
+static void RegisterHandler() {
+#if __MINGW32__ && !defined(__MINGW64_VERSION_MAJOR)
+ // On MinGW.org, we need to load up the symbols explicitly, because the
+ // Win32 framework they include does not have support for the 64-bit
+ // versions of the APIs we need. If we cannot load up the APIs (which
+ // would be unexpected as they should exist on every version of Windows
+ // we support), we will bail out since there would be nothing to report.
+ if (!load64BitDebugHelp()) {
+ assert(false && "These APIs should always be available");
+ return;
+ }
+#endif
+
+ if (RegisteredUnhandledExceptionFilter) {
+ EnterCriticalSection(&CriticalSection);
+ return;
+ }
+
+ InitializeThreading();
+
+ // Enter it immediately. Now if someone hits CTRL/C, the console handler
+ // can't proceed until the globals are updated.
+ EnterCriticalSection(&CriticalSection);
+
+ RegisteredUnhandledExceptionFilter = true;
+ OldFilter = SetUnhandledExceptionFilter(LLVMUnhandledExceptionFilter);
+ SetConsoleCtrlHandler(LLVMConsoleCtrlHandler, TRUE);
+
+ // IMPORTANT NOTE: Caller must call LeaveCriticalSection(&CriticalSection) or
+ // else multi-threading problems will ensue.
+}
+
+// RemoveFileOnSignal - The public API
+bool sys::RemoveFileOnSignal(StringRef Filename, std::string* ErrMsg) {
+ RegisterHandler();
+
+ if (CleanupExecuted) {
+ if (ErrMsg)
+ *ErrMsg = "Process terminating -- cannot register for removal";
+ return true;
+ }
+
+ if (FilesToRemove == NULL)
+ FilesToRemove = new std::vector<std::string>;
+
+ FilesToRemove->push_back(Filename);
+
+ LeaveCriticalSection(&CriticalSection);
+ return false;
+}
+
+// DontRemoveFileOnSignal - The public API
+void sys::DontRemoveFileOnSignal(StringRef Filename) {
+ if (FilesToRemove == NULL)
+ return;
+
+ RegisterHandler();
+
+ std::vector<std::string>::reverse_iterator I =
+ std::find(FilesToRemove->rbegin(), FilesToRemove->rend(), Filename);
+ if (I != FilesToRemove->rend())
+ FilesToRemove->erase(I.base()-1);
+
+ LeaveCriticalSection(&CriticalSection);
+}
+
+void sys::DisableSystemDialogsOnCrash() {
+ // Crash to stack trace handler on abort.
+ signal(SIGABRT, HandleAbort);
+
+ // The following functions are not reliably accessible on MinGW.
+#ifdef _MSC_VER
+ // We're already handling writing a "something went wrong" message.
+ _set_abort_behavior(0, _WRITE_ABORT_MSG);
+ // Disable Dr. Watson.
+ _set_abort_behavior(0, _CALL_REPORTFAULT);
+ _CrtSetReportHook(AvoidMessageBoxHook);
+#endif
+
+ // Disable standard error dialog box.
+ SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX |
+ SEM_NOOPENFILEERRORBOX);
+ _set_error_mode(_OUT_TO_STDERR);
+}
+
+/// PrintStackTraceOnErrorSignal - When an error signal (such as SIBABRT or
+/// SIGSEGV) is delivered to the process, print a stack trace and then exit.
+void sys::PrintStackTraceOnErrorSignal(bool DisableCrashReporting) {
+ DisableSystemDialogsOnCrash();
+ RegisterHandler();
+ LeaveCriticalSection(&CriticalSection);
+}
+}
+
+#if defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR)
+// Provide a prototype for RtlCaptureContext, mingw32 from mingw.org is
+// missing it but mingw-w64 has it.
+extern "C" VOID WINAPI RtlCaptureContext(PCONTEXT ContextRecord);
+#endif
+
+void llvm::sys::PrintStackTrace(raw_ostream &OS) {
+
+ STACKFRAME64 StackFrame = {};
+ CONTEXT Context = {};
+ ::RtlCaptureContext(&Context);
+#if defined(_M_X64)
+ StackFrame.AddrPC.Offset = Context.Rip;
+ StackFrame.AddrStack.Offset = Context.Rsp;
+ StackFrame.AddrFrame.Offset = Context.Rbp;
+#else
+ StackFrame.AddrPC.Offset = Context.Eip;
+ StackFrame.AddrStack.Offset = Context.Esp;
+ StackFrame.AddrFrame.Offset = Context.Ebp;
+#endif
+ StackFrame.AddrPC.Mode = AddrModeFlat;
+ StackFrame.AddrStack.Mode = AddrModeFlat;
+ StackFrame.AddrFrame.Mode = AddrModeFlat;
+ PrintStackTraceForThread(OS, GetCurrentProcess(), GetCurrentThread(),
+ StackFrame, &Context);
+}
+
+
+void llvm::sys::SetInterruptFunction(void (*IF)()) {
+ RegisterHandler();
+ InterruptFunction = IF;
+ LeaveCriticalSection(&CriticalSection);
+}
+
+
+/// AddSignalHandler - Add a function to be called when a signal is delivered
+/// to the process. The handler can have a cookie passed to it to identify
+/// what instance of the handler it is.
+void llvm::sys::AddSignalHandler(void (*FnPtr)(void *), void *Cookie) {
+ if (CallBacksToRun == 0)
+ CallBacksToRun = new std::vector<std::pair<void(*)(void*), void*> >();
+ CallBacksToRun->push_back(std::make_pair(FnPtr, Cookie));
+ RegisterHandler();
+ LeaveCriticalSection(&CriticalSection);
+}
+
+static void Cleanup() {
+ if (CleanupExecuted)
+ return;
+
+ EnterCriticalSection(&CriticalSection);
+
+ // Prevent other thread from registering new files and directories for
+ // removal, should we be executing because of the console handler callback.
+ CleanupExecuted = true;
+
+ // FIXME: open files cannot be deleted.
+
+ if (FilesToRemove != NULL)
+ while (!FilesToRemove->empty()) {
+ llvm::sys::fs::remove(FilesToRemove->back());
+ FilesToRemove->pop_back();
+ }
+
+ if (CallBacksToRun)
+ for (auto &I : *CallBacksToRun)
+ I.first(I.second);
+
+ LeaveCriticalSection(&CriticalSection);
+}
+
+void llvm::sys::RunInterruptHandlers() {
+ // The interrupt handler may be called from an interrupt, but it may also be
+ // called manually (such as the case of report_fatal_error with no registered
+ // error handler). We must ensure that the critical section is properly
+ // initialized.
+ InitializeThreading();
+ Cleanup();
+}
+
+static LONG WINAPI LLVMUnhandledExceptionFilter(LPEXCEPTION_POINTERS ep) {
+ Cleanup();
+
+ // Initialize the STACKFRAME structure.
+ STACKFRAME64 StackFrame = {};
+
+#if defined(_M_X64)
+ StackFrame.AddrPC.Offset = ep->ContextRecord->Rip;
+ StackFrame.AddrPC.Mode = AddrModeFlat;
+ StackFrame.AddrStack.Offset = ep->ContextRecord->Rsp;
+ StackFrame.AddrStack.Mode = AddrModeFlat;
+ StackFrame.AddrFrame.Offset = ep->ContextRecord->Rbp;
+ StackFrame.AddrFrame.Mode = AddrModeFlat;
+#elif defined(_M_IX86)
+ StackFrame.AddrPC.Offset = ep->ContextRecord->Eip;
+ StackFrame.AddrPC.Mode = AddrModeFlat;
+ StackFrame.AddrStack.Offset = ep->ContextRecord->Esp;
+ StackFrame.AddrStack.Mode = AddrModeFlat;
+ StackFrame.AddrFrame.Offset = ep->ContextRecord->Ebp;
+ StackFrame.AddrFrame.Mode = AddrModeFlat;
+#endif
+
+ HANDLE hProcess = GetCurrentProcess();
+ HANDLE hThread = GetCurrentThread();
+ PrintStackTraceForThread(llvm::errs(), hProcess, hThread, StackFrame,
+ ep->ContextRecord);
+
+ _exit(ep->ExceptionRecord->ExceptionCode);
+}
+
+static BOOL WINAPI LLVMConsoleCtrlHandler(DWORD dwCtrlType) {
+ // We are running in our very own thread, courtesy of Windows.
+ EnterCriticalSection(&CriticalSection);
+ Cleanup();
+
+ // If an interrupt function has been set, go and run one it; otherwise,
+ // the process dies.
+ void (*IF)() = InterruptFunction;
+ InterruptFunction = 0; // Don't run it on another CTRL-C.
+
+ if (IF) {
+ // Note: if the interrupt function throws an exception, there is nothing
+ // to catch it in this thread so it will kill the process.
+ IF(); // Run it now.
+ LeaveCriticalSection(&CriticalSection);
+ return TRUE; // Don't kill the process.
+ }
+
+ // Allow normal processing to take place; i.e., the process dies.
+ LeaveCriticalSection(&CriticalSection);
+ return FALSE;
+}
+
+#if __MINGW32__
+ // We turned these warnings off for this file so that MinGW-g++ doesn't
+ // complain about the ll format specifiers used. Now we are turning the
+ // warnings back on. If MinGW starts to support diagnostic stacks, we can
+ // replace this with a pop.
+ #pragma GCC diagnostic warning "-Wformat"
+ #pragma GCC diagnostic warning "-Wformat-extra-args"
+#endif
diff --git a/contrib/llvm/lib/Support/Windows/ThreadLocal.inc b/contrib/llvm/lib/Support/Windows/ThreadLocal.inc
new file mode 100644
index 000000000000..b9cb8ff9836e
--- /dev/null
+++ b/contrib/llvm/lib/Support/Windows/ThreadLocal.inc
@@ -0,0 +1,53 @@
+//= llvm/Support/Win32/ThreadLocal.inc - Win32 Thread Local Data -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the Win32 specific (non-pthread) ThreadLocal class.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only generic Win32 code that
+//=== is guaranteed to work on *all* Win32 variants.
+//===----------------------------------------------------------------------===//
+
+#include "WindowsSupport.h"
+#include "llvm/Support/ThreadLocal.h"
+
+namespace llvm {
+using namespace sys;
+
+ThreadLocalImpl::ThreadLocalImpl() : data() {
+ static_assert(sizeof(DWORD) <= sizeof(data), "size too big");
+ DWORD* tls = reinterpret_cast<DWORD*>(&data);
+ *tls = TlsAlloc();
+ assert(*tls != TLS_OUT_OF_INDEXES);
+}
+
+ThreadLocalImpl::~ThreadLocalImpl() {
+ DWORD* tls = reinterpret_cast<DWORD*>(&data);
+ TlsFree(*tls);
+}
+
+void *ThreadLocalImpl::getInstance() {
+ DWORD* tls = reinterpret_cast<DWORD*>(&data);
+ return TlsGetValue(*tls);
+}
+
+void ThreadLocalImpl::setInstance(const void* d){
+ DWORD* tls = reinterpret_cast<DWORD*>(&data);
+ int errorcode = TlsSetValue(*tls, const_cast<void*>(d));
+ assert(errorcode != 0);
+ (void)errorcode;
+}
+
+void ThreadLocalImpl::removeInstance() {
+ setInstance(0);
+}
+
+}
diff --git a/contrib/llvm/lib/Support/Windows/TimeValue.inc b/contrib/llvm/lib/Support/Windows/TimeValue.inc
new file mode 100644
index 000000000000..b90b4f1da008
--- /dev/null
+++ b/contrib/llvm/lib/Support/Windows/TimeValue.inc
@@ -0,0 +1,61 @@
+//===- Win32/TimeValue.cpp - Win32 TimeValue Implementation -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides the Win32 implementation of the TimeValue class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "WindowsSupport.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cctype>
+#include <time.h>
+
+using namespace llvm;
+using namespace llvm::sys;
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only Win32 specific code.
+//===----------------------------------------------------------------------===//
+
+TimeValue TimeValue::now() {
+ uint64_t ft;
+ GetSystemTimeAsFileTime(reinterpret_cast<FILETIME *>(&ft));
+
+ TimeValue t(0, 0);
+ t.fromWin32Time(ft);
+ return t;
+}
+
+std::string TimeValue::str() const {
+ std::string S;
+ struct tm *LT;
+#ifdef __MINGW32__
+ // Old versions of mingw don't have _localtime64_s. Remove this once we drop support
+ // for them.
+ time_t OurTime = time_t(this->toEpochTime());
+ LT = ::localtime(&OurTime);
+ assert(LT);
+#else
+ struct tm Storage;
+ __time64_t OurTime = this->toEpochTime();
+ int Error = ::_localtime64_s(&Storage, &OurTime);
+ assert(!Error);
+ (void)Error;
+ LT = &Storage;
+#endif
+
+ char Buffer[sizeof("YYYY-MM-DD HH:MM:SS")];
+ strftime(Buffer, sizeof(Buffer), "%Y-%m-%d %H:%M:%S", LT);
+ raw_string_ostream OS(S);
+ OS << format("%s.%.9u", static_cast<const char *>(Buffer),
+ this->nanoseconds());
+ OS.flush();
+ return S;
+}
diff --git a/contrib/llvm/lib/Support/Windows/Watchdog.inc b/contrib/llvm/lib/Support/Windows/Watchdog.inc
new file mode 100644
index 000000000000..fab2bdf2a941
--- /dev/null
+++ b/contrib/llvm/lib/Support/Windows/Watchdog.inc
@@ -0,0 +1,24 @@
+//===--- Windows/Watchdog.inc - Windows Watchdog Implementation -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides the generic Windows implementation of the Watchdog class.
+//
+//===----------------------------------------------------------------------===//
+
+// TODO: implement.
+// Currently this is only used by PrettyStackTrace which is also unimplemented
+// on Windows. Roughly, a Windows implementation would use CreateWaitableTimer
+// and a second thread to run the TimerAPCProc.
+
+namespace llvm {
+ namespace sys {
+ Watchdog::Watchdog(unsigned int seconds) {}
+ Watchdog::~Watchdog() {}
+ }
+}
diff --git a/contrib/llvm/lib/Support/Windows/WindowsSupport.h b/contrib/llvm/lib/Support/Windows/WindowsSupport.h
new file mode 100644
index 000000000000..5bb0b8d2d788
--- /dev/null
+++ b/contrib/llvm/lib/Support/Windows/WindowsSupport.h
@@ -0,0 +1,185 @@
+//===- WindowsSupport.h - Common Windows Include File -----------*- 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 things specific to Windows implementations. In addition to
+// providing some helpers for working with win32 APIs, this header wraps
+// <windows.h> with some portability macros. Always include WindowsSupport.h
+// instead of including <windows.h> directly.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only generic Win32 code that
+//=== is guaranteed to work on *all* Win32 variants.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_WINDOWSSUPPORT_H
+#define LLVM_SUPPORT_WINDOWSSUPPORT_H
+
+// mingw-w64 tends to define it as 0x0502 in its headers.
+#undef _WIN32_WINNT
+#undef _WIN32_IE
+
+// Require at least Windows XP(5.1) API.
+#define _WIN32_WINNT 0x0501
+#define _WIN32_IE 0x0600 // MinGW at it again.
+#define WIN32_LEAN_AND_MEAN
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Config/config.h" // Get build system configuration settings
+#include "llvm/Support/Compiler.h"
+#include <system_error>
+#include <windows.h>
+#include <wincrypt.h>
+#include <cassert>
+#include <string>
+#include <vector>
+
+inline bool MakeErrMsg(std::string* ErrMsg, const std::string& prefix) {
+ if (!ErrMsg)
+ return true;
+ char *buffer = NULL;
+ DWORD R = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL, GetLastError(), 0, (LPSTR)&buffer, 1, NULL);
+ if (R)
+ *ErrMsg = prefix + buffer;
+ else
+ *ErrMsg = prefix + "Unknown error";
+
+ LocalFree(buffer);
+ return R != 0;
+}
+
+template <typename HandleTraits>
+class ScopedHandle {
+ typedef typename HandleTraits::handle_type handle_type;
+ handle_type Handle;
+
+ ScopedHandle(const ScopedHandle &other); // = delete;
+ void operator=(const ScopedHandle &other); // = delete;
+public:
+ ScopedHandle()
+ : Handle(HandleTraits::GetInvalid()) {}
+
+ explicit ScopedHandle(handle_type h)
+ : Handle(h) {}
+
+ ~ScopedHandle() {
+ if (HandleTraits::IsValid(Handle))
+ HandleTraits::Close(Handle);
+ }
+
+ handle_type take() {
+ handle_type t = Handle;
+ Handle = HandleTraits::GetInvalid();
+ return t;
+ }
+
+ ScopedHandle &operator=(handle_type h) {
+ if (HandleTraits::IsValid(Handle))
+ HandleTraits::Close(Handle);
+ Handle = h;
+ return *this;
+ }
+
+ // True if Handle is valid.
+ explicit operator bool() const {
+ return HandleTraits::IsValid(Handle) ? true : false;
+ }
+
+ operator handle_type() const {
+ return Handle;
+ }
+};
+
+struct CommonHandleTraits {
+ typedef HANDLE handle_type;
+
+ static handle_type GetInvalid() {
+ return INVALID_HANDLE_VALUE;
+ }
+
+ static void Close(handle_type h) {
+ ::CloseHandle(h);
+ }
+
+ static bool IsValid(handle_type h) {
+ return h != GetInvalid();
+ }
+};
+
+struct JobHandleTraits : CommonHandleTraits {
+ static handle_type GetInvalid() {
+ return NULL;
+ }
+};
+
+struct CryptContextTraits : CommonHandleTraits {
+ typedef HCRYPTPROV handle_type;
+
+ static handle_type GetInvalid() {
+ return 0;
+ }
+
+ static void Close(handle_type h) {
+ ::CryptReleaseContext(h, 0);
+ }
+
+ static bool IsValid(handle_type h) {
+ return h != GetInvalid();
+ }
+};
+
+struct FindHandleTraits : CommonHandleTraits {
+ static void Close(handle_type h) {
+ ::FindClose(h);
+ }
+};
+
+struct FileHandleTraits : CommonHandleTraits {};
+
+typedef ScopedHandle<CommonHandleTraits> ScopedCommonHandle;
+typedef ScopedHandle<FileHandleTraits> ScopedFileHandle;
+typedef ScopedHandle<CryptContextTraits> ScopedCryptContext;
+typedef ScopedHandle<FindHandleTraits> ScopedFindHandle;
+typedef ScopedHandle<JobHandleTraits> ScopedJobHandle;
+
+namespace llvm {
+template <class T>
+class SmallVectorImpl;
+
+template <class T>
+typename SmallVectorImpl<T>::const_pointer
+c_str(SmallVectorImpl<T> &str) {
+ str.push_back(0);
+ str.pop_back();
+ return str.data();
+}
+
+namespace sys {
+namespace path {
+std::error_code widenPath(const Twine &Path8,
+ SmallVectorImpl<wchar_t> &Path16);
+} // end namespace path
+
+namespace windows {
+std::error_code UTF8ToUTF16(StringRef utf8, SmallVectorImpl<wchar_t> &utf16);
+std::error_code UTF16ToUTF8(const wchar_t *utf16, size_t utf16_len,
+ SmallVectorImpl<char> &utf8);
+/// Convert from UTF16 to the current code page used in the system
+std::error_code UTF16ToCurCP(const wchar_t *utf16, size_t utf16_len,
+ SmallVectorImpl<char> &utf8);
+} // end namespace windows
+} // end namespace sys
+} // end namespace llvm.
+
+#endif
diff --git a/contrib/llvm/lib/Support/Windows/explicit_symbols.inc b/contrib/llvm/lib/Support/Windows/explicit_symbols.inc
new file mode 100644
index 000000000000..bbbf7ea6a777
--- /dev/null
+++ b/contrib/llvm/lib/Support/Windows/explicit_symbols.inc
@@ -0,0 +1,102 @@
+/* in libgcc.a */
+
+#ifdef HAVE__ALLOCA
+ EXPLICIT_SYMBOL(_alloca)
+ EXPLICIT_SYMBOL2(alloca, _alloca)
+#endif
+#ifdef HAVE___ALLOCA
+ EXPLICIT_SYMBOL(__alloca)
+#endif
+#ifdef HAVE___CHKSTK
+ EXPLICIT_SYMBOL(__chkstk)
+#endif
+#ifdef HAVE___CHKSTK_MS
+ EXPLICIT_SYMBOL(__chkstk_ms)
+#endif
+#ifdef HAVE____CHKSTK
+ EXPLICIT_SYMBOL(___chkstk)
+#endif
+#ifdef HAVE____CHKSTK_MS
+ EXPLICIT_SYMBOL(___chkstk_ms)
+#endif
+#ifdef HAVE___MAIN
+ EXPLICIT_SYMBOL(__main) // FIXME: Don't call it.
+#endif
+
+#ifdef HAVE___ASHLDI3
+ EXPLICIT_SYMBOL(__ashldi3)
+#endif
+#ifdef HAVE___ASHRDI3
+ EXPLICIT_SYMBOL(__ashrdi3)
+#endif
+#ifdef HAVE___CMPDI2 // FIXME: unused
+ EXPLICIT_SYMBOL(__cmpdi2)
+#endif
+#ifdef HAVE___DIVDI3
+ EXPLICIT_SYMBOL(__divdi3)
+#endif
+#ifdef HAVE___FIXDFDI
+ EXPLICIT_SYMBOL(__fixdfdi)
+#endif
+#ifdef HAVE___FIXSFDI
+ EXPLICIT_SYMBOL(__fixsfdi)
+#endif
+#ifdef HAVE___FIXUNSDFDI
+ EXPLICIT_SYMBOL(__fixunsdfdi)
+#endif
+#ifdef HAVE___FIXUNSSFDI
+ EXPLICIT_SYMBOL(__fixunssfdi)
+#endif
+#ifdef HAVE___FLOATDIDF
+ EXPLICIT_SYMBOL(__floatdidf)
+#endif
+#ifdef HAVE___FLOATDISF
+ EXPLICIT_SYMBOL(__floatdisf)
+#endif
+#ifdef HAVE___LSHRDI3
+ EXPLICIT_SYMBOL(__lshrdi3)
+#endif
+#ifdef HAVE___MODDI3
+ EXPLICIT_SYMBOL(__moddi3)
+#endif
+#ifdef HAVE___UDIVDI3
+ EXPLICIT_SYMBOL(__udivdi3)
+#endif
+#ifdef HAVE___UMODDI3
+ EXPLICIT_SYMBOL(__umoddi3)
+#endif
+
+/* msvcrt */
+#if defined(_MSC_VER)
+ EXPLICIT_SYMBOL2(alloca, _alloca_probe)
+
+#ifdef _M_IX86
+#define INLINE_DEF_FLOAT_SYMBOL(SYM, ARGC) INLINE_DEF_SYMBOL##ARGC(float, SYM)
+ INLINE_DEF_FLOAT_SYMBOL(acosf, 1)
+ INLINE_DEF_FLOAT_SYMBOL(asinf, 1)
+ INLINE_DEF_FLOAT_SYMBOL(atanf, 1)
+ INLINE_DEF_FLOAT_SYMBOL(atan2f, 2)
+ INLINE_DEF_FLOAT_SYMBOL(ceilf, 1)
+ INLINE_DEF_FLOAT_SYMBOL(cosf, 1)
+ INLINE_DEF_FLOAT_SYMBOL(coshf, 1)
+ INLINE_DEF_FLOAT_SYMBOL(expf, 1)
+ INLINE_DEF_FLOAT_SYMBOL(floorf, 1)
+ INLINE_DEF_FLOAT_SYMBOL(fmodf, 2)
+ INLINE_DEF_FLOAT_SYMBOL(logf, 1)
+ INLINE_DEF_FLOAT_SYMBOL(powf, 2)
+ INLINE_DEF_FLOAT_SYMBOL(sinf, 1)
+ INLINE_DEF_FLOAT_SYMBOL(sinhf, 1)
+ INLINE_DEF_FLOAT_SYMBOL(sqrtf, 1)
+ INLINE_DEF_FLOAT_SYMBOL(tanf, 1)
+ INLINE_DEF_FLOAT_SYMBOL(tanhf, 1)
+
+ // These were added in VS 2013.
+#if (1800 <= _MSC_VER && _MSC_VER < 1900)
+ INLINE_DEF_FLOAT_SYMBOL(copysignf, 2)
+ INLINE_DEF_FLOAT_SYMBOL(fminf, 2)
+ INLINE_DEF_FLOAT_SYMBOL(fmaxf, 2)
+#endif
+#undef INLINE_DEF_FLOAT_SYMBOL
+#endif
+
+#endif
diff --git a/contrib/llvm/lib/Support/YAMLParser.cpp b/contrib/llvm/lib/Support/YAMLParser.cpp
new file mode 100644
index 000000000000..5ca28a052068
--- /dev/null
+++ b/contrib/llvm/lib/Support/YAMLParser.cpp
@@ -0,0 +1,2447 @@
+//===--- YAMLParser.cpp - Simple YAML parser ------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a YAML parser.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/YAMLParser.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/ADT/ilist.h"
+#include "llvm/ADT/ilist_node.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace llvm;
+using namespace yaml;
+
+enum UnicodeEncodingForm {
+ UEF_UTF32_LE, ///< UTF-32 Little Endian
+ UEF_UTF32_BE, ///< UTF-32 Big Endian
+ UEF_UTF16_LE, ///< UTF-16 Little Endian
+ UEF_UTF16_BE, ///< UTF-16 Big Endian
+ UEF_UTF8, ///< UTF-8 or ascii.
+ UEF_Unknown ///< Not a valid Unicode encoding.
+};
+
+/// EncodingInfo - Holds the encoding type and length of the byte order mark if
+/// it exists. Length is in {0, 2, 3, 4}.
+typedef std::pair<UnicodeEncodingForm, unsigned> EncodingInfo;
+
+/// getUnicodeEncoding - Reads up to the first 4 bytes to determine the Unicode
+/// encoding form of \a Input.
+///
+/// @param Input A string of length 0 or more.
+/// @returns An EncodingInfo indicating the Unicode encoding form of the input
+/// and how long the byte order mark is if one exists.
+static EncodingInfo getUnicodeEncoding(StringRef Input) {
+ if (Input.size() == 0)
+ return std::make_pair(UEF_Unknown, 0);
+
+ switch (uint8_t(Input[0])) {
+ case 0x00:
+ if (Input.size() >= 4) {
+ if ( Input[1] == 0
+ && uint8_t(Input[2]) == 0xFE
+ && uint8_t(Input[3]) == 0xFF)
+ return std::make_pair(UEF_UTF32_BE, 4);
+ if (Input[1] == 0 && Input[2] == 0 && Input[3] != 0)
+ return std::make_pair(UEF_UTF32_BE, 0);
+ }
+
+ if (Input.size() >= 2 && Input[1] != 0)
+ return std::make_pair(UEF_UTF16_BE, 0);
+ return std::make_pair(UEF_Unknown, 0);
+ case 0xFF:
+ if ( Input.size() >= 4
+ && uint8_t(Input[1]) == 0xFE
+ && Input[2] == 0
+ && Input[3] == 0)
+ return std::make_pair(UEF_UTF32_LE, 4);
+
+ if (Input.size() >= 2 && uint8_t(Input[1]) == 0xFE)
+ return std::make_pair(UEF_UTF16_LE, 2);
+ return std::make_pair(UEF_Unknown, 0);
+ case 0xFE:
+ if (Input.size() >= 2 && uint8_t(Input[1]) == 0xFF)
+ return std::make_pair(UEF_UTF16_BE, 2);
+ return std::make_pair(UEF_Unknown, 0);
+ case 0xEF:
+ if ( Input.size() >= 3
+ && uint8_t(Input[1]) == 0xBB
+ && uint8_t(Input[2]) == 0xBF)
+ return std::make_pair(UEF_UTF8, 3);
+ return std::make_pair(UEF_Unknown, 0);
+ }
+
+ // It could still be utf-32 or utf-16.
+ if (Input.size() >= 4 && Input[1] == 0 && Input[2] == 0 && Input[3] == 0)
+ return std::make_pair(UEF_UTF32_LE, 0);
+
+ if (Input.size() >= 2 && Input[1] == 0)
+ return std::make_pair(UEF_UTF16_LE, 0);
+
+ return std::make_pair(UEF_UTF8, 0);
+}
+
+namespace llvm {
+namespace yaml {
+/// Pin the vtables to this file.
+void Node::anchor() {}
+void NullNode::anchor() {}
+void ScalarNode::anchor() {}
+void BlockScalarNode::anchor() {}
+void KeyValueNode::anchor() {}
+void MappingNode::anchor() {}
+void SequenceNode::anchor() {}
+void AliasNode::anchor() {}
+
+/// Token - A single YAML token.
+struct Token : ilist_node<Token> {
+ enum TokenKind {
+ TK_Error, // Uninitialized token.
+ TK_StreamStart,
+ TK_StreamEnd,
+ TK_VersionDirective,
+ TK_TagDirective,
+ TK_DocumentStart,
+ TK_DocumentEnd,
+ TK_BlockEntry,
+ TK_BlockEnd,
+ TK_BlockSequenceStart,
+ TK_BlockMappingStart,
+ TK_FlowEntry,
+ TK_FlowSequenceStart,
+ TK_FlowSequenceEnd,
+ TK_FlowMappingStart,
+ TK_FlowMappingEnd,
+ TK_Key,
+ TK_Value,
+ TK_Scalar,
+ TK_BlockScalar,
+ TK_Alias,
+ TK_Anchor,
+ TK_Tag
+ } Kind;
+
+ /// A string of length 0 or more whose begin() points to the logical location
+ /// of the token in the input.
+ StringRef Range;
+
+ /// The value of a block scalar node.
+ std::string Value;
+
+ Token() : Kind(TK_Error) {}
+};
+} // namespace yaml
+} // namespace llvm
+
+namespace llvm {
+template<>
+struct ilist_sentinel_traits<Token> {
+ Token *createSentinel() const {
+ return &Sentinel;
+ }
+ static void destroySentinel(Token*) {}
+
+ Token *provideInitialHead() const { return createSentinel(); }
+ Token *ensureHead(Token*) const { return createSentinel(); }
+ static void noteHead(Token*, Token*) {}
+
+private:
+ mutable Token Sentinel;
+};
+
+template<>
+struct ilist_node_traits<Token> {
+ Token *createNode(const Token &V) {
+ return new (Alloc.Allocate<Token>()) Token(V);
+ }
+ static void deleteNode(Token *V) { V->~Token(); }
+
+ void addNodeToList(Token *) {}
+ void removeNodeFromList(Token *) {}
+ void transferNodesFromList(ilist_node_traits & /*SrcTraits*/,
+ ilist_iterator<Token> /*first*/,
+ ilist_iterator<Token> /*last*/) {}
+
+ BumpPtrAllocator Alloc;
+};
+} // namespace llvm
+
+typedef ilist<Token> TokenQueueT;
+
+namespace {
+/// @brief This struct is used to track simple keys.
+///
+/// Simple keys are handled by creating an entry in SimpleKeys for each Token
+/// which could legally be the start of a simple key. When peekNext is called,
+/// if the Token To be returned is referenced by a SimpleKey, we continue
+/// tokenizing until that potential simple key has either been found to not be
+/// a simple key (we moved on to the next line or went further than 1024 chars).
+/// Or when we run into a Value, and then insert a Key token (and possibly
+/// others) before the SimpleKey's Tok.
+struct SimpleKey {
+ TokenQueueT::iterator Tok;
+ unsigned Column;
+ unsigned Line;
+ unsigned FlowLevel;
+ bool IsRequired;
+
+ bool operator ==(const SimpleKey &Other) {
+ return Tok == Other.Tok;
+ }
+};
+} // namespace
+
+/// @brief The Unicode scalar value of a UTF-8 minimal well-formed code unit
+/// subsequence and the subsequence's length in code units (uint8_t).
+/// A length of 0 represents an error.
+typedef std::pair<uint32_t, unsigned> UTF8Decoded;
+
+static UTF8Decoded decodeUTF8(StringRef Range) {
+ StringRef::iterator Position= Range.begin();
+ StringRef::iterator End = Range.end();
+ // 1 byte: [0x00, 0x7f]
+ // Bit pattern: 0xxxxxxx
+ if ((*Position & 0x80) == 0) {
+ return std::make_pair(*Position, 1);
+ }
+ // 2 bytes: [0x80, 0x7ff]
+ // Bit pattern: 110xxxxx 10xxxxxx
+ if (Position + 1 != End &&
+ ((*Position & 0xE0) == 0xC0) &&
+ ((*(Position + 1) & 0xC0) == 0x80)) {
+ uint32_t codepoint = ((*Position & 0x1F) << 6) |
+ (*(Position + 1) & 0x3F);
+ if (codepoint >= 0x80)
+ return std::make_pair(codepoint, 2);
+ }
+ // 3 bytes: [0x8000, 0xffff]
+ // Bit pattern: 1110xxxx 10xxxxxx 10xxxxxx
+ if (Position + 2 != End &&
+ ((*Position & 0xF0) == 0xE0) &&
+ ((*(Position + 1) & 0xC0) == 0x80) &&
+ ((*(Position + 2) & 0xC0) == 0x80)) {
+ uint32_t codepoint = ((*Position & 0x0F) << 12) |
+ ((*(Position + 1) & 0x3F) << 6) |
+ (*(Position + 2) & 0x3F);
+ // Codepoints between 0xD800 and 0xDFFF are invalid, as
+ // they are high / low surrogate halves used by UTF-16.
+ if (codepoint >= 0x800 &&
+ (codepoint < 0xD800 || codepoint > 0xDFFF))
+ return std::make_pair(codepoint, 3);
+ }
+ // 4 bytes: [0x10000, 0x10FFFF]
+ // Bit pattern: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+ if (Position + 3 != End &&
+ ((*Position & 0xF8) == 0xF0) &&
+ ((*(Position + 1) & 0xC0) == 0x80) &&
+ ((*(Position + 2) & 0xC0) == 0x80) &&
+ ((*(Position + 3) & 0xC0) == 0x80)) {
+ uint32_t codepoint = ((*Position & 0x07) << 18) |
+ ((*(Position + 1) & 0x3F) << 12) |
+ ((*(Position + 2) & 0x3F) << 6) |
+ (*(Position + 3) & 0x3F);
+ if (codepoint >= 0x10000 && codepoint <= 0x10FFFF)
+ return std::make_pair(codepoint, 4);
+ }
+ return std::make_pair(0, 0);
+}
+
+namespace llvm {
+namespace yaml {
+/// @brief Scans YAML tokens from a MemoryBuffer.
+class Scanner {
+public:
+ Scanner(StringRef Input, SourceMgr &SM, bool ShowColors = true);
+ Scanner(MemoryBufferRef Buffer, SourceMgr &SM_, bool ShowColors = true);
+
+ /// @brief Parse the next token and return it without popping it.
+ Token &peekNext();
+
+ /// @brief Parse the next token and pop it from the queue.
+ Token getNext();
+
+ void printError(SMLoc Loc, SourceMgr::DiagKind Kind, const Twine &Message,
+ ArrayRef<SMRange> Ranges = None) {
+ SM.PrintMessage(Loc, Kind, Message, Ranges, /* FixIts= */ None, ShowColors);
+ }
+
+ void setError(const Twine &Message, StringRef::iterator Position) {
+ if (Current >= End)
+ Current = End - 1;
+
+ // Don't print out more errors after the first one we encounter. The rest
+ // are just the result of the first, and have no meaning.
+ if (!Failed)
+ printError(SMLoc::getFromPointer(Current), SourceMgr::DK_Error, Message);
+ Failed = true;
+ }
+
+ void setError(const Twine &Message) {
+ setError(Message, Current);
+ }
+
+ /// @brief Returns true if an error occurred while parsing.
+ bool failed() {
+ return Failed;
+ }
+
+private:
+ void init(MemoryBufferRef Buffer);
+
+ StringRef currentInput() {
+ return StringRef(Current, End - Current);
+ }
+
+ /// @brief Decode a UTF-8 minimal well-formed code unit subsequence starting
+ /// at \a Position.
+ ///
+ /// If the UTF-8 code units starting at Position do not form a well-formed
+ /// code unit subsequence, then the Unicode scalar value is 0, and the length
+ /// is 0.
+ UTF8Decoded decodeUTF8(StringRef::iterator Position) {
+ return ::decodeUTF8(StringRef(Position, End - Position));
+ }
+
+ // The following functions are based on the gramar rules in the YAML spec. The
+ // style of the function names it meant to closely match how they are written
+ // in the spec. The number within the [] is the number of the grammar rule in
+ // the spec.
+ //
+ // See 4.2 [Production Naming Conventions] for the meaning of the prefixes.
+ //
+ // c-
+ // A production starting and ending with a special character.
+ // b-
+ // A production matching a single line break.
+ // nb-
+ // A production starting and ending with a non-break character.
+ // s-
+ // A production starting and ending with a white space character.
+ // ns-
+ // A production starting and ending with a non-space character.
+ // l-
+ // A production matching complete line(s).
+
+ /// @brief Skip a single nb-char[27] starting at Position.
+ ///
+ /// A nb-char is 0x9 | [0x20-0x7E] | 0x85 | [0xA0-0xD7FF] | [0xE000-0xFEFE]
+ /// | [0xFF00-0xFFFD] | [0x10000-0x10FFFF]
+ ///
+ /// @returns The code unit after the nb-char, or Position if it's not an
+ /// nb-char.
+ StringRef::iterator skip_nb_char(StringRef::iterator Position);
+
+ /// @brief Skip a single b-break[28] starting at Position.
+ ///
+ /// A b-break is 0xD 0xA | 0xD | 0xA
+ ///
+ /// @returns The code unit after the b-break, or Position if it's not a
+ /// b-break.
+ StringRef::iterator skip_b_break(StringRef::iterator Position);
+
+ /// Skip a single s-space[31] starting at Position.
+ ///
+ /// An s-space is 0x20
+ ///
+ /// @returns The code unit after the s-space, or Position if it's not a
+ /// s-space.
+ StringRef::iterator skip_s_space(StringRef::iterator Position);
+
+ /// @brief Skip a single s-white[33] starting at Position.
+ ///
+ /// A s-white is 0x20 | 0x9
+ ///
+ /// @returns The code unit after the s-white, or Position if it's not a
+ /// s-white.
+ StringRef::iterator skip_s_white(StringRef::iterator Position);
+
+ /// @brief Skip a single ns-char[34] starting at Position.
+ ///
+ /// A ns-char is nb-char - s-white
+ ///
+ /// @returns The code unit after the ns-char, or Position if it's not a
+ /// ns-char.
+ StringRef::iterator skip_ns_char(StringRef::iterator Position);
+
+ typedef StringRef::iterator (Scanner::*SkipWhileFunc)(StringRef::iterator);
+ /// @brief Skip minimal well-formed code unit subsequences until Func
+ /// returns its input.
+ ///
+ /// @returns The code unit after the last minimal well-formed code unit
+ /// subsequence that Func accepted.
+ StringRef::iterator skip_while( SkipWhileFunc Func
+ , StringRef::iterator Position);
+
+ /// Skip minimal well-formed code unit subsequences until Func returns its
+ /// input.
+ void advanceWhile(SkipWhileFunc Func);
+
+ /// @brief Scan ns-uri-char[39]s starting at Cur.
+ ///
+ /// This updates Cur and Column while scanning.
+ ///
+ /// @returns A StringRef starting at Cur which covers the longest contiguous
+ /// sequence of ns-uri-char.
+ StringRef scan_ns_uri_char();
+
+ /// @brief Consume a minimal well-formed code unit subsequence starting at
+ /// \a Cur. Return false if it is not the same Unicode scalar value as
+ /// \a Expected. This updates \a Column.
+ bool consume(uint32_t Expected);
+
+ /// @brief Skip \a Distance UTF-8 code units. Updates \a Cur and \a Column.
+ void skip(uint32_t Distance);
+
+ /// @brief Return true if the minimal well-formed code unit subsequence at
+ /// Pos is whitespace or a new line
+ bool isBlankOrBreak(StringRef::iterator Position);
+
+ /// Consume a single b-break[28] if it's present at the current position.
+ ///
+ /// Return false if the code unit at the current position isn't a line break.
+ bool consumeLineBreakIfPresent();
+
+ /// @brief If IsSimpleKeyAllowed, create and push_back a new SimpleKey.
+ void saveSimpleKeyCandidate( TokenQueueT::iterator Tok
+ , unsigned AtColumn
+ , bool IsRequired);
+
+ /// @brief Remove simple keys that can no longer be valid simple keys.
+ ///
+ /// Invalid simple keys are not on the current line or are further than 1024
+ /// columns back.
+ void removeStaleSimpleKeyCandidates();
+
+ /// @brief Remove all simple keys on FlowLevel \a Level.
+ void removeSimpleKeyCandidatesOnFlowLevel(unsigned Level);
+
+ /// @brief Unroll indentation in \a Indents back to \a Col. Creates BlockEnd
+ /// tokens if needed.
+ bool unrollIndent(int ToColumn);
+
+ /// @brief Increase indent to \a Col. Creates \a Kind token at \a InsertPoint
+ /// if needed.
+ bool rollIndent( int ToColumn
+ , Token::TokenKind Kind
+ , TokenQueueT::iterator InsertPoint);
+
+ /// @brief Skip a single-line comment when the comment starts at the current
+ /// position of the scanner.
+ void skipComment();
+
+ /// @brief Skip whitespace and comments until the start of the next token.
+ void scanToNextToken();
+
+ /// @brief Must be the first token generated.
+ bool scanStreamStart();
+
+ /// @brief Generate tokens needed to close out the stream.
+ bool scanStreamEnd();
+
+ /// @brief Scan a %BLAH directive.
+ bool scanDirective();
+
+ /// @brief Scan a ... or ---.
+ bool scanDocumentIndicator(bool IsStart);
+
+ /// @brief Scan a [ or { and generate the proper flow collection start token.
+ bool scanFlowCollectionStart(bool IsSequence);
+
+ /// @brief Scan a ] or } and generate the proper flow collection end token.
+ bool scanFlowCollectionEnd(bool IsSequence);
+
+ /// @brief Scan the , that separates entries in a flow collection.
+ bool scanFlowEntry();
+
+ /// @brief Scan the - that starts block sequence entries.
+ bool scanBlockEntry();
+
+ /// @brief Scan an explicit ? indicating a key.
+ bool scanKey();
+
+ /// @brief Scan an explicit : indicating a value.
+ bool scanValue();
+
+ /// @brief Scan a quoted scalar.
+ bool scanFlowScalar(bool IsDoubleQuoted);
+
+ /// @brief Scan an unquoted scalar.
+ bool scanPlainScalar();
+
+ /// @brief Scan an Alias or Anchor starting with * or &.
+ bool scanAliasOrAnchor(bool IsAlias);
+
+ /// @brief Scan a block scalar starting with | or >.
+ bool scanBlockScalar(bool IsLiteral);
+
+ /// Scan a chomping indicator in a block scalar header.
+ char scanBlockChompingIndicator();
+
+ /// Scan an indentation indicator in a block scalar header.
+ unsigned scanBlockIndentationIndicator();
+
+ /// Scan a block scalar header.
+ ///
+ /// Return false if an error occurred.
+ bool scanBlockScalarHeader(char &ChompingIndicator, unsigned &IndentIndicator,
+ bool &IsDone);
+
+ /// Look for the indentation level of a block scalar.
+ ///
+ /// Return false if an error occurred.
+ bool findBlockScalarIndent(unsigned &BlockIndent, unsigned BlockExitIndent,
+ unsigned &LineBreaks, bool &IsDone);
+
+ /// Scan the indentation of a text line in a block scalar.
+ ///
+ /// Return false if an error occurred.
+ bool scanBlockScalarIndent(unsigned BlockIndent, unsigned BlockExitIndent,
+ bool &IsDone);
+
+ /// @brief Scan a tag of the form !stuff.
+ bool scanTag();
+
+ /// @brief Dispatch to the next scanning function based on \a *Cur.
+ bool fetchMoreTokens();
+
+ /// @brief The SourceMgr used for diagnostics and buffer management.
+ SourceMgr &SM;
+
+ /// @brief The original input.
+ MemoryBufferRef InputBuffer;
+
+ /// @brief The current position of the scanner.
+ StringRef::iterator Current;
+
+ /// @brief The end of the input (one past the last character).
+ StringRef::iterator End;
+
+ /// @brief Current YAML indentation level in spaces.
+ int Indent;
+
+ /// @brief Current column number in Unicode code points.
+ unsigned Column;
+
+ /// @brief Current line number.
+ unsigned Line;
+
+ /// @brief How deep we are in flow style containers. 0 Means at block level.
+ unsigned FlowLevel;
+
+ /// @brief Are we at the start of the stream?
+ bool IsStartOfStream;
+
+ /// @brief Can the next token be the start of a simple key?
+ bool IsSimpleKeyAllowed;
+
+ /// @brief True if an error has occurred.
+ bool Failed;
+
+ /// @brief Should colors be used when printing out the diagnostic messages?
+ bool ShowColors;
+
+ /// @brief Queue of tokens. This is required to queue up tokens while looking
+ /// for the end of a simple key. And for cases where a single character
+ /// can produce multiple tokens (e.g. BlockEnd).
+ TokenQueueT TokenQueue;
+
+ /// @brief Indentation levels.
+ SmallVector<int, 4> Indents;
+
+ /// @brief Potential simple keys.
+ SmallVector<SimpleKey, 4> SimpleKeys;
+};
+
+} // end namespace yaml
+} // end namespace llvm
+
+/// encodeUTF8 - Encode \a UnicodeScalarValue in UTF-8 and append it to result.
+static void encodeUTF8( uint32_t UnicodeScalarValue
+ , SmallVectorImpl<char> &Result) {
+ if (UnicodeScalarValue <= 0x7F) {
+ Result.push_back(UnicodeScalarValue & 0x7F);
+ } else if (UnicodeScalarValue <= 0x7FF) {
+ uint8_t FirstByte = 0xC0 | ((UnicodeScalarValue & 0x7C0) >> 6);
+ uint8_t SecondByte = 0x80 | (UnicodeScalarValue & 0x3F);
+ Result.push_back(FirstByte);
+ Result.push_back(SecondByte);
+ } else if (UnicodeScalarValue <= 0xFFFF) {
+ uint8_t FirstByte = 0xE0 | ((UnicodeScalarValue & 0xF000) >> 12);
+ uint8_t SecondByte = 0x80 | ((UnicodeScalarValue & 0xFC0) >> 6);
+ uint8_t ThirdByte = 0x80 | (UnicodeScalarValue & 0x3F);
+ Result.push_back(FirstByte);
+ Result.push_back(SecondByte);
+ Result.push_back(ThirdByte);
+ } else if (UnicodeScalarValue <= 0x10FFFF) {
+ uint8_t FirstByte = 0xF0 | ((UnicodeScalarValue & 0x1F0000) >> 18);
+ uint8_t SecondByte = 0x80 | ((UnicodeScalarValue & 0x3F000) >> 12);
+ uint8_t ThirdByte = 0x80 | ((UnicodeScalarValue & 0xFC0) >> 6);
+ uint8_t FourthByte = 0x80 | (UnicodeScalarValue & 0x3F);
+ Result.push_back(FirstByte);
+ Result.push_back(SecondByte);
+ Result.push_back(ThirdByte);
+ Result.push_back(FourthByte);
+ }
+}
+
+bool yaml::dumpTokens(StringRef Input, raw_ostream &OS) {
+ SourceMgr SM;
+ Scanner scanner(Input, SM);
+ while (true) {
+ Token T = scanner.getNext();
+ switch (T.Kind) {
+ case Token::TK_StreamStart:
+ OS << "Stream-Start: ";
+ break;
+ case Token::TK_StreamEnd:
+ OS << "Stream-End: ";
+ break;
+ case Token::TK_VersionDirective:
+ OS << "Version-Directive: ";
+ break;
+ case Token::TK_TagDirective:
+ OS << "Tag-Directive: ";
+ break;
+ case Token::TK_DocumentStart:
+ OS << "Document-Start: ";
+ break;
+ case Token::TK_DocumentEnd:
+ OS << "Document-End: ";
+ break;
+ case Token::TK_BlockEntry:
+ OS << "Block-Entry: ";
+ break;
+ case Token::TK_BlockEnd:
+ OS << "Block-End: ";
+ break;
+ case Token::TK_BlockSequenceStart:
+ OS << "Block-Sequence-Start: ";
+ break;
+ case Token::TK_BlockMappingStart:
+ OS << "Block-Mapping-Start: ";
+ break;
+ case Token::TK_FlowEntry:
+ OS << "Flow-Entry: ";
+ break;
+ case Token::TK_FlowSequenceStart:
+ OS << "Flow-Sequence-Start: ";
+ break;
+ case Token::TK_FlowSequenceEnd:
+ OS << "Flow-Sequence-End: ";
+ break;
+ case Token::TK_FlowMappingStart:
+ OS << "Flow-Mapping-Start: ";
+ break;
+ case Token::TK_FlowMappingEnd:
+ OS << "Flow-Mapping-End: ";
+ break;
+ case Token::TK_Key:
+ OS << "Key: ";
+ break;
+ case Token::TK_Value:
+ OS << "Value: ";
+ break;
+ case Token::TK_Scalar:
+ OS << "Scalar: ";
+ break;
+ case Token::TK_BlockScalar:
+ OS << "Block Scalar: ";
+ break;
+ case Token::TK_Alias:
+ OS << "Alias: ";
+ break;
+ case Token::TK_Anchor:
+ OS << "Anchor: ";
+ break;
+ case Token::TK_Tag:
+ OS << "Tag: ";
+ break;
+ case Token::TK_Error:
+ break;
+ }
+ OS << T.Range << "\n";
+ if (T.Kind == Token::TK_StreamEnd)
+ break;
+ else if (T.Kind == Token::TK_Error)
+ return false;
+ }
+ return true;
+}
+
+bool yaml::scanTokens(StringRef Input) {
+ llvm::SourceMgr SM;
+ llvm::yaml::Scanner scanner(Input, SM);
+ for (;;) {
+ llvm::yaml::Token T = scanner.getNext();
+ if (T.Kind == Token::TK_StreamEnd)
+ break;
+ else if (T.Kind == Token::TK_Error)
+ return false;
+ }
+ return true;
+}
+
+std::string yaml::escape(StringRef Input) {
+ std::string EscapedInput;
+ for (StringRef::iterator i = Input.begin(), e = Input.end(); i != e; ++i) {
+ if (*i == '\\')
+ EscapedInput += "\\\\";
+ else if (*i == '"')
+ EscapedInput += "\\\"";
+ else if (*i == 0)
+ EscapedInput += "\\0";
+ else if (*i == 0x07)
+ EscapedInput += "\\a";
+ else if (*i == 0x08)
+ EscapedInput += "\\b";
+ else if (*i == 0x09)
+ EscapedInput += "\\t";
+ else if (*i == 0x0A)
+ EscapedInput += "\\n";
+ else if (*i == 0x0B)
+ EscapedInput += "\\v";
+ else if (*i == 0x0C)
+ EscapedInput += "\\f";
+ else if (*i == 0x0D)
+ EscapedInput += "\\r";
+ else if (*i == 0x1B)
+ EscapedInput += "\\e";
+ else if ((unsigned char)*i < 0x20) { // Control characters not handled above.
+ std::string HexStr = utohexstr(*i);
+ EscapedInput += "\\x" + std::string(2 - HexStr.size(), '0') + HexStr;
+ } else if (*i & 0x80) { // UTF-8 multiple code unit subsequence.
+ UTF8Decoded UnicodeScalarValue
+ = decodeUTF8(StringRef(i, Input.end() - i));
+ if (UnicodeScalarValue.second == 0) {
+ // Found invalid char.
+ SmallString<4> Val;
+ encodeUTF8(0xFFFD, Val);
+ EscapedInput.insert(EscapedInput.end(), Val.begin(), Val.end());
+ // FIXME: Error reporting.
+ return EscapedInput;
+ }
+ if (UnicodeScalarValue.first == 0x85)
+ EscapedInput += "\\N";
+ else if (UnicodeScalarValue.first == 0xA0)
+ EscapedInput += "\\_";
+ else if (UnicodeScalarValue.first == 0x2028)
+ EscapedInput += "\\L";
+ else if (UnicodeScalarValue.first == 0x2029)
+ EscapedInput += "\\P";
+ else {
+ std::string HexStr = utohexstr(UnicodeScalarValue.first);
+ if (HexStr.size() <= 2)
+ EscapedInput += "\\x" + std::string(2 - HexStr.size(), '0') + HexStr;
+ else if (HexStr.size() <= 4)
+ EscapedInput += "\\u" + std::string(4 - HexStr.size(), '0') + HexStr;
+ else if (HexStr.size() <= 8)
+ EscapedInput += "\\U" + std::string(8 - HexStr.size(), '0') + HexStr;
+ }
+ i += UnicodeScalarValue.second - 1;
+ } else
+ EscapedInput.push_back(*i);
+ }
+ return EscapedInput;
+}
+
+Scanner::Scanner(StringRef Input, SourceMgr &sm, bool ShowColors)
+ : SM(sm), ShowColors(ShowColors) {
+ init(MemoryBufferRef(Input, "YAML"));
+}
+
+Scanner::Scanner(MemoryBufferRef Buffer, SourceMgr &SM_, bool ShowColors)
+ : SM(SM_), ShowColors(ShowColors) {
+ init(Buffer);
+}
+
+void Scanner::init(MemoryBufferRef Buffer) {
+ InputBuffer = Buffer;
+ Current = InputBuffer.getBufferStart();
+ End = InputBuffer.getBufferEnd();
+ Indent = -1;
+ Column = 0;
+ Line = 0;
+ FlowLevel = 0;
+ IsStartOfStream = true;
+ IsSimpleKeyAllowed = true;
+ Failed = false;
+ std::unique_ptr<MemoryBuffer> InputBufferOwner =
+ MemoryBuffer::getMemBuffer(Buffer);
+ SM.AddNewSourceBuffer(std::move(InputBufferOwner), SMLoc());
+}
+
+Token &Scanner::peekNext() {
+ // If the current token is a possible simple key, keep parsing until we
+ // can confirm.
+ bool NeedMore = false;
+ while (true) {
+ if (TokenQueue.empty() || NeedMore) {
+ if (!fetchMoreTokens()) {
+ TokenQueue.clear();
+ TokenQueue.push_back(Token());
+ return TokenQueue.front();
+ }
+ }
+ assert(!TokenQueue.empty() &&
+ "fetchMoreTokens lied about getting tokens!");
+
+ removeStaleSimpleKeyCandidates();
+ SimpleKey SK;
+ SK.Tok = TokenQueue.front();
+ if (std::find(SimpleKeys.begin(), SimpleKeys.end(), SK)
+ == SimpleKeys.end())
+ break;
+ else
+ NeedMore = true;
+ }
+ return TokenQueue.front();
+}
+
+Token Scanner::getNext() {
+ Token Ret = peekNext();
+ // TokenQueue can be empty if there was an error getting the next token.
+ if (!TokenQueue.empty())
+ TokenQueue.pop_front();
+
+ // There cannot be any referenced Token's if the TokenQueue is empty. So do a
+ // quick deallocation of them all.
+ if (TokenQueue.empty()) {
+ TokenQueue.Alloc.Reset();
+ }
+
+ return Ret;
+}
+
+StringRef::iterator Scanner::skip_nb_char(StringRef::iterator Position) {
+ if (Position == End)
+ return Position;
+ // Check 7 bit c-printable - b-char.
+ if ( *Position == 0x09
+ || (*Position >= 0x20 && *Position <= 0x7E))
+ return Position + 1;
+
+ // Check for valid UTF-8.
+ if (uint8_t(*Position) & 0x80) {
+ UTF8Decoded u8d = decodeUTF8(Position);
+ if ( u8d.second != 0
+ && u8d.first != 0xFEFF
+ && ( u8d.first == 0x85
+ || ( u8d.first >= 0xA0
+ && u8d.first <= 0xD7FF)
+ || ( u8d.first >= 0xE000
+ && u8d.first <= 0xFFFD)
+ || ( u8d.first >= 0x10000
+ && u8d.first <= 0x10FFFF)))
+ return Position + u8d.second;
+ }
+ return Position;
+}
+
+StringRef::iterator Scanner::skip_b_break(StringRef::iterator Position) {
+ if (Position == End)
+ return Position;
+ if (*Position == 0x0D) {
+ if (Position + 1 != End && *(Position + 1) == 0x0A)
+ return Position + 2;
+ return Position + 1;
+ }
+
+ if (*Position == 0x0A)
+ return Position + 1;
+ return Position;
+}
+
+StringRef::iterator Scanner::skip_s_space(StringRef::iterator Position) {
+ if (Position == End)
+ return Position;
+ if (*Position == ' ')
+ return Position + 1;
+ return Position;
+}
+
+StringRef::iterator Scanner::skip_s_white(StringRef::iterator Position) {
+ if (Position == End)
+ return Position;
+ if (*Position == ' ' || *Position == '\t')
+ return Position + 1;
+ return Position;
+}
+
+StringRef::iterator Scanner::skip_ns_char(StringRef::iterator Position) {
+ if (Position == End)
+ return Position;
+ if (*Position == ' ' || *Position == '\t')
+ return Position;
+ return skip_nb_char(Position);
+}
+
+StringRef::iterator Scanner::skip_while( SkipWhileFunc Func
+ , StringRef::iterator Position) {
+ while (true) {
+ StringRef::iterator i = (this->*Func)(Position);
+ if (i == Position)
+ break;
+ Position = i;
+ }
+ return Position;
+}
+
+void Scanner::advanceWhile(SkipWhileFunc Func) {
+ auto Final = skip_while(Func, Current);
+ Column += Final - Current;
+ Current = Final;
+}
+
+static bool is_ns_hex_digit(const char C) {
+ return (C >= '0' && C <= '9')
+ || (C >= 'a' && C <= 'z')
+ || (C >= 'A' && C <= 'Z');
+}
+
+static bool is_ns_word_char(const char C) {
+ return C == '-'
+ || (C >= 'a' && C <= 'z')
+ || (C >= 'A' && C <= 'Z');
+}
+
+StringRef Scanner::scan_ns_uri_char() {
+ StringRef::iterator Start = Current;
+ while (true) {
+ if (Current == End)
+ break;
+ if (( *Current == '%'
+ && Current + 2 < End
+ && is_ns_hex_digit(*(Current + 1))
+ && is_ns_hex_digit(*(Current + 2)))
+ || is_ns_word_char(*Current)
+ || StringRef(Current, 1).find_first_of("#;/?:@&=+$,_.!~*'()[]")
+ != StringRef::npos) {
+ ++Current;
+ ++Column;
+ } else
+ break;
+ }
+ return StringRef(Start, Current - Start);
+}
+
+bool Scanner::consume(uint32_t Expected) {
+ if (Expected >= 0x80)
+ report_fatal_error("Not dealing with this yet");
+ if (Current == End)
+ return false;
+ if (uint8_t(*Current) >= 0x80)
+ report_fatal_error("Not dealing with this yet");
+ if (uint8_t(*Current) == Expected) {
+ ++Current;
+ ++Column;
+ return true;
+ }
+ return false;
+}
+
+void Scanner::skip(uint32_t Distance) {
+ Current += Distance;
+ Column += Distance;
+ assert(Current <= End && "Skipped past the end");
+}
+
+bool Scanner::isBlankOrBreak(StringRef::iterator Position) {
+ if (Position == End)
+ return false;
+ if ( *Position == ' ' || *Position == '\t'
+ || *Position == '\r' || *Position == '\n')
+ return true;
+ return false;
+}
+
+bool Scanner::consumeLineBreakIfPresent() {
+ auto Next = skip_b_break(Current);
+ if (Next == Current)
+ return false;
+ Column = 0;
+ ++Line;
+ Current = Next;
+ return true;
+}
+
+void Scanner::saveSimpleKeyCandidate( TokenQueueT::iterator Tok
+ , unsigned AtColumn
+ , bool IsRequired) {
+ if (IsSimpleKeyAllowed) {
+ SimpleKey SK;
+ SK.Tok = Tok;
+ SK.Line = Line;
+ SK.Column = AtColumn;
+ SK.IsRequired = IsRequired;
+ SK.FlowLevel = FlowLevel;
+ SimpleKeys.push_back(SK);
+ }
+}
+
+void Scanner::removeStaleSimpleKeyCandidates() {
+ for (SmallVectorImpl<SimpleKey>::iterator i = SimpleKeys.begin();
+ i != SimpleKeys.end();) {
+ if (i->Line != Line || i->Column + 1024 < Column) {
+ if (i->IsRequired)
+ setError( "Could not find expected : for simple key"
+ , i->Tok->Range.begin());
+ i = SimpleKeys.erase(i);
+ } else
+ ++i;
+ }
+}
+
+void Scanner::removeSimpleKeyCandidatesOnFlowLevel(unsigned Level) {
+ if (!SimpleKeys.empty() && (SimpleKeys.end() - 1)->FlowLevel == Level)
+ SimpleKeys.pop_back();
+}
+
+bool Scanner::unrollIndent(int ToColumn) {
+ Token T;
+ // Indentation is ignored in flow.
+ if (FlowLevel != 0)
+ return true;
+
+ while (Indent > ToColumn) {
+ T.Kind = Token::TK_BlockEnd;
+ T.Range = StringRef(Current, 1);
+ TokenQueue.push_back(T);
+ Indent = Indents.pop_back_val();
+ }
+
+ return true;
+}
+
+bool Scanner::rollIndent( int ToColumn
+ , Token::TokenKind Kind
+ , TokenQueueT::iterator InsertPoint) {
+ if (FlowLevel)
+ return true;
+ if (Indent < ToColumn) {
+ Indents.push_back(Indent);
+ Indent = ToColumn;
+
+ Token T;
+ T.Kind = Kind;
+ T.Range = StringRef(Current, 0);
+ TokenQueue.insert(InsertPoint, T);
+ }
+ return true;
+}
+
+void Scanner::skipComment() {
+ if (*Current != '#')
+ return;
+ while (true) {
+ // This may skip more than one byte, thus Column is only incremented
+ // for code points.
+ StringRef::iterator I = skip_nb_char(Current);
+ if (I == Current)
+ break;
+ Current = I;
+ ++Column;
+ }
+}
+
+void Scanner::scanToNextToken() {
+ while (true) {
+ while (*Current == ' ' || *Current == '\t') {
+ skip(1);
+ }
+
+ skipComment();
+
+ // Skip EOL.
+ StringRef::iterator i = skip_b_break(Current);
+ if (i == Current)
+ break;
+ Current = i;
+ ++Line;
+ Column = 0;
+ // New lines may start a simple key.
+ if (!FlowLevel)
+ IsSimpleKeyAllowed = true;
+ }
+}
+
+bool Scanner::scanStreamStart() {
+ IsStartOfStream = false;
+
+ EncodingInfo EI = getUnicodeEncoding(currentInput());
+
+ Token T;
+ T.Kind = Token::TK_StreamStart;
+ T.Range = StringRef(Current, EI.second);
+ TokenQueue.push_back(T);
+ Current += EI.second;
+ return true;
+}
+
+bool Scanner::scanStreamEnd() {
+ // Force an ending new line if one isn't present.
+ if (Column != 0) {
+ Column = 0;
+ ++Line;
+ }
+
+ unrollIndent(-1);
+ SimpleKeys.clear();
+ IsSimpleKeyAllowed = false;
+
+ Token T;
+ T.Kind = Token::TK_StreamEnd;
+ T.Range = StringRef(Current, 0);
+ TokenQueue.push_back(T);
+ return true;
+}
+
+bool Scanner::scanDirective() {
+ // Reset the indentation level.
+ unrollIndent(-1);
+ SimpleKeys.clear();
+ IsSimpleKeyAllowed = false;
+
+ StringRef::iterator Start = Current;
+ consume('%');
+ StringRef::iterator NameStart = Current;
+ Current = skip_while(&Scanner::skip_ns_char, Current);
+ StringRef Name(NameStart, Current - NameStart);
+ Current = skip_while(&Scanner::skip_s_white, Current);
+
+ Token T;
+ if (Name == "YAML") {
+ Current = skip_while(&Scanner::skip_ns_char, Current);
+ T.Kind = Token::TK_VersionDirective;
+ T.Range = StringRef(Start, Current - Start);
+ TokenQueue.push_back(T);
+ return true;
+ } else if(Name == "TAG") {
+ Current = skip_while(&Scanner::skip_ns_char, Current);
+ Current = skip_while(&Scanner::skip_s_white, Current);
+ Current = skip_while(&Scanner::skip_ns_char, Current);
+ T.Kind = Token::TK_TagDirective;
+ T.Range = StringRef(Start, Current - Start);
+ TokenQueue.push_back(T);
+ return true;
+ }
+ return false;
+}
+
+bool Scanner::scanDocumentIndicator(bool IsStart) {
+ unrollIndent(-1);
+ SimpleKeys.clear();
+ IsSimpleKeyAllowed = false;
+
+ Token T;
+ T.Kind = IsStart ? Token::TK_DocumentStart : Token::TK_DocumentEnd;
+ T.Range = StringRef(Current, 3);
+ skip(3);
+ TokenQueue.push_back(T);
+ return true;
+}
+
+bool Scanner::scanFlowCollectionStart(bool IsSequence) {
+ Token T;
+ T.Kind = IsSequence ? Token::TK_FlowSequenceStart
+ : Token::TK_FlowMappingStart;
+ T.Range = StringRef(Current, 1);
+ skip(1);
+ TokenQueue.push_back(T);
+
+ // [ and { may begin a simple key.
+ saveSimpleKeyCandidate(TokenQueue.back(), Column - 1, false);
+
+ // And may also be followed by a simple key.
+ IsSimpleKeyAllowed = true;
+ ++FlowLevel;
+ return true;
+}
+
+bool Scanner::scanFlowCollectionEnd(bool IsSequence) {
+ removeSimpleKeyCandidatesOnFlowLevel(FlowLevel);
+ IsSimpleKeyAllowed = false;
+ Token T;
+ T.Kind = IsSequence ? Token::TK_FlowSequenceEnd
+ : Token::TK_FlowMappingEnd;
+ T.Range = StringRef(Current, 1);
+ skip(1);
+ TokenQueue.push_back(T);
+ if (FlowLevel)
+ --FlowLevel;
+ return true;
+}
+
+bool Scanner::scanFlowEntry() {
+ removeSimpleKeyCandidatesOnFlowLevel(FlowLevel);
+ IsSimpleKeyAllowed = true;
+ Token T;
+ T.Kind = Token::TK_FlowEntry;
+ T.Range = StringRef(Current, 1);
+ skip(1);
+ TokenQueue.push_back(T);
+ return true;
+}
+
+bool Scanner::scanBlockEntry() {
+ rollIndent(Column, Token::TK_BlockSequenceStart, TokenQueue.end());
+ removeSimpleKeyCandidatesOnFlowLevel(FlowLevel);
+ IsSimpleKeyAllowed = true;
+ Token T;
+ T.Kind = Token::TK_BlockEntry;
+ T.Range = StringRef(Current, 1);
+ skip(1);
+ TokenQueue.push_back(T);
+ return true;
+}
+
+bool Scanner::scanKey() {
+ if (!FlowLevel)
+ rollIndent(Column, Token::TK_BlockMappingStart, TokenQueue.end());
+
+ removeSimpleKeyCandidatesOnFlowLevel(FlowLevel);
+ IsSimpleKeyAllowed = !FlowLevel;
+
+ Token T;
+ T.Kind = Token::TK_Key;
+ T.Range = StringRef(Current, 1);
+ skip(1);
+ TokenQueue.push_back(T);
+ return true;
+}
+
+bool Scanner::scanValue() {
+ // If the previous token could have been a simple key, insert the key token
+ // into the token queue.
+ if (!SimpleKeys.empty()) {
+ SimpleKey SK = SimpleKeys.pop_back_val();
+ Token T;
+ T.Kind = Token::TK_Key;
+ T.Range = SK.Tok->Range;
+ TokenQueueT::iterator i, e;
+ for (i = TokenQueue.begin(), e = TokenQueue.end(); i != e; ++i) {
+ if (i == SK.Tok)
+ break;
+ }
+ assert(i != e && "SimpleKey not in token queue!");
+ i = TokenQueue.insert(i, T);
+
+ // We may also need to add a Block-Mapping-Start token.
+ rollIndent(SK.Column, Token::TK_BlockMappingStart, i);
+
+ IsSimpleKeyAllowed = false;
+ } else {
+ if (!FlowLevel)
+ rollIndent(Column, Token::TK_BlockMappingStart, TokenQueue.end());
+ IsSimpleKeyAllowed = !FlowLevel;
+ }
+
+ Token T;
+ T.Kind = Token::TK_Value;
+ T.Range = StringRef(Current, 1);
+ skip(1);
+ TokenQueue.push_back(T);
+ return true;
+}
+
+// Forbidding inlining improves performance by roughly 20%.
+// FIXME: Remove once llvm optimizes this to the faster version without hints.
+LLVM_ATTRIBUTE_NOINLINE static bool
+wasEscaped(StringRef::iterator First, StringRef::iterator Position);
+
+// Returns whether a character at 'Position' was escaped with a leading '\'.
+// 'First' specifies the position of the first character in the string.
+static bool wasEscaped(StringRef::iterator First,
+ StringRef::iterator Position) {
+ assert(Position - 1 >= First);
+ StringRef::iterator I = Position - 1;
+ // We calculate the number of consecutive '\'s before the current position
+ // by iterating backwards through our string.
+ while (I >= First && *I == '\\') --I;
+ // (Position - 1 - I) now contains the number of '\'s before the current
+ // position. If it is odd, the character at 'Position' was escaped.
+ return (Position - 1 - I) % 2 == 1;
+}
+
+bool Scanner::scanFlowScalar(bool IsDoubleQuoted) {
+ StringRef::iterator Start = Current;
+ unsigned ColStart = Column;
+ if (IsDoubleQuoted) {
+ do {
+ ++Current;
+ while (Current != End && *Current != '"')
+ ++Current;
+ // Repeat until the previous character was not a '\' or was an escaped
+ // backslash.
+ } while ( Current != End
+ && *(Current - 1) == '\\'
+ && wasEscaped(Start + 1, Current));
+ } else {
+ skip(1);
+ while (true) {
+ // Skip a ' followed by another '.
+ if (Current + 1 < End && *Current == '\'' && *(Current + 1) == '\'') {
+ skip(2);
+ continue;
+ } else if (*Current == '\'')
+ break;
+ StringRef::iterator i = skip_nb_char(Current);
+ if (i == Current) {
+ i = skip_b_break(Current);
+ if (i == Current)
+ break;
+ Current = i;
+ Column = 0;
+ ++Line;
+ } else {
+ if (i == End)
+ break;
+ Current = i;
+ ++Column;
+ }
+ }
+ }
+
+ if (Current == End) {
+ setError("Expected quote at end of scalar", Current);
+ return false;
+ }
+
+ skip(1); // Skip ending quote.
+ Token T;
+ T.Kind = Token::TK_Scalar;
+ T.Range = StringRef(Start, Current - Start);
+ TokenQueue.push_back(T);
+
+ saveSimpleKeyCandidate(TokenQueue.back(), ColStart, false);
+
+ IsSimpleKeyAllowed = false;
+
+ return true;
+}
+
+bool Scanner::scanPlainScalar() {
+ StringRef::iterator Start = Current;
+ unsigned ColStart = Column;
+ unsigned LeadingBlanks = 0;
+ assert(Indent >= -1 && "Indent must be >= -1 !");
+ unsigned indent = static_cast<unsigned>(Indent + 1);
+ while (true) {
+ if (*Current == '#')
+ break;
+
+ while (!isBlankOrBreak(Current)) {
+ if ( FlowLevel && *Current == ':'
+ && !(isBlankOrBreak(Current + 1) || *(Current + 1) == ',')) {
+ setError("Found unexpected ':' while scanning a plain scalar", Current);
+ return false;
+ }
+
+ // Check for the end of the plain scalar.
+ if ( (*Current == ':' && isBlankOrBreak(Current + 1))
+ || ( FlowLevel
+ && (StringRef(Current, 1).find_first_of(",:?[]{}")
+ != StringRef::npos)))
+ break;
+
+ StringRef::iterator i = skip_nb_char(Current);
+ if (i == Current)
+ break;
+ Current = i;
+ ++Column;
+ }
+
+ // Are we at the end?
+ if (!isBlankOrBreak(Current))
+ break;
+
+ // Eat blanks.
+ StringRef::iterator Tmp = Current;
+ while (isBlankOrBreak(Tmp)) {
+ StringRef::iterator i = skip_s_white(Tmp);
+ if (i != Tmp) {
+ if (LeadingBlanks && (Column < indent) && *Tmp == '\t') {
+ setError("Found invalid tab character in indentation", Tmp);
+ return false;
+ }
+ Tmp = i;
+ ++Column;
+ } else {
+ i = skip_b_break(Tmp);
+ if (!LeadingBlanks)
+ LeadingBlanks = 1;
+ Tmp = i;
+ Column = 0;
+ ++Line;
+ }
+ }
+
+ if (!FlowLevel && Column < indent)
+ break;
+
+ Current = Tmp;
+ }
+ if (Start == Current) {
+ setError("Got empty plain scalar", Start);
+ return false;
+ }
+ Token T;
+ T.Kind = Token::TK_Scalar;
+ T.Range = StringRef(Start, Current - Start);
+ TokenQueue.push_back(T);
+
+ // Plain scalars can be simple keys.
+ saveSimpleKeyCandidate(TokenQueue.back(), ColStart, false);
+
+ IsSimpleKeyAllowed = false;
+
+ return true;
+}
+
+bool Scanner::scanAliasOrAnchor(bool IsAlias) {
+ StringRef::iterator Start = Current;
+ unsigned ColStart = Column;
+ skip(1);
+ while(true) {
+ if ( *Current == '[' || *Current == ']'
+ || *Current == '{' || *Current == '}'
+ || *Current == ','
+ || *Current == ':')
+ break;
+ StringRef::iterator i = skip_ns_char(Current);
+ if (i == Current)
+ break;
+ Current = i;
+ ++Column;
+ }
+
+ if (Start == Current) {
+ setError("Got empty alias or anchor", Start);
+ return false;
+ }
+
+ Token T;
+ T.Kind = IsAlias ? Token::TK_Alias : Token::TK_Anchor;
+ T.Range = StringRef(Start, Current - Start);
+ TokenQueue.push_back(T);
+
+ // Alias and anchors can be simple keys.
+ saveSimpleKeyCandidate(TokenQueue.back(), ColStart, false);
+
+ IsSimpleKeyAllowed = false;
+
+ return true;
+}
+
+char Scanner::scanBlockChompingIndicator() {
+ char Indicator = ' ';
+ if (Current != End && (*Current == '+' || *Current == '-')) {
+ Indicator = *Current;
+ skip(1);
+ }
+ return Indicator;
+}
+
+/// Get the number of line breaks after chomping.
+///
+/// Return the number of trailing line breaks to emit, depending on
+/// \p ChompingIndicator.
+static unsigned getChompedLineBreaks(char ChompingIndicator,
+ unsigned LineBreaks, StringRef Str) {
+ if (ChompingIndicator == '-') // Strip all line breaks.
+ return 0;
+ if (ChompingIndicator == '+') // Keep all line breaks.
+ return LineBreaks;
+ // Clip trailing lines.
+ return Str.empty() ? 0 : 1;
+}
+
+unsigned Scanner::scanBlockIndentationIndicator() {
+ unsigned Indent = 0;
+ if (Current != End && (*Current >= '1' && *Current <= '9')) {
+ Indent = unsigned(*Current - '0');
+ skip(1);
+ }
+ return Indent;
+}
+
+bool Scanner::scanBlockScalarHeader(char &ChompingIndicator,
+ unsigned &IndentIndicator, bool &IsDone) {
+ auto Start = Current;
+
+ ChompingIndicator = scanBlockChompingIndicator();
+ IndentIndicator = scanBlockIndentationIndicator();
+ // Check for the chomping indicator once again.
+ if (ChompingIndicator == ' ')
+ ChompingIndicator = scanBlockChompingIndicator();
+ Current = skip_while(&Scanner::skip_s_white, Current);
+ skipComment();
+
+ if (Current == End) { // EOF, we have an empty scalar.
+ Token T;
+ T.Kind = Token::TK_BlockScalar;
+ T.Range = StringRef(Start, Current - Start);
+ TokenQueue.push_back(T);
+ IsDone = true;
+ return true;
+ }
+
+ if (!consumeLineBreakIfPresent()) {
+ setError("Expected a line break after block scalar header", Current);
+ return false;
+ }
+ return true;
+}
+
+bool Scanner::findBlockScalarIndent(unsigned &BlockIndent,
+ unsigned BlockExitIndent,
+ unsigned &LineBreaks, bool &IsDone) {
+ unsigned MaxAllSpaceLineCharacters = 0;
+ StringRef::iterator LongestAllSpaceLine;
+
+ while (true) {
+ advanceWhile(&Scanner::skip_s_space);
+ if (skip_nb_char(Current) != Current) {
+ // This line isn't empty, so try and find the indentation.
+ if (Column <= BlockExitIndent) { // End of the block literal.
+ IsDone = true;
+ return true;
+ }
+ // We found the block's indentation.
+ BlockIndent = Column;
+ if (MaxAllSpaceLineCharacters > BlockIndent) {
+ setError(
+ "Leading all-spaces line must be smaller than the block indent",
+ LongestAllSpaceLine);
+ return false;
+ }
+ return true;
+ }
+ if (skip_b_break(Current) != Current &&
+ Column > MaxAllSpaceLineCharacters) {
+ // Record the longest all-space line in case it's longer than the
+ // discovered block indent.
+ MaxAllSpaceLineCharacters = Column;
+ LongestAllSpaceLine = Current;
+ }
+
+ // Check for EOF.
+ if (Current == End) {
+ IsDone = true;
+ return true;
+ }
+
+ if (!consumeLineBreakIfPresent()) {
+ IsDone = true;
+ return true;
+ }
+ ++LineBreaks;
+ }
+ return true;
+}
+
+bool Scanner::scanBlockScalarIndent(unsigned BlockIndent,
+ unsigned BlockExitIndent, bool &IsDone) {
+ // Skip the indentation.
+ while (Column < BlockIndent) {
+ auto I = skip_s_space(Current);
+ if (I == Current)
+ break;
+ Current = I;
+ ++Column;
+ }
+
+ if (skip_nb_char(Current) == Current)
+ return true;
+
+ if (Column <= BlockExitIndent) { // End of the block literal.
+ IsDone = true;
+ return true;
+ }
+
+ if (Column < BlockIndent) {
+ if (Current != End && *Current == '#') { // Trailing comment.
+ IsDone = true;
+ return true;
+ }
+ setError("A text line is less indented than the block scalar", Current);
+ return false;
+ }
+ return true; // A normal text line.
+}
+
+bool Scanner::scanBlockScalar(bool IsLiteral) {
+ // Eat '|' or '>'
+ assert(*Current == '|' || *Current == '>');
+ skip(1);
+
+ char ChompingIndicator;
+ unsigned BlockIndent;
+ bool IsDone = false;
+ if (!scanBlockScalarHeader(ChompingIndicator, BlockIndent, IsDone))
+ return false;
+ if (IsDone)
+ return true;
+
+ auto Start = Current;
+ unsigned BlockExitIndent = Indent < 0 ? 0 : (unsigned)Indent;
+ unsigned LineBreaks = 0;
+ if (BlockIndent == 0) {
+ if (!findBlockScalarIndent(BlockIndent, BlockExitIndent, LineBreaks,
+ IsDone))
+ return false;
+ }
+
+ // Scan the block's scalars body.
+ SmallString<256> Str;
+ while (!IsDone) {
+ if (!scanBlockScalarIndent(BlockIndent, BlockExitIndent, IsDone))
+ return false;
+ if (IsDone)
+ break;
+
+ // Parse the current line.
+ auto LineStart = Current;
+ advanceWhile(&Scanner::skip_nb_char);
+ if (LineStart != Current) {
+ Str.append(LineBreaks, '\n');
+ Str.append(StringRef(LineStart, Current - LineStart));
+ LineBreaks = 0;
+ }
+
+ // Check for EOF.
+ if (Current == End)
+ break;
+
+ if (!consumeLineBreakIfPresent())
+ break;
+ ++LineBreaks;
+ }
+
+ if (Current == End && !LineBreaks)
+ // Ensure that there is at least one line break before the end of file.
+ LineBreaks = 1;
+ Str.append(getChompedLineBreaks(ChompingIndicator, LineBreaks, Str), '\n');
+
+ // New lines may start a simple key.
+ if (!FlowLevel)
+ IsSimpleKeyAllowed = true;
+
+ Token T;
+ T.Kind = Token::TK_BlockScalar;
+ T.Range = StringRef(Start, Current - Start);
+ T.Value = Str.str().str();
+ TokenQueue.push_back(T);
+ return true;
+}
+
+bool Scanner::scanTag() {
+ StringRef::iterator Start = Current;
+ unsigned ColStart = Column;
+ skip(1); // Eat !.
+ if (Current == End || isBlankOrBreak(Current)); // An empty tag.
+ else if (*Current == '<') {
+ skip(1);
+ scan_ns_uri_char();
+ if (!consume('>'))
+ return false;
+ } else {
+ // FIXME: Actually parse the c-ns-shorthand-tag rule.
+ Current = skip_while(&Scanner::skip_ns_char, Current);
+ }
+
+ Token T;
+ T.Kind = Token::TK_Tag;
+ T.Range = StringRef(Start, Current - Start);
+ TokenQueue.push_back(T);
+
+ // Tags can be simple keys.
+ saveSimpleKeyCandidate(TokenQueue.back(), ColStart, false);
+
+ IsSimpleKeyAllowed = false;
+
+ return true;
+}
+
+bool Scanner::fetchMoreTokens() {
+ if (IsStartOfStream)
+ return scanStreamStart();
+
+ scanToNextToken();
+
+ if (Current == End)
+ return scanStreamEnd();
+
+ removeStaleSimpleKeyCandidates();
+
+ unrollIndent(Column);
+
+ if (Column == 0 && *Current == '%')
+ return scanDirective();
+
+ if (Column == 0 && Current + 4 <= End
+ && *Current == '-'
+ && *(Current + 1) == '-'
+ && *(Current + 2) == '-'
+ && (Current + 3 == End || isBlankOrBreak(Current + 3)))
+ return scanDocumentIndicator(true);
+
+ if (Column == 0 && Current + 4 <= End
+ && *Current == '.'
+ && *(Current + 1) == '.'
+ && *(Current + 2) == '.'
+ && (Current + 3 == End || isBlankOrBreak(Current + 3)))
+ return scanDocumentIndicator(false);
+
+ if (*Current == '[')
+ return scanFlowCollectionStart(true);
+
+ if (*Current == '{')
+ return scanFlowCollectionStart(false);
+
+ if (*Current == ']')
+ return scanFlowCollectionEnd(true);
+
+ if (*Current == '}')
+ return scanFlowCollectionEnd(false);
+
+ if (*Current == ',')
+ return scanFlowEntry();
+
+ if (*Current == '-' && isBlankOrBreak(Current + 1))
+ return scanBlockEntry();
+
+ if (*Current == '?' && (FlowLevel || isBlankOrBreak(Current + 1)))
+ return scanKey();
+
+ if (*Current == ':' && (FlowLevel || isBlankOrBreak(Current + 1)))
+ return scanValue();
+
+ if (*Current == '*')
+ return scanAliasOrAnchor(true);
+
+ if (*Current == '&')
+ return scanAliasOrAnchor(false);
+
+ if (*Current == '!')
+ return scanTag();
+
+ if (*Current == '|' && !FlowLevel)
+ return scanBlockScalar(true);
+
+ if (*Current == '>' && !FlowLevel)
+ return scanBlockScalar(false);
+
+ if (*Current == '\'')
+ return scanFlowScalar(false);
+
+ if (*Current == '"')
+ return scanFlowScalar(true);
+
+ // Get a plain scalar.
+ StringRef FirstChar(Current, 1);
+ if (!(isBlankOrBreak(Current)
+ || FirstChar.find_first_of("-?:,[]{}#&*!|>'\"%@`") != StringRef::npos)
+ || (*Current == '-' && !isBlankOrBreak(Current + 1))
+ || (!FlowLevel && (*Current == '?' || *Current == ':')
+ && isBlankOrBreak(Current + 1))
+ || (!FlowLevel && *Current == ':'
+ && Current + 2 < End
+ && *(Current + 1) == ':'
+ && !isBlankOrBreak(Current + 2)))
+ return scanPlainScalar();
+
+ setError("Unrecognized character while tokenizing.");
+ return false;
+}
+
+Stream::Stream(StringRef Input, SourceMgr &SM, bool ShowColors)
+ : scanner(new Scanner(Input, SM, ShowColors)), CurrentDoc() {}
+
+Stream::Stream(MemoryBufferRef InputBuffer, SourceMgr &SM, bool ShowColors)
+ : scanner(new Scanner(InputBuffer, SM, ShowColors)), CurrentDoc() {}
+
+Stream::~Stream() {}
+
+bool Stream::failed() { return scanner->failed(); }
+
+void Stream::printError(Node *N, const Twine &Msg) {
+ scanner->printError( N->getSourceRange().Start
+ , SourceMgr::DK_Error
+ , Msg
+ , N->getSourceRange());
+}
+
+document_iterator Stream::begin() {
+ if (CurrentDoc)
+ report_fatal_error("Can only iterate over the stream once");
+
+ // Skip Stream-Start.
+ scanner->getNext();
+
+ CurrentDoc.reset(new Document(*this));
+ return document_iterator(CurrentDoc);
+}
+
+document_iterator Stream::end() {
+ return document_iterator();
+}
+
+void Stream::skip() {
+ for (document_iterator i = begin(), e = end(); i != e; ++i)
+ i->skip();
+}
+
+Node::Node(unsigned int Type, std::unique_ptr<Document> &D, StringRef A,
+ StringRef T)
+ : Doc(D), TypeID(Type), Anchor(A), Tag(T) {
+ SMLoc Start = SMLoc::getFromPointer(peekNext().Range.begin());
+ SourceRange = SMRange(Start, Start);
+}
+
+std::string Node::getVerbatimTag() const {
+ StringRef Raw = getRawTag();
+ if (!Raw.empty() && Raw != "!") {
+ std::string Ret;
+ if (Raw.find_last_of('!') == 0) {
+ Ret = Doc->getTagMap().find("!")->second;
+ Ret += Raw.substr(1);
+ return Ret;
+ } else if (Raw.startswith("!!")) {
+ Ret = Doc->getTagMap().find("!!")->second;
+ Ret += Raw.substr(2);
+ return Ret;
+ } else {
+ StringRef TagHandle = Raw.substr(0, Raw.find_last_of('!') + 1);
+ std::map<StringRef, StringRef>::const_iterator It =
+ Doc->getTagMap().find(TagHandle);
+ if (It != Doc->getTagMap().end())
+ Ret = It->second;
+ else {
+ Token T;
+ T.Kind = Token::TK_Tag;
+ T.Range = TagHandle;
+ setError(Twine("Unknown tag handle ") + TagHandle, T);
+ }
+ Ret += Raw.substr(Raw.find_last_of('!') + 1);
+ return Ret;
+ }
+ }
+
+ switch (getType()) {
+ case NK_Null:
+ return "tag:yaml.org,2002:null";
+ case NK_Scalar:
+ case NK_BlockScalar:
+ // TODO: Tag resolution.
+ return "tag:yaml.org,2002:str";
+ case NK_Mapping:
+ return "tag:yaml.org,2002:map";
+ case NK_Sequence:
+ return "tag:yaml.org,2002:seq";
+ }
+
+ return "";
+}
+
+Token &Node::peekNext() {
+ return Doc->peekNext();
+}
+
+Token Node::getNext() {
+ return Doc->getNext();
+}
+
+Node *Node::parseBlockNode() {
+ return Doc->parseBlockNode();
+}
+
+BumpPtrAllocator &Node::getAllocator() {
+ return Doc->NodeAllocator;
+}
+
+void Node::setError(const Twine &Msg, Token &Tok) const {
+ Doc->setError(Msg, Tok);
+}
+
+bool Node::failed() const {
+ return Doc->failed();
+}
+
+
+
+StringRef ScalarNode::getValue(SmallVectorImpl<char> &Storage) const {
+ // TODO: Handle newlines properly. We need to remove leading whitespace.
+ if (Value[0] == '"') { // Double quoted.
+ // Pull off the leading and trailing "s.
+ StringRef UnquotedValue = Value.substr(1, Value.size() - 2);
+ // Search for characters that would require unescaping the value.
+ StringRef::size_type i = UnquotedValue.find_first_of("\\\r\n");
+ if (i != StringRef::npos)
+ return unescapeDoubleQuoted(UnquotedValue, i, Storage);
+ return UnquotedValue;
+ } else if (Value[0] == '\'') { // Single quoted.
+ // Pull off the leading and trailing 's.
+ StringRef UnquotedValue = Value.substr(1, Value.size() - 2);
+ StringRef::size_type i = UnquotedValue.find('\'');
+ if (i != StringRef::npos) {
+ // We're going to need Storage.
+ Storage.clear();
+ Storage.reserve(UnquotedValue.size());
+ for (; i != StringRef::npos; i = UnquotedValue.find('\'')) {
+ StringRef Valid(UnquotedValue.begin(), i);
+ Storage.insert(Storage.end(), Valid.begin(), Valid.end());
+ Storage.push_back('\'');
+ UnquotedValue = UnquotedValue.substr(i + 2);
+ }
+ Storage.insert(Storage.end(), UnquotedValue.begin(), UnquotedValue.end());
+ return StringRef(Storage.begin(), Storage.size());
+ }
+ return UnquotedValue;
+ }
+ // Plain or block.
+ return Value.rtrim(" ");
+}
+
+StringRef ScalarNode::unescapeDoubleQuoted( StringRef UnquotedValue
+ , StringRef::size_type i
+ , SmallVectorImpl<char> &Storage)
+ const {
+ // Use Storage to build proper value.
+ Storage.clear();
+ Storage.reserve(UnquotedValue.size());
+ for (; i != StringRef::npos; i = UnquotedValue.find_first_of("\\\r\n")) {
+ // Insert all previous chars into Storage.
+ StringRef Valid(UnquotedValue.begin(), i);
+ Storage.insert(Storage.end(), Valid.begin(), Valid.end());
+ // Chop off inserted chars.
+ UnquotedValue = UnquotedValue.substr(i);
+
+ assert(!UnquotedValue.empty() && "Can't be empty!");
+
+ // Parse escape or line break.
+ switch (UnquotedValue[0]) {
+ case '\r':
+ case '\n':
+ Storage.push_back('\n');
+ if ( UnquotedValue.size() > 1
+ && (UnquotedValue[1] == '\r' || UnquotedValue[1] == '\n'))
+ UnquotedValue = UnquotedValue.substr(1);
+ UnquotedValue = UnquotedValue.substr(1);
+ break;
+ default:
+ if (UnquotedValue.size() == 1)
+ // TODO: Report error.
+ break;
+ UnquotedValue = UnquotedValue.substr(1);
+ switch (UnquotedValue[0]) {
+ default: {
+ Token T;
+ T.Range = StringRef(UnquotedValue.begin(), 1);
+ setError("Unrecognized escape code!", T);
+ return "";
+ }
+ case '\r':
+ case '\n':
+ // Remove the new line.
+ if ( UnquotedValue.size() > 1
+ && (UnquotedValue[1] == '\r' || UnquotedValue[1] == '\n'))
+ UnquotedValue = UnquotedValue.substr(1);
+ // If this was just a single byte newline, it will get skipped
+ // below.
+ break;
+ case '0':
+ Storage.push_back(0x00);
+ break;
+ case 'a':
+ Storage.push_back(0x07);
+ break;
+ case 'b':
+ Storage.push_back(0x08);
+ break;
+ case 't':
+ case 0x09:
+ Storage.push_back(0x09);
+ break;
+ case 'n':
+ Storage.push_back(0x0A);
+ break;
+ case 'v':
+ Storage.push_back(0x0B);
+ break;
+ case 'f':
+ Storage.push_back(0x0C);
+ break;
+ case 'r':
+ Storage.push_back(0x0D);
+ break;
+ case 'e':
+ Storage.push_back(0x1B);
+ break;
+ case ' ':
+ Storage.push_back(0x20);
+ break;
+ case '"':
+ Storage.push_back(0x22);
+ break;
+ case '/':
+ Storage.push_back(0x2F);
+ break;
+ case '\\':
+ Storage.push_back(0x5C);
+ break;
+ case 'N':
+ encodeUTF8(0x85, Storage);
+ break;
+ case '_':
+ encodeUTF8(0xA0, Storage);
+ break;
+ case 'L':
+ encodeUTF8(0x2028, Storage);
+ break;
+ case 'P':
+ encodeUTF8(0x2029, Storage);
+ break;
+ case 'x': {
+ if (UnquotedValue.size() < 3)
+ // TODO: Report error.
+ break;
+ unsigned int UnicodeScalarValue;
+ if (UnquotedValue.substr(1, 2).getAsInteger(16, UnicodeScalarValue))
+ // TODO: Report error.
+ UnicodeScalarValue = 0xFFFD;
+ encodeUTF8(UnicodeScalarValue, Storage);
+ UnquotedValue = UnquotedValue.substr(2);
+ break;
+ }
+ case 'u': {
+ if (UnquotedValue.size() < 5)
+ // TODO: Report error.
+ break;
+ unsigned int UnicodeScalarValue;
+ if (UnquotedValue.substr(1, 4).getAsInteger(16, UnicodeScalarValue))
+ // TODO: Report error.
+ UnicodeScalarValue = 0xFFFD;
+ encodeUTF8(UnicodeScalarValue, Storage);
+ UnquotedValue = UnquotedValue.substr(4);
+ break;
+ }
+ case 'U': {
+ if (UnquotedValue.size() < 9)
+ // TODO: Report error.
+ break;
+ unsigned int UnicodeScalarValue;
+ if (UnquotedValue.substr(1, 8).getAsInteger(16, UnicodeScalarValue))
+ // TODO: Report error.
+ UnicodeScalarValue = 0xFFFD;
+ encodeUTF8(UnicodeScalarValue, Storage);
+ UnquotedValue = UnquotedValue.substr(8);
+ break;
+ }
+ }
+ UnquotedValue = UnquotedValue.substr(1);
+ }
+ }
+ Storage.insert(Storage.end(), UnquotedValue.begin(), UnquotedValue.end());
+ return StringRef(Storage.begin(), Storage.size());
+}
+
+Node *KeyValueNode::getKey() {
+ if (Key)
+ return Key;
+ // Handle implicit null keys.
+ {
+ Token &t = peekNext();
+ if ( t.Kind == Token::TK_BlockEnd
+ || t.Kind == Token::TK_Value
+ || t.Kind == Token::TK_Error) {
+ return Key = new (getAllocator()) NullNode(Doc);
+ }
+ if (t.Kind == Token::TK_Key)
+ getNext(); // skip TK_Key.
+ }
+
+ // Handle explicit null keys.
+ Token &t = peekNext();
+ if (t.Kind == Token::TK_BlockEnd || t.Kind == Token::TK_Value) {
+ return Key = new (getAllocator()) NullNode(Doc);
+ }
+
+ // We've got a normal key.
+ return Key = parseBlockNode();
+}
+
+Node *KeyValueNode::getValue() {
+ if (Value)
+ return Value;
+ getKey()->skip();
+ if (failed())
+ return Value = new (getAllocator()) NullNode(Doc);
+
+ // Handle implicit null values.
+ {
+ Token &t = peekNext();
+ if ( t.Kind == Token::TK_BlockEnd
+ || t.Kind == Token::TK_FlowMappingEnd
+ || t.Kind == Token::TK_Key
+ || t.Kind == Token::TK_FlowEntry
+ || t.Kind == Token::TK_Error) {
+ return Value = new (getAllocator()) NullNode(Doc);
+ }
+
+ if (t.Kind != Token::TK_Value) {
+ setError("Unexpected token in Key Value.", t);
+ return Value = new (getAllocator()) NullNode(Doc);
+ }
+ getNext(); // skip TK_Value.
+ }
+
+ // Handle explicit null values.
+ Token &t = peekNext();
+ if (t.Kind == Token::TK_BlockEnd || t.Kind == Token::TK_Key) {
+ return Value = new (getAllocator()) NullNode(Doc);
+ }
+
+ // We got a normal value.
+ return Value = parseBlockNode();
+}
+
+void MappingNode::increment() {
+ if (failed()) {
+ IsAtEnd = true;
+ CurrentEntry = nullptr;
+ return;
+ }
+ if (CurrentEntry) {
+ CurrentEntry->skip();
+ if (Type == MT_Inline) {
+ IsAtEnd = true;
+ CurrentEntry = nullptr;
+ return;
+ }
+ }
+ Token T = peekNext();
+ if (T.Kind == Token::TK_Key || T.Kind == Token::TK_Scalar) {
+ // KeyValueNode eats the TK_Key. That way it can detect null keys.
+ CurrentEntry = new (getAllocator()) KeyValueNode(Doc);
+ } else if (Type == MT_Block) {
+ switch (T.Kind) {
+ case Token::TK_BlockEnd:
+ getNext();
+ IsAtEnd = true;
+ CurrentEntry = nullptr;
+ break;
+ default:
+ setError("Unexpected token. Expected Key or Block End", T);
+ case Token::TK_Error:
+ IsAtEnd = true;
+ CurrentEntry = nullptr;
+ }
+ } else {
+ switch (T.Kind) {
+ case Token::TK_FlowEntry:
+ // Eat the flow entry and recurse.
+ getNext();
+ return increment();
+ case Token::TK_FlowMappingEnd:
+ getNext();
+ case Token::TK_Error:
+ // Set this to end iterator.
+ IsAtEnd = true;
+ CurrentEntry = nullptr;
+ break;
+ default:
+ setError( "Unexpected token. Expected Key, Flow Entry, or Flow "
+ "Mapping End."
+ , T);
+ IsAtEnd = true;
+ CurrentEntry = nullptr;
+ }
+ }
+}
+
+void SequenceNode::increment() {
+ if (failed()) {
+ IsAtEnd = true;
+ CurrentEntry = nullptr;
+ return;
+ }
+ if (CurrentEntry)
+ CurrentEntry->skip();
+ Token T = peekNext();
+ if (SeqType == ST_Block) {
+ switch (T.Kind) {
+ case Token::TK_BlockEntry:
+ getNext();
+ CurrentEntry = parseBlockNode();
+ if (!CurrentEntry) { // An error occurred.
+ IsAtEnd = true;
+ CurrentEntry = nullptr;
+ }
+ break;
+ case Token::TK_BlockEnd:
+ getNext();
+ IsAtEnd = true;
+ CurrentEntry = nullptr;
+ break;
+ default:
+ setError( "Unexpected token. Expected Block Entry or Block End."
+ , T);
+ case Token::TK_Error:
+ IsAtEnd = true;
+ CurrentEntry = nullptr;
+ }
+ } else if (SeqType == ST_Indentless) {
+ switch (T.Kind) {
+ case Token::TK_BlockEntry:
+ getNext();
+ CurrentEntry = parseBlockNode();
+ if (!CurrentEntry) { // An error occurred.
+ IsAtEnd = true;
+ CurrentEntry = nullptr;
+ }
+ break;
+ default:
+ case Token::TK_Error:
+ IsAtEnd = true;
+ CurrentEntry = nullptr;
+ }
+ } else if (SeqType == ST_Flow) {
+ switch (T.Kind) {
+ case Token::TK_FlowEntry:
+ // Eat the flow entry and recurse.
+ getNext();
+ WasPreviousTokenFlowEntry = true;
+ return increment();
+ case Token::TK_FlowSequenceEnd:
+ getNext();
+ case Token::TK_Error:
+ // Set this to end iterator.
+ IsAtEnd = true;
+ CurrentEntry = nullptr;
+ break;
+ case Token::TK_StreamEnd:
+ case Token::TK_DocumentEnd:
+ case Token::TK_DocumentStart:
+ setError("Could not find closing ]!", T);
+ // Set this to end iterator.
+ IsAtEnd = true;
+ CurrentEntry = nullptr;
+ break;
+ default:
+ if (!WasPreviousTokenFlowEntry) {
+ setError("Expected , between entries!", T);
+ IsAtEnd = true;
+ CurrentEntry = nullptr;
+ break;
+ }
+ // Otherwise it must be a flow entry.
+ CurrentEntry = parseBlockNode();
+ if (!CurrentEntry) {
+ IsAtEnd = true;
+ }
+ WasPreviousTokenFlowEntry = false;
+ break;
+ }
+ }
+}
+
+Document::Document(Stream &S) : stream(S), Root(nullptr) {
+ // Tag maps starts with two default mappings.
+ TagMap["!"] = "!";
+ TagMap["!!"] = "tag:yaml.org,2002:";
+
+ if (parseDirectives())
+ expectToken(Token::TK_DocumentStart);
+ Token &T = peekNext();
+ if (T.Kind == Token::TK_DocumentStart)
+ getNext();
+}
+
+bool Document::skip() {
+ if (stream.scanner->failed())
+ return false;
+ if (!Root)
+ getRoot();
+ Root->skip();
+ Token &T = peekNext();
+ if (T.Kind == Token::TK_StreamEnd)
+ return false;
+ if (T.Kind == Token::TK_DocumentEnd) {
+ getNext();
+ return skip();
+ }
+ return true;
+}
+
+Token &Document::peekNext() {
+ return stream.scanner->peekNext();
+}
+
+Token Document::getNext() {
+ return stream.scanner->getNext();
+}
+
+void Document::setError(const Twine &Message, Token &Location) const {
+ stream.scanner->setError(Message, Location.Range.begin());
+}
+
+bool Document::failed() const {
+ return stream.scanner->failed();
+}
+
+Node *Document::parseBlockNode() {
+ Token T = peekNext();
+ // Handle properties.
+ Token AnchorInfo;
+ Token TagInfo;
+parse_property:
+ switch (T.Kind) {
+ case Token::TK_Alias:
+ getNext();
+ return new (NodeAllocator) AliasNode(stream.CurrentDoc, T.Range.substr(1));
+ case Token::TK_Anchor:
+ if (AnchorInfo.Kind == Token::TK_Anchor) {
+ setError("Already encountered an anchor for this node!", T);
+ return nullptr;
+ }
+ AnchorInfo = getNext(); // Consume TK_Anchor.
+ T = peekNext();
+ goto parse_property;
+ case Token::TK_Tag:
+ if (TagInfo.Kind == Token::TK_Tag) {
+ setError("Already encountered a tag for this node!", T);
+ return nullptr;
+ }
+ TagInfo = getNext(); // Consume TK_Tag.
+ T = peekNext();
+ goto parse_property;
+ default:
+ break;
+ }
+
+ switch (T.Kind) {
+ case Token::TK_BlockEntry:
+ // We got an unindented BlockEntry sequence. This is not terminated with
+ // a BlockEnd.
+ // Don't eat the TK_BlockEntry, SequenceNode needs it.
+ return new (NodeAllocator) SequenceNode( stream.CurrentDoc
+ , AnchorInfo.Range.substr(1)
+ , TagInfo.Range
+ , SequenceNode::ST_Indentless);
+ case Token::TK_BlockSequenceStart:
+ getNext();
+ return new (NodeAllocator)
+ SequenceNode( stream.CurrentDoc
+ , AnchorInfo.Range.substr(1)
+ , TagInfo.Range
+ , SequenceNode::ST_Block);
+ case Token::TK_BlockMappingStart:
+ getNext();
+ return new (NodeAllocator)
+ MappingNode( stream.CurrentDoc
+ , AnchorInfo.Range.substr(1)
+ , TagInfo.Range
+ , MappingNode::MT_Block);
+ case Token::TK_FlowSequenceStart:
+ getNext();
+ return new (NodeAllocator)
+ SequenceNode( stream.CurrentDoc
+ , AnchorInfo.Range.substr(1)
+ , TagInfo.Range
+ , SequenceNode::ST_Flow);
+ case Token::TK_FlowMappingStart:
+ getNext();
+ return new (NodeAllocator)
+ MappingNode( stream.CurrentDoc
+ , AnchorInfo.Range.substr(1)
+ , TagInfo.Range
+ , MappingNode::MT_Flow);
+ case Token::TK_Scalar:
+ getNext();
+ return new (NodeAllocator)
+ ScalarNode( stream.CurrentDoc
+ , AnchorInfo.Range.substr(1)
+ , TagInfo.Range
+ , T.Range);
+ case Token::TK_BlockScalar: {
+ getNext();
+ StringRef NullTerminatedStr(T.Value.c_str(), T.Value.length() + 1);
+ StringRef StrCopy = NullTerminatedStr.copy(NodeAllocator).drop_back();
+ return new (NodeAllocator)
+ BlockScalarNode(stream.CurrentDoc, AnchorInfo.Range.substr(1),
+ TagInfo.Range, StrCopy, T.Range);
+ }
+ case Token::TK_Key:
+ // Don't eat the TK_Key, KeyValueNode expects it.
+ return new (NodeAllocator)
+ MappingNode( stream.CurrentDoc
+ , AnchorInfo.Range.substr(1)
+ , TagInfo.Range
+ , MappingNode::MT_Inline);
+ case Token::TK_DocumentStart:
+ case Token::TK_DocumentEnd:
+ case Token::TK_StreamEnd:
+ default:
+ // TODO: Properly handle tags. "[!!str ]" should resolve to !!str "", not
+ // !!null null.
+ return new (NodeAllocator) NullNode(stream.CurrentDoc);
+ case Token::TK_Error:
+ return nullptr;
+ }
+ llvm_unreachable("Control flow shouldn't reach here.");
+ return nullptr;
+}
+
+bool Document::parseDirectives() {
+ bool isDirective = false;
+ while (true) {
+ Token T = peekNext();
+ if (T.Kind == Token::TK_TagDirective) {
+ parseTAGDirective();
+ isDirective = true;
+ } else if (T.Kind == Token::TK_VersionDirective) {
+ parseYAMLDirective();
+ isDirective = true;
+ } else
+ break;
+ }
+ return isDirective;
+}
+
+void Document::parseYAMLDirective() {
+ getNext(); // Eat %YAML <version>
+}
+
+void Document::parseTAGDirective() {
+ Token Tag = getNext(); // %TAG <handle> <prefix>
+ StringRef T = Tag.Range;
+ // Strip %TAG
+ T = T.substr(T.find_first_of(" \t")).ltrim(" \t");
+ std::size_t HandleEnd = T.find_first_of(" \t");
+ StringRef TagHandle = T.substr(0, HandleEnd);
+ StringRef TagPrefix = T.substr(HandleEnd).ltrim(" \t");
+ TagMap[TagHandle] = TagPrefix;
+}
+
+bool Document::expectToken(int TK) {
+ Token T = getNext();
+ if (T.Kind != TK) {
+ setError("Unexpected token", T);
+ return false;
+ }
+ return true;
+}
diff --git a/contrib/llvm/lib/Support/YAMLTraits.cpp b/contrib/llvm/lib/Support/YAMLTraits.cpp
new file mode 100644
index 000000000000..6b59a16514b1
--- /dev/null
+++ b/contrib/llvm/lib/Support/YAMLTraits.cpp
@@ -0,0 +1,980 @@
+//===- lib/Support/YAMLTraits.cpp -----------------------------------------===//
+//
+// The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/YAMLTraits.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/Errc.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/LineIterator.h"
+#include "llvm/Support/YAMLParser.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cctype>
+#include <cstring>
+using namespace llvm;
+using namespace yaml;
+
+//===----------------------------------------------------------------------===//
+// IO
+//===----------------------------------------------------------------------===//
+
+IO::IO(void *Context) : Ctxt(Context) {
+}
+
+IO::~IO() {
+}
+
+void *IO::getContext() {
+ return Ctxt;
+}
+
+void IO::setContext(void *Context) {
+ Ctxt = Context;
+}
+
+//===----------------------------------------------------------------------===//
+// Input
+//===----------------------------------------------------------------------===//
+
+Input::Input(StringRef InputContent,
+ void *Ctxt,
+ SourceMgr::DiagHandlerTy DiagHandler,
+ void *DiagHandlerCtxt)
+ : IO(Ctxt),
+ Strm(new Stream(InputContent, SrcMgr)),
+ CurrentNode(nullptr) {
+ if (DiagHandler)
+ SrcMgr.setDiagHandler(DiagHandler, DiagHandlerCtxt);
+ DocIterator = Strm->begin();
+}
+
+Input::~Input() {
+}
+
+std::error_code Input::error() { return EC; }
+
+// Pin the vtables to this file.
+void Input::HNode::anchor() {}
+void Input::EmptyHNode::anchor() {}
+void Input::ScalarHNode::anchor() {}
+void Input::MapHNode::anchor() {}
+void Input::SequenceHNode::anchor() {}
+
+bool Input::outputting() {
+ return false;
+}
+
+bool Input::setCurrentDocument() {
+ if (DocIterator != Strm->end()) {
+ Node *N = DocIterator->getRoot();
+ if (!N) {
+ assert(Strm->failed() && "Root is NULL iff parsing failed");
+ EC = make_error_code(errc::invalid_argument);
+ return false;
+ }
+
+ if (isa<NullNode>(N)) {
+ // Empty files are allowed and ignored
+ ++DocIterator;
+ return setCurrentDocument();
+ }
+ TopNode = this->createHNodes(N);
+ CurrentNode = TopNode.get();
+ return true;
+ }
+ return false;
+}
+
+bool Input::nextDocument() {
+ return ++DocIterator != Strm->end();
+}
+
+const Node *Input::getCurrentNode() const {
+ return CurrentNode ? CurrentNode->_node : nullptr;
+}
+
+bool Input::mapTag(StringRef Tag, bool Default) {
+ std::string foundTag = CurrentNode->_node->getVerbatimTag();
+ if (foundTag.empty()) {
+ // If no tag found and 'Tag' is the default, say it was found.
+ return Default;
+ }
+ // Return true iff found tag matches supplied tag.
+ return Tag.equals(foundTag);
+}
+
+void Input::beginMapping() {
+ if (EC)
+ return;
+ // CurrentNode can be null if the document is empty.
+ MapHNode *MN = dyn_cast_or_null<MapHNode>(CurrentNode);
+ if (MN) {
+ MN->ValidKeys.clear();
+ }
+}
+
+bool Input::preflightKey(const char *Key, bool Required, bool, bool &UseDefault,
+ void *&SaveInfo) {
+ UseDefault = false;
+ if (EC)
+ return false;
+
+ // CurrentNode is null for empty documents, which is an error in case required
+ // nodes are present.
+ if (!CurrentNode) {
+ if (Required)
+ EC = make_error_code(errc::invalid_argument);
+ return false;
+ }
+
+ MapHNode *MN = dyn_cast<MapHNode>(CurrentNode);
+ if (!MN) {
+ setError(CurrentNode, "not a mapping");
+ return false;
+ }
+ MN->ValidKeys.push_back(Key);
+ HNode *Value = MN->Mapping[Key].get();
+ if (!Value) {
+ if (Required)
+ setError(CurrentNode, Twine("missing required key '") + Key + "'");
+ else
+ UseDefault = true;
+ return false;
+ }
+ SaveInfo = CurrentNode;
+ CurrentNode = Value;
+ return true;
+}
+
+void Input::postflightKey(void *saveInfo) {
+ CurrentNode = reinterpret_cast<HNode *>(saveInfo);
+}
+
+void Input::endMapping() {
+ if (EC)
+ return;
+ // CurrentNode can be null if the document is empty.
+ MapHNode *MN = dyn_cast_or_null<MapHNode>(CurrentNode);
+ if (!MN)
+ return;
+ for (const auto &NN : MN->Mapping) {
+ if (!MN->isValidKey(NN.first())) {
+ setError(NN.second.get(), Twine("unknown key '") + NN.first() + "'");
+ break;
+ }
+ }
+}
+
+void Input::beginFlowMapping() { beginMapping(); }
+
+void Input::endFlowMapping() { endMapping(); }
+
+unsigned Input::beginSequence() {
+ if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode))
+ return SQ->Entries.size();
+ if (isa<EmptyHNode>(CurrentNode))
+ return 0;
+ // Treat case where there's a scalar "null" value as an empty sequence.
+ if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) {
+ if (isNull(SN->value()))
+ return 0;
+ }
+ // Any other type of HNode is an error.
+ setError(CurrentNode, "not a sequence");
+ return 0;
+}
+
+void Input::endSequence() {
+}
+
+bool Input::preflightElement(unsigned Index, void *&SaveInfo) {
+ if (EC)
+ return false;
+ if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
+ SaveInfo = CurrentNode;
+ CurrentNode = SQ->Entries[Index].get();
+ return true;
+ }
+ return false;
+}
+
+void Input::postflightElement(void *SaveInfo) {
+ CurrentNode = reinterpret_cast<HNode *>(SaveInfo);
+}
+
+unsigned Input::beginFlowSequence() { return beginSequence(); }
+
+bool Input::preflightFlowElement(unsigned index, void *&SaveInfo) {
+ if (EC)
+ return false;
+ if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
+ SaveInfo = CurrentNode;
+ CurrentNode = SQ->Entries[index].get();
+ return true;
+ }
+ return false;
+}
+
+void Input::postflightFlowElement(void *SaveInfo) {
+ CurrentNode = reinterpret_cast<HNode *>(SaveInfo);
+}
+
+void Input::endFlowSequence() {
+}
+
+void Input::beginEnumScalar() {
+ ScalarMatchFound = false;
+}
+
+bool Input::matchEnumScalar(const char *Str, bool) {
+ if (ScalarMatchFound)
+ return false;
+ if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) {
+ if (SN->value().equals(Str)) {
+ ScalarMatchFound = true;
+ return true;
+ }
+ }
+ return false;
+}
+
+bool Input::matchEnumFallback() {
+ if (ScalarMatchFound)
+ return false;
+ ScalarMatchFound = true;
+ return true;
+}
+
+void Input::endEnumScalar() {
+ if (!ScalarMatchFound) {
+ setError(CurrentNode, "unknown enumerated scalar");
+ }
+}
+
+bool Input::beginBitSetScalar(bool &DoClear) {
+ BitValuesUsed.clear();
+ if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
+ BitValuesUsed.insert(BitValuesUsed.begin(), SQ->Entries.size(), false);
+ } else {
+ setError(CurrentNode, "expected sequence of bit values");
+ }
+ DoClear = true;
+ return true;
+}
+
+bool Input::bitSetMatch(const char *Str, bool) {
+ if (EC)
+ return false;
+ if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
+ unsigned Index = 0;
+ for (auto &N : SQ->Entries) {
+ if (ScalarHNode *SN = dyn_cast<ScalarHNode>(N.get())) {
+ if (SN->value().equals(Str)) {
+ BitValuesUsed[Index] = true;
+ return true;
+ }
+ } else {
+ setError(CurrentNode, "unexpected scalar in sequence of bit values");
+ }
+ ++Index;
+ }
+ } else {
+ setError(CurrentNode, "expected sequence of bit values");
+ }
+ return false;
+}
+
+void Input::endBitSetScalar() {
+ if (EC)
+ return;
+ if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
+ assert(BitValuesUsed.size() == SQ->Entries.size());
+ for (unsigned i = 0; i < SQ->Entries.size(); ++i) {
+ if (!BitValuesUsed[i]) {
+ setError(SQ->Entries[i].get(), "unknown bit value");
+ return;
+ }
+ }
+ }
+}
+
+void Input::scalarString(StringRef &S, bool) {
+ if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) {
+ S = SN->value();
+ } else {
+ setError(CurrentNode, "unexpected scalar");
+ }
+}
+
+void Input::blockScalarString(StringRef &S) { scalarString(S, false); }
+
+void Input::setError(HNode *hnode, const Twine &message) {
+ assert(hnode && "HNode must not be NULL");
+ this->setError(hnode->_node, message);
+}
+
+void Input::setError(Node *node, const Twine &message) {
+ Strm->printError(node, message);
+ EC = make_error_code(errc::invalid_argument);
+}
+
+std::unique_ptr<Input::HNode> Input::createHNodes(Node *N) {
+ SmallString<128> StringStorage;
+ if (ScalarNode *SN = dyn_cast<ScalarNode>(N)) {
+ StringRef KeyStr = SN->getValue(StringStorage);
+ if (!StringStorage.empty()) {
+ // Copy string to permanent storage
+ unsigned Len = StringStorage.size();
+ char *Buf = StringAllocator.Allocate<char>(Len);
+ memcpy(Buf, &StringStorage[0], Len);
+ KeyStr = StringRef(Buf, Len);
+ }
+ return llvm::make_unique<ScalarHNode>(N, KeyStr);
+ } else if (BlockScalarNode *BSN = dyn_cast<BlockScalarNode>(N)) {
+ StringRef Value = BSN->getValue();
+ char *Buf = StringAllocator.Allocate<char>(Value.size());
+ memcpy(Buf, Value.data(), Value.size());
+ return llvm::make_unique<ScalarHNode>(N, StringRef(Buf, Value.size()));
+ } else if (SequenceNode *SQ = dyn_cast<SequenceNode>(N)) {
+ auto SQHNode = llvm::make_unique<SequenceHNode>(N);
+ for (Node &SN : *SQ) {
+ auto Entry = this->createHNodes(&SN);
+ if (EC)
+ break;
+ SQHNode->Entries.push_back(std::move(Entry));
+ }
+ return std::move(SQHNode);
+ } else if (MappingNode *Map = dyn_cast<MappingNode>(N)) {
+ auto mapHNode = llvm::make_unique<MapHNode>(N);
+ for (KeyValueNode &KVN : *Map) {
+ Node *KeyNode = KVN.getKey();
+ ScalarNode *KeyScalar = dyn_cast<ScalarNode>(KeyNode);
+ if (!KeyScalar) {
+ setError(KeyNode, "Map key must be a scalar");
+ break;
+ }
+ StringStorage.clear();
+ StringRef KeyStr = KeyScalar->getValue(StringStorage);
+ if (!StringStorage.empty()) {
+ // Copy string to permanent storage
+ unsigned Len = StringStorage.size();
+ char *Buf = StringAllocator.Allocate<char>(Len);
+ memcpy(Buf, &StringStorage[0], Len);
+ KeyStr = StringRef(Buf, Len);
+ }
+ auto ValueHNode = this->createHNodes(KVN.getValue());
+ if (EC)
+ break;
+ mapHNode->Mapping[KeyStr] = std::move(ValueHNode);
+ }
+ return std::move(mapHNode);
+ } else if (isa<NullNode>(N)) {
+ return llvm::make_unique<EmptyHNode>(N);
+ } else {
+ setError(N, "unknown node kind");
+ return nullptr;
+ }
+}
+
+bool Input::MapHNode::isValidKey(StringRef Key) {
+ for (const char *K : ValidKeys) {
+ if (Key.equals(K))
+ return true;
+ }
+ return false;
+}
+
+void Input::setError(const Twine &Message) {
+ this->setError(CurrentNode, Message);
+}
+
+bool Input::canElideEmptySequence() {
+ return false;
+}
+
+//===----------------------------------------------------------------------===//
+// Output
+//===----------------------------------------------------------------------===//
+
+Output::Output(raw_ostream &yout, void *context, int WrapColumn)
+ : IO(context),
+ Out(yout),
+ WrapColumn(WrapColumn),
+ Column(0),
+ ColumnAtFlowStart(0),
+ ColumnAtMapFlowStart(0),
+ NeedBitValueComma(false),
+ NeedFlowSequenceComma(false),
+ EnumerationMatchFound(false),
+ NeedsNewLine(false) {
+}
+
+Output::~Output() {
+}
+
+bool Output::outputting() {
+ return true;
+}
+
+void Output::beginMapping() {
+ StateStack.push_back(inMapFirstKey);
+ NeedsNewLine = true;
+}
+
+bool Output::mapTag(StringRef Tag, bool Use) {
+ if (Use) {
+ this->output(" ");
+ this->output(Tag);
+ }
+ return Use;
+}
+
+void Output::endMapping() {
+ StateStack.pop_back();
+}
+
+bool Output::preflightKey(const char *Key, bool Required, bool SameAsDefault,
+ bool &UseDefault, void *&) {
+ UseDefault = false;
+ if (Required || !SameAsDefault) {
+ auto State = StateStack.back();
+ if (State == inFlowMapFirstKey || State == inFlowMapOtherKey) {
+ flowKey(Key);
+ } else {
+ this->newLineCheck();
+ this->paddedKey(Key);
+ }
+ return true;
+ }
+ return false;
+}
+
+void Output::postflightKey(void *) {
+ if (StateStack.back() == inMapFirstKey) {
+ StateStack.pop_back();
+ StateStack.push_back(inMapOtherKey);
+ } else if (StateStack.back() == inFlowMapFirstKey) {
+ StateStack.pop_back();
+ StateStack.push_back(inFlowMapOtherKey);
+ }
+}
+
+void Output::beginFlowMapping() {
+ StateStack.push_back(inFlowMapFirstKey);
+ this->newLineCheck();
+ ColumnAtMapFlowStart = Column;
+ output("{ ");
+}
+
+void Output::endFlowMapping() {
+ StateStack.pop_back();
+ this->outputUpToEndOfLine(" }");
+}
+
+void Output::beginDocuments() {
+ this->outputUpToEndOfLine("---");
+}
+
+bool Output::preflightDocument(unsigned index) {
+ if (index > 0)
+ this->outputUpToEndOfLine("\n---");
+ return true;
+}
+
+void Output::postflightDocument() {
+}
+
+void Output::endDocuments() {
+ output("\n...\n");
+}
+
+unsigned Output::beginSequence() {
+ StateStack.push_back(inSeq);
+ NeedsNewLine = true;
+ return 0;
+}
+
+void Output::endSequence() {
+ StateStack.pop_back();
+}
+
+bool Output::preflightElement(unsigned, void *&) {
+ return true;
+}
+
+void Output::postflightElement(void *) {
+}
+
+unsigned Output::beginFlowSequence() {
+ StateStack.push_back(inFlowSeq);
+ this->newLineCheck();
+ ColumnAtFlowStart = Column;
+ output("[ ");
+ NeedFlowSequenceComma = false;
+ return 0;
+}
+
+void Output::endFlowSequence() {
+ StateStack.pop_back();
+ this->outputUpToEndOfLine(" ]");
+}
+
+bool Output::preflightFlowElement(unsigned, void *&) {
+ if (NeedFlowSequenceComma)
+ output(", ");
+ if (WrapColumn && Column > WrapColumn) {
+ output("\n");
+ for (int i = 0; i < ColumnAtFlowStart; ++i)
+ output(" ");
+ Column = ColumnAtFlowStart;
+ output(" ");
+ }
+ return true;
+}
+
+void Output::postflightFlowElement(void *) {
+ NeedFlowSequenceComma = true;
+}
+
+void Output::beginEnumScalar() {
+ EnumerationMatchFound = false;
+}
+
+bool Output::matchEnumScalar(const char *Str, bool Match) {
+ if (Match && !EnumerationMatchFound) {
+ this->newLineCheck();
+ this->outputUpToEndOfLine(Str);
+ EnumerationMatchFound = true;
+ }
+ return false;
+}
+
+bool Output::matchEnumFallback() {
+ if (EnumerationMatchFound)
+ return false;
+ EnumerationMatchFound = true;
+ return true;
+}
+
+void Output::endEnumScalar() {
+ if (!EnumerationMatchFound)
+ llvm_unreachable("bad runtime enum value");
+}
+
+bool Output::beginBitSetScalar(bool &DoClear) {
+ this->newLineCheck();
+ output("[ ");
+ NeedBitValueComma = false;
+ DoClear = false;
+ return true;
+}
+
+bool Output::bitSetMatch(const char *Str, bool Matches) {
+ if (Matches) {
+ if (NeedBitValueComma)
+ output(", ");
+ this->output(Str);
+ NeedBitValueComma = true;
+ }
+ return false;
+}
+
+void Output::endBitSetScalar() {
+ this->outputUpToEndOfLine(" ]");
+}
+
+void Output::scalarString(StringRef &S, bool MustQuote) {
+ this->newLineCheck();
+ if (S.empty()) {
+ // Print '' for the empty string because leaving the field empty is not
+ // allowed.
+ this->outputUpToEndOfLine("''");
+ return;
+ }
+ if (!MustQuote) {
+ // Only quote if we must.
+ this->outputUpToEndOfLine(S);
+ return;
+ }
+ unsigned i = 0;
+ unsigned j = 0;
+ unsigned End = S.size();
+ output("'"); // Starting single quote.
+ const char *Base = S.data();
+ while (j < End) {
+ // Escape a single quote by doubling it.
+ if (S[j] == '\'') {
+ output(StringRef(&Base[i], j - i + 1));
+ output("'");
+ i = j + 1;
+ }
+ ++j;
+ }
+ output(StringRef(&Base[i], j - i));
+ this->outputUpToEndOfLine("'"); // Ending single quote.
+}
+
+void Output::blockScalarString(StringRef &S) {
+ if (!StateStack.empty())
+ newLineCheck();
+ output(" |");
+ outputNewLine();
+
+ unsigned Indent = StateStack.empty() ? 1 : StateStack.size();
+
+ auto Buffer = MemoryBuffer::getMemBuffer(S, "", false);
+ for (line_iterator Lines(*Buffer, false); !Lines.is_at_end(); ++Lines) {
+ for (unsigned I = 0; I < Indent; ++I) {
+ output(" ");
+ }
+ output(*Lines);
+ outputNewLine();
+ }
+}
+
+void Output::setError(const Twine &message) {
+}
+
+bool Output::canElideEmptySequence() {
+ // Normally, with an optional key/value where the value is an empty sequence,
+ // the whole key/value can be not written. But, that produces wrong yaml
+ // if the key/value is the only thing in the map and the map is used in
+ // a sequence. This detects if the this sequence is the first key/value
+ // in map that itself is embedded in a sequnce.
+ if (StateStack.size() < 2)
+ return true;
+ if (StateStack.back() != inMapFirstKey)
+ return true;
+ return (StateStack[StateStack.size()-2] != inSeq);
+}
+
+void Output::output(StringRef s) {
+ Column += s.size();
+ Out << s;
+}
+
+void Output::outputUpToEndOfLine(StringRef s) {
+ this->output(s);
+ if (StateStack.empty() || (StateStack.back() != inFlowSeq &&
+ StateStack.back() != inFlowMapFirstKey &&
+ StateStack.back() != inFlowMapOtherKey))
+ NeedsNewLine = true;
+}
+
+void Output::outputNewLine() {
+ Out << "\n";
+ Column = 0;
+}
+
+// if seq at top, indent as if map, then add "- "
+// if seq in middle, use "- " if firstKey, else use " "
+//
+
+void Output::newLineCheck() {
+ if (!NeedsNewLine)
+ return;
+ NeedsNewLine = false;
+
+ this->outputNewLine();
+
+ assert(StateStack.size() > 0);
+ unsigned Indent = StateStack.size() - 1;
+ bool OutputDash = false;
+
+ if (StateStack.back() == inSeq) {
+ OutputDash = true;
+ } else if ((StateStack.size() > 1) && ((StateStack.back() == inMapFirstKey) ||
+ (StateStack.back() == inFlowSeq) ||
+ (StateStack.back() == inFlowMapFirstKey)) &&
+ (StateStack[StateStack.size() - 2] == inSeq)) {
+ --Indent;
+ OutputDash = true;
+ }
+
+ for (unsigned i = 0; i < Indent; ++i) {
+ output(" ");
+ }
+ if (OutputDash) {
+ output("- ");
+ }
+
+}
+
+void Output::paddedKey(StringRef key) {
+ output(key);
+ output(":");
+ const char *spaces = " ";
+ if (key.size() < strlen(spaces))
+ output(&spaces[key.size()]);
+ else
+ output(" ");
+}
+
+void Output::flowKey(StringRef Key) {
+ if (StateStack.back() == inFlowMapOtherKey)
+ output(", ");
+ if (WrapColumn && Column > WrapColumn) {
+ output("\n");
+ for (int I = 0; I < ColumnAtMapFlowStart; ++I)
+ output(" ");
+ Column = ColumnAtMapFlowStart;
+ output(" ");
+ }
+ output(Key);
+ output(": ");
+}
+
+//===----------------------------------------------------------------------===//
+// traits for built-in types
+//===----------------------------------------------------------------------===//
+
+void ScalarTraits<bool>::output(const bool &Val, void *, raw_ostream &Out) {
+ Out << (Val ? "true" : "false");
+}
+
+StringRef ScalarTraits<bool>::input(StringRef Scalar, void *, bool &Val) {
+ if (Scalar.equals("true")) {
+ Val = true;
+ return StringRef();
+ } else if (Scalar.equals("false")) {
+ Val = false;
+ return StringRef();
+ }
+ return "invalid boolean";
+}
+
+void ScalarTraits<StringRef>::output(const StringRef &Val, void *,
+ raw_ostream &Out) {
+ Out << Val;
+}
+
+StringRef ScalarTraits<StringRef>::input(StringRef Scalar, void *,
+ StringRef &Val) {
+ Val = Scalar;
+ return StringRef();
+}
+
+void ScalarTraits<std::string>::output(const std::string &Val, void *,
+ raw_ostream &Out) {
+ Out << Val;
+}
+
+StringRef ScalarTraits<std::string>::input(StringRef Scalar, void *,
+ std::string &Val) {
+ Val = Scalar.str();
+ return StringRef();
+}
+
+void ScalarTraits<uint8_t>::output(const uint8_t &Val, void *,
+ raw_ostream &Out) {
+ // use temp uin32_t because ostream thinks uint8_t is a character
+ uint32_t Num = Val;
+ Out << Num;
+}
+
+StringRef ScalarTraits<uint8_t>::input(StringRef Scalar, void *, uint8_t &Val) {
+ unsigned long long n;
+ if (getAsUnsignedInteger(Scalar, 0, n))
+ return "invalid number";
+ if (n > 0xFF)
+ return "out of range number";
+ Val = n;
+ return StringRef();
+}
+
+void ScalarTraits<uint16_t>::output(const uint16_t &Val, void *,
+ raw_ostream &Out) {
+ Out << Val;
+}
+
+StringRef ScalarTraits<uint16_t>::input(StringRef Scalar, void *,
+ uint16_t &Val) {
+ unsigned long long n;
+ if (getAsUnsignedInteger(Scalar, 0, n))
+ return "invalid number";
+ if (n > 0xFFFF)
+ return "out of range number";
+ Val = n;
+ return StringRef();
+}
+
+void ScalarTraits<uint32_t>::output(const uint32_t &Val, void *,
+ raw_ostream &Out) {
+ Out << Val;
+}
+
+StringRef ScalarTraits<uint32_t>::input(StringRef Scalar, void *,
+ uint32_t &Val) {
+ unsigned long long n;
+ if (getAsUnsignedInteger(Scalar, 0, n))
+ return "invalid number";
+ if (n > 0xFFFFFFFFUL)
+ return "out of range number";
+ Val = n;
+ return StringRef();
+}
+
+void ScalarTraits<uint64_t>::output(const uint64_t &Val, void *,
+ raw_ostream &Out) {
+ Out << Val;
+}
+
+StringRef ScalarTraits<uint64_t>::input(StringRef Scalar, void *,
+ uint64_t &Val) {
+ unsigned long long N;
+ if (getAsUnsignedInteger(Scalar, 0, N))
+ return "invalid number";
+ Val = N;
+ return StringRef();
+}
+
+void ScalarTraits<int8_t>::output(const int8_t &Val, void *, raw_ostream &Out) {
+ // use temp in32_t because ostream thinks int8_t is a character
+ int32_t Num = Val;
+ Out << Num;
+}
+
+StringRef ScalarTraits<int8_t>::input(StringRef Scalar, void *, int8_t &Val) {
+ long long N;
+ if (getAsSignedInteger(Scalar, 0, N))
+ return "invalid number";
+ if ((N > 127) || (N < -128))
+ return "out of range number";
+ Val = N;
+ return StringRef();
+}
+
+void ScalarTraits<int16_t>::output(const int16_t &Val, void *,
+ raw_ostream &Out) {
+ Out << Val;
+}
+
+StringRef ScalarTraits<int16_t>::input(StringRef Scalar, void *, int16_t &Val) {
+ long long N;
+ if (getAsSignedInteger(Scalar, 0, N))
+ return "invalid number";
+ if ((N > INT16_MAX) || (N < INT16_MIN))
+ return "out of range number";
+ Val = N;
+ return StringRef();
+}
+
+void ScalarTraits<int32_t>::output(const int32_t &Val, void *,
+ raw_ostream &Out) {
+ Out << Val;
+}
+
+StringRef ScalarTraits<int32_t>::input(StringRef Scalar, void *, int32_t &Val) {
+ long long N;
+ if (getAsSignedInteger(Scalar, 0, N))
+ return "invalid number";
+ if ((N > INT32_MAX) || (N < INT32_MIN))
+ return "out of range number";
+ Val = N;
+ return StringRef();
+}
+
+void ScalarTraits<int64_t>::output(const int64_t &Val, void *,
+ raw_ostream &Out) {
+ Out << Val;
+}
+
+StringRef ScalarTraits<int64_t>::input(StringRef Scalar, void *, int64_t &Val) {
+ long long N;
+ if (getAsSignedInteger(Scalar, 0, N))
+ return "invalid number";
+ Val = N;
+ return StringRef();
+}
+
+void ScalarTraits<double>::output(const double &Val, void *, raw_ostream &Out) {
+ Out << format("%g", Val);
+}
+
+StringRef ScalarTraits<double>::input(StringRef Scalar, void *, double &Val) {
+ SmallString<32> buff(Scalar.begin(), Scalar.end());
+ char *end;
+ Val = strtod(buff.c_str(), &end);
+ if (*end != '\0')
+ return "invalid floating point number";
+ return StringRef();
+}
+
+void ScalarTraits<float>::output(const float &Val, void *, raw_ostream &Out) {
+ Out << format("%g", Val);
+}
+
+StringRef ScalarTraits<float>::input(StringRef Scalar, void *, float &Val) {
+ SmallString<32> buff(Scalar.begin(), Scalar.end());
+ char *end;
+ Val = strtod(buff.c_str(), &end);
+ if (*end != '\0')
+ return "invalid floating point number";
+ return StringRef();
+}
+
+void ScalarTraits<Hex8>::output(const Hex8 &Val, void *, raw_ostream &Out) {
+ uint8_t Num = Val;
+ Out << format("0x%02X", Num);
+}
+
+StringRef ScalarTraits<Hex8>::input(StringRef Scalar, void *, Hex8 &Val) {
+ unsigned long long n;
+ if (getAsUnsignedInteger(Scalar, 0, n))
+ return "invalid hex8 number";
+ if (n > 0xFF)
+ return "out of range hex8 number";
+ Val = n;
+ return StringRef();
+}
+
+void ScalarTraits<Hex16>::output(const Hex16 &Val, void *, raw_ostream &Out) {
+ uint16_t Num = Val;
+ Out << format("0x%04X", Num);
+}
+
+StringRef ScalarTraits<Hex16>::input(StringRef Scalar, void *, Hex16 &Val) {
+ unsigned long long n;
+ if (getAsUnsignedInteger(Scalar, 0, n))
+ return "invalid hex16 number";
+ if (n > 0xFFFF)
+ return "out of range hex16 number";
+ Val = n;
+ return StringRef();
+}
+
+void ScalarTraits<Hex32>::output(const Hex32 &Val, void *, raw_ostream &Out) {
+ uint32_t Num = Val;
+ Out << format("0x%08X", Num);
+}
+
+StringRef ScalarTraits<Hex32>::input(StringRef Scalar, void *, Hex32 &Val) {
+ unsigned long long n;
+ if (getAsUnsignedInteger(Scalar, 0, n))
+ return "invalid hex32 number";
+ if (n > 0xFFFFFFFFUL)
+ return "out of range hex32 number";
+ Val = n;
+ return StringRef();
+}
+
+void ScalarTraits<Hex64>::output(const Hex64 &Val, void *, raw_ostream &Out) {
+ uint64_t Num = Val;
+ Out << format("0x%016llX", Num);
+}
+
+StringRef ScalarTraits<Hex64>::input(StringRef Scalar, void *, Hex64 &Val) {
+ unsigned long long Num;
+ if (getAsUnsignedInteger(Scalar, 0, Num))
+ return "invalid hex64 number";
+ Val = Num;
+ return StringRef();
+}
diff --git a/contrib/llvm/lib/Support/circular_raw_ostream.cpp b/contrib/llvm/lib/Support/circular_raw_ostream.cpp
new file mode 100644
index 000000000000..ca0d30db388c
--- /dev/null
+++ b/contrib/llvm/lib/Support/circular_raw_ostream.cpp
@@ -0,0 +1,45 @@
+//===- circular_raw_ostream.cpp - Implement circular_raw_ostream ----------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This implements support for circular buffered streams.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/circular_raw_ostream.h"
+#include <algorithm>
+using namespace llvm;
+
+void circular_raw_ostream::write_impl(const char *Ptr, size_t Size) {
+ if (BufferSize == 0) {
+ TheStream->write(Ptr, Size);
+ return;
+ }
+
+ // Write into the buffer, wrapping if necessary.
+ while (Size != 0) {
+ unsigned Bytes =
+ std::min(unsigned(Size), unsigned(BufferSize - (Cur - BufferArray)));
+ memcpy(Cur, Ptr, Bytes);
+ Size -= Bytes;
+ Cur += Bytes;
+ if (Cur == BufferArray + BufferSize) {
+ // Reset the output pointer to the start of the buffer.
+ Cur = BufferArray;
+ Filled = true;
+ }
+ }
+}
+
+void circular_raw_ostream::flushBufferWithBanner() {
+ if (BufferSize != 0) {
+ // Write out the buffer
+ TheStream->write(Banner, std::strlen(Banner));
+ flushBuffer();
+ }
+}
diff --git a/contrib/llvm/lib/Support/raw_os_ostream.cpp b/contrib/llvm/lib/Support/raw_os_ostream.cpp
new file mode 100644
index 000000000000..44f2325d7f8a
--- /dev/null
+++ b/contrib/llvm/lib/Support/raw_os_ostream.cpp
@@ -0,0 +1,30 @@
+//===--- raw_os_ostream.cpp - Implement the raw_os_ostream class ----------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This implements support adapting raw_ostream to std::ostream.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/raw_os_ostream.h"
+#include <ostream>
+using namespace llvm;
+
+//===----------------------------------------------------------------------===//
+// raw_os_ostream
+//===----------------------------------------------------------------------===//
+
+raw_os_ostream::~raw_os_ostream() {
+ flush();
+}
+
+void raw_os_ostream::write_impl(const char *Ptr, size_t Size) {
+ OS.write(Ptr, Size);
+}
+
+uint64_t raw_os_ostream::current_pos() const { return OS.tellp(); }
diff --git a/contrib/llvm/lib/Support/raw_ostream.cpp b/contrib/llvm/lib/Support/raw_ostream.cpp
new file mode 100644
index 000000000000..42f830bbf0fa
--- /dev/null
+++ b/contrib/llvm/lib/Support/raw_ostream.cpp
@@ -0,0 +1,847 @@
+//===--- raw_ostream.cpp - Implement the raw_ostream classes --------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This implements support for bulk buffered stream output.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Config/config.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/Process.h"
+#include "llvm/Support/Program.h"
+#include <cctype>
+#include <cerrno>
+#include <sys/stat.h>
+#include <system_error>
+
+// <fcntl.h> may provide O_BINARY.
+#if defined(HAVE_FCNTL_H)
+# include <fcntl.h>
+#endif
+
+#if defined(HAVE_UNISTD_H)
+# include <unistd.h>
+#endif
+#if defined(HAVE_SYS_UIO_H) && defined(HAVE_WRITEV)
+# include <sys/uio.h>
+#endif
+
+#if defined(__CYGWIN__)
+#include <io.h>
+#endif
+
+#if defined(_MSC_VER)
+#include <io.h>
+#ifndef STDIN_FILENO
+# define STDIN_FILENO 0
+#endif
+#ifndef STDOUT_FILENO
+# define STDOUT_FILENO 1
+#endif
+#ifndef STDERR_FILENO
+# define STDERR_FILENO 2
+#endif
+#endif
+
+using namespace llvm;
+
+raw_ostream::~raw_ostream() {
+ // raw_ostream's subclasses should take care to flush the buffer
+ // in their destructors.
+ assert(OutBufCur == OutBufStart &&
+ "raw_ostream destructor called with non-empty buffer!");
+
+ if (BufferMode == InternalBuffer)
+ delete [] OutBufStart;
+}
+
+// An out of line virtual method to provide a home for the class vtable.
+void raw_ostream::handle() {}
+
+size_t raw_ostream::preferred_buffer_size() const {
+ // BUFSIZ is intended to be a reasonable default.
+ return BUFSIZ;
+}
+
+void raw_ostream::SetBuffered() {
+ // Ask the subclass to determine an appropriate buffer size.
+ if (size_t Size = preferred_buffer_size())
+ SetBufferSize(Size);
+ else
+ // It may return 0, meaning this stream should be unbuffered.
+ SetUnbuffered();
+}
+
+void raw_ostream::SetBufferAndMode(char *BufferStart, size_t Size,
+ BufferKind Mode) {
+ assert(((Mode == Unbuffered && !BufferStart && Size == 0) ||
+ (Mode != Unbuffered && BufferStart && Size != 0)) &&
+ "stream must be unbuffered or have at least one byte");
+ // Make sure the current buffer is free of content (we can't flush here; the
+ // child buffer management logic will be in write_impl).
+ assert(GetNumBytesInBuffer() == 0 && "Current buffer is non-empty!");
+
+ if (BufferMode == InternalBuffer)
+ delete [] OutBufStart;
+ OutBufStart = BufferStart;
+ OutBufEnd = OutBufStart+Size;
+ OutBufCur = OutBufStart;
+ BufferMode = Mode;
+
+ assert(OutBufStart <= OutBufEnd && "Invalid size!");
+}
+
+raw_ostream &raw_ostream::operator<<(unsigned long N) {
+ // Zero is a special case.
+ if (N == 0)
+ return *this << '0';
+
+ char NumberBuffer[20];
+ char *EndPtr = NumberBuffer+sizeof(NumberBuffer);
+ char *CurPtr = EndPtr;
+
+ while (N) {
+ *--CurPtr = '0' + char(N % 10);
+ N /= 10;
+ }
+ return write(CurPtr, EndPtr-CurPtr);
+}
+
+raw_ostream &raw_ostream::operator<<(long N) {
+ if (N < 0) {
+ *this << '-';
+ // Avoid undefined behavior on LONG_MIN with a cast.
+ N = -(unsigned long)N;
+ }
+
+ return this->operator<<(static_cast<unsigned long>(N));
+}
+
+raw_ostream &raw_ostream::operator<<(unsigned long long N) {
+ // Output using 32-bit div/mod when possible.
+ if (N == static_cast<unsigned long>(N))
+ return this->operator<<(static_cast<unsigned long>(N));
+
+ char NumberBuffer[20];
+ char *EndPtr = NumberBuffer+sizeof(NumberBuffer);
+ char *CurPtr = EndPtr;
+
+ while (N) {
+ *--CurPtr = '0' + char(N % 10);
+ N /= 10;
+ }
+ return write(CurPtr, EndPtr-CurPtr);
+}
+
+raw_ostream &raw_ostream::operator<<(long long N) {
+ if (N < 0) {
+ *this << '-';
+ // Avoid undefined behavior on INT64_MIN with a cast.
+ N = -(unsigned long long)N;
+ }
+
+ return this->operator<<(static_cast<unsigned long long>(N));
+}
+
+raw_ostream &raw_ostream::write_hex(unsigned long long N) {
+ // Zero is a special case.
+ if (N == 0)
+ return *this << '0';
+
+ char NumberBuffer[20];
+ char *EndPtr = NumberBuffer+sizeof(NumberBuffer);
+ char *CurPtr = EndPtr;
+
+ while (N) {
+ uintptr_t x = N % 16;
+ *--CurPtr = (x < 10 ? '0' + x : 'a' + x - 10);
+ N /= 16;
+ }
+
+ return write(CurPtr, EndPtr-CurPtr);
+}
+
+raw_ostream &raw_ostream::write_escaped(StringRef Str,
+ bool UseHexEscapes) {
+ for (unsigned i = 0, e = Str.size(); i != e; ++i) {
+ unsigned char c = Str[i];
+
+ switch (c) {
+ case '\\':
+ *this << '\\' << '\\';
+ break;
+ case '\t':
+ *this << '\\' << 't';
+ break;
+ case '\n':
+ *this << '\\' << 'n';
+ break;
+ case '"':
+ *this << '\\' << '"';
+ break;
+ default:
+ if (std::isprint(c)) {
+ *this << c;
+ break;
+ }
+
+ // Write out the escaped representation.
+ if (UseHexEscapes) {
+ *this << '\\' << 'x';
+ *this << hexdigit((c >> 4 & 0xF));
+ *this << hexdigit((c >> 0) & 0xF);
+ } else {
+ // Always use a full 3-character octal escape.
+ *this << '\\';
+ *this << char('0' + ((c >> 6) & 7));
+ *this << char('0' + ((c >> 3) & 7));
+ *this << char('0' + ((c >> 0) & 7));
+ }
+ }
+ }
+
+ return *this;
+}
+
+raw_ostream &raw_ostream::operator<<(const void *P) {
+ *this << '0' << 'x';
+
+ return write_hex((uintptr_t) P);
+}
+
+raw_ostream &raw_ostream::operator<<(double N) {
+#ifdef _WIN32
+ // On MSVCRT and compatible, output of %e is incompatible to Posix
+ // by default. Number of exponent digits should be at least 2. "%+03d"
+ // FIXME: Implement our formatter to here or Support/Format.h!
+#if __cplusplus >= 201103L && defined(__MINGW32__)
+ // FIXME: It should be generic to C++11.
+ if (N == 0.0 && std::signbit(N))
+ return *this << "-0.000000e+00";
+#else
+ int fpcl = _fpclass(N);
+
+ // negative zero
+ if (fpcl == _FPCLASS_NZ)
+ return *this << "-0.000000e+00";
+#endif
+
+ char buf[16];
+ unsigned len;
+ len = format("%e", N).snprint(buf, sizeof(buf));
+ if (len <= sizeof(buf) - 2) {
+ if (len >= 5 && buf[len - 5] == 'e' && buf[len - 3] == '0') {
+ int cs = buf[len - 4];
+ if (cs == '+' || cs == '-') {
+ int c1 = buf[len - 2];
+ int c0 = buf[len - 1];
+ if (isdigit(static_cast<unsigned char>(c1)) &&
+ isdigit(static_cast<unsigned char>(c0))) {
+ // Trim leading '0': "...e+012" -> "...e+12\0"
+ buf[len - 3] = c1;
+ buf[len - 2] = c0;
+ buf[--len] = 0;
+ }
+ }
+ }
+ return this->operator<<(buf);
+ }
+#endif
+ return this->operator<<(format("%e", N));
+}
+
+
+
+void raw_ostream::flush_nonempty() {
+ assert(OutBufCur > OutBufStart && "Invalid call to flush_nonempty.");
+ size_t Length = OutBufCur - OutBufStart;
+ OutBufCur = OutBufStart;
+ write_impl(OutBufStart, Length);
+}
+
+raw_ostream &raw_ostream::write(unsigned char C) {
+ // Group exceptional cases into a single branch.
+ if (LLVM_UNLIKELY(OutBufCur >= OutBufEnd)) {
+ if (LLVM_UNLIKELY(!OutBufStart)) {
+ if (BufferMode == Unbuffered) {
+ write_impl(reinterpret_cast<char*>(&C), 1);
+ return *this;
+ }
+ // Set up a buffer and start over.
+ SetBuffered();
+ return write(C);
+ }
+
+ flush_nonempty();
+ }
+
+ *OutBufCur++ = C;
+ return *this;
+}
+
+raw_ostream &raw_ostream::write(const char *Ptr, size_t Size) {
+ // Group exceptional cases into a single branch.
+ if (LLVM_UNLIKELY(size_t(OutBufEnd - OutBufCur) < Size)) {
+ if (LLVM_UNLIKELY(!OutBufStart)) {
+ if (BufferMode == Unbuffered) {
+ write_impl(Ptr, Size);
+ return *this;
+ }
+ // Set up a buffer and start over.
+ SetBuffered();
+ return write(Ptr, Size);
+ }
+
+ size_t NumBytes = OutBufEnd - OutBufCur;
+
+ // If the buffer is empty at this point we have a string that is larger
+ // than the buffer. Directly write the chunk that is a multiple of the
+ // preferred buffer size and put the remainder in the buffer.
+ if (LLVM_UNLIKELY(OutBufCur == OutBufStart)) {
+ assert(NumBytes != 0 && "undefined behavior");
+ size_t BytesToWrite = Size - (Size % NumBytes);
+ write_impl(Ptr, BytesToWrite);
+ size_t BytesRemaining = Size - BytesToWrite;
+ if (BytesRemaining > size_t(OutBufEnd - OutBufCur)) {
+ // Too much left over to copy into our buffer.
+ return write(Ptr + BytesToWrite, BytesRemaining);
+ }
+ copy_to_buffer(Ptr + BytesToWrite, BytesRemaining);
+ return *this;
+ }
+
+ // We don't have enough space in the buffer to fit the string in. Insert as
+ // much as possible, flush and start over with the remainder.
+ copy_to_buffer(Ptr, NumBytes);
+ flush_nonempty();
+ return write(Ptr + NumBytes, Size - NumBytes);
+ }
+
+ copy_to_buffer(Ptr, Size);
+
+ return *this;
+}
+
+void raw_ostream::copy_to_buffer(const char *Ptr, size_t Size) {
+ assert(Size <= size_t(OutBufEnd - OutBufCur) && "Buffer overrun!");
+
+ // Handle short strings specially, memcpy isn't very good at very short
+ // strings.
+ switch (Size) {
+ case 4: OutBufCur[3] = Ptr[3]; // FALL THROUGH
+ case 3: OutBufCur[2] = Ptr[2]; // FALL THROUGH
+ case 2: OutBufCur[1] = Ptr[1]; // FALL THROUGH
+ case 1: OutBufCur[0] = Ptr[0]; // FALL THROUGH
+ case 0: break;
+ default:
+ memcpy(OutBufCur, Ptr, Size);
+ break;
+ }
+
+ OutBufCur += Size;
+}
+
+// Formatted output.
+raw_ostream &raw_ostream::operator<<(const format_object_base &Fmt) {
+ // If we have more than a few bytes left in our output buffer, try
+ // formatting directly onto its end.
+ size_t NextBufferSize = 127;
+ size_t BufferBytesLeft = OutBufEnd - OutBufCur;
+ if (BufferBytesLeft > 3) {
+ size_t BytesUsed = Fmt.print(OutBufCur, BufferBytesLeft);
+
+ // Common case is that we have plenty of space.
+ if (BytesUsed <= BufferBytesLeft) {
+ OutBufCur += BytesUsed;
+ return *this;
+ }
+
+ // Otherwise, we overflowed and the return value tells us the size to try
+ // again with.
+ NextBufferSize = BytesUsed;
+ }
+
+ // If we got here, we didn't have enough space in the output buffer for the
+ // string. Try printing into a SmallVector that is resized to have enough
+ // space. Iterate until we win.
+ SmallVector<char, 128> V;
+
+ while (1) {
+ V.resize(NextBufferSize);
+
+ // Try formatting into the SmallVector.
+ size_t BytesUsed = Fmt.print(V.data(), NextBufferSize);
+
+ // If BytesUsed fit into the vector, we win.
+ if (BytesUsed <= NextBufferSize)
+ return write(V.data(), BytesUsed);
+
+ // Otherwise, try again with a new size.
+ assert(BytesUsed > NextBufferSize && "Didn't grow buffer!?");
+ NextBufferSize = BytesUsed;
+ }
+}
+
+raw_ostream &raw_ostream::operator<<(const FormattedString &FS) {
+ unsigned Len = FS.Str.size();
+ int PadAmount = FS.Width - Len;
+ if (FS.RightJustify && (PadAmount > 0))
+ this->indent(PadAmount);
+ this->operator<<(FS.Str);
+ if (!FS.RightJustify && (PadAmount > 0))
+ this->indent(PadAmount);
+ return *this;
+}
+
+raw_ostream &raw_ostream::operator<<(const FormattedNumber &FN) {
+ if (FN.Hex) {
+ unsigned Nibbles = (64 - countLeadingZeros(FN.HexValue)+3)/4;
+ unsigned PrefixChars = FN.HexPrefix ? 2 : 0;
+ unsigned Width = std::max(FN.Width, Nibbles + PrefixChars);
+
+ char NumberBuffer[20] = "0x0000000000000000";
+ if (!FN.HexPrefix)
+ NumberBuffer[1] = '0';
+ char *EndPtr = NumberBuffer+Width;
+ char *CurPtr = EndPtr;
+ const char A = FN.Upper ? 'A' : 'a';
+ unsigned long long N = FN.HexValue;
+ while (N) {
+ uintptr_t x = N % 16;
+ *--CurPtr = (x < 10 ? '0' + x : A + x - 10);
+ N /= 16;
+ }
+
+ return write(NumberBuffer, Width);
+ } else {
+ // Zero is a special case.
+ if (FN.DecValue == 0) {
+ this->indent(FN.Width-1);
+ return *this << '0';
+ }
+ char NumberBuffer[32];
+ char *EndPtr = NumberBuffer+sizeof(NumberBuffer);
+ char *CurPtr = EndPtr;
+ bool Neg = (FN.DecValue < 0);
+ uint64_t N = Neg ? -static_cast<uint64_t>(FN.DecValue) : FN.DecValue;
+ while (N) {
+ *--CurPtr = '0' + char(N % 10);
+ N /= 10;
+ }
+ int Len = EndPtr - CurPtr;
+ int Pad = FN.Width - Len;
+ if (Neg)
+ --Pad;
+ if (Pad > 0)
+ this->indent(Pad);
+ if (Neg)
+ *this << '-';
+ return write(CurPtr, Len);
+ }
+}
+
+
+/// indent - Insert 'NumSpaces' spaces.
+raw_ostream &raw_ostream::indent(unsigned NumSpaces) {
+ static const char Spaces[] = " "
+ " "
+ " ";
+
+ // Usually the indentation is small, handle it with a fastpath.
+ if (NumSpaces < array_lengthof(Spaces))
+ return write(Spaces, NumSpaces);
+
+ while (NumSpaces) {
+ unsigned NumToWrite = std::min(NumSpaces,
+ (unsigned)array_lengthof(Spaces)-1);
+ write(Spaces, NumToWrite);
+ NumSpaces -= NumToWrite;
+ }
+ return *this;
+}
+
+
+//===----------------------------------------------------------------------===//
+// Formatted Output
+//===----------------------------------------------------------------------===//
+
+// Out of line virtual method.
+void format_object_base::home() {
+}
+
+//===----------------------------------------------------------------------===//
+// raw_fd_ostream
+//===----------------------------------------------------------------------===//
+
+static int getFD(StringRef Filename, std::error_code &EC,
+ sys::fs::OpenFlags Flags) {
+ // Handle "-" as stdout. Note that when we do this, we consider ourself
+ // the owner of stdout. This means that we can do things like close the
+ // file descriptor when we're done and set the "binary" flag globally.
+ if (Filename == "-") {
+ EC = std::error_code();
+ // If user requested binary then put stdout into binary mode if
+ // possible.
+ if (!(Flags & sys::fs::F_Text))
+ sys::ChangeStdoutToBinary();
+ return STDOUT_FILENO;
+ }
+
+ int FD;
+ EC = sys::fs::openFileForWrite(Filename, FD, Flags);
+ if (EC)
+ return -1;
+
+ return FD;
+}
+
+raw_fd_ostream::raw_fd_ostream(StringRef Filename, std::error_code &EC,
+ sys::fs::OpenFlags Flags)
+ : raw_fd_ostream(getFD(Filename, EC, Flags), true) {}
+
+/// FD is the file descriptor that this writes to. If ShouldClose is true, this
+/// closes the file when the stream is destroyed.
+raw_fd_ostream::raw_fd_ostream(int fd, bool shouldClose, bool unbuffered)
+ : raw_pwrite_stream(unbuffered), FD(fd), ShouldClose(shouldClose),
+ Error(false), UseAtomicWrites(false) {
+ if (FD < 0 ) {
+ ShouldClose = false;
+ return;
+ }
+
+ // Get the starting position.
+ off_t loc = ::lseek(FD, 0, SEEK_CUR);
+#ifdef LLVM_ON_WIN32
+ // MSVCRT's _lseek(SEEK_CUR) doesn't return -1 for pipes.
+ sys::fs::file_status Status;
+ std::error_code EC = status(FD, Status);
+ SupportsSeeking = !EC && Status.type() == sys::fs::file_type::regular_file;
+#else
+ SupportsSeeking = loc != (off_t)-1;
+#endif
+ if (!SupportsSeeking)
+ pos = 0;
+ else
+ pos = static_cast<uint64_t>(loc);
+}
+
+raw_fd_ostream::~raw_fd_ostream() {
+ if (FD >= 0) {
+ flush();
+ if (ShouldClose && sys::Process::SafelyCloseFileDescriptor(FD))
+ error_detected();
+ }
+
+#ifdef __MINGW32__
+ // On mingw, global dtors should not call exit().
+ // report_fatal_error() invokes exit(). We know report_fatal_error()
+ // might not write messages to stderr when any errors were detected
+ // on FD == 2.
+ if (FD == 2) return;
+#endif
+
+ // If there are any pending errors, report them now. Clients wishing
+ // to avoid report_fatal_error calls should check for errors with
+ // has_error() and clear the error flag with clear_error() before
+ // destructing raw_ostream objects which may have errors.
+ if (has_error())
+ report_fatal_error("IO failure on output stream.", /*GenCrashDiag=*/false);
+}
+
+
+void raw_fd_ostream::write_impl(const char *Ptr, size_t Size) {
+ assert(FD >= 0 && "File already closed.");
+ pos += Size;
+
+ do {
+ ssize_t ret;
+
+ // Check whether we should attempt to use atomic writes.
+ if (LLVM_LIKELY(!UseAtomicWrites)) {
+ ret = ::write(FD, Ptr, Size);
+ } else {
+ // Use ::writev() where available.
+#if defined(HAVE_WRITEV)
+ const void *Addr = static_cast<const void *>(Ptr);
+ struct iovec IOV = {const_cast<void *>(Addr), Size };
+ ret = ::writev(FD, &IOV, 1);
+#else
+ ret = ::write(FD, Ptr, Size);
+#endif
+ }
+
+ if (ret < 0) {
+ // If it's a recoverable error, swallow it and retry the write.
+ //
+ // Ideally we wouldn't ever see EAGAIN or EWOULDBLOCK here, since
+ // raw_ostream isn't designed to do non-blocking I/O. However, some
+ // programs, such as old versions of bjam, have mistakenly used
+ // O_NONBLOCK. For compatibility, emulate blocking semantics by
+ // spinning until the write succeeds. If you don't want spinning,
+ // don't use O_NONBLOCK file descriptors with raw_ostream.
+ if (errno == EINTR || errno == EAGAIN
+#ifdef EWOULDBLOCK
+ || errno == EWOULDBLOCK
+#endif
+ )
+ continue;
+
+ // Otherwise it's a non-recoverable error. Note it and quit.
+ error_detected();
+ break;
+ }
+
+ // The write may have written some or all of the data. Update the
+ // size and buffer pointer to reflect the remainder that needs
+ // to be written. If there are no bytes left, we're done.
+ Ptr += ret;
+ Size -= ret;
+ } while (Size > 0);
+}
+
+void raw_fd_ostream::close() {
+ assert(ShouldClose);
+ ShouldClose = false;
+ flush();
+ if (sys::Process::SafelyCloseFileDescriptor(FD))
+ error_detected();
+ FD = -1;
+}
+
+uint64_t raw_fd_ostream::seek(uint64_t off) {
+ flush();
+ pos = ::lseek(FD, off, SEEK_SET);
+ if (pos == (uint64_t)-1)
+ error_detected();
+ return pos;
+}
+
+void raw_fd_ostream::pwrite_impl(const char *Ptr, size_t Size,
+ uint64_t Offset) {
+ uint64_t Pos = tell();
+ seek(Offset);
+ write(Ptr, Size);
+ seek(Pos);
+}
+
+size_t raw_fd_ostream::preferred_buffer_size() const {
+#if !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(__minix)
+ // Windows and Minix have no st_blksize.
+ assert(FD >= 0 && "File not yet open!");
+ struct stat statbuf;
+ if (fstat(FD, &statbuf) != 0)
+ return 0;
+
+ // If this is a terminal, don't use buffering. Line buffering
+ // would be a more traditional thing to do, but it's not worth
+ // the complexity.
+ if (S_ISCHR(statbuf.st_mode) && isatty(FD))
+ return 0;
+ // Return the preferred block size.
+ return statbuf.st_blksize;
+#else
+ return raw_ostream::preferred_buffer_size();
+#endif
+}
+
+raw_ostream &raw_fd_ostream::changeColor(enum Colors colors, bool bold,
+ bool bg) {
+ if (sys::Process::ColorNeedsFlush())
+ flush();
+ const char *colorcode =
+ (colors == SAVEDCOLOR) ? sys::Process::OutputBold(bg)
+ : sys::Process::OutputColor(colors, bold, bg);
+ if (colorcode) {
+ size_t len = strlen(colorcode);
+ write(colorcode, len);
+ // don't account colors towards output characters
+ pos -= len;
+ }
+ return *this;
+}
+
+raw_ostream &raw_fd_ostream::resetColor() {
+ if (sys::Process::ColorNeedsFlush())
+ flush();
+ const char *colorcode = sys::Process::ResetColor();
+ if (colorcode) {
+ size_t len = strlen(colorcode);
+ write(colorcode, len);
+ // don't account colors towards output characters
+ pos -= len;
+ }
+ return *this;
+}
+
+raw_ostream &raw_fd_ostream::reverseColor() {
+ if (sys::Process::ColorNeedsFlush())
+ flush();
+ const char *colorcode = sys::Process::OutputReverse();
+ if (colorcode) {
+ size_t len = strlen(colorcode);
+ write(colorcode, len);
+ // don't account colors towards output characters
+ pos -= len;
+ }
+ return *this;
+}
+
+bool raw_fd_ostream::is_displayed() const {
+ return sys::Process::FileDescriptorIsDisplayed(FD);
+}
+
+bool raw_fd_ostream::has_colors() const {
+ return sys::Process::FileDescriptorHasColors(FD);
+}
+
+//===----------------------------------------------------------------------===//
+// outs(), errs(), nulls()
+//===----------------------------------------------------------------------===//
+
+/// outs() - This returns a reference to a raw_ostream for standard output.
+/// Use it like: outs() << "foo" << "bar";
+raw_ostream &llvm::outs() {
+ // Set buffer settings to model stdout behavior.
+ // Delete the file descriptor when the program exits, forcing error
+ // detection. If you don't want this behavior, don't use outs().
+ std::error_code EC;
+ static raw_fd_ostream S("-", EC, sys::fs::F_None);
+ assert(!EC);
+ return S;
+}
+
+/// errs() - This returns a reference to a raw_ostream for standard error.
+/// Use it like: errs() << "foo" << "bar";
+raw_ostream &llvm::errs() {
+ // Set standard error to be unbuffered by default.
+ static raw_fd_ostream S(STDERR_FILENO, false, true);
+ return S;
+}
+
+/// nulls() - This returns a reference to a raw_ostream which discards output.
+raw_ostream &llvm::nulls() {
+ static raw_null_ostream S;
+ return S;
+}
+
+
+//===----------------------------------------------------------------------===//
+// raw_string_ostream
+//===----------------------------------------------------------------------===//
+
+raw_string_ostream::~raw_string_ostream() {
+ flush();
+}
+
+void raw_string_ostream::write_impl(const char *Ptr, size_t Size) {
+ OS.append(Ptr, Size);
+}
+
+//===----------------------------------------------------------------------===//
+// raw_svector_ostream
+//===----------------------------------------------------------------------===//
+
+// The raw_svector_ostream implementation uses the SmallVector itself as the
+// buffer for the raw_ostream. We guarantee that the raw_ostream buffer is
+// always pointing past the end of the vector, but within the vector
+// capacity. This allows raw_ostream to write directly into the correct place,
+// and we only need to set the vector size when the data is flushed.
+
+raw_svector_ostream::raw_svector_ostream(SmallVectorImpl<char> &O, unsigned)
+ : OS(O) {}
+
+raw_svector_ostream::raw_svector_ostream(SmallVectorImpl<char> &O) : OS(O) {
+ init();
+}
+
+void raw_svector_ostream::init() {
+ // Set up the initial external buffer. We make sure that the buffer has at
+ // least 128 bytes free; raw_ostream itself only requires 64, but we want to
+ // make sure that we don't grow the buffer unnecessarily on destruction (when
+ // the data is flushed). See the FIXME below.
+ OS.reserve(OS.size() + 128);
+ SetBuffer(OS.end(), OS.capacity() - OS.size());
+}
+
+raw_svector_ostream::~raw_svector_ostream() {
+ // FIXME: Prevent resizing during this flush().
+ flush();
+}
+
+void raw_svector_ostream::pwrite_impl(const char *Ptr, size_t Size,
+ uint64_t Offset) {
+ flush();
+ memcpy(OS.begin() + Offset, Ptr, Size);
+}
+
+/// resync - This is called when the SmallVector we're appending to is changed
+/// outside of the raw_svector_ostream's control. It is only safe to do this
+/// if the raw_svector_ostream has previously been flushed.
+void raw_svector_ostream::resync() {
+ assert(GetNumBytesInBuffer() == 0 && "Didn't flush before mutating vector");
+
+ if (OS.capacity() - OS.size() < 64)
+ OS.reserve(OS.capacity() * 2);
+ SetBuffer(OS.end(), OS.capacity() - OS.size());
+}
+
+void raw_svector_ostream::write_impl(const char *Ptr, size_t Size) {
+ if (Ptr == OS.end()) {
+ // Grow the buffer to include the scratch area without copying.
+ size_t NewSize = OS.size() + Size;
+ assert(NewSize <= OS.capacity() && "Invalid write_impl() call!");
+ OS.set_size(NewSize);
+ } else {
+ assert(!GetNumBytesInBuffer());
+ OS.append(Ptr, Ptr + Size);
+ }
+
+ OS.reserve(OS.size() + 64);
+ SetBuffer(OS.end(), OS.capacity() - OS.size());
+}
+
+uint64_t raw_svector_ostream::current_pos() const {
+ return OS.size();
+}
+
+StringRef raw_svector_ostream::str() {
+ flush();
+ return StringRef(OS.begin(), OS.size());
+}
+
+//===----------------------------------------------------------------------===//
+// raw_null_ostream
+//===----------------------------------------------------------------------===//
+
+raw_null_ostream::~raw_null_ostream() {
+#ifndef NDEBUG
+ // ~raw_ostream asserts that the buffer is empty. This isn't necessary
+ // with raw_null_ostream, but it's better to have raw_null_ostream follow
+ // the rules than to change the rules just for raw_null_ostream.
+ flush();
+#endif
+}
+
+void raw_null_ostream::write_impl(const char *Ptr, size_t Size) {
+}
+
+uint64_t raw_null_ostream::current_pos() const {
+ return 0;
+}
+
+void raw_null_ostream::pwrite_impl(const char *Ptr, size_t Size,
+ uint64_t Offset) {}
diff --git a/contrib/llvm/lib/Support/regcclass.h b/contrib/llvm/lib/Support/regcclass.h
new file mode 100644
index 000000000000..7fd66046cd87
--- /dev/null
+++ b/contrib/llvm/lib/Support/regcclass.h
@@ -0,0 +1,75 @@
+/*-
+ * This code is derived from OpenBSD's libc/regex, original license follows:
+ *
+ * This code is derived from OpenBSD's libc/regex, original license follows:
+ *
+ * Copyright (c) 1992, 1993, 1994 Henry Spencer.
+ * Copyright (c) 1992, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Henry Spencer.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)cclass.h 8.3 (Berkeley) 3/20/94
+ */
+
+#ifndef LLVM_SUPPORT_REGCCLASS_H
+#define LLVM_SUPPORT_REGCCLASS_H
+
+/* character-class table */
+static struct cclass {
+ const char *name;
+ const char *chars;
+ const char *multis;
+} cclasses[] = {
+ { "alnum", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\
+0123456789", ""} ,
+ { "alpha", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
+ ""} ,
+ { "blank", " \t", ""} ,
+ { "cntrl", "\007\b\t\n\v\f\r\1\2\3\4\5\6\16\17\20\21\22\23\24\
+\25\26\27\30\31\32\33\34\35\36\37\177", ""} ,
+ { "digit", "0123456789", ""} ,
+ { "graph", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\
+0123456789!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
+ ""} ,
+ { "lower", "abcdefghijklmnopqrstuvwxyz",
+ ""} ,
+ { "print", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\
+0123456789!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~ ",
+ ""} ,
+ { "punct", "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
+ ""} ,
+ { "space", "\t\n\v\f\r ", ""} ,
+ { "upper", "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
+ ""} ,
+ { "xdigit", "0123456789ABCDEFabcdef",
+ ""} ,
+ { NULL, 0, "" }
+};
+
+#endif
diff --git a/contrib/llvm/lib/Support/regcname.h b/contrib/llvm/lib/Support/regcname.h
new file mode 100644
index 000000000000..891d25573e8c
--- /dev/null
+++ b/contrib/llvm/lib/Support/regcname.h
@@ -0,0 +1,144 @@
+/*-
+ * This code is derived from OpenBSD's libc/regex, original license follows:
+ *
+ * Copyright (c) 1992, 1993, 1994 Henry Spencer.
+ * Copyright (c) 1992, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Henry Spencer.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)cname.h 8.3 (Berkeley) 3/20/94
+ */
+
+#ifndef LLVM_SUPPORT_REGCNAME_H
+#define LLVM_SUPPORT_REGCNAME_H
+
+/* character-name table */
+static struct cname {
+ const char *name;
+ char code;
+} cnames[] = {
+ { "NUL", '\0' },
+ { "SOH", '\001' },
+ { "STX", '\002' },
+ { "ETX", '\003' },
+ { "EOT", '\004' },
+ { "ENQ", '\005' },
+ { "ACK", '\006' },
+ { "BEL", '\007' },
+ { "alert", '\007' },
+ { "BS", '\010' },
+ { "backspace", '\b' },
+ { "HT", '\011' },
+ { "tab", '\t' },
+ { "LF", '\012' },
+ { "newline", '\n' },
+ { "VT", '\013' },
+ { "vertical-tab", '\v' },
+ { "FF", '\014' },
+ { "form-feed", '\f' },
+ { "CR", '\015' },
+ { "carriage-return", '\r' },
+ { "SO", '\016' },
+ { "SI", '\017' },
+ { "DLE", '\020' },
+ { "DC1", '\021' },
+ { "DC2", '\022' },
+ { "DC3", '\023' },
+ { "DC4", '\024' },
+ { "NAK", '\025' },
+ { "SYN", '\026' },
+ { "ETB", '\027' },
+ { "CAN", '\030' },
+ { "EM", '\031' },
+ { "SUB", '\032' },
+ { "ESC", '\033' },
+ { "IS4", '\034' },
+ { "FS", '\034' },
+ { "IS3", '\035' },
+ { "GS", '\035' },
+ { "IS2", '\036' },
+ { "RS", '\036' },
+ { "IS1", '\037' },
+ { "US", '\037' },
+ { "space", ' ' },
+ { "exclamation-mark", '!' },
+ { "quotation-mark", '"' },
+ { "number-sign", '#' },
+ { "dollar-sign", '$' },
+ { "percent-sign", '%' },
+ { "ampersand", '&' },
+ { "apostrophe", '\'' },
+ { "left-parenthesis", '(' },
+ { "right-parenthesis", ')' },
+ { "asterisk", '*' },
+ { "plus-sign", '+' },
+ { "comma", ',' },
+ { "hyphen", '-' },
+ { "hyphen-minus", '-' },
+ { "period", '.' },
+ { "full-stop", '.' },
+ { "slash", '/' },
+ { "solidus", '/' },
+ { "zero", '0' },
+ { "one", '1' },
+ { "two", '2' },
+ { "three", '3' },
+ { "four", '4' },
+ { "five", '5' },
+ { "six", '6' },
+ { "seven", '7' },
+ { "eight", '8' },
+ { "nine", '9' },
+ { "colon", ':' },
+ { "semicolon", ';' },
+ { "less-than-sign", '<' },
+ { "equals-sign", '=' },
+ { "greater-than-sign", '>' },
+ { "question-mark", '?' },
+ { "commercial-at", '@' },
+ { "left-square-bracket", '[' },
+ { "backslash", '\\' },
+ { "reverse-solidus", '\\' },
+ { "right-square-bracket", ']' },
+ { "circumflex", '^' },
+ { "circumflex-accent", '^' },
+ { "underscore", '_' },
+ { "low-line", '_' },
+ { "grave-accent", '`' },
+ { "left-brace", '{' },
+ { "left-curly-bracket", '{' },
+ { "vertical-line", '|' },
+ { "right-brace", '}' },
+ { "right-curly-bracket", '}' },
+ { "tilde", '~' },
+ { "DEL", '\177' },
+ { NULL, 0 }
+};
+
+#endif
diff --git a/contrib/llvm/lib/Support/regcomp.c b/contrib/llvm/lib/Support/regcomp.c
new file mode 100644
index 000000000000..ebde64f9cf75
--- /dev/null
+++ b/contrib/llvm/lib/Support/regcomp.c
@@ -0,0 +1,1574 @@
+/*-
+ * This code is derived from OpenBSD's libc/regex, original license follows:
+ *
+ * Copyright (c) 1992, 1993, 1994 Henry Spencer.
+ * Copyright (c) 1992, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Henry Spencer.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)regcomp.c 8.5 (Berkeley) 3/20/94
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <limits.h>
+#include <stdlib.h>
+#include "regex_impl.h"
+
+#include "regutils.h"
+#include "regex2.h"
+
+#include "regcclass.h"
+#include "regcname.h"
+
+#include "llvm/Config/config.h"
+#if HAVE_STDINT_H
+#include <stdint.h>
+#else
+/* Pessimistically bound memory use */
+#define SIZE_MAX UINT_MAX
+#endif
+
+/*
+ * parse structure, passed up and down to avoid global variables and
+ * other clumsinesses
+ */
+struct parse {
+ char *next; /* next character in RE */
+ char *end; /* end of string (-> NUL normally) */
+ int error; /* has an error been seen? */
+ sop *strip; /* malloced strip */
+ sopno ssize; /* malloced strip size (allocated) */
+ sopno slen; /* malloced strip length (used) */
+ int ncsalloc; /* number of csets allocated */
+ struct re_guts *g;
+# define NPAREN 10 /* we need to remember () 1-9 for back refs */
+ sopno pbegin[NPAREN]; /* -> ( ([0] unused) */
+ sopno pend[NPAREN]; /* -> ) ([0] unused) */
+};
+
+static void p_ere(struct parse *, int);
+static void p_ere_exp(struct parse *);
+static void p_str(struct parse *);
+static void p_bre(struct parse *, int, int);
+static int p_simp_re(struct parse *, int);
+static int p_count(struct parse *);
+static void p_bracket(struct parse *);
+static void p_b_term(struct parse *, cset *);
+static void p_b_cclass(struct parse *, cset *);
+static void p_b_eclass(struct parse *, cset *);
+static char p_b_symbol(struct parse *);
+static char p_b_coll_elem(struct parse *, int);
+static char othercase(int);
+static void bothcases(struct parse *, int);
+static void ordinary(struct parse *, int);
+static void nonnewline(struct parse *);
+static void repeat(struct parse *, sopno, int, int);
+static int seterr(struct parse *, int);
+static cset *allocset(struct parse *);
+static void freeset(struct parse *, cset *);
+static int freezeset(struct parse *, cset *);
+static int firstch(struct parse *, cset *);
+static int nch(struct parse *, cset *);
+static void mcadd(struct parse *, cset *, const char *);
+static void mcinvert(struct parse *, cset *);
+static void mccase(struct parse *, cset *);
+static int isinsets(struct re_guts *, int);
+static int samesets(struct re_guts *, int, int);
+static void categorize(struct parse *, struct re_guts *);
+static sopno dupl(struct parse *, sopno, sopno);
+static void doemit(struct parse *, sop, size_t);
+static void doinsert(struct parse *, sop, size_t, sopno);
+static void dofwd(struct parse *, sopno, sop);
+static void enlarge(struct parse *, sopno);
+static void stripsnug(struct parse *, struct re_guts *);
+static void findmust(struct parse *, struct re_guts *);
+static sopno pluscount(struct parse *, struct re_guts *);
+
+static char nuls[10]; /* place to point scanner in event of error */
+
+/*
+ * macros for use with parse structure
+ * BEWARE: these know that the parse structure is named `p' !!!
+ */
+#define PEEK() (*p->next)
+#define PEEK2() (*(p->next+1))
+#define MORE() (p->next < p->end)
+#define MORE2() (p->next+1 < p->end)
+#define SEE(c) (MORE() && PEEK() == (c))
+#define SEETWO(a, b) (MORE() && MORE2() && PEEK() == (a) && PEEK2() == (b))
+#define EAT(c) ((SEE(c)) ? (NEXT(), 1) : 0)
+#define EATTWO(a, b) ((SEETWO(a, b)) ? (NEXT2(), 1) : 0)
+#define NEXT() (p->next++)
+#define NEXT2() (p->next += 2)
+#define NEXTn(n) (p->next += (n))
+#define GETNEXT() (*p->next++)
+#define SETERROR(e) seterr(p, (e))
+#define REQUIRE(co, e) (void)((co) || SETERROR(e))
+#define MUSTSEE(c, e) (REQUIRE(MORE() && PEEK() == (c), e))
+#define MUSTEAT(c, e) (REQUIRE(MORE() && GETNEXT() == (c), e))
+#define MUSTNOTSEE(c, e) (REQUIRE(!MORE() || PEEK() != (c), e))
+#define EMIT(op, sopnd) doemit(p, (sop)(op), (size_t)(sopnd))
+#define INSERT(op, pos) doinsert(p, (sop)(op), HERE()-(pos)+1, pos)
+#define AHEAD(pos) dofwd(p, pos, HERE()-(pos))
+#define ASTERN(sop, pos) EMIT(sop, HERE()-pos)
+#define HERE() (p->slen)
+#define THERE() (p->slen - 1)
+#define THERETHERE() (p->slen - 2)
+#define DROP(n) (p->slen -= (n))
+
+#ifdef _POSIX2_RE_DUP_MAX
+#define DUPMAX _POSIX2_RE_DUP_MAX
+#else
+#define DUPMAX 255
+#endif
+#define INFINITY (DUPMAX + 1)
+
+#ifndef NDEBUG
+static int never = 0; /* for use in asserts; shuts lint up */
+#else
+#define never 0 /* some <assert.h>s have bugs too */
+#endif
+
+/*
+ - llvm_regcomp - interface for parser and compilation
+ */
+int /* 0 success, otherwise REG_something */
+llvm_regcomp(llvm_regex_t *preg, const char *pattern, int cflags)
+{
+ struct parse pa;
+ struct re_guts *g;
+ struct parse *p = &pa;
+ int i;
+ size_t len;
+#ifdef REDEBUG
+# define GOODFLAGS(f) (f)
+#else
+# define GOODFLAGS(f) ((f)&~REG_DUMP)
+#endif
+
+ cflags = GOODFLAGS(cflags);
+ if ((cflags&REG_EXTENDED) && (cflags&REG_NOSPEC))
+ return(REG_INVARG);
+
+ if (cflags&REG_PEND) {
+ if (preg->re_endp < pattern)
+ return(REG_INVARG);
+ len = preg->re_endp - pattern;
+ } else
+ len = strlen((const char *)pattern);
+
+ /* do the mallocs early so failure handling is easy */
+ g = (struct re_guts *)malloc(sizeof(struct re_guts) +
+ (NC-1)*sizeof(cat_t));
+ if (g == NULL)
+ return(REG_ESPACE);
+ p->ssize = len/(size_t)2*(size_t)3 + (size_t)1; /* ugh */
+ p->strip = (sop *)calloc(p->ssize, sizeof(sop));
+ p->slen = 0;
+ if (p->strip == NULL) {
+ free((char *)g);
+ return(REG_ESPACE);
+ }
+
+ /* set things up */
+ p->g = g;
+ p->next = (char *)pattern; /* convenience; we do not modify it */
+ p->end = p->next + len;
+ p->error = 0;
+ p->ncsalloc = 0;
+ for (i = 0; i < NPAREN; i++) {
+ p->pbegin[i] = 0;
+ p->pend[i] = 0;
+ }
+ g->csetsize = NC;
+ g->sets = NULL;
+ g->setbits = NULL;
+ g->ncsets = 0;
+ g->cflags = cflags;
+ g->iflags = 0;
+ g->nbol = 0;
+ g->neol = 0;
+ g->must = NULL;
+ g->mlen = 0;
+ g->nsub = 0;
+ g->ncategories = 1; /* category 0 is "everything else" */
+ g->categories = &g->catspace[-(CHAR_MIN)];
+ (void) memset((char *)g->catspace, 0, NC*sizeof(cat_t));
+ g->backrefs = 0;
+
+ /* do it */
+ EMIT(OEND, 0);
+ g->firststate = THERE();
+ if (cflags&REG_EXTENDED)
+ p_ere(p, OUT);
+ else if (cflags&REG_NOSPEC)
+ p_str(p);
+ else
+ p_bre(p, OUT, OUT);
+ EMIT(OEND, 0);
+ g->laststate = THERE();
+
+ /* tidy up loose ends and fill things in */
+ categorize(p, g);
+ stripsnug(p, g);
+ findmust(p, g);
+ g->nplus = pluscount(p, g);
+ g->magic = MAGIC2;
+ preg->re_nsub = g->nsub;
+ preg->re_g = g;
+ preg->re_magic = MAGIC1;
+#ifndef REDEBUG
+ /* not debugging, so can't rely on the assert() in llvm_regexec() */
+ if (g->iflags&REGEX_BAD)
+ SETERROR(REG_ASSERT);
+#endif
+
+ /* win or lose, we're done */
+ if (p->error != 0) /* lose */
+ llvm_regfree(preg);
+ return(p->error);
+}
+
+/*
+ - p_ere - ERE parser top level, concatenation and alternation
+ */
+static void
+p_ere(struct parse *p, int stop) /* character this ERE should end at */
+{
+ char c;
+ sopno prevback = 0;
+ sopno prevfwd = 0;
+ sopno conc;
+ int first = 1; /* is this the first alternative? */
+
+ for (;;) {
+ /* do a bunch of concatenated expressions */
+ conc = HERE();
+ while (MORE() && (c = PEEK()) != '|' && c != stop)
+ p_ere_exp(p);
+ REQUIRE(HERE() != conc, REG_EMPTY); /* require nonempty */
+
+ if (!EAT('|'))
+ break; /* NOTE BREAK OUT */
+
+ if (first) {
+ INSERT(OCH_, conc); /* offset is wrong */
+ prevfwd = conc;
+ prevback = conc;
+ first = 0;
+ }
+ ASTERN(OOR1, prevback);
+ prevback = THERE();
+ AHEAD(prevfwd); /* fix previous offset */
+ prevfwd = HERE();
+ EMIT(OOR2, 0); /* offset is very wrong */
+ }
+
+ if (!first) { /* tail-end fixups */
+ AHEAD(prevfwd);
+ ASTERN(O_CH, prevback);
+ }
+
+ assert(!MORE() || SEE(stop));
+}
+
+/*
+ - p_ere_exp - parse one subERE, an atom possibly followed by a repetition op
+ */
+static void
+p_ere_exp(struct parse *p)
+{
+ char c;
+ sopno pos;
+ int count;
+ int count2;
+ int backrefnum;
+ sopno subno;
+ int wascaret = 0;
+
+ assert(MORE()); /* caller should have ensured this */
+ c = GETNEXT();
+
+ pos = HERE();
+ switch (c) {
+ case '(':
+ REQUIRE(MORE(), REG_EPAREN);
+ p->g->nsub++;
+ subno = p->g->nsub;
+ if (subno < NPAREN)
+ p->pbegin[subno] = HERE();
+ EMIT(OLPAREN, subno);
+ if (!SEE(')'))
+ p_ere(p, ')');
+ if (subno < NPAREN) {
+ p->pend[subno] = HERE();
+ assert(p->pend[subno] != 0);
+ }
+ EMIT(ORPAREN, subno);
+ MUSTEAT(')', REG_EPAREN);
+ break;
+#ifndef POSIX_MISTAKE
+ case ')': /* happens only if no current unmatched ( */
+ /*
+ * You may ask, why the ifndef? Because I didn't notice
+ * this until slightly too late for 1003.2, and none of the
+ * other 1003.2 regular-expression reviewers noticed it at
+ * all. So an unmatched ) is legal POSIX, at least until
+ * we can get it fixed.
+ */
+ SETERROR(REG_EPAREN);
+ break;
+#endif
+ case '^':
+ EMIT(OBOL, 0);
+ p->g->iflags |= USEBOL;
+ p->g->nbol++;
+ wascaret = 1;
+ break;
+ case '$':
+ EMIT(OEOL, 0);
+ p->g->iflags |= USEEOL;
+ p->g->neol++;
+ break;
+ case '|':
+ SETERROR(REG_EMPTY);
+ break;
+ case '*':
+ case '+':
+ case '?':
+ SETERROR(REG_BADRPT);
+ break;
+ case '.':
+ if (p->g->cflags&REG_NEWLINE)
+ nonnewline(p);
+ else
+ EMIT(OANY, 0);
+ break;
+ case '[':
+ p_bracket(p);
+ break;
+ case '\\':
+ REQUIRE(MORE(), REG_EESCAPE);
+ c = GETNEXT();
+ if (c >= '1' && c <= '9') {
+ /* \[0-9] is taken to be a back-reference to a previously specified
+ * matching group. backrefnum will hold the number. The matching
+ * group must exist (i.e. if \4 is found there must have been at
+ * least 4 matching groups specified in the pattern previously).
+ */
+ backrefnum = c - '0';
+ if (p->pend[backrefnum] == 0) {
+ SETERROR(REG_ESUBREG);
+ break;
+ }
+
+ /* Make sure everything checks out and emit the sequence
+ * that marks a back-reference to the parse structure.
+ */
+ assert(backrefnum <= p->g->nsub);
+ EMIT(OBACK_, backrefnum);
+ assert(p->pbegin[backrefnum] != 0);
+ assert(OP(p->strip[p->pbegin[backrefnum]]) != OLPAREN);
+ assert(OP(p->strip[p->pend[backrefnum]]) != ORPAREN);
+ (void) dupl(p, p->pbegin[backrefnum]+1, p->pend[backrefnum]);
+ EMIT(O_BACK, backrefnum);
+ p->g->backrefs = 1;
+ } else {
+ /* Other chars are simply themselves when escaped with a backslash.
+ */
+ ordinary(p, c);
+ }
+ break;
+ case '{': /* okay as ordinary except if digit follows */
+ REQUIRE(!MORE() || !isdigit((uch)PEEK()), REG_BADRPT);
+ /* FALLTHROUGH */
+ default:
+ ordinary(p, c);
+ break;
+ }
+
+ if (!MORE())
+ return;
+ c = PEEK();
+ /* we call { a repetition if followed by a digit */
+ if (!( c == '*' || c == '+' || c == '?' ||
+ (c == '{' && MORE2() && isdigit((uch)PEEK2())) ))
+ return; /* no repetition, we're done */
+ NEXT();
+
+ REQUIRE(!wascaret, REG_BADRPT);
+ switch (c) {
+ case '*': /* implemented as +? */
+ /* this case does not require the (y|) trick, noKLUDGE */
+ INSERT(OPLUS_, pos);
+ ASTERN(O_PLUS, pos);
+ INSERT(OQUEST_, pos);
+ ASTERN(O_QUEST, pos);
+ break;
+ case '+':
+ INSERT(OPLUS_, pos);
+ ASTERN(O_PLUS, pos);
+ break;
+ case '?':
+ /* KLUDGE: emit y? as (y|) until subtle bug gets fixed */
+ INSERT(OCH_, pos); /* offset slightly wrong */
+ ASTERN(OOR1, pos); /* this one's right */
+ AHEAD(pos); /* fix the OCH_ */
+ EMIT(OOR2, 0); /* offset very wrong... */
+ AHEAD(THERE()); /* ...so fix it */
+ ASTERN(O_CH, THERETHERE());
+ break;
+ case '{':
+ count = p_count(p);
+ if (EAT(',')) {
+ if (isdigit((uch)PEEK())) {
+ count2 = p_count(p);
+ REQUIRE(count <= count2, REG_BADBR);
+ } else /* single number with comma */
+ count2 = INFINITY;
+ } else /* just a single number */
+ count2 = count;
+ repeat(p, pos, count, count2);
+ if (!EAT('}')) { /* error heuristics */
+ while (MORE() && PEEK() != '}')
+ NEXT();
+ REQUIRE(MORE(), REG_EBRACE);
+ SETERROR(REG_BADBR);
+ }
+ break;
+ }
+
+ if (!MORE())
+ return;
+ c = PEEK();
+ if (!( c == '*' || c == '+' || c == '?' ||
+ (c == '{' && MORE2() && isdigit((uch)PEEK2())) ) )
+ return;
+ SETERROR(REG_BADRPT);
+}
+
+/*
+ - p_str - string (no metacharacters) "parser"
+ */
+static void
+p_str(struct parse *p)
+{
+ REQUIRE(MORE(), REG_EMPTY);
+ while (MORE())
+ ordinary(p, GETNEXT());
+}
+
+/*
+ - p_bre - BRE parser top level, anchoring and concatenation
+ * Giving end1 as OUT essentially eliminates the end1/end2 check.
+ *
+ * This implementation is a bit of a kludge, in that a trailing $ is first
+ * taken as an ordinary character and then revised to be an anchor. The
+ * only undesirable side effect is that '$' gets included as a character
+ * category in such cases. This is fairly harmless; not worth fixing.
+ * The amount of lookahead needed to avoid this kludge is excessive.
+ */
+static void
+p_bre(struct parse *p,
+ int end1, /* first terminating character */
+ int end2) /* second terminating character */
+{
+ sopno start = HERE();
+ int first = 1; /* first subexpression? */
+ int wasdollar = 0;
+
+ if (EAT('^')) {
+ EMIT(OBOL, 0);
+ p->g->iflags |= USEBOL;
+ p->g->nbol++;
+ }
+ while (MORE() && !SEETWO(end1, end2)) {
+ wasdollar = p_simp_re(p, first);
+ first = 0;
+ }
+ if (wasdollar) { /* oops, that was a trailing anchor */
+ DROP(1);
+ EMIT(OEOL, 0);
+ p->g->iflags |= USEEOL;
+ p->g->neol++;
+ }
+
+ REQUIRE(HERE() != start, REG_EMPTY); /* require nonempty */
+}
+
+/*
+ - p_simp_re - parse a simple RE, an atom possibly followed by a repetition
+ */
+static int /* was the simple RE an unbackslashed $? */
+p_simp_re(struct parse *p,
+ int starordinary) /* is a leading * an ordinary character? */
+{
+ int c;
+ int count;
+ int count2;
+ sopno pos;
+ int i;
+ sopno subno;
+# define BACKSL (1<<CHAR_BIT)
+
+ pos = HERE(); /* repetition op, if any, covers from here */
+
+ assert(MORE()); /* caller should have ensured this */
+ c = GETNEXT();
+ if (c == '\\') {
+ REQUIRE(MORE(), REG_EESCAPE);
+ c = BACKSL | GETNEXT();
+ }
+ switch (c) {
+ case '.':
+ if (p->g->cflags&REG_NEWLINE)
+ nonnewline(p);
+ else
+ EMIT(OANY, 0);
+ break;
+ case '[':
+ p_bracket(p);
+ break;
+ case BACKSL|'{':
+ SETERROR(REG_BADRPT);
+ break;
+ case BACKSL|'(':
+ p->g->nsub++;
+ subno = p->g->nsub;
+ if (subno < NPAREN)
+ p->pbegin[subno] = HERE();
+ EMIT(OLPAREN, subno);
+ /* the MORE here is an error heuristic */
+ if (MORE() && !SEETWO('\\', ')'))
+ p_bre(p, '\\', ')');
+ if (subno < NPAREN) {
+ p->pend[subno] = HERE();
+ assert(p->pend[subno] != 0);
+ }
+ EMIT(ORPAREN, subno);
+ REQUIRE(EATTWO('\\', ')'), REG_EPAREN);
+ break;
+ case BACKSL|')': /* should not get here -- must be user */
+ case BACKSL|'}':
+ SETERROR(REG_EPAREN);
+ break;
+ case BACKSL|'1':
+ case BACKSL|'2':
+ case BACKSL|'3':
+ case BACKSL|'4':
+ case BACKSL|'5':
+ case BACKSL|'6':
+ case BACKSL|'7':
+ case BACKSL|'8':
+ case BACKSL|'9':
+ i = (c&~BACKSL) - '0';
+ assert(i < NPAREN);
+ if (p->pend[i] != 0) {
+ assert(i <= p->g->nsub);
+ EMIT(OBACK_, i);
+ assert(p->pbegin[i] != 0);
+ assert(OP(p->strip[p->pbegin[i]]) == OLPAREN);
+ assert(OP(p->strip[p->pend[i]]) == ORPAREN);
+ (void) dupl(p, p->pbegin[i]+1, p->pend[i]);
+ EMIT(O_BACK, i);
+ } else
+ SETERROR(REG_ESUBREG);
+ p->g->backrefs = 1;
+ break;
+ case '*':
+ REQUIRE(starordinary, REG_BADRPT);
+ /* FALLTHROUGH */
+ default:
+ ordinary(p, (char)c);
+ break;
+ }
+
+ if (EAT('*')) { /* implemented as +? */
+ /* this case does not require the (y|) trick, noKLUDGE */
+ INSERT(OPLUS_, pos);
+ ASTERN(O_PLUS, pos);
+ INSERT(OQUEST_, pos);
+ ASTERN(O_QUEST, pos);
+ } else if (EATTWO('\\', '{')) {
+ count = p_count(p);
+ if (EAT(',')) {
+ if (MORE() && isdigit((uch)PEEK())) {
+ count2 = p_count(p);
+ REQUIRE(count <= count2, REG_BADBR);
+ } else /* single number with comma */
+ count2 = INFINITY;
+ } else /* just a single number */
+ count2 = count;
+ repeat(p, pos, count, count2);
+ if (!EATTWO('\\', '}')) { /* error heuristics */
+ while (MORE() && !SEETWO('\\', '}'))
+ NEXT();
+ REQUIRE(MORE(), REG_EBRACE);
+ SETERROR(REG_BADBR);
+ }
+ } else if (c == '$') /* $ (but not \$) ends it */
+ return(1);
+
+ return(0);
+}
+
+/*
+ - p_count - parse a repetition count
+ */
+static int /* the value */
+p_count(struct parse *p)
+{
+ int count = 0;
+ int ndigits = 0;
+
+ while (MORE() && isdigit((uch)PEEK()) && count <= DUPMAX) {
+ count = count*10 + (GETNEXT() - '0');
+ ndigits++;
+ }
+
+ REQUIRE(ndigits > 0 && count <= DUPMAX, REG_BADBR);
+ return(count);
+}
+
+/*
+ - p_bracket - parse a bracketed character list
+ *
+ * Note a significant property of this code: if the allocset() did SETERROR,
+ * no set operations are done.
+ */
+static void
+p_bracket(struct parse *p)
+{
+ cset *cs;
+ int invert = 0;
+
+ /* Dept of Truly Sickening Special-Case Kludges */
+ if (p->next + 5 < p->end && strncmp(p->next, "[:<:]]", 6) == 0) {
+ EMIT(OBOW, 0);
+ NEXTn(6);
+ return;
+ }
+ if (p->next + 5 < p->end && strncmp(p->next, "[:>:]]", 6) == 0) {
+ EMIT(OEOW, 0);
+ NEXTn(6);
+ return;
+ }
+
+ if ((cs = allocset(p)) == NULL) {
+ /* allocset did set error status in p */
+ return;
+ }
+
+ if (EAT('^'))
+ invert++; /* make note to invert set at end */
+ if (EAT(']'))
+ CHadd(cs, ']');
+ else if (EAT('-'))
+ CHadd(cs, '-');
+ while (MORE() && PEEK() != ']' && !SEETWO('-', ']'))
+ p_b_term(p, cs);
+ if (EAT('-'))
+ CHadd(cs, '-');
+ MUSTEAT(']', REG_EBRACK);
+
+ if (p->error != 0) { /* don't mess things up further */
+ freeset(p, cs);
+ return;
+ }
+
+ if (p->g->cflags&REG_ICASE) {
+ int i;
+ int ci;
+
+ for (i = p->g->csetsize - 1; i >= 0; i--)
+ if (CHIN(cs, i) && isalpha(i)) {
+ ci = othercase(i);
+ if (ci != i)
+ CHadd(cs, ci);
+ }
+ if (cs->multis != NULL)
+ mccase(p, cs);
+ }
+ if (invert) {
+ int i;
+
+ for (i = p->g->csetsize - 1; i >= 0; i--)
+ if (CHIN(cs, i))
+ CHsub(cs, i);
+ else
+ CHadd(cs, i);
+ if (p->g->cflags&REG_NEWLINE)
+ CHsub(cs, '\n');
+ if (cs->multis != NULL)
+ mcinvert(p, cs);
+ }
+
+ assert(cs->multis == NULL); /* xxx */
+
+ if (nch(p, cs) == 1) { /* optimize singleton sets */
+ ordinary(p, firstch(p, cs));
+ freeset(p, cs);
+ } else
+ EMIT(OANYOF, freezeset(p, cs));
+}
+
+/*
+ - p_b_term - parse one term of a bracketed character list
+ */
+static void
+p_b_term(struct parse *p, cset *cs)
+{
+ char c;
+ char start, finish;
+ int i;
+
+ /* classify what we've got */
+ switch ((MORE()) ? PEEK() : '\0') {
+ case '[':
+ c = (MORE2()) ? PEEK2() : '\0';
+ break;
+ case '-':
+ SETERROR(REG_ERANGE);
+ return; /* NOTE RETURN */
+ break;
+ default:
+ c = '\0';
+ break;
+ }
+
+ switch (c) {
+ case ':': /* character class */
+ NEXT2();
+ REQUIRE(MORE(), REG_EBRACK);
+ c = PEEK();
+ REQUIRE(c != '-' && c != ']', REG_ECTYPE);
+ p_b_cclass(p, cs);
+ REQUIRE(MORE(), REG_EBRACK);
+ REQUIRE(EATTWO(':', ']'), REG_ECTYPE);
+ break;
+ case '=': /* equivalence class */
+ NEXT2();
+ REQUIRE(MORE(), REG_EBRACK);
+ c = PEEK();
+ REQUIRE(c != '-' && c != ']', REG_ECOLLATE);
+ p_b_eclass(p, cs);
+ REQUIRE(MORE(), REG_EBRACK);
+ REQUIRE(EATTWO('=', ']'), REG_ECOLLATE);
+ break;
+ default: /* symbol, ordinary character, or range */
+/* xxx revision needed for multichar stuff */
+ start = p_b_symbol(p);
+ if (SEE('-') && MORE2() && PEEK2() != ']') {
+ /* range */
+ NEXT();
+ if (EAT('-'))
+ finish = '-';
+ else
+ finish = p_b_symbol(p);
+ } else
+ finish = start;
+/* xxx what about signed chars here... */
+ REQUIRE(start <= finish, REG_ERANGE);
+ for (i = start; i <= finish; i++)
+ CHadd(cs, i);
+ break;
+ }
+}
+
+/*
+ - p_b_cclass - parse a character-class name and deal with it
+ */
+static void
+p_b_cclass(struct parse *p, cset *cs)
+{
+ char *sp = p->next;
+ struct cclass *cp;
+ size_t len;
+ const char *u;
+ char c;
+
+ while (MORE() && isalpha((uch)PEEK()))
+ NEXT();
+ len = p->next - sp;
+ for (cp = cclasses; cp->name != NULL; cp++)
+ if (strncmp(cp->name, sp, len) == 0 && cp->name[len] == '\0')
+ break;
+ if (cp->name == NULL) {
+ /* oops, didn't find it */
+ SETERROR(REG_ECTYPE);
+ return;
+ }
+
+ u = cp->chars;
+ while ((c = *u++) != '\0')
+ CHadd(cs, c);
+ for (u = cp->multis; *u != '\0'; u += strlen(u) + 1)
+ MCadd(p, cs, u);
+}
+
+/*
+ - p_b_eclass - parse an equivalence-class name and deal with it
+ *
+ * This implementation is incomplete. xxx
+ */
+static void
+p_b_eclass(struct parse *p, cset *cs)
+{
+ char c;
+
+ c = p_b_coll_elem(p, '=');
+ CHadd(cs, c);
+}
+
+/*
+ - p_b_symbol - parse a character or [..]ed multicharacter collating symbol
+ */
+static char /* value of symbol */
+p_b_symbol(struct parse *p)
+{
+ char value;
+
+ REQUIRE(MORE(), REG_EBRACK);
+ if (!EATTWO('[', '.'))
+ return(GETNEXT());
+
+ /* collating symbol */
+ value = p_b_coll_elem(p, '.');
+ REQUIRE(EATTWO('.', ']'), REG_ECOLLATE);
+ return(value);
+}
+
+/*
+ - p_b_coll_elem - parse a collating-element name and look it up
+ */
+static char /* value of collating element */
+p_b_coll_elem(struct parse *p,
+ int endc) /* name ended by endc,']' */
+{
+ char *sp = p->next;
+ struct cname *cp;
+ int len;
+
+ while (MORE() && !SEETWO(endc, ']'))
+ NEXT();
+ if (!MORE()) {
+ SETERROR(REG_EBRACK);
+ return(0);
+ }
+ len = p->next - sp;
+ for (cp = cnames; cp->name != NULL; cp++)
+ if (strncmp(cp->name, sp, len) == 0 && cp->name[len] == '\0')
+ return(cp->code); /* known name */
+ if (len == 1)
+ return(*sp); /* single character */
+ SETERROR(REG_ECOLLATE); /* neither */
+ return(0);
+}
+
+/*
+ - othercase - return the case counterpart of an alphabetic
+ */
+static char /* if no counterpart, return ch */
+othercase(int ch)
+{
+ ch = (uch)ch;
+ assert(isalpha(ch));
+ if (isupper(ch))
+ return ((uch)tolower(ch));
+ else if (islower(ch))
+ return ((uch)toupper(ch));
+ else /* peculiar, but could happen */
+ return(ch);
+}
+
+/*
+ - bothcases - emit a dualcase version of a two-case character
+ *
+ * Boy, is this implementation ever a kludge...
+ */
+static void
+bothcases(struct parse *p, int ch)
+{
+ char *oldnext = p->next;
+ char *oldend = p->end;
+ char bracket[3];
+
+ ch = (uch)ch;
+ assert(othercase(ch) != ch); /* p_bracket() would recurse */
+ p->next = bracket;
+ p->end = bracket+2;
+ bracket[0] = ch;
+ bracket[1] = ']';
+ bracket[2] = '\0';
+ p_bracket(p);
+ assert(p->next == bracket+2);
+ p->next = oldnext;
+ p->end = oldend;
+}
+
+/*
+ - ordinary - emit an ordinary character
+ */
+static void
+ordinary(struct parse *p, int ch)
+{
+ cat_t *cap = p->g->categories;
+
+ if ((p->g->cflags&REG_ICASE) && isalpha((uch)ch) && othercase(ch) != ch)
+ bothcases(p, ch);
+ else {
+ EMIT(OCHAR, (uch)ch);
+ if (cap[ch] == 0)
+ cap[ch] = p->g->ncategories++;
+ }
+}
+
+/*
+ - nonnewline - emit REG_NEWLINE version of OANY
+ *
+ * Boy, is this implementation ever a kludge...
+ */
+static void
+nonnewline(struct parse *p)
+{
+ char *oldnext = p->next;
+ char *oldend = p->end;
+ char bracket[4];
+
+ p->next = bracket;
+ p->end = bracket+3;
+ bracket[0] = '^';
+ bracket[1] = '\n';
+ bracket[2] = ']';
+ bracket[3] = '\0';
+ p_bracket(p);
+ assert(p->next == bracket+3);
+ p->next = oldnext;
+ p->end = oldend;
+}
+
+/*
+ - repeat - generate code for a bounded repetition, recursively if needed
+ */
+static void
+repeat(struct parse *p,
+ sopno start, /* operand from here to end of strip */
+ int from, /* repeated from this number */
+ int to) /* to this number of times (maybe INFINITY) */
+{
+ sopno finish = HERE();
+# define N 2
+# define INF 3
+# define REP(f, t) ((f)*8 + (t))
+# define MAP(n) (((n) <= 1) ? (n) : ((n) == INFINITY) ? INF : N)
+ sopno copy;
+
+ if (p->error != 0) /* head off possible runaway recursion */
+ return;
+
+ assert(from <= to);
+
+ switch (REP(MAP(from), MAP(to))) {
+ case REP(0, 0): /* must be user doing this */
+ DROP(finish-start); /* drop the operand */
+ break;
+ case REP(0, 1): /* as x{1,1}? */
+ case REP(0, N): /* as x{1,n}? */
+ case REP(0, INF): /* as x{1,}? */
+ /* KLUDGE: emit y? as (y|) until subtle bug gets fixed */
+ INSERT(OCH_, start); /* offset is wrong... */
+ repeat(p, start+1, 1, to);
+ ASTERN(OOR1, start);
+ AHEAD(start); /* ... fix it */
+ EMIT(OOR2, 0);
+ AHEAD(THERE());
+ ASTERN(O_CH, THERETHERE());
+ break;
+ case REP(1, 1): /* trivial case */
+ /* done */
+ break;
+ case REP(1, N): /* as x?x{1,n-1} */
+ /* KLUDGE: emit y? as (y|) until subtle bug gets fixed */
+ INSERT(OCH_, start);
+ ASTERN(OOR1, start);
+ AHEAD(start);
+ EMIT(OOR2, 0); /* offset very wrong... */
+ AHEAD(THERE()); /* ...so fix it */
+ ASTERN(O_CH, THERETHERE());
+ copy = dupl(p, start+1, finish+1);
+ assert(copy == finish+4);
+ repeat(p, copy, 1, to-1);
+ break;
+ case REP(1, INF): /* as x+ */
+ INSERT(OPLUS_, start);
+ ASTERN(O_PLUS, start);
+ break;
+ case REP(N, N): /* as xx{m-1,n-1} */
+ copy = dupl(p, start, finish);
+ repeat(p, copy, from-1, to-1);
+ break;
+ case REP(N, INF): /* as xx{n-1,INF} */
+ copy = dupl(p, start, finish);
+ repeat(p, copy, from-1, to);
+ break;
+ default: /* "can't happen" */
+ SETERROR(REG_ASSERT); /* just in case */
+ break;
+ }
+}
+
+/*
+ - seterr - set an error condition
+ */
+static int /* useless but makes type checking happy */
+seterr(struct parse *p, int e)
+{
+ if (p->error == 0) /* keep earliest error condition */
+ p->error = e;
+ p->next = nuls; /* try to bring things to a halt */
+ p->end = nuls;
+ return(0); /* make the return value well-defined */
+}
+
+/*
+ - allocset - allocate a set of characters for []
+ */
+static cset *
+allocset(struct parse *p)
+{
+ int no = p->g->ncsets++;
+ size_t nc;
+ size_t nbytes;
+ cset *cs;
+ size_t css = (size_t)p->g->csetsize;
+ int i;
+
+ if (no >= p->ncsalloc) { /* need another column of space */
+ void *ptr;
+
+ p->ncsalloc += CHAR_BIT;
+ nc = p->ncsalloc;
+ if (nc > SIZE_MAX / sizeof(cset))
+ goto nomem;
+ assert(nc % CHAR_BIT == 0);
+ nbytes = nc / CHAR_BIT * css;
+
+ ptr = (cset *)realloc((char *)p->g->sets, nc * sizeof(cset));
+ if (ptr == NULL)
+ goto nomem;
+ p->g->sets = ptr;
+
+ ptr = (uch *)realloc((char *)p->g->setbits, nbytes);
+ if (ptr == NULL)
+ goto nomem;
+ p->g->setbits = ptr;
+
+ for (i = 0; i < no; i++)
+ p->g->sets[i].ptr = p->g->setbits + css*(i/CHAR_BIT);
+
+ (void) memset((char *)p->g->setbits + (nbytes - css), 0, css);
+ }
+ /* XXX should not happen */
+ if (p->g->sets == NULL || p->g->setbits == NULL)
+ goto nomem;
+
+ cs = &p->g->sets[no];
+ cs->ptr = p->g->setbits + css*((no)/CHAR_BIT);
+ cs->mask = 1 << ((no) % CHAR_BIT);
+ cs->hash = 0;
+ cs->smultis = 0;
+ cs->multis = NULL;
+
+ return(cs);
+nomem:
+ free(p->g->sets);
+ p->g->sets = NULL;
+ free(p->g->setbits);
+ p->g->setbits = NULL;
+
+ SETERROR(REG_ESPACE);
+ /* caller's responsibility not to do set ops */
+ return(NULL);
+}
+
+/*
+ - freeset - free a now-unused set
+ */
+static void
+freeset(struct parse *p, cset *cs)
+{
+ size_t i;
+ cset *top = &p->g->sets[p->g->ncsets];
+ size_t css = (size_t)p->g->csetsize;
+
+ for (i = 0; i < css; i++)
+ CHsub(cs, i);
+ if (cs == top-1) /* recover only the easy case */
+ p->g->ncsets--;
+}
+
+/*
+ - freezeset - final processing on a set of characters
+ *
+ * The main task here is merging identical sets. This is usually a waste
+ * of time (although the hash code minimizes the overhead), but can win
+ * big if REG_ICASE is being used. REG_ICASE, by the way, is why the hash
+ * is done using addition rather than xor -- all ASCII [aA] sets xor to
+ * the same value!
+ */
+static int /* set number */
+freezeset(struct parse *p, cset *cs)
+{
+ uch h = cs->hash;
+ size_t i;
+ cset *top = &p->g->sets[p->g->ncsets];
+ cset *cs2;
+ size_t css = (size_t)p->g->csetsize;
+
+ /* look for an earlier one which is the same */
+ for (cs2 = &p->g->sets[0]; cs2 < top; cs2++)
+ if (cs2->hash == h && cs2 != cs) {
+ /* maybe */
+ for (i = 0; i < css; i++)
+ if (!!CHIN(cs2, i) != !!CHIN(cs, i))
+ break; /* no */
+ if (i == css)
+ break; /* yes */
+ }
+
+ if (cs2 < top) { /* found one */
+ freeset(p, cs);
+ cs = cs2;
+ }
+
+ return((int)(cs - p->g->sets));
+}
+
+/*
+ - firstch - return first character in a set (which must have at least one)
+ */
+static int /* character; there is no "none" value */
+firstch(struct parse *p, cset *cs)
+{
+ size_t i;
+ size_t css = (size_t)p->g->csetsize;
+
+ for (i = 0; i < css; i++)
+ if (CHIN(cs, i))
+ return((char)i);
+ assert(never);
+ return(0); /* arbitrary */
+}
+
+/*
+ - nch - number of characters in a set
+ */
+static int
+nch(struct parse *p, cset *cs)
+{
+ size_t i;
+ size_t css = (size_t)p->g->csetsize;
+ int n = 0;
+
+ for (i = 0; i < css; i++)
+ if (CHIN(cs, i))
+ n++;
+ return(n);
+}
+
+/*
+ - mcadd - add a collating element to a cset
+ */
+static void
+mcadd( struct parse *p, cset *cs, const char *cp)
+{
+ size_t oldend = cs->smultis;
+ void *np;
+
+ cs->smultis += strlen(cp) + 1;
+ np = realloc(cs->multis, cs->smultis);
+ if (np == NULL) {
+ if (cs->multis)
+ free(cs->multis);
+ cs->multis = NULL;
+ SETERROR(REG_ESPACE);
+ return;
+ }
+ cs->multis = np;
+
+ llvm_strlcpy(cs->multis + oldend - 1, cp, cs->smultis - oldend + 1);
+}
+
+/*
+ - mcinvert - invert the list of collating elements in a cset
+ *
+ * This would have to know the set of possibilities. Implementation
+ * is deferred.
+ */
+/* ARGSUSED */
+static void
+mcinvert(struct parse *p, cset *cs)
+{
+ assert(cs->multis == NULL); /* xxx */
+}
+
+/*
+ - mccase - add case counterparts of the list of collating elements in a cset
+ *
+ * This would have to know the set of possibilities. Implementation
+ * is deferred.
+ */
+/* ARGSUSED */
+static void
+mccase(struct parse *p, cset *cs)
+{
+ assert(cs->multis == NULL); /* xxx */
+}
+
+/*
+ - isinsets - is this character in any sets?
+ */
+static int /* predicate */
+isinsets(struct re_guts *g, int c)
+{
+ uch *col;
+ int i;
+ int ncols = (g->ncsets+(CHAR_BIT-1)) / CHAR_BIT;
+ unsigned uc = (uch)c;
+
+ for (i = 0, col = g->setbits; i < ncols; i++, col += g->csetsize)
+ if (col[uc] != 0)
+ return(1);
+ return(0);
+}
+
+/*
+ - samesets - are these two characters in exactly the same sets?
+ */
+static int /* predicate */
+samesets(struct re_guts *g, int c1, int c2)
+{
+ uch *col;
+ int i;
+ int ncols = (g->ncsets+(CHAR_BIT-1)) / CHAR_BIT;
+ unsigned uc1 = (uch)c1;
+ unsigned uc2 = (uch)c2;
+
+ for (i = 0, col = g->setbits; i < ncols; i++, col += g->csetsize)
+ if (col[uc1] != col[uc2])
+ return(0);
+ return(1);
+}
+
+/*
+ - categorize - sort out character categories
+ */
+static void
+categorize(struct parse *p, struct re_guts *g)
+{
+ cat_t *cats = g->categories;
+ int c;
+ int c2;
+ cat_t cat;
+
+ /* avoid making error situations worse */
+ if (p->error != 0)
+ return;
+
+ for (c = CHAR_MIN; c <= CHAR_MAX; c++)
+ if (cats[c] == 0 && isinsets(g, c)) {
+ cat = g->ncategories++;
+ cats[c] = cat;
+ for (c2 = c+1; c2 <= CHAR_MAX; c2++)
+ if (cats[c2] == 0 && samesets(g, c, c2))
+ cats[c2] = cat;
+ }
+}
+
+/*
+ - dupl - emit a duplicate of a bunch of sops
+ */
+static sopno /* start of duplicate */
+dupl(struct parse *p,
+ sopno start, /* from here */
+ sopno finish) /* to this less one */
+{
+ sopno ret = HERE();
+ sopno len = finish - start;
+
+ assert(finish >= start);
+ if (len == 0)
+ return(ret);
+ enlarge(p, p->ssize + len); /* this many unexpected additions */
+ assert(p->ssize >= p->slen + len);
+ (void) memmove((char *)(p->strip + p->slen),
+ (char *)(p->strip + start), (size_t)len*sizeof(sop));
+ p->slen += len;
+ return(ret);
+}
+
+/*
+ - doemit - emit a strip operator
+ *
+ * It might seem better to implement this as a macro with a function as
+ * hard-case backup, but it's just too big and messy unless there are
+ * some changes to the data structures. Maybe later.
+ */
+static void
+doemit(struct parse *p, sop op, size_t opnd)
+{
+ /* avoid making error situations worse */
+ if (p->error != 0)
+ return;
+
+ /* deal with oversize operands ("can't happen", more or less) */
+ assert(opnd < 1<<OPSHIFT);
+
+ /* deal with undersized strip */
+ if (p->slen >= p->ssize)
+ enlarge(p, (p->ssize+1) / 2 * 3); /* +50% */
+ assert(p->slen < p->ssize);
+
+ /* finally, it's all reduced to the easy case */
+ p->strip[p->slen++] = SOP(op, opnd);
+}
+
+/*
+ - doinsert - insert a sop into the strip
+ */
+static void
+doinsert(struct parse *p, sop op, size_t opnd, sopno pos)
+{
+ sopno sn;
+ sop s;
+ int i;
+
+ /* avoid making error situations worse */
+ if (p->error != 0)
+ return;
+
+ sn = HERE();
+ EMIT(op, opnd); /* do checks, ensure space */
+ assert(HERE() == sn+1);
+ s = p->strip[sn];
+
+ /* adjust paren pointers */
+ assert(pos > 0);
+ for (i = 1; i < NPAREN; i++) {
+ if (p->pbegin[i] >= pos) {
+ p->pbegin[i]++;
+ }
+ if (p->pend[i] >= pos) {
+ p->pend[i]++;
+ }
+ }
+
+ memmove((char *)&p->strip[pos+1], (char *)&p->strip[pos],
+ (HERE()-pos-1)*sizeof(sop));
+ p->strip[pos] = s;
+}
+
+/*
+ - dofwd - complete a forward reference
+ */
+static void
+dofwd(struct parse *p, sopno pos, sop value)
+{
+ /* avoid making error situations worse */
+ if (p->error != 0)
+ return;
+
+ assert(value < 1<<OPSHIFT);
+ p->strip[pos] = OP(p->strip[pos]) | value;
+}
+
+/*
+ - enlarge - enlarge the strip
+ */
+static void
+enlarge(struct parse *p, sopno size)
+{
+ sop *sp;
+
+ if (p->ssize >= size)
+ return;
+
+ if ((uintptr_t)size > SIZE_MAX / sizeof(sop)) {
+ SETERROR(REG_ESPACE);
+ return;
+ }
+
+ sp = (sop *)realloc(p->strip, size*sizeof(sop));
+ if (sp == NULL) {
+ SETERROR(REG_ESPACE);
+ return;
+ }
+ p->strip = sp;
+ p->ssize = size;
+}
+
+/*
+ - stripsnug - compact the strip
+ */
+static void
+stripsnug(struct parse *p, struct re_guts *g)
+{
+ g->nstates = p->slen;
+ if ((uintptr_t)p->slen > SIZE_MAX / sizeof(sop)) {
+ g->strip = p->strip;
+ SETERROR(REG_ESPACE);
+ return;
+ }
+
+ g->strip = (sop *)realloc((char *)p->strip, p->slen * sizeof(sop));
+ if (g->strip == NULL) {
+ SETERROR(REG_ESPACE);
+ g->strip = p->strip;
+ }
+}
+
+/*
+ - findmust - fill in must and mlen with longest mandatory literal string
+ *
+ * This algorithm could do fancy things like analyzing the operands of |
+ * for common subsequences. Someday. This code is simple and finds most
+ * of the interesting cases.
+ *
+ * Note that must and mlen got initialized during setup.
+ */
+static void
+findmust(struct parse *p, struct re_guts *g)
+{
+ sop *scan;
+ sop *start = 0; /* start initialized in the default case, after that */
+ sop *newstart = 0; /* newstart was initialized in the OCHAR case */
+ sopno newlen;
+ sop s;
+ char *cp;
+ sopno i;
+
+ /* avoid making error situations worse */
+ if (p->error != 0)
+ return;
+
+ /* find the longest OCHAR sequence in strip */
+ newlen = 0;
+ scan = g->strip + 1;
+ do {
+ s = *scan++;
+ switch (OP(s)) {
+ case OCHAR: /* sequence member */
+ if (newlen == 0) /* new sequence */
+ newstart = scan - 1;
+ newlen++;
+ break;
+ case OPLUS_: /* things that don't break one */
+ case OLPAREN:
+ case ORPAREN:
+ break;
+ case OQUEST_: /* things that must be skipped */
+ case OCH_:
+ scan--;
+ do {
+ scan += OPND(s);
+ s = *scan;
+ /* assert() interferes w debug printouts */
+ if (OP(s) != O_QUEST && OP(s) != O_CH &&
+ OP(s) != OOR2) {
+ g->iflags |= REGEX_BAD;
+ return;
+ }
+ } while (OP(s) != O_QUEST && OP(s) != O_CH);
+ /* fallthrough */
+ default: /* things that break a sequence */
+ if (newlen > g->mlen) { /* ends one */
+ start = newstart;
+ g->mlen = newlen;
+ }
+ newlen = 0;
+ break;
+ }
+ } while (OP(s) != OEND);
+
+ if (g->mlen == 0) /* there isn't one */
+ return;
+
+ /* turn it into a character string */
+ g->must = malloc((size_t)g->mlen + 1);
+ if (g->must == NULL) { /* argh; just forget it */
+ g->mlen = 0;
+ return;
+ }
+ cp = g->must;
+ scan = start;
+ for (i = g->mlen; i > 0; i--) {
+ while (OP(s = *scan++) != OCHAR)
+ continue;
+ assert(cp < g->must + g->mlen);
+ *cp++ = (char)OPND(s);
+ }
+ assert(cp == g->must + g->mlen);
+ *cp++ = '\0'; /* just on general principles */
+}
+
+/*
+ - pluscount - count + nesting
+ */
+static sopno /* nesting depth */
+pluscount(struct parse *p, struct re_guts *g)
+{
+ sop *scan;
+ sop s;
+ sopno plusnest = 0;
+ sopno maxnest = 0;
+
+ if (p->error != 0)
+ return(0); /* there may not be an OEND */
+
+ scan = g->strip + 1;
+ do {
+ s = *scan++;
+ switch (OP(s)) {
+ case OPLUS_:
+ plusnest++;
+ break;
+ case O_PLUS:
+ if (plusnest > maxnest)
+ maxnest = plusnest;
+ plusnest--;
+ break;
+ }
+ } while (OP(s) != OEND);
+ if (plusnest != 0)
+ g->iflags |= REGEX_BAD;
+ return(maxnest);
+}
diff --git a/contrib/llvm/lib/Support/regengine.inc b/contrib/llvm/lib/Support/regengine.inc
new file mode 100644
index 000000000000..62d8c267f22f
--- /dev/null
+++ b/contrib/llvm/lib/Support/regengine.inc
@@ -0,0 +1,1034 @@
+/*-
+ * This code is derived from OpenBSD's libc/regex, original license follows:
+ *
+ * Copyright (c) 1992, 1993, 1994 Henry Spencer.
+ * Copyright (c) 1992, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Henry Spencer.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)engine.c 8.5 (Berkeley) 3/20/94
+ */
+
+/*
+ * The matching engine and friends. This file is #included by regexec.c
+ * after suitable #defines of a variety of macros used herein, so that
+ * different state representations can be used without duplicating masses
+ * of code.
+ */
+
+#ifdef SNAMES
+#define matcher smatcher
+#define fast sfast
+#define slow sslow
+#define dissect sdissect
+#define backref sbackref
+#define step sstep
+#define print sprint
+#define at sat
+#define match smat
+#define nope snope
+#endif
+#ifdef LNAMES
+#define matcher lmatcher
+#define fast lfast
+#define slow lslow
+#define dissect ldissect
+#define backref lbackref
+#define step lstep
+#define print lprint
+#define at lat
+#define match lmat
+#define nope lnope
+#endif
+
+/* another structure passed up and down to avoid zillions of parameters */
+struct match {
+ struct re_guts *g;
+ int eflags;
+ llvm_regmatch_t *pmatch; /* [nsub+1] (0 element unused) */
+ const char *offp; /* offsets work from here */
+ const char *beginp; /* start of string -- virtual NUL precedes */
+ const char *endp; /* end of string -- virtual NUL here */
+ const char *coldp; /* can be no match starting before here */
+ const char **lastpos; /* [nplus+1] */
+ STATEVARS;
+ states st; /* current states */
+ states fresh; /* states for a fresh start */
+ states tmp; /* temporary */
+ states empty; /* empty set of states */
+};
+
+static int matcher(struct re_guts *, const char *, size_t,
+ llvm_regmatch_t[], int);
+static const char *dissect(struct match *, const char *, const char *, sopno,
+ sopno);
+static const char *backref(struct match *, const char *, const char *, sopno,
+ sopno, sopno, int);
+static const char *fast(struct match *, const char *, const char *, sopno, sopno);
+static const char *slow(struct match *, const char *, const char *, sopno, sopno);
+static states step(struct re_guts *, sopno, sopno, states, int, states);
+#define MAX_RECURSION 100
+#define BOL (OUT+1)
+#define EOL (BOL+1)
+#define BOLEOL (BOL+2)
+#define NOTHING (BOL+3)
+#define BOW (BOL+4)
+#define EOW (BOL+5)
+#define CODEMAX (BOL+5) /* highest code used */
+#define NONCHAR(c) ((c) > CHAR_MAX)
+#define NNONCHAR (CODEMAX-CHAR_MAX)
+#ifdef REDEBUG
+static void print(struct match *, char *, states, int, FILE *);
+#endif
+#ifdef REDEBUG
+static void at(struct match *, char *, char *, char *, sopno, sopno);
+#endif
+#ifdef REDEBUG
+static char *pchar(int);
+#endif
+
+#ifdef REDEBUG
+#define SP(t, s, c) print(m, t, s, c, stdout)
+#define AT(t, p1, p2, s1, s2) at(m, t, p1, p2, s1, s2)
+#define NOTE(str) { if (m->eflags&REG_TRACE) (void)printf("=%s\n", (str)); }
+static int nope = 0;
+#else
+#define SP(t, s, c) /* nothing */
+#define AT(t, p1, p2, s1, s2) /* nothing */
+#define NOTE(s) /* nothing */
+#endif
+
+/*
+ - matcher - the actual matching engine
+ */
+static int /* 0 success, REG_NOMATCH failure */
+matcher(struct re_guts *g, const char *string, size_t nmatch,
+ llvm_regmatch_t pmatch[],
+ int eflags)
+{
+ const char *endp;
+ size_t i;
+ struct match mv;
+ struct match *m = &mv;
+ const char *dp;
+ const sopno gf = g->firststate+1; /* +1 for OEND */
+ const sopno gl = g->laststate;
+ const char *start;
+ const char *stop;
+
+ /* simplify the situation where possible */
+ if (g->cflags&REG_NOSUB)
+ nmatch = 0;
+ if (eflags&REG_STARTEND) {
+ start = string + pmatch[0].rm_so;
+ stop = string + pmatch[0].rm_eo;
+ } else {
+ start = string;
+ stop = start + strlen(start);
+ }
+ if (stop < start)
+ return(REG_INVARG);
+
+ /* prescreening; this does wonders for this rather slow code */
+ if (g->must != NULL) {
+ for (dp = start; dp < stop; dp++)
+ if (*dp == g->must[0] && stop - dp >= g->mlen &&
+ memcmp(dp, g->must, (size_t)g->mlen) == 0)
+ break;
+ if (dp == stop) /* we didn't find g->must */
+ return(REG_NOMATCH);
+ }
+
+ /* match struct setup */
+ m->g = g;
+ m->eflags = eflags;
+ m->pmatch = NULL;
+ m->lastpos = NULL;
+ m->offp = string;
+ m->beginp = start;
+ m->endp = stop;
+ STATESETUP(m, 4);
+ SETUP(m->st);
+ SETUP(m->fresh);
+ SETUP(m->tmp);
+ SETUP(m->empty);
+ CLEAR(m->empty);
+
+ /* this loop does only one repetition except for backrefs */
+ for (;;) {
+ endp = fast(m, start, stop, gf, gl);
+ if (endp == NULL) { /* a miss */
+ free(m->pmatch);
+ free((void*)m->lastpos);
+ STATETEARDOWN(m);
+ return(REG_NOMATCH);
+ }
+ if (nmatch == 0 && !g->backrefs)
+ break; /* no further info needed */
+
+ /* where? */
+ assert(m->coldp != NULL);
+ for (;;) {
+ NOTE("finding start");
+ endp = slow(m, m->coldp, stop, gf, gl);
+ if (endp != NULL)
+ break;
+ assert(m->coldp < m->endp);
+ m->coldp++;
+ }
+ if (nmatch == 1 && !g->backrefs)
+ break; /* no further info needed */
+
+ /* oh my, they want the subexpressions... */
+ if (m->pmatch == NULL)
+ m->pmatch = (llvm_regmatch_t *)malloc((m->g->nsub + 1) *
+ sizeof(llvm_regmatch_t));
+ if (m->pmatch == NULL) {
+ STATETEARDOWN(m);
+ return(REG_ESPACE);
+ }
+ for (i = 1; i <= m->g->nsub; i++)
+ m->pmatch[i].rm_so = m->pmatch[i].rm_eo = -1;
+ if (!g->backrefs && !(m->eflags&REG_BACKR)) {
+ NOTE("dissecting");
+ dp = dissect(m, m->coldp, endp, gf, gl);
+ } else {
+ if (g->nplus > 0 && m->lastpos == NULL)
+ m->lastpos = (const char **)malloc((g->nplus+1) *
+ sizeof(char *));
+ if (g->nplus > 0 && m->lastpos == NULL) {
+ free(m->pmatch);
+ STATETEARDOWN(m);
+ return(REG_ESPACE);
+ }
+ NOTE("backref dissect");
+ dp = backref(m, m->coldp, endp, gf, gl, (sopno)0, 0);
+ }
+ if (dp != NULL)
+ break;
+
+ /* uh-oh... we couldn't find a subexpression-level match */
+ assert(g->backrefs); /* must be back references doing it */
+ assert(g->nplus == 0 || m->lastpos != NULL);
+ for (;;) {
+ if (dp != NULL || endp <= m->coldp)
+ break; /* defeat */
+ NOTE("backoff");
+ endp = slow(m, m->coldp, endp-1, gf, gl);
+ if (endp == NULL)
+ break; /* defeat */
+ /* try it on a shorter possibility */
+#ifndef NDEBUG
+ for (i = 1; i <= m->g->nsub; i++) {
+ assert(m->pmatch[i].rm_so == -1);
+ assert(m->pmatch[i].rm_eo == -1);
+ }
+#endif
+ NOTE("backoff dissect");
+ dp = backref(m, m->coldp, endp, gf, gl, (sopno)0, 0);
+ }
+ assert(dp == NULL || dp == endp);
+ if (dp != NULL) /* found a shorter one */
+ break;
+
+ /* despite initial appearances, there is no match here */
+ NOTE("false alarm");
+ if (m->coldp == stop)
+ break;
+ start = m->coldp + 1; /* recycle starting later */
+ }
+
+ /* fill in the details if requested */
+ if (nmatch > 0) {
+ pmatch[0].rm_so = m->coldp - m->offp;
+ pmatch[0].rm_eo = endp - m->offp;
+ }
+ if (nmatch > 1) {
+ assert(m->pmatch != NULL);
+ for (i = 1; i < nmatch; i++)
+ if (i <= m->g->nsub)
+ pmatch[i] = m->pmatch[i];
+ else {
+ pmatch[i].rm_so = -1;
+ pmatch[i].rm_eo = -1;
+ }
+ }
+
+ if (m->pmatch != NULL)
+ free((char *)m->pmatch);
+ if (m->lastpos != NULL)
+ free((char *)m->lastpos);
+ STATETEARDOWN(m);
+ return(0);
+}
+
+/*
+ - dissect - figure out what matched what, no back references
+ */
+static const char * /* == stop (success) always */
+dissect(struct match *m, const char *start, const char *stop, sopno startst,
+ sopno stopst)
+{
+ int i;
+ sopno ss; /* start sop of current subRE */
+ sopno es; /* end sop of current subRE */
+ const char *sp; /* start of string matched by it */
+ const char *stp; /* string matched by it cannot pass here */
+ const char *rest; /* start of rest of string */
+ const char *tail; /* string unmatched by rest of RE */
+ sopno ssub; /* start sop of subsubRE */
+ sopno esub; /* end sop of subsubRE */
+ const char *ssp; /* start of string matched by subsubRE */
+ const char *sep; /* end of string matched by subsubRE */
+ const char *oldssp; /* previous ssp */
+
+ AT("diss", start, stop, startst, stopst);
+ sp = start;
+ for (ss = startst; ss < stopst; ss = es) {
+ /* identify end of subRE */
+ es = ss;
+ switch (OP(m->g->strip[es])) {
+ case OPLUS_:
+ case OQUEST_:
+ es += OPND(m->g->strip[es]);
+ break;
+ case OCH_:
+ while (OP(m->g->strip[es]) != O_CH)
+ es += OPND(m->g->strip[es]);
+ break;
+ }
+ es++;
+
+ /* figure out what it matched */
+ switch (OP(m->g->strip[ss])) {
+ case OEND:
+ assert(nope);
+ break;
+ case OCHAR:
+ sp++;
+ break;
+ case OBOL:
+ case OEOL:
+ case OBOW:
+ case OEOW:
+ break;
+ case OANY:
+ case OANYOF:
+ sp++;
+ break;
+ case OBACK_:
+ case O_BACK:
+ assert(nope);
+ break;
+ /* cases where length of match is hard to find */
+ case OQUEST_:
+ stp = stop;
+ for (;;) {
+ /* how long could this one be? */
+ rest = slow(m, sp, stp, ss, es);
+ assert(rest != NULL); /* it did match */
+ /* could the rest match the rest? */
+ tail = slow(m, rest, stop, es, stopst);
+ if (tail == stop)
+ break; /* yes! */
+ /* no -- try a shorter match for this one */
+ stp = rest - 1;
+ assert(stp >= sp); /* it did work */
+ }
+ ssub = ss + 1;
+ esub = es - 1;
+ /* did innards match? */
+ if (slow(m, sp, rest, ssub, esub) != NULL) {
+ const char *dp = dissect(m, sp, rest, ssub, esub);
+ (void)dp; /* avoid warning if assertions off */
+ assert(dp == rest);
+ } else /* no */
+ assert(sp == rest);
+ sp = rest;
+ break;
+ case OPLUS_:
+ stp = stop;
+ for (;;) {
+ /* how long could this one be? */
+ rest = slow(m, sp, stp, ss, es);
+ assert(rest != NULL); /* it did match */
+ /* could the rest match the rest? */
+ tail = slow(m, rest, stop, es, stopst);
+ if (tail == stop)
+ break; /* yes! */
+ /* no -- try a shorter match for this one */
+ stp = rest - 1;
+ assert(stp >= sp); /* it did work */
+ }
+ ssub = ss + 1;
+ esub = es - 1;
+ ssp = sp;
+ oldssp = ssp;
+ for (;;) { /* find last match of innards */
+ sep = slow(m, ssp, rest, ssub, esub);
+ if (sep == NULL || sep == ssp)
+ break; /* failed or matched null */
+ oldssp = ssp; /* on to next try */
+ ssp = sep;
+ }
+ if (sep == NULL) {
+ /* last successful match */
+ sep = ssp;
+ ssp = oldssp;
+ }
+ assert(sep == rest); /* must exhaust substring */
+ assert(slow(m, ssp, sep, ssub, esub) == rest);
+ {
+ const char *dp = dissect(m, ssp, sep, ssub, esub);
+ (void)dp; /* avoid warning if assertions off */
+ assert(dp == sep);
+ }
+ sp = rest;
+ break;
+ case OCH_:
+ stp = stop;
+ for (;;) {
+ /* how long could this one be? */
+ rest = slow(m, sp, stp, ss, es);
+ assert(rest != NULL); /* it did match */
+ /* could the rest match the rest? */
+ tail = slow(m, rest, stop, es, stopst);
+ if (tail == stop)
+ break; /* yes! */
+ /* no -- try a shorter match for this one */
+ stp = rest - 1;
+ assert(stp >= sp); /* it did work */
+ }
+ ssub = ss + 1;
+ esub = ss + OPND(m->g->strip[ss]) - 1;
+ assert(OP(m->g->strip[esub]) == OOR1);
+ for (;;) { /* find first matching branch */
+ if (slow(m, sp, rest, ssub, esub) == rest)
+ break; /* it matched all of it */
+ /* that one missed, try next one */
+ assert(OP(m->g->strip[esub]) == OOR1);
+ esub++;
+ assert(OP(m->g->strip[esub]) == OOR2);
+ ssub = esub + 1;
+ esub += OPND(m->g->strip[esub]);
+ if (OP(m->g->strip[esub]) == OOR2)
+ esub--;
+ else
+ assert(OP(m->g->strip[esub]) == O_CH);
+ }
+ {
+ const char *dp = dissect(m, sp, rest, ssub, esub);
+ (void)dp; /* avoid warning if assertions off */
+ assert(dp == rest);
+ }
+ sp = rest;
+ break;
+ case O_PLUS:
+ case O_QUEST:
+ case OOR1:
+ case OOR2:
+ case O_CH:
+ assert(nope);
+ break;
+ case OLPAREN:
+ i = OPND(m->g->strip[ss]);
+ assert(0 < i && i <= m->g->nsub);
+ m->pmatch[i].rm_so = sp - m->offp;
+ break;
+ case ORPAREN:
+ i = OPND(m->g->strip[ss]);
+ assert(0 < i && i <= m->g->nsub);
+ m->pmatch[i].rm_eo = sp - m->offp;
+ break;
+ default: /* uh oh */
+ assert(nope);
+ break;
+ }
+ }
+
+ assert(sp == stop);
+ return(sp);
+}
+
+/*
+ - backref - figure out what matched what, figuring in back references
+ */
+static const char * /* == stop (success) or NULL (failure) */
+backref(struct match *m, const char *start, const char *stop, sopno startst,
+ sopno stopst, sopno lev, int rec) /* PLUS nesting level */
+{
+ int i;
+ sopno ss; /* start sop of current subRE */
+ const char *sp; /* start of string matched by it */
+ sopno ssub; /* start sop of subsubRE */
+ sopno esub; /* end sop of subsubRE */
+ const char *ssp; /* start of string matched by subsubRE */
+ const char *dp;
+ size_t len;
+ int hard;
+ sop s;
+ llvm_regoff_t offsave;
+ cset *cs;
+
+ AT("back", start, stop, startst, stopst);
+ sp = start;
+
+ /* get as far as we can with easy stuff */
+ hard = 0;
+ for (ss = startst; !hard && ss < stopst; ss++)
+ switch (OP(s = m->g->strip[ss])) {
+ case OCHAR:
+ if (sp == stop || *sp++ != (char)OPND(s))
+ return(NULL);
+ break;
+ case OANY:
+ if (sp == stop)
+ return(NULL);
+ sp++;
+ break;
+ case OANYOF:
+ cs = &m->g->sets[OPND(s)];
+ if (sp == stop || !CHIN(cs, *sp++))
+ return(NULL);
+ break;
+ case OBOL:
+ if ( (sp == m->beginp && !(m->eflags&REG_NOTBOL)) ||
+ (sp < m->endp && *(sp-1) == '\n' &&
+ (m->g->cflags&REG_NEWLINE)) )
+ { /* yes */ }
+ else
+ return(NULL);
+ break;
+ case OEOL:
+ if ( (sp == m->endp && !(m->eflags&REG_NOTEOL)) ||
+ (sp < m->endp && *sp == '\n' &&
+ (m->g->cflags&REG_NEWLINE)) )
+ { /* yes */ }
+ else
+ return(NULL);
+ break;
+ case OBOW:
+ if (( (sp == m->beginp && !(m->eflags&REG_NOTBOL)) ||
+ (sp < m->endp && *(sp-1) == '\n' &&
+ (m->g->cflags&REG_NEWLINE)) ||
+ (sp > m->beginp &&
+ !ISWORD(*(sp-1))) ) &&
+ (sp < m->endp && ISWORD(*sp)) )
+ { /* yes */ }
+ else
+ return(NULL);
+ break;
+ case OEOW:
+ if (( (sp == m->endp && !(m->eflags&REG_NOTEOL)) ||
+ (sp < m->endp && *sp == '\n' &&
+ (m->g->cflags&REG_NEWLINE)) ||
+ (sp < m->endp && !ISWORD(*sp)) ) &&
+ (sp > m->beginp && ISWORD(*(sp-1))) )
+ { /* yes */ }
+ else
+ return(NULL);
+ break;
+ case O_QUEST:
+ break;
+ case OOR1: /* matches null but needs to skip */
+ ss++;
+ s = m->g->strip[ss];
+ do {
+ assert(OP(s) == OOR2);
+ ss += OPND(s);
+ } while (OP(s = m->g->strip[ss]) != O_CH);
+ /* note that the ss++ gets us past the O_CH */
+ break;
+ default: /* have to make a choice */
+ hard = 1;
+ break;
+ }
+ if (!hard) { /* that was it! */
+ if (sp != stop)
+ return(NULL);
+ return(sp);
+ }
+ ss--; /* adjust for the for's final increment */
+
+ /* the hard stuff */
+ AT("hard", sp, stop, ss, stopst);
+ s = m->g->strip[ss];
+ switch (OP(s)) {
+ case OBACK_: /* the vilest depths */
+ i = OPND(s);
+ assert(0 < i && i <= m->g->nsub);
+ if (m->pmatch[i].rm_eo == -1)
+ return(NULL);
+ assert(m->pmatch[i].rm_so != -1);
+ len = m->pmatch[i].rm_eo - m->pmatch[i].rm_so;
+ if (len == 0 && rec++ > MAX_RECURSION)
+ return(NULL);
+ assert(stop - m->beginp >= len);
+ if (sp > stop - len)
+ return(NULL); /* not enough left to match */
+ ssp = m->offp + m->pmatch[i].rm_so;
+ if (memcmp(sp, ssp, len) != 0)
+ return(NULL);
+ while (m->g->strip[ss] != SOP(O_BACK, i))
+ ss++;
+ return(backref(m, sp+len, stop, ss+1, stopst, lev, rec));
+ break;
+ case OQUEST_: /* to null or not */
+ dp = backref(m, sp, stop, ss+1, stopst, lev, rec);
+ if (dp != NULL)
+ return(dp); /* not */
+ return(backref(m, sp, stop, ss+OPND(s)+1, stopst, lev, rec));
+ break;
+ case OPLUS_:
+ assert(m->lastpos != NULL);
+ assert(lev+1 <= m->g->nplus);
+ m->lastpos[lev+1] = sp;
+ return(backref(m, sp, stop, ss+1, stopst, lev+1, rec));
+ break;
+ case O_PLUS:
+ if (sp == m->lastpos[lev]) /* last pass matched null */
+ return(backref(m, sp, stop, ss+1, stopst, lev-1, rec));
+ /* try another pass */
+ m->lastpos[lev] = sp;
+ dp = backref(m, sp, stop, ss-OPND(s)+1, stopst, lev, rec);
+ if (dp == NULL)
+ return(backref(m, sp, stop, ss+1, stopst, lev-1, rec));
+ else
+ return(dp);
+ break;
+ case OCH_: /* find the right one, if any */
+ ssub = ss + 1;
+ esub = ss + OPND(s) - 1;
+ assert(OP(m->g->strip[esub]) == OOR1);
+ for (;;) { /* find first matching branch */
+ dp = backref(m, sp, stop, ssub, esub, lev, rec);
+ if (dp != NULL)
+ return(dp);
+ /* that one missed, try next one */
+ if (OP(m->g->strip[esub]) == O_CH)
+ return(NULL); /* there is none */
+ esub++;
+ assert(OP(m->g->strip[esub]) == OOR2);
+ ssub = esub + 1;
+ esub += OPND(m->g->strip[esub]);
+ if (OP(m->g->strip[esub]) == OOR2)
+ esub--;
+ else
+ assert(OP(m->g->strip[esub]) == O_CH);
+ }
+ break;
+ case OLPAREN: /* must undo assignment if rest fails */
+ i = OPND(s);
+ assert(0 < i && i <= m->g->nsub);
+ offsave = m->pmatch[i].rm_so;
+ m->pmatch[i].rm_so = sp - m->offp;
+ dp = backref(m, sp, stop, ss+1, stopst, lev, rec);
+ if (dp != NULL)
+ return(dp);
+ m->pmatch[i].rm_so = offsave;
+ return(NULL);
+ break;
+ case ORPAREN: /* must undo assignment if rest fails */
+ i = OPND(s);
+ assert(0 < i && i <= m->g->nsub);
+ offsave = m->pmatch[i].rm_eo;
+ m->pmatch[i].rm_eo = sp - m->offp;
+ dp = backref(m, sp, stop, ss+1, stopst, lev, rec);
+ if (dp != NULL)
+ return(dp);
+ m->pmatch[i].rm_eo = offsave;
+ return(NULL);
+ break;
+ default: /* uh oh */
+ assert(nope);
+ break;
+ }
+
+ /* "can't happen" */
+ assert(nope);
+ /* NOTREACHED */
+ return NULL;
+}
+
+/*
+ - fast - step through the string at top speed
+ */
+static const char * /* where tentative match ended, or NULL */
+fast(struct match *m, const char *start, const char *stop, sopno startst,
+ sopno stopst)
+{
+ states st = m->st;
+ states fresh = m->fresh;
+ states tmp = m->tmp;
+ const char *p = start;
+ int c = (start == m->beginp) ? OUT : *(start-1);
+ int lastc; /* previous c */
+ int flagch;
+ int i;
+ const char *coldp; /* last p after which no match was underway */
+
+ CLEAR(st);
+ SET1(st, startst);
+ st = step(m->g, startst, stopst, st, NOTHING, st);
+ ASSIGN(fresh, st);
+ SP("start", st, *p);
+ coldp = NULL;
+ for (;;) {
+ /* next character */
+ lastc = c;
+ c = (p == m->endp) ? OUT : *p;
+ if (EQ(st, fresh))
+ coldp = p;
+
+ /* is there an EOL and/or BOL between lastc and c? */
+ flagch = '\0';
+ i = 0;
+ if ( (lastc == '\n' && m->g->cflags&REG_NEWLINE) ||
+ (lastc == OUT && !(m->eflags&REG_NOTBOL)) ) {
+ flagch = BOL;
+ i = m->g->nbol;
+ }
+ if ( (c == '\n' && m->g->cflags&REG_NEWLINE) ||
+ (c == OUT && !(m->eflags&REG_NOTEOL)) ) {
+ flagch = (flagch == BOL) ? BOLEOL : EOL;
+ i += m->g->neol;
+ }
+ if (i != 0) {
+ for (; i > 0; i--)
+ st = step(m->g, startst, stopst, st, flagch, st);
+ SP("boleol", st, c);
+ }
+
+ /* how about a word boundary? */
+ if ( (flagch == BOL || (lastc != OUT && !ISWORD(lastc))) &&
+ (c != OUT && ISWORD(c)) ) {
+ flagch = BOW;
+ }
+ if ( (lastc != OUT && ISWORD(lastc)) &&
+ (flagch == EOL || (c != OUT && !ISWORD(c))) ) {
+ flagch = EOW;
+ }
+ if (flagch == BOW || flagch == EOW) {
+ st = step(m->g, startst, stopst, st, flagch, st);
+ SP("boweow", st, c);
+ }
+
+ /* are we done? */
+ if (ISSET(st, stopst) || p == stop)
+ break; /* NOTE BREAK OUT */
+
+ /* no, we must deal with this character */
+ ASSIGN(tmp, st);
+ ASSIGN(st, fresh);
+ assert(c != OUT);
+ st = step(m->g, startst, stopst, tmp, c, st);
+ SP("aft", st, c);
+ assert(EQ(step(m->g, startst, stopst, st, NOTHING, st), st));
+ p++;
+ }
+
+ assert(coldp != NULL);
+ m->coldp = coldp;
+ if (ISSET(st, stopst))
+ return(p+1);
+ else
+ return(NULL);
+}
+
+/*
+ - slow - step through the string more deliberately
+ */
+static const char * /* where it ended */
+slow(struct match *m, const char *start, const char *stop, sopno startst,
+ sopno stopst)
+{
+ states st = m->st;
+ states empty = m->empty;
+ states tmp = m->tmp;
+ const char *p = start;
+ int c = (start == m->beginp) ? OUT : *(start-1);
+ int lastc; /* previous c */
+ int flagch;
+ int i;
+ const char *matchp; /* last p at which a match ended */
+
+ AT("slow", start, stop, startst, stopst);
+ CLEAR(st);
+ SET1(st, startst);
+ SP("sstart", st, *p);
+ st = step(m->g, startst, stopst, st, NOTHING, st);
+ matchp = NULL;
+ for (;;) {
+ /* next character */
+ lastc = c;
+ c = (p == m->endp) ? OUT : *p;
+
+ /* is there an EOL and/or BOL between lastc and c? */
+ flagch = '\0';
+ i = 0;
+ if ( (lastc == '\n' && m->g->cflags&REG_NEWLINE) ||
+ (lastc == OUT && !(m->eflags&REG_NOTBOL)) ) {
+ flagch = BOL;
+ i = m->g->nbol;
+ }
+ if ( (c == '\n' && m->g->cflags&REG_NEWLINE) ||
+ (c == OUT && !(m->eflags&REG_NOTEOL)) ) {
+ flagch = (flagch == BOL) ? BOLEOL : EOL;
+ i += m->g->neol;
+ }
+ if (i != 0) {
+ for (; i > 0; i--)
+ st = step(m->g, startst, stopst, st, flagch, st);
+ SP("sboleol", st, c);
+ }
+
+ /* how about a word boundary? */
+ if ( (flagch == BOL || (lastc != OUT && !ISWORD(lastc))) &&
+ (c != OUT && ISWORD(c)) ) {
+ flagch = BOW;
+ }
+ if ( (lastc != OUT && ISWORD(lastc)) &&
+ (flagch == EOL || (c != OUT && !ISWORD(c))) ) {
+ flagch = EOW;
+ }
+ if (flagch == BOW || flagch == EOW) {
+ st = step(m->g, startst, stopst, st, flagch, st);
+ SP("sboweow", st, c);
+ }
+
+ /* are we done? */
+ if (ISSET(st, stopst))
+ matchp = p;
+ if (EQ(st, empty) || p == stop)
+ break; /* NOTE BREAK OUT */
+
+ /* no, we must deal with this character */
+ ASSIGN(tmp, st);
+ ASSIGN(st, empty);
+ assert(c != OUT);
+ st = step(m->g, startst, stopst, tmp, c, st);
+ SP("saft", st, c);
+ assert(EQ(step(m->g, startst, stopst, st, NOTHING, st), st));
+ p++;
+ }
+
+ return(matchp);
+}
+
+
+/*
+ - step - map set of states reachable before char to set reachable after
+ */
+static states
+step(struct re_guts *g,
+ sopno start, /* start state within strip */
+ sopno stop, /* state after stop state within strip */
+ states bef, /* states reachable before */
+ int ch, /* character or NONCHAR code */
+ states aft) /* states already known reachable after */
+{
+ cset *cs;
+ sop s;
+ sopno pc;
+ onestate here; /* note, macros know this name */
+ sopno look;
+ int i;
+
+ for (pc = start, INIT(here, pc); pc != stop; pc++, INC(here)) {
+ s = g->strip[pc];
+ switch (OP(s)) {
+ case OEND:
+ assert(pc == stop-1);
+ break;
+ case OCHAR:
+ /* only characters can match */
+ assert(!NONCHAR(ch) || ch != (char)OPND(s));
+ if (ch == (char)OPND(s))
+ FWD(aft, bef, 1);
+ break;
+ case OBOL:
+ if (ch == BOL || ch == BOLEOL)
+ FWD(aft, bef, 1);
+ break;
+ case OEOL:
+ if (ch == EOL || ch == BOLEOL)
+ FWD(aft, bef, 1);
+ break;
+ case OBOW:
+ if (ch == BOW)
+ FWD(aft, bef, 1);
+ break;
+ case OEOW:
+ if (ch == EOW)
+ FWD(aft, bef, 1);
+ break;
+ case OANY:
+ if (!NONCHAR(ch))
+ FWD(aft, bef, 1);
+ break;
+ case OANYOF:
+ cs = &g->sets[OPND(s)];
+ if (!NONCHAR(ch) && CHIN(cs, ch))
+ FWD(aft, bef, 1);
+ break;
+ case OBACK_: /* ignored here */
+ case O_BACK:
+ FWD(aft, aft, 1);
+ break;
+ case OPLUS_: /* forward, this is just an empty */
+ FWD(aft, aft, 1);
+ break;
+ case O_PLUS: /* both forward and back */
+ FWD(aft, aft, 1);
+ i = ISSETBACK(aft, OPND(s));
+ BACK(aft, aft, OPND(s));
+ if (!i && ISSETBACK(aft, OPND(s))) {
+ /* oho, must reconsider loop body */
+ pc -= OPND(s) + 1;
+ INIT(here, pc);
+ }
+ break;
+ case OQUEST_: /* two branches, both forward */
+ FWD(aft, aft, 1);
+ FWD(aft, aft, OPND(s));
+ break;
+ case O_QUEST: /* just an empty */
+ FWD(aft, aft, 1);
+ break;
+ case OLPAREN: /* not significant here */
+ case ORPAREN:
+ FWD(aft, aft, 1);
+ break;
+ case OCH_: /* mark the first two branches */
+ FWD(aft, aft, 1);
+ assert(OP(g->strip[pc+OPND(s)]) == OOR2);
+ FWD(aft, aft, OPND(s));
+ break;
+ case OOR1: /* done a branch, find the O_CH */
+ if (ISSTATEIN(aft, here)) {
+ for (look = 1;
+ OP(s = g->strip[pc+look]) != O_CH;
+ look += OPND(s))
+ assert(OP(s) == OOR2);
+ FWD(aft, aft, look);
+ }
+ break;
+ case OOR2: /* propagate OCH_'s marking */
+ FWD(aft, aft, 1);
+ if (OP(g->strip[pc+OPND(s)]) != O_CH) {
+ assert(OP(g->strip[pc+OPND(s)]) == OOR2);
+ FWD(aft, aft, OPND(s));
+ }
+ break;
+ case O_CH: /* just empty */
+ FWD(aft, aft, 1);
+ break;
+ default: /* ooooops... */
+ assert(nope);
+ break;
+ }
+ }
+
+ return(aft);
+}
+
+#ifdef REDEBUG
+/*
+ - print - print a set of states
+ */
+static void
+print(struct match *m, char *caption, states st, int ch, FILE *d)
+{
+ struct re_guts *g = m->g;
+ int i;
+ int first = 1;
+
+ if (!(m->eflags&REG_TRACE))
+ return;
+
+ (void)fprintf(d, "%s", caption);
+ if (ch != '\0')
+ (void)fprintf(d, " %s", pchar(ch));
+ for (i = 0; i < g->nstates; i++)
+ if (ISSET(st, i)) {
+ (void)fprintf(d, "%s%d", (first) ? "\t" : ", ", i);
+ first = 0;
+ }
+ (void)fprintf(d, "\n");
+}
+
+/*
+ - at - print current situation
+ */
+static void
+at(struct match *m, char *title, char *start, char *stop, sopno startst,
+ sopno stopst)
+{
+ if (!(m->eflags&REG_TRACE))
+ return;
+
+ (void)printf("%s %s-", title, pchar(*start));
+ (void)printf("%s ", pchar(*stop));
+ (void)printf("%ld-%ld\n", (long)startst, (long)stopst);
+}
+
+#ifndef PCHARDONE
+#define PCHARDONE /* never again */
+/*
+ - pchar - make a character printable
+ *
+ * Is this identical to regchar() over in debug.c? Well, yes. But a
+ * duplicate here avoids having a debugging-capable regexec.o tied to
+ * a matching debug.o, and this is convenient. It all disappears in
+ * the non-debug compilation anyway, so it doesn't matter much.
+ */
+static char * /* -> representation */
+pchar(int ch)
+{
+ static char pbuf[10];
+
+ if (isprint(ch) || ch == ' ')
+ (void)snprintf(pbuf, sizeof pbuf, "%c", ch);
+ else
+ (void)snprintf(pbuf, sizeof pbuf, "\\%o", ch);
+ return(pbuf);
+}
+#endif
+#endif
+
+#undef matcher
+#undef fast
+#undef slow
+#undef dissect
+#undef backref
+#undef step
+#undef print
+#undef at
+#undef match
+#undef nope
diff --git a/contrib/llvm/lib/Support/regerror.c b/contrib/llvm/lib/Support/regerror.c
new file mode 100644
index 000000000000..1d67c9a2b03b
--- /dev/null
+++ b/contrib/llvm/lib/Support/regerror.c
@@ -0,0 +1,135 @@
+/*-
+ * This code is derived from OpenBSD's libc/regex, original license follows:
+ *
+ * Copyright (c) 1992, 1993, 1994 Henry Spencer.
+ * Copyright (c) 1992, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Henry Spencer.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)regerror.c 8.4 (Berkeley) 3/20/94
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <limits.h>
+#include <stdlib.h>
+#include "regex_impl.h"
+
+#include "regutils.h"
+
+#ifdef _MSC_VER
+#define snprintf _snprintf
+#endif
+
+static const char *regatoi(const llvm_regex_t *, char *, int);
+
+static struct rerr {
+ int code;
+ const char *name;
+ const char *explain;
+} rerrs[] = {
+ { REG_NOMATCH, "REG_NOMATCH", "llvm_regexec() failed to match" },
+ { REG_BADPAT, "REG_BADPAT", "invalid regular expression" },
+ { REG_ECOLLATE, "REG_ECOLLATE", "invalid collating element" },
+ { REG_ECTYPE, "REG_ECTYPE", "invalid character class" },
+ { REG_EESCAPE, "REG_EESCAPE", "trailing backslash (\\)" },
+ { REG_ESUBREG, "REG_ESUBREG", "invalid backreference number" },
+ { REG_EBRACK, "REG_EBRACK", "brackets ([ ]) not balanced" },
+ { REG_EPAREN, "REG_EPAREN", "parentheses not balanced" },
+ { REG_EBRACE, "REG_EBRACE", "braces not balanced" },
+ { REG_BADBR, "REG_BADBR", "invalid repetition count(s)" },
+ { REG_ERANGE, "REG_ERANGE", "invalid character range" },
+ { REG_ESPACE, "REG_ESPACE", "out of memory" },
+ { REG_BADRPT, "REG_BADRPT", "repetition-operator operand invalid" },
+ { REG_EMPTY, "REG_EMPTY", "empty (sub)expression" },
+ { REG_ASSERT, "REG_ASSERT", "\"can't happen\" -- you found a bug" },
+ { REG_INVARG, "REG_INVARG", "invalid argument to regex routine" },
+ { 0, "", "*** unknown regexp error code ***" }
+};
+
+/*
+ - llvm_regerror - the interface to error numbers
+ = extern size_t llvm_regerror(int, const llvm_regex_t *, char *, size_t);
+ */
+/* ARGSUSED */
+size_t
+llvm_regerror(int errcode, const llvm_regex_t *preg, char *errbuf, size_t errbuf_size)
+{
+ struct rerr *r;
+ size_t len;
+ int target = errcode &~ REG_ITOA;
+ const char *s;
+ char convbuf[50];
+
+ if (errcode == REG_ATOI)
+ s = regatoi(preg, convbuf, sizeof convbuf);
+ else {
+ for (r = rerrs; r->code != 0; r++)
+ if (r->code == target)
+ break;
+
+ if (errcode&REG_ITOA) {
+ if (r->code != 0) {
+ assert(strlen(r->name) < sizeof(convbuf));
+ (void) llvm_strlcpy(convbuf, r->name, sizeof convbuf);
+ } else
+ (void)snprintf(convbuf, sizeof convbuf,
+ "REG_0x%x", target);
+ s = convbuf;
+ } else
+ s = r->explain;
+ }
+
+ len = strlen(s) + 1;
+ if (errbuf_size > 0) {
+ llvm_strlcpy(errbuf, s, errbuf_size);
+ }
+
+ return(len);
+}
+
+/*
+ - regatoi - internal routine to implement REG_ATOI
+ */
+static const char *
+regatoi(const llvm_regex_t *preg, char *localbuf, int localbufsize)
+{
+ struct rerr *r;
+
+ for (r = rerrs; r->code != 0; r++)
+ if (strcmp(r->name, preg->re_endp) == 0)
+ break;
+ if (r->code == 0)
+ return("0");
+
+ (void)snprintf(localbuf, localbufsize, "%d", r->code);
+ return(localbuf);
+}
diff --git a/contrib/llvm/lib/Support/regex2.h b/contrib/llvm/lib/Support/regex2.h
new file mode 100644
index 000000000000..d81bfbc97d02
--- /dev/null
+++ b/contrib/llvm/lib/Support/regex2.h
@@ -0,0 +1,162 @@
+/*-
+ * This code is derived from OpenBSD's libc/regex, original license follows:
+ *
+ * Copyright (c) 1992, 1993, 1994 Henry Spencer.
+ * Copyright (c) 1992, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Henry Spencer.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)regex2.h 8.4 (Berkeley) 3/20/94
+ */
+
+#ifndef LLVM_SUPPORT_REGEX2_H
+#define LLVM_SUPPORT_REGEX2_H
+
+/*
+ * internals of regex_t
+ */
+#define MAGIC1 ((('r'^0200)<<8) | 'e')
+
+/*
+ * The internal representation is a *strip*, a sequence of
+ * operators ending with an endmarker. (Some terminology etc. is a
+ * historical relic of earlier versions which used multiple strips.)
+ * Certain oddities in the representation are there to permit running
+ * the machinery backwards; in particular, any deviation from sequential
+ * flow must be marked at both its source and its destination. Some
+ * fine points:
+ *
+ * - OPLUS_ and O_PLUS are *inside* the loop they create.
+ * - OQUEST_ and O_QUEST are *outside* the bypass they create.
+ * - OCH_ and O_CH are *outside* the multi-way branch they create, while
+ * OOR1 and OOR2 are respectively the end and the beginning of one of
+ * the branches. Note that there is an implicit OOR2 following OCH_
+ * and an implicit OOR1 preceding O_CH.
+ *
+ * In state representations, an operator's bit is on to signify a state
+ * immediately *preceding* "execution" of that operator.
+ */
+typedef unsigned long sop; /* strip operator */
+typedef long sopno;
+#define OPRMASK 0xf8000000LU
+#define OPDMASK 0x07ffffffLU
+#define OPSHIFT ((unsigned)27)
+#define OP(n) ((n)&OPRMASK)
+#define OPND(n) ((n)&OPDMASK)
+#define SOP(op, opnd) ((op)|(opnd))
+/* operators meaning operand */
+/* (back, fwd are offsets) */
+#define OEND (1LU<<OPSHIFT) /* endmarker - */
+#define OCHAR (2LU<<OPSHIFT) /* character unsigned char */
+#define OBOL (3LU<<OPSHIFT) /* left anchor - */
+#define OEOL (4LU<<OPSHIFT) /* right anchor - */
+#define OANY (5LU<<OPSHIFT) /* . - */
+#define OANYOF (6LU<<OPSHIFT) /* [...] set number */
+#define OBACK_ (7LU<<OPSHIFT) /* begin \d paren number */
+#define O_BACK (8LU<<OPSHIFT) /* end \d paren number */
+#define OPLUS_ (9LU<<OPSHIFT) /* + prefix fwd to suffix */
+#define O_PLUS (10LU<<OPSHIFT) /* + suffix back to prefix */
+#define OQUEST_ (11LU<<OPSHIFT) /* ? prefix fwd to suffix */
+#define O_QUEST (12LU<<OPSHIFT) /* ? suffix back to prefix */
+#define OLPAREN (13LU<<OPSHIFT) /* ( fwd to ) */
+#define ORPAREN (14LU<<OPSHIFT) /* ) back to ( */
+#define OCH_ (15LU<<OPSHIFT) /* begin choice fwd to OOR2 */
+#define OOR1 (16LU<<OPSHIFT) /* | pt. 1 back to OOR1 or OCH_ */
+#define OOR2 (17LU<<OPSHIFT) /* | pt. 2 fwd to OOR2 or O_CH */
+#define O_CH (18LU<<OPSHIFT) /* end choice back to OOR1 */
+#define OBOW (19LU<<OPSHIFT) /* begin word - */
+#define OEOW (20LU<<OPSHIFT) /* end word - */
+
+/*
+ * Structure for [] character-set representation. Character sets are
+ * done as bit vectors, grouped 8 to a byte vector for compactness.
+ * The individual set therefore has both a pointer to the byte vector
+ * and a mask to pick out the relevant bit of each byte. A hash code
+ * simplifies testing whether two sets could be identical.
+ *
+ * This will get trickier for multicharacter collating elements. As
+ * preliminary hooks for dealing with such things, we also carry along
+ * a string of multi-character elements, and decide the size of the
+ * vectors at run time.
+ */
+typedef struct {
+ uch *ptr; /* -> uch [csetsize] */
+ uch mask; /* bit within array */
+ uch hash; /* hash code */
+ size_t smultis;
+ char *multis; /* -> char[smulti] ab\0cd\0ef\0\0 */
+} cset;
+/* note that CHadd and CHsub are unsafe, and CHIN doesn't yield 0/1 */
+#define CHadd(cs, c) ((cs)->ptr[(uch)(c)] |= (cs)->mask, (cs)->hash += (c))
+#define CHsub(cs, c) ((cs)->ptr[(uch)(c)] &= ~(cs)->mask, (cs)->hash -= (c))
+#define CHIN(cs, c) ((cs)->ptr[(uch)(c)] & (cs)->mask)
+#define MCadd(p, cs, cp) mcadd(p, cs, cp) /* llvm_regcomp() internal fns */
+#define MCsub(p, cs, cp) mcsub(p, cs, cp)
+#define MCin(p, cs, cp) mcin(p, cs, cp)
+
+/* stuff for character categories */
+typedef unsigned char cat_t;
+
+/*
+ * main compiled-expression structure
+ */
+struct re_guts {
+ int magic;
+# define MAGIC2 ((('R'^0200)<<8)|'E')
+ sop *strip; /* malloced area for strip */
+ int csetsize; /* number of bits in a cset vector */
+ int ncsets; /* number of csets in use */
+ cset *sets; /* -> cset [ncsets] */
+ uch *setbits; /* -> uch[csetsize][ncsets/CHAR_BIT] */
+ int cflags; /* copy of llvm_regcomp() cflags argument */
+ sopno nstates; /* = number of sops */
+ sopno firststate; /* the initial OEND (normally 0) */
+ sopno laststate; /* the final OEND */
+ int iflags; /* internal flags */
+# define USEBOL 01 /* used ^ */
+# define USEEOL 02 /* used $ */
+# define REGEX_BAD 04 /* something wrong */
+ int nbol; /* number of ^ used */
+ int neol; /* number of $ used */
+ int ncategories; /* how many character categories */
+ cat_t *categories; /* ->catspace[-CHAR_MIN] */
+ char *must; /* match must contain this string */
+ int mlen; /* length of must */
+ size_t nsub; /* copy of re_nsub */
+ int backrefs; /* does it use back references? */
+ sopno nplus; /* how deep does it nest +s? */
+ /* catspace must be last */
+ cat_t catspace[1]; /* actually [NC] */
+};
+
+/* misc utilities */
+#define OUT (CHAR_MAX+1) /* a non-character value */
+#define ISWORD(c) (isalnum(c&0xff) || (c) == '_')
+
+#endif
diff --git a/contrib/llvm/lib/Support/regex_impl.h b/contrib/llvm/lib/Support/regex_impl.h
new file mode 100644
index 000000000000..f8296c9ff75e
--- /dev/null
+++ b/contrib/llvm/lib/Support/regex_impl.h
@@ -0,0 +1,108 @@
+/*-
+ * This code is derived from OpenBSD's libc/regex, original license follows:
+ *
+ * Copyright (c) 1992 Henry Spencer.
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Henry Spencer of the University of Toronto.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)regex.h 8.1 (Berkeley) 6/2/93
+ */
+
+#ifndef _REGEX_H_
+#define _REGEX_H_
+
+#include <sys/types.h>
+typedef off_t llvm_regoff_t;
+typedef struct {
+ llvm_regoff_t rm_so; /* start of match */
+ llvm_regoff_t rm_eo; /* end of match */
+} llvm_regmatch_t;
+
+typedef struct llvm_regex {
+ int re_magic;
+ size_t re_nsub; /* number of parenthesized subexpressions */
+ const char *re_endp; /* end pointer for REG_PEND */
+ struct re_guts *re_g; /* none of your business :-) */
+} llvm_regex_t;
+
+/* llvm_regcomp() flags */
+#define REG_BASIC 0000
+#define REG_EXTENDED 0001
+#define REG_ICASE 0002
+#define REG_NOSUB 0004
+#define REG_NEWLINE 0010
+#define REG_NOSPEC 0020
+#define REG_PEND 0040
+#define REG_DUMP 0200
+
+/* llvm_regerror() flags */
+#define REG_NOMATCH 1
+#define REG_BADPAT 2
+#define REG_ECOLLATE 3
+#define REG_ECTYPE 4
+#define REG_EESCAPE 5
+#define REG_ESUBREG 6
+#define REG_EBRACK 7
+#define REG_EPAREN 8
+#define REG_EBRACE 9
+#define REG_BADBR 10
+#define REG_ERANGE 11
+#define REG_ESPACE 12
+#define REG_BADRPT 13
+#define REG_EMPTY 14
+#define REG_ASSERT 15
+#define REG_INVARG 16
+#define REG_ATOI 255 /* convert name to number (!) */
+#define REG_ITOA 0400 /* convert number to name (!) */
+
+/* llvm_regexec() flags */
+#define REG_NOTBOL 00001
+#define REG_NOTEOL 00002
+#define REG_STARTEND 00004
+#define REG_TRACE 00400 /* tracing of execution */
+#define REG_LARGE 01000 /* force large representation */
+#define REG_BACKR 02000 /* force use of backref code */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int llvm_regcomp(llvm_regex_t *, const char *, int);
+size_t llvm_regerror(int, const llvm_regex_t *, char *, size_t);
+int llvm_regexec(const llvm_regex_t *, const char *, size_t,
+ llvm_regmatch_t [], int);
+void llvm_regfree(llvm_regex_t *);
+size_t llvm_strlcpy(char *dst, const char *src, size_t siz);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !_REGEX_H_ */
diff --git a/contrib/llvm/lib/Support/regexec.c b/contrib/llvm/lib/Support/regexec.c
new file mode 100644
index 000000000000..bd5e72d4c522
--- /dev/null
+++ b/contrib/llvm/lib/Support/regexec.c
@@ -0,0 +1,162 @@
+/*-
+ * This code is derived from OpenBSD's libc/regex, original license follows:
+ *
+ * Copyright (c) 1992, 1993, 1994 Henry Spencer.
+ * Copyright (c) 1992, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Henry Spencer.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)regexec.c 8.3 (Berkeley) 3/20/94
+ */
+
+/*
+ * the outer shell of llvm_regexec()
+ *
+ * This file includes engine.inc *twice*, after muchos fiddling with the
+ * macros that code uses. This lets the same code operate on two different
+ * representations for state sets.
+ */
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include <ctype.h>
+#include "regex_impl.h"
+
+#include "regutils.h"
+#include "regex2.h"
+
+/* macros for manipulating states, small version */
+/* FIXME: 'states' is assumed as 'long' on small version. */
+#define states1 long /* for later use in llvm_regexec() decision */
+#define states states1
+#define CLEAR(v) ((v) = 0)
+#define SET0(v, n) ((v) &= ~((unsigned long)1 << (n)))
+#define SET1(v, n) ((v) |= (unsigned long)1 << (n))
+#define ISSET(v, n) (((v) & ((unsigned long)1 << (n))) != 0)
+#define ASSIGN(d, s) ((d) = (s))
+#define EQ(a, b) ((a) == (b))
+#define STATEVARS long dummy /* dummy version */
+#define STATESETUP(m, n) /* nothing */
+#define STATETEARDOWN(m) /* nothing */
+#define SETUP(v) ((v) = 0)
+#define onestate long
+#define INIT(o, n) ((o) = (unsigned long)1 << (n))
+#define INC(o) ((o) = (unsigned long)(o) << 1)
+#define ISSTATEIN(v, o) (((v) & (o)) != 0)
+/* some abbreviations; note that some of these know variable names! */
+/* do "if I'm here, I can also be there" etc without branches */
+#define FWD(dst, src, n) ((dst) |= ((unsigned long)(src)&(here)) << (n))
+#define BACK(dst, src, n) ((dst) |= ((unsigned long)(src)&(here)) >> (n))
+#define ISSETBACK(v, n) (((v) & ((unsigned long)here >> (n))) != 0)
+/* function names */
+#define SNAMES /* engine.inc looks after details */
+
+#include "regengine.inc"
+
+/* now undo things */
+#undef states
+#undef CLEAR
+#undef SET0
+#undef SET1
+#undef ISSET
+#undef ASSIGN
+#undef EQ
+#undef STATEVARS
+#undef STATESETUP
+#undef STATETEARDOWN
+#undef SETUP
+#undef onestate
+#undef INIT
+#undef INC
+#undef ISSTATEIN
+#undef FWD
+#undef BACK
+#undef ISSETBACK
+#undef SNAMES
+
+/* macros for manipulating states, large version */
+#define states char *
+#define CLEAR(v) memset(v, 0, m->g->nstates)
+#define SET0(v, n) ((v)[n] = 0)
+#define SET1(v, n) ((v)[n] = 1)
+#define ISSET(v, n) ((v)[n])
+#define ASSIGN(d, s) memmove(d, s, m->g->nstates)
+#define EQ(a, b) (memcmp(a, b, m->g->nstates) == 0)
+#define STATEVARS long vn; char *space
+#define STATESETUP(m, nv) { (m)->space = malloc((nv)*(m)->g->nstates); \
+ if ((m)->space == NULL) return(REG_ESPACE); \
+ (m)->vn = 0; }
+#define STATETEARDOWN(m) { free((m)->space); }
+#define SETUP(v) ((v) = &m->space[m->vn++ * m->g->nstates])
+#define onestate long
+#define INIT(o, n) ((o) = (n))
+#define INC(o) ((o)++)
+#define ISSTATEIN(v, o) ((v)[o])
+/* some abbreviations; note that some of these know variable names! */
+/* do "if I'm here, I can also be there" etc without branches */
+#define FWD(dst, src, n) ((dst)[here+(n)] |= (src)[here])
+#define BACK(dst, src, n) ((dst)[here-(n)] |= (src)[here])
+#define ISSETBACK(v, n) ((v)[here - (n)])
+/* function names */
+#define LNAMES /* flag */
+
+#include "regengine.inc"
+
+/*
+ - llvm_regexec - interface for matching
+ *
+ * We put this here so we can exploit knowledge of the state representation
+ * when choosing which matcher to call. Also, by this point the matchers
+ * have been prototyped.
+ */
+int /* 0 success, REG_NOMATCH failure */
+llvm_regexec(const llvm_regex_t *preg, const char *string, size_t nmatch,
+ llvm_regmatch_t pmatch[], int eflags)
+{
+ struct re_guts *g = preg->re_g;
+#ifdef REDEBUG
+# define GOODFLAGS(f) (f)
+#else
+# define GOODFLAGS(f) ((f)&(REG_NOTBOL|REG_NOTEOL|REG_STARTEND))
+#endif
+
+ if (preg->re_magic != MAGIC1 || g->magic != MAGIC2)
+ return(REG_BADPAT);
+ assert(!(g->iflags&REGEX_BAD));
+ if (g->iflags&REGEX_BAD) /* backstop for no-debug case */
+ return(REG_BADPAT);
+ eflags = GOODFLAGS(eflags);
+
+ if (g->nstates <= (long)(CHAR_BIT*sizeof(states1)) && !(eflags&REG_LARGE))
+ return(smatcher(g, string, nmatch, pmatch, eflags));
+ else
+ return(lmatcher(g, string, nmatch, pmatch, eflags));
+}
diff --git a/contrib/llvm/lib/Support/regfree.c b/contrib/llvm/lib/Support/regfree.c
new file mode 100644
index 000000000000..dc2b4af90fa7
--- /dev/null
+++ b/contrib/llvm/lib/Support/regfree.c
@@ -0,0 +1,72 @@
+/*-
+ * This code is derived from OpenBSD's libc/regex, original license follows:
+ *
+ * Copyright (c) 1992, 1993, 1994 Henry Spencer.
+ * Copyright (c) 1992, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Henry Spencer.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)regfree.c 8.3 (Berkeley) 3/20/94
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "regex_impl.h"
+
+#include "regutils.h"
+#include "regex2.h"
+
+/*
+ - llvm_regfree - free everything
+ */
+void
+llvm_regfree(llvm_regex_t *preg)
+{
+ struct re_guts *g;
+
+ if (preg->re_magic != MAGIC1) /* oops */
+ return; /* nice to complain, but hard */
+
+ g = preg->re_g;
+ if (g == NULL || g->magic != MAGIC2) /* oops again */
+ return;
+ preg->re_magic = 0; /* mark it invalid */
+ g->magic = 0; /* mark it invalid */
+
+ if (g->strip != NULL)
+ free((char *)g->strip);
+ if (g->sets != NULL)
+ free((char *)g->sets);
+ if (g->setbits != NULL)
+ free((char *)g->setbits);
+ if (g->must != NULL)
+ free(g->must);
+ free((char *)g);
+}
diff --git a/contrib/llvm/lib/Support/regstrlcpy.c b/contrib/llvm/lib/Support/regstrlcpy.c
new file mode 100644
index 000000000000..8b68afdf75f1
--- /dev/null
+++ b/contrib/llvm/lib/Support/regstrlcpy.c
@@ -0,0 +1,52 @@
+/*
+ * This code is derived from OpenBSD's libc, original license follows:
+ *
+ * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+#include <string.h>
+
+#include "regex_impl.h"
+/*
+ * Copy src to string dst of size siz. At most siz-1 characters
+ * will be copied. Always NUL terminates (unless siz == 0).
+ * Returns strlen(src); if retval >= siz, truncation occurred.
+ */
+size_t
+llvm_strlcpy(char *dst, const char *src, size_t siz)
+{
+ char *d = dst;
+ const char *s = src;
+ size_t n = siz;
+
+ /* Copy as many bytes as will fit */
+ if (n != 0) {
+ while (--n != 0) {
+ if ((*d++ = *s++) == '\0')
+ break;
+ }
+ }
+
+ /* Not enough room in dst, add NUL and traverse rest of src */
+ if (n == 0) {
+ if (siz != 0)
+ *d = '\0'; /* NUL-terminate dst */
+ while (*s++)
+ ;
+ }
+
+ return(s - src - 1); /* count does not include NUL */
+}
diff --git a/contrib/llvm/lib/Support/regutils.h b/contrib/llvm/lib/Support/regutils.h
new file mode 100644
index 000000000000..49a975cd2703
--- /dev/null
+++ b/contrib/llvm/lib/Support/regutils.h
@@ -0,0 +1,58 @@
+/*-
+ * This code is derived from OpenBSD's libc/regex, original license follows:
+ *
+ * Copyright (c) 1992, 1993, 1994 Henry Spencer.
+ * Copyright (c) 1992, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Henry Spencer.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)utils.h 8.3 (Berkeley) 3/20/94
+ */
+
+#ifndef LLVM_SUPPORT_REGUTILS_H
+#define LLVM_SUPPORT_REGUTILS_H
+
+/* utility definitions */
+#define NC (CHAR_MAX - CHAR_MIN + 1)
+typedef unsigned char uch;
+
+/* switch off assertions (if not already off) if no REDEBUG */
+#ifndef REDEBUG
+#ifndef NDEBUG
+#define NDEBUG /* no assertions please */
+#endif
+#endif
+#include <assert.h>
+
+/* for old systems with bcopy() but no memmove() */
+#ifdef USEBCOPY
+#define memmove(d, s, c) bcopy(s, d, c)
+#endif
+
+#endif